diff --git a/src/helpers/tests/validator.test.ts b/src/helpers/tests/validator.test.ts index 8465095..d1b2a92 100644 --- a/src/helpers/tests/validator.test.ts +++ b/src/helpers/tests/validator.test.ts @@ -1,3 +1,4 @@ +import {MessageType} from '../constants'; import * as validator from '../validator'; describe('isNumeric', () => { @@ -324,56 +325,63 @@ describe('validateMessage', () => { }); test('should return false for an empty string rich message', () => { - expect(validator.validateMessage('', 2).success).toBe(false); + expect(validator.validateMessage('', MessageType.Rich).success).toBe(false); }); - test('should return false for an empty string signal message', () => { - expect(validator.validateMessage('', 3).success).toBe(false); + test('should return true for an empty string signal message', () => { + expect(validator.validateMessage('', MessageType.Signal).success).toBe( + true + ); }); - test('should return false for an empty json rich message', () => { - expect(validator.validateMessage('{}', 2).success).toBe(false); + test('should return true for an empty json rich message', () => { + expect(validator.validateMessage('{}', MessageType.Rich).success).toBe( + true + ); }); test('should return false for an empty json signal message', () => { - expect(validator.validateMessage('{}', 3).success).toBe(false); + expect(validator.validateMessage('{}', MessageType.Signal).success).toBe( + true + ); }); test('should return true for a json rich message with the given amount', () => { - expect(validator.validateMessage('{"amount": "0.13"}', 2).success).toBe( - true - ); + expect( + validator.validateMessage('{"amount": "0.13"}', MessageType.Rich).success + ).toBe(true); }); test('should return true for a json signal message with the given amount', () => { - expect(validator.validateMessage('{"amount": "0.13"}', 3).success).toBe( - true - ); + expect( + validator.validateMessage('{"amount": "0.13"}', MessageType.Signal) + .success + ).toBe(true); }); - test('should return false for a json rich message with upercase coin name', () => { + test('should return false for a json rich message with uppercase coin name', () => { expect( validator.validateMessage( '{"amount": "0.13", "type": "ETH_transaction"}', - 2 + MessageType.Rich ).success ).toBe(false); }); - test('should return false for a json signal message with upercase coin name', () => { + test('should return true for a json signal message with uppercase coin name', () => { expect( validator.validateMessage( '{"amount": "0.13", "type": "ETH_transaction"}', - 3 + MessageType.Signal ).success - ).toBe(false); + ).toBe(true); }); test('should return true for a json rich message with lowercase coin name', () => { expect( validator.validateMessage( '{"amount": "0.13", "type": "eth_transaction"}', - 2 + MessageType.Rich ).success ).toBe(true); }); @@ -382,10 +390,31 @@ describe('validateMessage', () => { expect( validator.validateMessage( '{"amount": "0.13", "type": "eth_transaction"}', - 3 + MessageType.Signal + ).success + ).toBe(true); + }); + + test('should return true for a push notification signal message', () => { + expect( + validator.validateMessage( + '{"token": "DeviceToken","provider":"apns","action":"add"}', + MessageType.Signal ).success ).toBe(true); }); + + test('should allow a string signal message', () => { + expect( + validator.validateMessage('not a json string', MessageType.Signal).success + ).toBe(true); + }); + + test('should NOT allow a string rich message', () => { + expect( + validator.validateMessage('not a json string', MessageType.Rich).success + ).toBe(false); + }); }); describe('isDelegateName', () => { diff --git a/src/helpers/validator.ts b/src/helpers/validator.ts index 852ade0..3068126 100644 --- a/src/helpers/validator.ts +++ b/src/helpers/validator.ts @@ -15,7 +15,7 @@ export const isNumeric = (str: unknown): str is string => export const parseJsonSafe = (json: string) => { try { - const result = JSON.parse(json); + const result = JSON.parse(json) as unknown; return { result, @@ -86,33 +86,37 @@ export const validateMessage = ( }; } - if ([MessageType.Rich, MessageType.Signal].includes(messageType)) { + if ([MessageType.Rich].includes(messageType)) { const data = parseJsonSafe(message); const {success, result} = data; - if (!success || typeof result !== 'object') { + if (!success || typeof result !== 'object' || result === null) { return { success: false, error: "For rich and signal message, 'message' should be a JSON string", }; } - const typeInLowerCase = result.type?.toLowerCase(); - if ( - typeInLowerCase?.includes('_transaction') && - typeInLowerCase !== result.type - ) { - return { - success: false, - error: "Value '_transaction' must be in lower case", - }; - } - - if (typeof result.amount !== 'string' || !isStringAmount(result.amount)) { - return { - success: false, - error: "Field 'amount' must be a string, representing a number", - }; + if ('type' in result && typeof result.type === 'string') { + const typeInLowerCase = result.type.toLowerCase(); + if (typeInLowerCase.endsWith('_transaction')) { + if (typeInLowerCase !== result.type) { + return { + success: false, + error: "Value '_transaction' must be in lower case", + }; + } + + if ( + 'amount' in result && + (typeof result.amount !== 'string' || !isStringAmount(result.amount)) + ) { + return { + success: false, + error: "Field 'amount' must be a string, representing a number", + }; + } + } } }