diff --git a/src/datasources/targeted-messaging/entities/__tests__/outreach-file.entity.spec.ts b/src/datasources/targeted-messaging/entities/__tests__/outreach-file.entity.spec.ts new file mode 100644 index 0000000000..12612c2c1a --- /dev/null +++ b/src/datasources/targeted-messaging/entities/__tests__/outreach-file.entity.spec.ts @@ -0,0 +1,115 @@ +import { faker } from '@faker-js/faker'; +import { outreachFileBuilder } from '@/datasources/targeted-messaging/entities/__tests__/outreach-file.builder'; +import { OutreachFileSchema } from '@/datasources/targeted-messaging/entities/outreach-file.entity'; +import { getAddress } from 'viem'; + +describe('OutreachFileSchema', () => { + it('should validate an OutreachFile', () => { + const outreachFile = outreachFileBuilder().build(); + + const result = OutreachFileSchema.safeParse(outreachFile); + + expect(result.success).toBe(true); + }); + + it('should throw if campaign_id is less than 1', () => { + const outreachFile = outreachFileBuilder().with('campaign_id', 0).build(); + + const result = OutreachFileSchema.safeParse(outreachFile); + + expect(!result.success && result.error.issues).toStrictEqual([ + { + code: 'too_small', + exact: false, + inclusive: true, + message: 'Number must be greater than or equal to 1', + minimum: 1, + path: ['campaign_id'], + type: 'number', + }, + ]); + }); + + it.each(['start_date' as const, 'end_date' as const])( + 'should coerce %s to a date', + (key) => { + const date = faker.date.recent(); + const outreachFile = outreachFileBuilder() + .with(key, date.toString() as unknown as Date) + .build(); + + const result = OutreachFileSchema.safeParse(outreachFile); + + // Zod coerces the date to the nearest millisecond + date.setMilliseconds(0); + expect(result.success && result.data[key]).toStrictEqual(date); + }, + ); + + it('should checksum the safe_addresses', () => { + const nonChecksummedAddresses = faker.helpers.multiple( + () => faker.finance.ethereumAddress().toLowerCase(), + { count: { min: 2, max: 5 } }, + ); + const outreachFile = outreachFileBuilder() + .with('safe_addresses', nonChecksummedAddresses as Array<`0x${string}`>) + .build(); + + const result = OutreachFileSchema.safeParse(outreachFile); + + expect(result.success && result.data.safe_addresses).toStrictEqual( + nonChecksummedAddresses.map((address) => { + return getAddress(address); + }), + ); + }); + + it('should throw if the OutreachFile is invalid', () => { + const outreachFile = { + invalid: 'outreachFile', + }; + + const result = OutreachFileSchema.safeParse(outreachFile); + + expect(!result.success && result.error.issues).toStrictEqual([ + { + code: 'invalid_type', + expected: 'number', + message: 'Required', + path: ['campaign_id'], + received: 'undefined', + }, + { + code: 'invalid_type', + expected: 'string', + message: 'Required', + path: ['campaign_name'], + received: 'undefined', + }, + { + code: 'invalid_type', + expected: 'string', + message: 'Required', + path: ['team_name'], + received: 'undefined', + }, + { + code: 'invalid_date', + message: 'Invalid date', + path: ['start_date'], + }, + { + code: 'invalid_date', + message: 'Invalid date', + path: ['end_date'], + }, + { + code: 'invalid_type', + expected: 'array', + message: 'Required', + path: ['safe_addresses'], + received: 'undefined', + }, + ]); + }); +}); diff --git a/src/datasources/targeted-messaging/entities/outreach-file.entity.ts b/src/datasources/targeted-messaging/entities/outreach-file.entity.ts index 442259cbf3..31cefb364b 100644 --- a/src/datasources/targeted-messaging/entities/outreach-file.entity.ts +++ b/src/datasources/targeted-messaging/entities/outreach-file.entity.ts @@ -11,5 +11,3 @@ export const OutreachFileSchema = z.object({ end_date: z.coerce.date(), safe_addresses: z.array(AddressSchema), }); - -// TODO: Add tests for this schema.