Skip to content

Commit

Permalink
[AUTO DIAGNOSTIC] Publie l’événement AUTO_DIAGNOSTIC_LANCE et crée la…
Browse files Browse the repository at this point in the history
… relation avec la demande correspondante
  • Loading branch information
bbougon committed Nov 15, 2024
1 parent 9cccd2f commit 552e948
Show file tree
Hide file tree
Showing 10 changed files with 196 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
reinitialisationMotDePasseDemandee,
reinitialisationMotDePasseErronee,
reinitialisationMotDePasseFaite,
autoDiagnosticLance,
} from '../journalisation/evenements';
import { EntrepotJournalisationPostgres } from '../infrastructure/entrepots/postgres/EntrepotJournalisationPostgres';
import configurationJournalisation from '../infrastructure/entrepots/postgres/configurationJournalisation';
Expand All @@ -23,6 +24,7 @@ import { EntrepotEvenementJournal } from '../journalisation/Publication';
import { AdaptateurRelations } from '../relation/AdaptateurRelations';
import { AdaptateurRelationsMAC } from '../relation/AdaptateurRelationsMAC';
import { aidantInitieDiagnostic } from '../espace-aidant/tableau-de-bord/consommateursEvenements';
import { demandeInitieAutoDiagnostic } from '../auto-diagnostic/consommateursEvenements';

const fabriqueEntrepotJournalisation = () => {
return process.env.URL_JOURNALISATION_BASE_DONNEES
Expand Down Expand Up @@ -90,5 +92,12 @@ export const fabriqueConsommateursEvenements = (
'REINITIALISATION_MOT_DE_PASSE_ERRONEE',
[reinitialisationMotDePasseErronee(entrepotJournalisation)],
],
[
'AUTO_DIAGNOSTIC_LANCE',
[
autoDiagnosticLance(entrepotJournalisation),
demandeInitieAutoDiagnostic(adaptateurRelations),
],
],
]);
};
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import { initialiseDiagnostic } from '../diagnostic/Diagnostic';
import { Entrepot } from '../domaine/Entrepot';
import { Aggregat } from '../domaine/Aggregat';
import { adaptateurUUID } from '../infrastructure/adaptateurs/adaptateurUUID';
import { BusEvenement, Evenement } from '../domaine/BusEvenement';
import { FournisseurHorloge } from '../infrastructure/horloge/FournisseurHorloge';

