|
1 | 1 | import should from 'should'; |
| 2 | +import { CosmosUtils } from '@bitgo/abstract-cosmos'; |
2 | 3 |
|
3 | 4 | import utils from '../../src/lib/utils'; |
4 | 5 | import * as testData from '../resources/hash'; |
5 | | -import { blockHash, txIds } from '../resources/hash'; |
| 6 | +import { blockHash, txIds, TEST_CONTRACT_CALL } from '../resources/hash'; |
6 | 7 |
|
7 | 8 | describe('utils', () => { |
8 | 9 | it('should validate block hash correctly', () => { |
@@ -44,4 +45,75 @@ describe('utils', () => { |
44 | 45 | 'transactionBuilder: validateAmount: Invalid denom: ' + testData.coinAmounts.amount5.denom |
45 | 46 | ); |
46 | 47 | }); |
| 48 | + |
| 49 | + describe('decodeMsg', () => { |
| 50 | + it('should detect valid base64-encoded group proposal', () => { |
| 51 | + const result = CosmosUtils.decodeMsg(TEST_CONTRACT_CALL.encodedProposal); |
| 52 | + |
| 53 | + should.exist(result.typeUrl); |
| 54 | + if (result.typeUrl) { |
| 55 | + result.typeUrl.should.equal('/cosmos.group.v1.MsgSubmitProposal'); |
| 56 | + } |
| 57 | + should.not.exist(result.error); |
| 58 | + }); |
| 59 | + |
| 60 | + it('should reject invalid base64 string', () => { |
| 61 | + const result = CosmosUtils.decodeMsg('not-valid-base64!!!'); |
| 62 | + |
| 63 | + should.not.exist(result.typeUrl); |
| 64 | + should.exist(result.error); |
| 65 | + }); |
| 66 | + |
| 67 | + it('should reject valid base64 but invalid protobuf', () => { |
| 68 | + const result = CosmosUtils.decodeMsg(Buffer.from('random data').toString('base64')); |
| 69 | + |
| 70 | + should.not.exist(result.typeUrl); |
| 71 | + should.exist(result.error); |
| 72 | + }); |
| 73 | + |
| 74 | + it('should reject hex-encoded contract call data', () => { |
| 75 | + const result = CosmosUtils.decodeMsg('7b22696e6372656d656e74223a7b7d7d'); |
| 76 | + |
| 77 | + should.not.exist(result.typeUrl); |
| 78 | + }); |
| 79 | + |
| 80 | + it('should accept Uint8Array input', () => { |
| 81 | + const bytes = Buffer.from(TEST_CONTRACT_CALL.encodedProposal, 'base64'); |
| 82 | + const result = CosmosUtils.decodeMsg(bytes); |
| 83 | + |
| 84 | + should.exist(result.typeUrl); |
| 85 | + if (result.typeUrl) { |
| 86 | + result.typeUrl.should.equal('/cosmos.group.v1.MsgSubmitProposal'); |
| 87 | + } |
| 88 | + }); |
| 89 | + }); |
| 90 | + |
| 91 | + describe('isGroupProposal', () => { |
| 92 | + it('should return true when msg contains a group proposal', () => { |
| 93 | + const message = { |
| 94 | + sender: 'tp1tazefwk2e372fy2jq08w6lztg9yrrvс490r2gp4vt8d0fchlrfqqyahg0u', |
| 95 | + contract: 'tp12nyn83ynewtmpkw32wq6dg83wx8nqpat65gcld', |
| 96 | + msg: Buffer.from(TEST_CONTRACT_CALL.encodedProposal, 'base64'), |
| 97 | + }; |
| 98 | + should.equal(CosmosUtils.isGroupProposal(message), true); |
| 99 | + }); |
| 100 | + |
| 101 | + it('should return false when msg contains regular contract call data', () => { |
| 102 | + const message = { |
| 103 | + sender: 'tp1tazefwk2e372fy2jq08w6lztg9yrrvс490r2gp4vt8d0fchlrfqqyahg0u', |
| 104 | + contract: 'tp12nyn83ynewtmpkw32wq6dg83wx8nqpat65gcld', |
| 105 | + msg: Buffer.from(JSON.stringify({ increment: {} })), |
| 106 | + }; |
| 107 | + should.equal(CosmosUtils.isGroupProposal(message), false); |
| 108 | + }); |
| 109 | + |
| 110 | + it('should return false when msg is empty', () => { |
| 111 | + const message = { |
| 112 | + sender: 'tp1tazefwk2e372fy2jq08w6lztg9yrrvс490r2gp4vt8d0fchlrfqqyahg0u', |
| 113 | + contract: 'tp12nyn83ynewtmpkw32wq6dg83wx8nqpat65gcld', |
| 114 | + msg: new Uint8Array(0), |
| 115 | + }; |
| 116 | + should.equal(CosmosUtils.isGroupProposal(message), false); |
| 117 | + }); |
| 118 | + }); |
47 | 119 | }); |
0 commit comments