diff --git a/config/test.env b/config/test.env index a699c35..ac7cf6d 100644 --- a/config/test.env +++ b/config/test.env @@ -23,6 +23,9 @@ GIVETH_IO_THIRD_PARTY_MICRO_SERVICE=givethio GIV_ECONOMY_THIRD_PARTY_SECRET=secret GIV_ECONOMY_THIRD_PARTY_MICRO_SERVICE=giveconomy-notification-service +NOTIFY_REWARD_THIRD_PARTY_SECRET=secret +NOTIFY_REWARD_THIRD_PARTY_MICRO_SERVICE=notifyreward + # OPTIONAL - force logging to stdout when the value is true LOG_STDOUT=false diff --git a/migrations/1718888344202-seedNotificationTypeForNotifyRewardAmount.ts b/migrations/1718888344202-seedNotificationTypeForNotifyRewardAmount.ts index 0cb4861..5e4a341 100644 --- a/migrations/1718888344202-seedNotificationTypeForNotifyRewardAmount.ts +++ b/migrations/1718888344202-seedNotificationTypeForNotifyRewardAmount.ts @@ -8,7 +8,7 @@ const NotifyRewardAmountNotificationType = [ name: NOTIFICATION_TYPE_NAMES.NOTIFY_REWARD_AMOUNT, description: NOTIFICATION_TYPE_NAMES.NOTIFY_REWARD_AMOUNT, microService: MICRO_SERVICES.givethio, - category: NOTIFICATION_CATEGORY.NOTIFY_REWARD_AMOUNT, + category: NOTIFICATION_CATEGORY.GENERAL, schemaValidator: SCHEMA_VALIDATORS_NAMES.NOTIFY_REWARD_AMOUNT, title: "Notify reward report", } diff --git a/migrations/1720553769343-changeMicroserviceAndCategoryOfNotifyRewardNotificationType.ts b/migrations/1720553769343-changeMicroserviceAndCategoryOfNotifyRewardNotificationType.ts new file mode 100644 index 0000000..d83a425 --- /dev/null +++ b/migrations/1720553769343-changeMicroserviceAndCategoryOfNotifyRewardNotificationType.ts @@ -0,0 +1,23 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; +import { MICRO_SERVICES } from '../src/utils/utils'; +import { NOTIFICATION_CATEGORY } from '../src/types/general'; + +export class changeMicroserviceAndCategoryOfNotifyRewardNotificationType1720553769343 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(` + UPDATE notification_type + SET "microService" = '${MICRO_SERVICES.notifyReward}', + category = '${NOTIFICATION_CATEGORY.ORTTO}' + WHERE name = 'Notify reward amount'; + `); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(` + UPDATE notification_type + SET "microService" = '${MICRO_SERVICES.givethio}', + categoty = '${NOTIFICATION_CATEGORY.GENERAL}' + WHERE name = 'Notify reward amount'; + `); + } +} diff --git a/migrations/1720828190666-seedThirdPartyForNotifyReward.ts b/migrations/1720828190666-seedThirdPartyForNotifyReward.ts new file mode 100644 index 0000000..14b8d51 --- /dev/null +++ b/migrations/1720828190666-seedThirdPartyForNotifyReward.ts @@ -0,0 +1,27 @@ +import { MigrationInterface, QueryRunner } from "typeorm" + +export class seedThirdPartyForNotifyReward1720828190666 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + if ( + process.env.NODE_ENV === 'test' || + process.env.NODE_ENV === 'development' + ) { + // Create third part record for notifyreward in development and test ENVs + await queryRunner.query(` + INSERT INTO third_party( + "microService", secret, "isActive") + VALUES + ('notifyreward', 'secret', true) + ; + `); + } + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(` + DELETE FROM third_party + WHERE "microService" = 'notifyreward'; + `); + } + +} diff --git a/src/routes/v1/notificationRouter.test.ts b/src/routes/v1/notificationRouter.test.ts index 387c745..6e15a0a 100644 --- a/src/routes/v1/notificationRouter.test.ts +++ b/src/routes/v1/notificationRouter.test.ts @@ -5,6 +5,7 @@ import { getAccessTokenForMockAuthMicroService, getGivEconomyBasicAuth, getGivethIoBasicAuth, + getNotifyRewardBasicAuth, serverUrl, sleep, } from '../../../test/testUtils'; @@ -2092,6 +2093,77 @@ function sendNotificationTestCases() { const createdNotification = await findNotificationByTrackId(trackId); assert.equal(createdNotification?.createdAt.getTime(), creationTime); }); + + it('should create *Notify reward amount* notification, success', async () => { + const data = { + eventName: "Notify reward amount", + sendEmail: true, + sendSegment: true, + creationTime: 1667992708000, + email: "aliebrahimi2079@gmail.com", + segment: { + payload: { + round: 10, + date: "1667992708000", + amount: "12134", + contractAddress: "0xsfglsjfdflk", + farm: "test farm", + message: "test message", + network: "ethereum", + script: "test script", + transactionHash: "test txhash" + } + } + }; + + const result = await axios.post(sendNotificationUrl, data, { + headers: { + authorization: getNotifyRewardBasicAuth(), + }, + }); + + assert.equal(result.status, 200); + assert.isOk(result.data); + assert.isTrue(result.data.success); + }); + it('should create *Notify reward amount* notification, failed invalid payload', async () => { + try { + const data = { + eventName: "Notify reward amount", + sendEmail: true, + sendSegment: true, + creationTime: 1667992708000, + email: "aliebrahimi2079@gmail.com", + segment: { + payload: { + round: 10, + date: "1667992708000", + amount: "12134", + contractAddress: "0xsfglsjfdflk", + farm: "test farm", + message: "test message", + network: "ethereum", + script: "test script", + transactionHash: "test txhash", + invalidField: "invalid data" + } + } + }; + await axios.post(sendNotificationUrl, data, { + headers: { + authorization: getNotifyRewardBasicAuth(), + }, + }); + // If request doesn't fail, it means this test failed + assert.isTrue(false); + } catch (e: any) { + assert.equal( + e.response.data.message, + errorMessagesEnum.IMPACT_GRAPH_VALIDATION_ERROR.message, + ); + assert.equal(e.response.data.description, '"segment.payload.invalidField" is not allowed'); + } + }); } function sendBulkNotificationsTestCases() { diff --git a/src/services/notificationService.test.ts b/src/services/notificationService.test.ts new file mode 100644 index 0000000..9f5a5ce --- /dev/null +++ b/src/services/notificationService.test.ts @@ -0,0 +1,43 @@ +import { activityCreator } from './notificationService'; +import { NOTIFICATIONS_EVENT_NAMES } from '../types/notifications'; +import { expect } from 'chai'; + +describe('activityCreator', () => { + it('should create attributes for NOTIFY_REWARD_AMOUNT', () => { + const payload = { + round: 1, + date: '2024-06-01', + amount: '1000', + contractAddress: '0x123', + farm: 'Test Farm', + message: 'Test Message', + network: 'Test Network', + script: 'Test Script', + transactionHash: '0xabc', + email: 'test@example.com' + }; + const result = activityCreator(payload, NOTIFICATIONS_EVENT_NAMES.NOTIFY_REWARD_AMOUNT); + expect(JSON.stringify(result)).equal(JSON.stringify({ + activities: [ + { + activity_id: "act:cm:notify-reward-amount", + attributes: { + 'int:cm:round': payload.round, + 'str:cm:date': payload.date, + 'str:cm:amount': payload.amount, + 'str:cm:contractaddress': payload.contractAddress, + 'str:cm:farm': payload.farm, + 'str:cm:message': payload.message, + 'str:cm:network': payload.network, + 'str:cm:script': payload.script, + 'str:cm:transactionhash': payload.transactionHash, + }, + fields: { + 'str::email': payload.email, + }, + }, + ], + merge_by: ['str::email'], + })); + }) +}); diff --git a/src/services/notificationService.ts b/src/services/notificationService.ts index 2ae1d0a..09d0bf1 100644 --- a/src/services/notificationService.ts +++ b/src/services/notificationService.ts @@ -13,7 +13,7 @@ import { NOTIFICATIONS_EVENT_NAMES, ORTTO_EVENT_NAMES } from '../types/notificat import { getEmailAdapter } from '../adapters/adapterFactory'; import { NOTIFICATION_CATEGORY } from '../types/general'; -const activityCreator = (payload: any, orttoEventName: NOTIFICATIONS_EVENT_NAMES) : any=> { +export const activityCreator = (payload: any, orttoEventName: NOTIFICATIONS_EVENT_NAMES) : any=> { let attributes; switch (orttoEventName) { case NOTIFICATIONS_EVENT_NAMES.SUBSCRIBE_ONBOARDING: diff --git a/src/types/general.ts b/src/types/general.ts index a267f31..c0e3059 100644 --- a/src/types/general.ts +++ b/src/types/general.ts @@ -12,7 +12,6 @@ export enum NOTIFICATION_CATEGORY { SUPPORTED_PROJECTS = 'supportedProjects', GIV_POWER = 'givPower', ORTTO = 'ortto', - NOTIFY_REWARD_AMOUNT = 'notifyRewardAmount', } export enum NOTIFICATION_TYPE_NAMES { diff --git a/src/utils/utils.ts b/src/utils/utils.ts index 674ee1a..1d8c328 100644 --- a/src/utils/utils.ts +++ b/src/utils/utils.ts @@ -19,6 +19,7 @@ export const MICRO_SERVICES = { givethio: 'givethio', givEconomyNotificationMicroService: 'giveconomy-notification-service', trace: 'trace', + notifyReward: 'notifyreward', }; // Need to define trace, blockchain and miscellaneos events diff --git a/src/validators/schemaValidators.ts b/src/validators/schemaValidators.ts index 179f86b..34b07a4 100644 --- a/src/validators/schemaValidators.ts +++ b/src/validators/schemaValidators.ts @@ -94,8 +94,14 @@ export const sendNotificationValidator = Joi.object({ update: Joi.string(), // Notify reward attributes + round: Joi.number(), + date: Joi.string(), contractAddress: Joi.string(), farm: Joi.string(), + message: Joi.string(), + network: Joi.string(), + script: Joi.string(), + transactionHash: Joi.string(), }), }), }); diff --git a/test/testUtils.ts b/test/testUtils.ts index 9890c5d..96b744b 100644 --- a/test/testUtils.ts +++ b/test/testUtils.ts @@ -112,6 +112,13 @@ export const getGivEconomyBasicAuth = () => { }); }; +export const getNotifyRewardBasicAuth = () => { + return createBasicAuthentication({ + secret: process.env.NOTIFY_REWARD_THIRD_PARTY_SECRET as string, + username: process.env.NOTIFY_REWARD_THIRD_PARTY_MICRO_SERVICE as string, + }); +}; + export const getAccessTokenForMockAuthMicroService = ( walletAddress: string, ) => {