diff --git a/src/features/users/__tests__/confirm-newsletter-subscriptions.spec.ts b/src/features/users/__tests__/confirm-newsletter-subscriptions.spec.ts index 7beb89f3..5066e553 100644 --- a/src/features/users/__tests__/confirm-newsletter-subscriptions.spec.ts +++ b/src/features/users/__tests__/confirm-newsletter-subscriptions.spec.ts @@ -324,23 +324,23 @@ describe('Given a NGC user', () => { }) describe('And user already has a brevo contact with some subscribed news letters', () => { - beforeEach(async () => { - ;({ - id: userId, - listIds, - email, - code, - } = await subscribeToNewsLetter({ - agent, - user: { - contact: { - listIds: [ListIds.LOGEMENT_NEWSLETTER], + describe('When clicking the confirmation email link', () => { + beforeEach(async () => { + ;({ + id: userId, + listIds, + email, + code, + } = await subscribeToNewsLetter({ + agent, + user: { + contact: { + listIds: [ListIds.LOGEMENT_NEWSLETTER], + }, }, - }, - })) - }) + })) + }) - describe('When clicking the confirmation email link', () => { test('Then it redirects to a success page', async () => { mswServer.use( brevoGetContact(email, { @@ -389,6 +389,77 @@ describe('Given a NGC user', () => { ) }) }) + + describe('And unknown newletter', () => { + describe('When clicking the confirmation email link', () => { + beforeEach(async () => { + ;({ + id: userId, + listIds, + email, + code, + } = await subscribeToNewsLetter({ + agent, + user: { + contact: { + listIds: [ListIds.LOGEMENT_NEWSLETTER], + }, + }, + })) + }) + + test('Then it redirects to a success page', async () => { + mswServer.use( + brevoGetContact(email, { + customResponses: [ + { + body: getBrevoContact({ + email, + attributes: { + USER_ID: userId, + }, + listIds: [ListIds.MAIN_NEWSLETTER, 404], + }), + }, + ], + }), + brevoRemoveFromList(ListIds.MAIN_NEWSLETTER, { + expectBody: { + emails: [email], + }, + }), + brevoUpdateContact({ + expectBody: { + email, + attributes: { + USER_ID: userId, + PRENOM: null, + }, + updateEnabled: true, + listIds: expect.arrayContaining([ + ListIds.LOGEMENT_NEWSLETTER, + 404, + ]), + }, + }) + ) + + const response = await agent + .get(url.replace(':userId', userId)) + .query({ + code, + email, + listIds: [...listIds, 404], + origin: 'https://nosgestesclimat.fr', + }) + .expect(StatusCodes.MOVED_TEMPORARILY) + + expect(response.get('location')).toBe( + 'https://nosgestesclimat.fr/newsletter-confirmation?success=true' + ) + }) + }) + }) }) }) diff --git a/src/features/users/__tests__/update-user.spec.ts b/src/features/users/__tests__/update-user.spec.ts index 881520b7..be22ec2c 100644 --- a/src/features/users/__tests__/update-user.spec.ts +++ b/src/features/users/__tests__/update-user.spec.ts @@ -704,6 +704,64 @@ describe('Given a NGC user', () => { }) }) + describe('And contact has already subscribed an unknown newsletter', () => { + beforeEach(() => { + contact.listIds = [404] + }) + + test(`Then it sends an email and returns a ${StatusCodes.ACCEPTED} response`, async () => { + const payload = { + email, + contact: { + listIds: [ListIds.MAIN_NEWSLETTER], + }, + } + + mswServer.use( + brevoGetContact(email, { + customResponses: [ + { + body: contact, + }, + ], + }), + brevoSendEmail({ + expectBody: { + to: [ + { + name: email, + email, + }, + ], + templateId: 118, + params: { + NEWSLETTER_CONFIRMATION_URL: `https://server.nosgestesclimat.fr/users/v1/${userId}/newsletter-confirmation?code=${code}&email=${encodeURIComponent(email)}&origin=${encodeURIComponent('https://preprod.nosgestesclimat.fr')}&listIds=22&listIds=404`, + }, + }, + }) + ) + + const { body } = await agent + .put(url.replace(':userId', userId)) + .set('origin', 'https://preprod.nosgestesclimat.fr') + .send(payload) + .expect(StatusCodes.ACCEPTED) + + expect(body).toEqual({ + id: userId, + email, + name: null, + contact: { + id: contact.id, + email, + listIds: [404], + }, + createdAt: expect.any(String), + updatedAt: expect.any(String), + }) + }) + }) + describe('And no email provided', () => { test(`Then it returns a ${StatusCodes.OK} response with the updated user`, async () => { const { body } = await agent @@ -1155,6 +1213,62 @@ describe('Given a NGC user', () => { }) }) + describe('And contact has already subscribed an unknown newsletter', () => { + beforeEach(() => { + contact.listIds = [404] + }) + + test(`Then it sends an email and returns a ${StatusCodes.ACCEPTED} response`, async () => { + const payload = { + contact: { + listIds: [ListIds.MAIN_NEWSLETTER], + }, + } + + mswServer.use( + brevoGetContact(email, { + customResponses: [ + { + body: contact, + }, + ], + }), + brevoSendEmail({ + expectBody: { + to: [ + { + name: email, + email, + }, + ], + templateId: 118, + params: { + NEWSLETTER_CONFIRMATION_URL: `https://server.nosgestesclimat.fr/users/v1/${userId}/newsletter-confirmation?code=${code}&email=${encodeURIComponent(email)}&origin=${encodeURIComponent('https://nosgestesclimat.fr')}&listIds=22&listIds=404`, + }, + }, + }) + ) + + const { body } = await agent + .put(url.replace(':userId', userId)) + .send(payload) + .expect(StatusCodes.ACCEPTED) + + expect(body).toEqual({ + id: userId, + email, + name: null, + contact: { + id: contact.id, + email, + listIds: [404], + }, + createdAt: expect.any(String), + updatedAt: expect.any(String), + }) + }) + }) + describe('And contact has already subscribed to the newsletter', () => { beforeEach(() => { contact.listIds = [ListIds.MAIN_NEWSLETTER] @@ -1809,7 +1923,7 @@ describe('Given a NGC user', () => { }) }) - test(`Then it returns a ${StatusCodes.ACCEPTED} response`, async () => { + test(`Then it returns a ${StatusCodes.OK} response`, async () => { const payload = { contact: { listIds: [], diff --git a/src/features/users/users.service.ts b/src/features/users/users.service.ts index 4c2fd467..30fccf47 100644 --- a/src/features/users/users.service.ts +++ b/src/features/users/users.service.ts @@ -48,7 +48,7 @@ const getNewsletterMutation = ({ }: { contact?: BrevoContact previousContact?: BrevoContact - wantedNewsletters?: ListIds[] + wantedNewsletters?: number[] }) => { const newslettersToSubscribe = new Set() const newslettersToUnsubscribe = new Set() diff --git a/src/features/users/users.validator.ts b/src/features/users/users.validator.ts index 88a09f01..b51c397e 100644 --- a/src/features/users/users.validator.ts +++ b/src/features/users/users.validator.ts @@ -65,11 +65,13 @@ export const NewsletterConfirmationQuery = z .transform((email) => email.toLocaleLowerCase()), listIds: z .union([ - z.coerce.number().pipe(z.nativeEnum(ListIds).transform((s) => [s])), - z.array(z.coerce.number().pipe(z.nativeEnum(ListIds))), + z.coerce.number().positive(), + z.array(z.coerce.number().positive()), ]) .optional() - .transform((listIds) => listIds || []), + .transform((listIds) => + typeof listIds === 'number' ? [listIds] : listIds || [] + ), }) .strict()