export type DemandeAutoDiagnostic = Aggregat & {
dateSignatureCGU: Date;
Expand All @@ -27,15 +29,19 @@ type CommandeDemandeAutoDiagnostic = Commande & {
};

export class CapteurCommandeDemandeAutoDiagnostic
implements CapteurCommande<CommandeDemandeAutoDiagnostic, void>
implements CapteurCommande<CommandeDemandeAutoDiagnostic, crypto.UUID>
{
constructor(private readonly entrepots: Entrepots) {}

execute(commande: CommandeDemandeAutoDiagnostic): Promise<void> {
return this.entrepots.demandesAutoDiagnostic().persiste({
identifiant: adaptateurUUID.genereUUID(),
dateSignatureCGU: commande.dateSignatureCGU,
});
execute(commande: CommandeDemandeAutoDiagnostic): Promise<crypto.UUID> {
const identifiant: crypto.UUID = adaptateurUUID.genereUUID();
return this.entrepots
.demandesAutoDiagnostic()
.persiste({
identifiant,
dateSignatureCGU: commande.dateSignatureCGU,
})
.then(() => identifiant);
}
}

Expand All @@ -51,24 +57,47 @@ export class CapteurSagaLanceAutoDiagnostic
constructor(
private readonly entrepots: Entrepots,
private readonly busCommande: BusCommande,
private readonly busEvenement: BusEvenement,
private readonly referentiel: Adaptateur<Referentiel>,
private readonly referentielDeMesures: Adaptateur<ReferentielDeMesures>
) {}

execute(saga: SagaLanceAutoDiagnostic): Promise<crypto.UUID> {
this.busCommande.publie<CommandeDemandeAutoDiagnostic, void>({
type: 'CommandeDemandeAutoDiagnostic',
dateSignatureCGU: saga.dateSignatureCGU,
});
return Promise.all([
this.referentiel.lis(),
this.referentielDeMesures.lis(),
]).then(([ref, rem]) => {
const diagnostic = initialiseDiagnostic(ref, rem);
return this.entrepots
.diagnostic()
.persiste(diagnostic)
.then(() => diagnostic.identifiant);
});
return this.busCommande
.publie<CommandeDemandeAutoDiagnostic, crypto.UUID>({
type: 'CommandeDemandeAutoDiagnostic',
dateSignatureCGU: saga.dateSignatureCGU,
})
.then((identifiantDemande) => {
return Promise.all([
this.referentiel.lis(),
this.referentielDeMesures.lis(),
])
.then(([ref, rem]) => {
const diagnostic = initialiseDiagnostic(ref, rem);
return this.entrepots
.diagnostic()
.persiste(diagnostic)
.then(() => diagnostic.identifiant);
})
.then((identifiantDiagnostic) => {
return this.busEvenement
.publie<AutoDiagnosticLance>({
type: 'AUTO_DIAGNOSTIC_LANCE',
date: FournisseurHorloge.maintenant(),
corps: {
idDiagnostic: identifiantDiagnostic,
idDemande: identifiantDemande,
},
identifiant: adaptateurUUID.genereUUID(),
})
.then(() => identifiantDiagnostic);
});
});
}
}

export type AutoDiagnosticLance = Evenement<{
idDiagnostic: crypto.UUID;
idDemande: crypto.UUID;
}> & { type: 'AUTO_DIAGNOSTIC_LANCE' };
47 changes: 47 additions & 0 deletions mon-aide-cyber-api/src/auto-diagnostic/consommateursEvenements.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { AdaptateurRelations } from '../relation/AdaptateurRelations';
import { ConsommateurEvenement, Evenement } from '../domaine/BusEvenement';
import { AutoDiagnosticLance } from './CapteurSagaLanceAutoDiagnostic';
import crypto from 'crypto';
import { DefinitionTuple, Tuple, unTuple } from '../relation/Tuple';

export const demandeInitieAutoDiagnostic = (
adaptateurRelations: AdaptateurRelations
) =>
new (class implements ConsommateurEvenement {
async consomme<E extends Evenement<unknown> = AutoDiagnosticLance>(
evenement: E
): Promise<void> {
const diagnosticLance = evenement as AutoDiagnosticLance;
const tuple = unTupleAidantInitieDiagnostic(
diagnosticLance.corps.idDemande,
diagnosticLance.corps.idDiagnostic
);

return adaptateurRelations.creeTuple(tuple);
}
})();

export const unTupleAidantInitieDiagnostic = (
identifiantDemande: crypto.UUID,
identifiantDiagnostic: crypto.UUID
): Tuple =>
unTuple<DefinitionAidantInitieDiagnostic>(definitionAidantInitieDiagnostic)
.avecUtilisateur(identifiantDemande)
.avecObjet(identifiantDiagnostic)
.construis();

export type DefinitionAidantInitieDiagnostic = DefinitionTuple & {
relation: 'initiateur';
typeObjet: 'auto-diagnostic';
typeUtilisateur: 'demande-aide';
};

export const definitionAidantInitieDiagnostic: {
definition: DefinitionAidantInitieDiagnostic;
} = {
definition: {
relation: 'initiateur',
typeObjet: 'auto-diagnostic',
typeUtilisateur: 'demande-aide',
},
};
1 change: 1 addition & 0 deletions mon-aide-cyber-api/src/domaine/BusEvenement.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export interface ConsommateurEvenement {
}

export type TypeEvenement =
| 'AUTO_DIAGNOSTIC_LANCE'
| 'DIAGNOSTIC_LANCE'
| 'REPONSE_AJOUTEE'
| 'RESTITUTION_LANCEE'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ const capteurs: Map<string, Capteur> = new Map([
new CapteurSagaLanceAutoDiagnostic(
parametres.entrepots,
parametres.busCommande!,
parametres.busEvenements!,
parametres.services.referentiels.diagnostic,
parametres.services.referentiels.mesures
),
Expand Down
2 changes: 2 additions & 0 deletions mon-aide-cyber-api/src/journalisation/evenements.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ export const reinitialisationMotDePasseFaite = consommateurEvenement();

export const reinitialisationMotDePasseErronee = consommateurEvenement();

export const autoDiagnosticLance = consommateurEvenement();

const genereEvenement = <E extends Evenement<unknown>>(
evenement: E
): Publication => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,11 @@ export class EntrepotRelationMemoire
extends EntrepotMemoire<Tuple>
implements EntrepotRelation
{
trouveObjetsLiesAUtilisateur(identifiantAidant: string): Promise<Tuple[]> {
trouveObjetsLiesAUtilisateur(
identifiantUtilisateur: string
): Promise<Tuple[]> {
const tuples = Array.from(this.entites.values()).filter(
(tuple) =>
tuple.utilisateur.identifiant === identifiantAidant &&
tuple.utilisateur.type === 'aidant' &&
tuple.relation === 'initiateur' &&
tuple.objet.type === 'diagnostic'
(tuple) => tuple.utilisateur.identifiant === identifiantUtilisateur
);

return Promise.resolve(tuples);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { beforeEach, describe } from 'vitest';
import { EntrepotsMemoire } from '../../src/infrastructure/entrepots/memoire/EntrepotsMemoire';
import {
AutoDiagnosticLance,
CapteurSagaLanceAutoDiagnostic,
DemandeAutoDiagnostic,
} from '../../src/auto-diagnostic/CapteurSagaLanceAutoDiagnostic';
Expand Down Expand Up @@ -38,18 +39,19 @@ describe('Capteur pour lancer un Auto-Diagnostic', () => {
adaptateurEnvoiMail,
unConstructeurDeServices(entrepots.aidants())
);
const referentiel = unReferentiel().construis();
adaptateurReferentiel.ajoute(referentiel);
});

it('Crée la demande correspondante', async () => {
FournisseurHorlogeDeTest.initialise(new Date());
const identifiantDemande = crypto.randomUUID();
adaptateurUUID.genereUUID = () => identifiantDemande;
const referentiel = unReferentiel().construis();
adaptateurReferentiel.ajoute(referentiel);

await new CapteurSagaLanceAutoDiagnostic(
entrepots,
busCommande,
busEvenement,
adaptateurReferentiel,
adaptateurMesures
).execute({
Expand All @@ -65,4 +67,33 @@ describe('Capteur pour lancer un Auto-Diagnostic', () => {
dateSignatureCGU: FournisseurHorloge.maintenant(),
});
});

it('Publie l’événement AUTO_DIAGNOSTIC_LANCE', async () => {
FournisseurHorlogeDeTest.initialise(new Date());

await new CapteurSagaLanceAutoDiagnostic(
entrepots,
busCommande,
busEvenement,
adaptateurReferentiel,
adaptateurMesures
).execute({
type: 'SagaLanceAutoDiagnostic',
email: '[email protected]',
dateSignatureCGU: FournisseurHorloge.maintenant(),
});

expect(
busEvenement.consommateursTestes.get('AUTO_DIAGNOSTIC_LANCE')?.[0]
.evenementConsomme
).toStrictEqual<AutoDiagnosticLance>({
identifiant: expect.any(String),
type: 'AUTO_DIAGNOSTIC_LANCE',
date: FournisseurHorloge.maintenant(),
corps: {
idDiagnostic: expect.any(String),
idDemande: expect.any(String),
},
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { describe, it } from 'vitest';
import { AdaptateurRelationsMAC } from '../../src/relation/AdaptateurRelationsMAC';
import { EntrepotRelationMemoire } from '../../src/relation/infrastructure/EntrepotRelationMemoire';
import crypto from 'crypto';
import { BusEvenementDeTest } from '../infrastructure/bus/BusEvenementDeTest';
import { EntrepotEvenementJournalMemoire } from '../../src/infrastructure/entrepots/memoire/EntrepotMemoire';
import { FournisseurHorloge } from '../../src/infrastructure/horloge/FournisseurHorloge';

describe("Les consommateurs d'évènements de l’auto diagnostic", () => {
describe("Lorsque l’événement 'AUTO_DIAGNOSTIC_LANCE' est consommé", () => {
it('Crée la relation entre la demande et l’auto diagnostic', async () => {
const adaptateurRelations = new AdaptateurRelationsMAC(
new EntrepotRelationMemoire()
);
const identifiantDemande = crypto.randomUUID();
const identifiantDiagnostic = crypto.randomUUID();
const busEvenement = new BusEvenementDeTest(
{
adaptateurRelations,
entrepotJournalisation: new EntrepotEvenementJournalMemoire(),
},
['AUTO_DIAGNOSTIC_LANCE']
);

await busEvenement.publie({
identifiant: crypto.randomUUID(),
type: 'AUTO_DIAGNOSTIC_LANCE',
date: FournisseurHorloge.maintenant(),
corps: {
idDiagnostic: identifiantDiagnostic,
idDemande: identifiantDemande,
},
});

expect(
await adaptateurRelations.identifiantsObjetsLiesAUtilisateur(
identifiantDemande
)
).toStrictEqual([identifiantDiagnostic]);
});
});
});
13 changes: 8 additions & 5 deletions mon-aide-cyber-api/test/infrastructure/bus/BusEvenementDeTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,20 @@ export class BusEvenementDeTest extends BusEvenementMAC {
new EntrepotRelationMemoire()
),
entrepotJournalisation: new EntrepotEvenementJournalMemoire(),
}
},
consomme: TypeEvenement[] = []
) {
const consommateursEvenements = fabriqueConsommateursEvenements(
configuration.adaptateurRelations,
configuration.entrepotJournalisation
);
for (const [clef, evenements] of consommateursEvenements.entries()) {
consommateursEvenements.set(
clef,
evenements.map(() => new ConsommateurEvenementDeTest())
);
if (!consomme.includes(clef)) {
consommateursEvenements.set(
clef,
evenements.map(() => new ConsommateurEvenementDeTest())
);
}
}
super(consommateursEvenements);
this.consommateursTestes = consommateursEvenements;
Expand Down

0 comments on commit 552e948

Please sign in to comment.