diff --git a/__tests__/workers/newNotificationV2Mail.ts b/__tests__/workers/newNotificationV2Mail.ts index 7ebb448f3e..3d4d0e296d 100644 --- a/__tests__/workers/newNotificationV2Mail.ts +++ b/__tests__/workers/newNotificationV2Mail.ts @@ -42,6 +42,7 @@ import { UserPersonalizedDigestSendType, UserPersonalizedDigestType, WelcomePost, + Organization, } from '../../src/entity'; import { PollPost } from '../../src/entity/posts/PollPost'; import { usersFixture } from '../fixture/user'; @@ -65,6 +66,7 @@ import { NotificationUserContext, Reference, type NotificationAwardContext, + type NotificationOpportunityMatchContext, } from '../../src/notifications'; import { postsFixture } from '../fixture/post'; import { sourcesFixture } from '../fixture/source'; @@ -92,6 +94,13 @@ import { env } from 'node:process'; import { Product, ProductType } from '../../src/entity/Product'; import { BriefPost } from '../../src/entity/posts/BriefPost'; import { CampaignUpdateEvent } from '../../src/common/campaign/common'; +import { Opportunity } from '../../src/entity/opportunities/Opportunity'; +import { OpportunityMatch } from '../../src/entity/OpportunityMatch'; +import { + opportunitiesFixture, + opportunityMatchesFixture, + organizationsFixture, +} from '../fixture/opportunity'; jest.mock('../../src/common/mailing', () => ({ ...(jest.requireActual('../../src/common/mailing') as Record< @@ -1858,6 +1867,38 @@ describe('user_post_added notification', () => { }); }); +describe('new_opportunity_match notification', () => { + it('should send email', async () => { + await saveFixtures(con, Organization, organizationsFixture); + await saveFixtures(con, Opportunity, opportunitiesFixture); + await saveFixtures(con, OpportunityMatch, opportunityMatchesFixture); + const ctx: NotificationOpportunityMatchContext = { + userIds: ['1'], + opportunityId: opportunitiesFixture[0].id, + reasoningShort: 'Your skills match this opportunity', + }; + + const notificationId = await saveNotificationV2Fixture( + con, + NotificationType.NewOpportunityMatch, + ctx, + ); + await expectSuccessfulBackground(worker, { + notification: { + id: notificationId, + userId: '1', + }, + }); + expect(sendEmail).toHaveBeenCalledTimes(1); + const args = jest.mocked(sendEmail).mock + .calls[0][0] as SendEmailRequestWithTemplate; + expect(args.message_data).toEqual({ + opportunity_link: `http://localhost:5002/opportunity/${opportunitiesFixture[0].id}`, + }); + expect(args.transactional_message_id).toEqual('87'); + }); +}); + describe('source_post_approved notification', () => { it('should send email of type shared post', async () => { await con.getRepository(Post).save(postsFixture); diff --git a/src/workers/newNotificationV2Mail.ts b/src/workers/newNotificationV2Mail.ts index 3763a80c51..81246fbd57 100644 --- a/src/workers/newNotificationV2Mail.ts +++ b/src/workers/newNotificationV2Mail.ts @@ -121,7 +121,7 @@ export const notificationToTemplateId: Record = { campaign_squad_completed: '83', campaign_post_first_milestone: '80', campaign_squad_first_milestone: '82', - new_opportunity_match: '', + new_opportunity_match: '87', post_analytics: '', poll_result: '84', poll_result_author: '84', @@ -1054,8 +1054,21 @@ const notificationToTemplateData: Record = { in_app_purchases: async () => { return null; }, - new_opportunity_match: async () => { - return null; + new_opportunity_match: async (con, _, notification) => { + const [foundUser, opportunityMatch] = await Promise.all([ + con.getRepository(User).findOneBy({ id: notification.uniqueKey }), + con.getRepository(OpportunityMatch).findOneByOrFail({ + opportunityId: notification.referenceId, + userId: notification.uniqueKey, + }), + ]); + if (!foundUser || !opportunityMatch) { + return null; + } + + return { + opportunity_link: notification.targetUrl, + }; }, post_analytics: async () => { return null;