Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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 .*/,
);
});
},
);

Expand All @@ -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) {
Expand Down
24 changes: 21 additions & 3 deletions packages/specifications/src/notification/notification.world.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ export class NotificationWorld {
}
}

récupérerNotification(emailValue: string, sujet?: string) {
vérifierNotification(emailValue: string, sujet?: string, variables?: Record<string, string>) {
const logger = getLogger('NotificationWorld');
const email = Email.convertirEnValueType(emailValue);
const notif = this.#notifications.find((notif) => {
if (notif.checked) {
Expand All @@ -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) => ({
Expand All @@ -43,7 +62,6 @@ export class NotificationWorld {
assert(notif, 'Pas de notification');

notif.checked = true;
return notif;
}

resetNotifications() {
Expand Down
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -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);
});
}

Expand Down
4 changes: 2 additions & 2 deletions packages/specifications/src/période/notifierPériode.feature
Original file line number Diff line number Diff line change
Expand Up @@ -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é
Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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())}`,
},
);
}
});
Expand All @@ -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;
}
});
},
Expand All @@ -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;
}
});
},
Expand Down
Loading