@@ -23,13 +23,17 @@ describe('ProposalActionsDecoder utils', () => {
2323 const validateAddressSpy = jest . spyOn ( addressUtils , 'isAddress' ) ;
2424 const validateBytesSpy = jest . spyOn ( proposalActionsDecoderUtils , 'validateBytes' ) ;
2525 const validateUnsignedNumberSpy = jest . spyOn ( proposalActionsDecoderUtils , 'validateUnsignedNumber' ) ;
26+ const validateSignedNumberSpy = jest . spyOn ( proposalActionsDecoderUtils , 'validateSignedNumber' ) ;
27+ const validateNumberRangeSpy = jest . spyOn ( proposalActionsDecoderUtils , 'validateNumberRange' ) ;
2628
2729 afterEach ( ( ) => {
2830 validateRequiredSpy . mockReset ( ) ;
2931 validateBooleanSpy . mockReset ( ) ;
3032 validateAddressSpy . mockReset ( ) ;
3133 validateBytesSpy . mockReset ( ) ;
3234 validateUnsignedNumberSpy . mockReset ( ) ;
35+ validateSignedNumberSpy . mockReset ( ) ;
36+ validateNumberRangeSpy . mockReset ( ) ;
3337 } ) ;
3438
3539 afterAll ( ( ) => {
@@ -38,6 +42,8 @@ describe('ProposalActionsDecoder utils', () => {
3842 validateAddressSpy . mockRestore ( ) ;
3943 validateBytesSpy . mockRestore ( ) ;
4044 validateUnsignedNumberSpy . mockRestore ( ) ;
45+ validateSignedNumberSpy . mockRestore ( ) ;
46+ validateNumberRangeSpy . mockRestore ( ) ;
4147 } ) ;
4248
4349 const buildValidateValueParams = ( params ?: Partial < IGetValidationRulesParams > ) : IGetValidationRulesParams => ( {
@@ -49,6 +55,8 @@ describe('ProposalActionsDecoder utils', () => {
4955 address : ( ) => 'address-error' ,
5056 bytes : ( ) => 'bytes-error' ,
5157 unsignedNumber : ( ) => 'uint-error' ,
58+ signedNumber : ( ) => 'int-error' ,
59+ numberRange : ( ) => 'range-error' ,
5260 } ,
5361 ...params ,
5462 } ) ;
@@ -119,6 +127,38 @@ describe('ProposalActionsDecoder utils', () => {
119127 const params = buildValidateValueParams ( { type : 'uint16' } ) ;
120128 expect ( proposalActionsDecoderUtils . validateValue ( '10' , params ) ) . toBeTruthy ( ) ;
121129 } ) ;
130+
131+ it ( 'returns range error message when value has uint type and does not fit its bit-width' , ( ) => {
132+ validateUnsignedNumberSpy . mockReturnValue ( true ) ;
133+ validateNumberRangeSpy . mockReturnValue ( false ) ;
134+ const params = buildValidateValueParams ( { type : 'uint8' } ) ;
135+ expect ( proposalActionsDecoderUtils . validateValue ( '300' , params ) ) . toEqual ( 'range-error' ) ;
136+ } ) ;
137+
138+ it ( 'returns int error message when value has int type and is not valid' , ( ) => {
139+ validateSignedNumberSpy . mockReturnValue ( false ) ;
140+ const params = buildValidateValueParams ( { type : 'int256' } ) ;
141+ expect ( proposalActionsDecoderUtils . validateValue ( '-' , params ) ) . toEqual ( 'int-error' ) ;
142+ } ) ;
143+
144+ it ( 'returns range error message when value has int type and does not fit its bit-width' , ( ) => {
145+ validateSignedNumberSpy . mockReturnValue ( true ) ;
146+ validateNumberRangeSpy . mockReturnValue ( false ) ;
147+ const params = buildValidateValueParams ( { type : 'int8' } ) ;
148+ expect ( proposalActionsDecoderUtils . validateValue ( '-129' , params ) ) . toEqual ( 'range-error' ) ;
149+ } ) ;
150+
151+ it ( 'returns true when value has int type and is valid' , ( ) => {
152+ const params = buildValidateValueParams ( { type : 'int32' } ) ;
153+ expect ( proposalActionsDecoderUtils . validateValue ( '-5' , params ) ) . toBeTruthy ( ) ;
154+ } ) ;
155+
156+ it ( 'validates addresses with strict checksum validation' , ( ) => {
157+ const value = '0x0B2a45c2bCb56dA84920585f985087973c715364' ;
158+ const params = buildValidateValueParams ( { type : 'address' } ) ;
159+ proposalActionsDecoderUtils . validateValue ( value , params ) ;
160+ expect ( validateAddressSpy ) . toHaveBeenCalledWith ( value , { strict : true } ) ;
161+ } ) ;
122162 } ) ;
123163
124164 describe ( 'validateRequired' , ( ) => {
@@ -179,6 +219,7 @@ describe('ProposalActionsDecoder utils', () => {
179219 describe ( 'validateUnsignedNumber' , ( ) => {
180220 it ( 'returns false when value is not a valid uint value' , ( ) => {
181221 expect ( proposalActionsDecoderUtils . validateUnsignedNumber ( undefined ) ) . toBeFalsy ( ) ;
222+ expect ( proposalActionsDecoderUtils . validateUnsignedNumber ( '' ) ) . toBeFalsy ( ) ;
182223 expect ( proposalActionsDecoderUtils . validateUnsignedNumber ( '-1' ) ) . toBeFalsy ( ) ;
183224 expect ( proposalActionsDecoderUtils . validateUnsignedNumber ( '79.11' ) ) . toBeFalsy ( ) ;
184225 } ) ;
@@ -189,6 +230,52 @@ describe('ProposalActionsDecoder utils', () => {
189230 } ) ;
190231 } ) ;
191232
233+ describe ( 'validateSignedNumber' , ( ) => {
234+ it ( 'returns false when value is not a valid int value' , ( ) => {
235+ expect ( proposalActionsDecoderUtils . validateSignedNumber ( undefined ) ) . toBeFalsy ( ) ;
236+ expect ( proposalActionsDecoderUtils . validateSignedNumber ( '' ) ) . toBeFalsy ( ) ;
237+ expect ( proposalActionsDecoderUtils . validateSignedNumber ( '-' ) ) . toBeFalsy ( ) ;
238+ expect ( proposalActionsDecoderUtils . validateSignedNumber ( '79.11' ) ) . toBeFalsy ( ) ;
239+ expect ( proposalActionsDecoderUtils . validateSignedNumber ( '1-2' ) ) . toBeFalsy ( ) ;
240+ } ) ;
241+
242+ it ( 'returns true when value is a valid int value' , ( ) => {
243+ expect ( proposalActionsDecoderUtils . validateSignedNumber ( '-1' ) ) . toBeTruthy ( ) ;
244+ expect ( proposalActionsDecoderUtils . validateSignedNumber ( '0' ) ) . toBeTruthy ( ) ;
245+ expect ( proposalActionsDecoderUtils . validateSignedNumber ( '8645312' ) ) . toBeTruthy ( ) ;
246+ } ) ;
247+ } ) ;
248+
249+ describe ( 'validateNumberRange' , ( ) => {
250+ it ( 'returns false when value does not fit the bit-width of the type' , ( ) => {
251+ expect ( proposalActionsDecoderUtils . validateNumberRange ( 'uint8' , '256' ) ) . toBeFalsy ( ) ;
252+ expect ( proposalActionsDecoderUtils . validateNumberRange ( 'uint16' , '65536' ) ) . toBeFalsy ( ) ;
253+ expect ( proposalActionsDecoderUtils . validateNumberRange ( 'int8' , '128' ) ) . toBeFalsy ( ) ;
254+ expect ( proposalActionsDecoderUtils . validateNumberRange ( 'int8' , '-129' ) ) . toBeFalsy ( ) ;
255+ expect ( proposalActionsDecoderUtils . validateNumberRange ( 'uint' , '-1' ) ) . toBeFalsy ( ) ;
256+ expect ( proposalActionsDecoderUtils . validateNumberRange ( 'uint256' , ( 2n ** 256n ) . toString ( ) ) ) . toBeFalsy ( ) ;
257+ } ) ;
258+
259+ it ( 'returns true when value fits the bit-width of the type' , ( ) => {
260+ expect ( proposalActionsDecoderUtils . validateNumberRange ( 'uint8' , '255' ) ) . toBeTruthy ( ) ;
261+ expect ( proposalActionsDecoderUtils . validateNumberRange ( 'int8' , '-128' ) ) . toBeTruthy ( ) ;
262+ expect ( proposalActionsDecoderUtils . validateNumberRange ( 'int8' , '127' ) ) . toBeTruthy ( ) ;
263+ expect ( proposalActionsDecoderUtils . validateNumberRange ( 'uint' , ( 2n ** 256n - 1n ) . toString ( ) ) ) . toBeTruthy ( ) ;
264+ expect ( proposalActionsDecoderUtils . validateNumberRange ( 'int' , ( - ( 2n ** 255n ) ) . toString ( ) ) ) . toBeTruthy ( ) ;
265+ } ) ;
266+
267+ it ( 'returns false when value cannot be parsed as an integer' , ( ) => {
268+ expect ( proposalActionsDecoderUtils . validateNumberRange ( 'uint8' , 'abc' ) ) . toBeFalsy ( ) ;
269+ } ) ;
270+
271+ it ( 'returns false when the type has an invalid bit-width' , ( ) => {
272+ expect ( proposalActionsDecoderUtils . validateNumberRange ( 'uint0' , '0' ) ) . toBeFalsy ( ) ;
273+ expect ( proposalActionsDecoderUtils . validateNumberRange ( 'uint12' , '0' ) ) . toBeFalsy ( ) ;
274+ expect ( proposalActionsDecoderUtils . validateNumberRange ( 'uint264' , '0' ) ) . toBeFalsy ( ) ;
275+ expect ( proposalActionsDecoderUtils . validateNumberRange ( 'int9999' , '0' ) ) . toBeFalsy ( ) ;
276+ } ) ;
277+ } ) ;
278+
192279 describe ( 'isArrayType' , ( ) => {
193280 it ( 'returns false when type is not an array type' , ( ) => {
194281 expect ( proposalActionsDecoderUtils . isArrayType ( 'uint' ) ) . toBeFalsy ( ) ;
0 commit comments