diff --git a/packages/specifications/src/candidature/stepDefinitions/candidature.then.ts b/packages/specifications/src/candidature/stepDefinitions/candidature.then.ts index cc6221ad8f4..5e59eb98072 100644 --- a/packages/specifications/src/candidature/stepDefinitions/candidature.then.ts +++ b/packages/specifications/src/candidature/stepDefinitions/candidature.then.ts @@ -60,15 +60,10 @@ Alors(`la candidature devrait être consultable`, async function (this: Potentie Alors( 'le porteur a été prévenu que son attestation a été modifiée', async function (this: PotentielWorld) { - const email = this.notificationWorld.récupérerNotification( + this.notificationWorld.vérifierNotification( this.candidatureWorld.importerCandidature.values.emailContactValue, + 'Potentiel - Une nouvelle attestation est disponible pour le projet .*', ); - - await waitForExpect(async () => { - expect(email.messageSubject).match( - /Potentiel - Une nouvelle attestation est disponible pour le projet .*/, - ); - }); }, ); @@ -78,7 +73,7 @@ Alors( // edge case because we want to wait for a notification that should not be sent await sleep(400); try { - this.notificationWorld.récupérerNotification( + this.notificationWorld.vérifierNotification( this.candidatureWorld.importerCandidature.values.emailContactValue, ); } catch (error) { diff --git a/packages/specifications/src/notification/notification.world.ts b/packages/specifications/src/notification/notification.world.ts index dbd0fcaf63d..c911013ed50 100644 --- a/packages/specifications/src/notification/notification.world.ts +++ b/packages/specifications/src/notification/notification.world.ts @@ -19,7 +19,8 @@ export class NotificationWorld { } } - récupérerNotification(emailValue: string, sujet?: string) { + vérifierNotification(emailValue: string, sujet?: string, variables?: Record) { + const logger = getLogger('NotificationWorld'); const email = Email.convertirEnValueType(emailValue); const notif = this.#notifications.find((notif) => { if (notif.checked) { @@ -28,10 +29,28 @@ export class NotificationWorld { if (sujet && !notif.messageSubject.match(new RegExp(sujet))) { return false; } + if (variables) { + for (const [key, value] of Object.entries(variables)) { + if (!new RegExp(value).test(notif.variables[key])) { + logger.debug( + "Une notification correspond au sujet et à l'email, mais pas aux variables", + { + key, + expected: value, + actual: notif.variables[key], + email: email.formatter(), + sujet, + }, + ); + + return false; + } + } + } return notif.email.estÉgaleÀ(email); }); if (!notif) { - getLogger('NotificationWorld').debug(`Aucune notification trouvée`, { + logger.debug(`Aucune notification trouvée`, { sujet, emailValue, notificationsEnvoyées: this.#notifications.map((x) => ({ @@ -43,7 +62,6 @@ export class NotificationWorld { assert(notif, 'Pas de notification'); notif.checked = true; - return notif; } resetNotifications() { diff --git a/packages/specifications/src/notification/stepDefinitions/notification.then.ts b/packages/specifications/src/notification/stepDefinitions/notification.then.ts index f1d601c2c97..0f08561c39d 100644 --- a/packages/specifications/src/notification/stepDefinitions/notification.then.ts +++ b/packages/specifications/src/notification/stepDefinitions/notification.then.ts @@ -1,5 +1,5 @@ import { Then as Alors, DataTable } from '@cucumber/cucumber'; -import { assert, expect } from 'chai'; +import { assert } from 'chai'; import waitForExpect from 'wait-for-expect'; import { mediator } from 'mediateur'; import { match } from 'ts-pattern'; @@ -14,16 +14,8 @@ import { sleep } from '../../helpers/sleep'; export async function vérifierEmailEnvoyé(this: PotentielWorld, email: string, data: DataTable) { await waitForExpect(async () => { const exemple = data.rowsHash(); - const notification = this.notificationWorld.récupérerNotification(email, exemple.sujet); - for (const [key, value] of Object.entries(exemple)) { - if (key === 'sujet') { - expect(notification.messageSubject).to.match(new RegExp(value)); - continue; - } - const variable = notification.variables[key]; - - expect(variable).to.match(new RegExp(value)); - } + const { sujet, ...variables } = exemple; + this.notificationWorld.vérifierNotification(email, sujet, variables); }); } diff --git "a/packages/specifications/src/p\303\251riode/notifierP\303\251riode.feature" "b/packages/specifications/src/p\303\251riode/notifierP\303\251riode.feature" index 48611cbb7e5..7f0118a3701 100644 --- "a/packages/specifications/src/p\303\251riode/notifierP\303\251riode.feature" +++ "b/packages/specifications/src/p\303\251riode/notifierP\303\251riode.feature" @@ -10,7 +10,7 @@ Fonctionnalité: Notifier une période d'un appel d'offres Et les lauréats et éliminés devraient être consultables Et les porteurs doivent avoir accès à leur projet Et les attestations de désignation des candidatures de la période notifiée devraient être consultables - Et les porteurs ont été prévenu que leurs candidatures ont été notifiées + Et les porteurs ont été prévenus que leurs candidatures ont été notifiées Et les partenaires ont été prévenus de la notification de la période Et l'administration a été prévenue de la notification de la période Et aucun autre email n'a été envoyé @@ -23,7 +23,7 @@ Fonctionnalité: Notifier une période d'un appel d'offres Et les candidatures de la période notifiée devraient être notifiées Et les porteurs doivent avoir accès à leur projet Et les attestations de désignation des candidatures de la période notifiée devraient être consultables - Et les porteurs ont été prévenu que leurs candidatures ont été notifiées + Et les porteurs ont été prévenus que leurs candidatures ont été notifiées Et les lauréats et éliminés devraient être consultables Scénario: Impossible de notifier une période sans fonction pour le validateur diff --git "a/packages/specifications/src/p\303\251riode/stepDefinitions/p\303\251riode.then.ts" "b/packages/specifications/src/p\303\251riode/stepDefinitions/p\303\251riode.then.ts" index a7022393a8d..4f3b8fc3306 100644 --- "a/packages/specifications/src/p\303\251riode/stepDefinitions/p\303\251riode.then.ts" +++ "b/packages/specifications/src/p\303\251riode/stepDefinitions/p\303\251riode.then.ts" @@ -107,22 +107,23 @@ Alors(`les porteurs doivent avoir accès à leur projet`, async function (this: }); Alors( - 'les porteurs ont été prévenu que leurs candidatures ont été notifiées', + 'les porteurs ont été prévenus que leurs candidatures ont été notifiées', async function (this: PotentielWorld) { - const candidats = this.périodeWorld.notifierPériodeFixture.lauréats.concat( - this.périodeWorld.notifierPériodeFixture.éliminés, - ); + const candidats = this.périodeWorld.notifierPériodeFixture.lauréats + .concat(this.périodeWorld.notifierPériodeFixture.éliminés) + .sort((a, b) => + IdentifiantProjet.bind(a).formatter().localeCompare(IdentifiantProjet.bind(b).formatter()), + ); await waitForExpect(async () => { for (const candidat of candidats) { - const notif = this.notificationWorld.récupérerNotification( + const identifiantProjet = IdentifiantProjet.bind(candidat); + this.notificationWorld.vérifierNotification( candidat.emailContact, "Résultats de la .* période de l'appel d'offres .*", - ); - const identifiantProjet = IdentifiantProjet.bind(candidat); - - expect(notif.variables.redirect_url).to.equal( - `https://potentiel.beta.gouv.fr${Routes.Projet.details(identifiantProjet.formatter())}`, + { + redirect_url: `https://potentiel.beta.gouv.fr${Routes.Projet.details(identifiantProjet.formatter())}`, + }, ); } }); @@ -146,12 +147,10 @@ Alors( expect(partenaires.items).to.have.length.greaterThan(0); for (const { email } of partenaires.items) { - const notif = this.notificationWorld.récupérerNotification( + this.notificationWorld.vérifierNotification( email, `Notification de la période ${identifiantPériode.période} de l'appel d'offres ${identifiantPériode.appelOffre}`, ); - - expect(notif).to.not.be.undefined; } }); }, @@ -174,12 +173,10 @@ Alors( expect(administration.items).to.have.length.greaterThan(0); for (const { email } of administration.items) { - const notif = this.notificationWorld.récupérerNotification( + this.notificationWorld.vérifierNotification( email, `Notification de la période ${identifiantPériode.période} de l'appel d'offres ${identifiantPériode.appelOffre}`, ); - - expect(notif).to.not.be.undefined; } }); },