From 58a09f969bd368388aeb1c0b69aba02306954d5a Mon Sep 17 00:00:00 2001 From: clement-duport Date: Tue, 3 Sep 2024 12:59:06 +0200 Subject: [PATCH] trigger ic user agency right changed when adding user --- back/src/config/bootstrap/createUseCases.ts | 1 + .../use-cases/CreateUserForAgency.ts | 49 +++++++----- .../CreateUserForAgency.unit.test.ts | 78 ++++++++++++++----- 3 files changed, 89 insertions(+), 39 deletions(-) diff --git a/back/src/config/bootstrap/createUseCases.ts b/back/src/config/bootstrap/createUseCases.ts index fde8463a92..d882f72168 100644 --- a/back/src/config/bootstrap/createUseCases.ts +++ b/back/src/config/bootstrap/createUseCases.ts @@ -636,6 +636,7 @@ export const createUseCases = ( uowPerformer, deps: { timeGateway: gateways.timeGateway, + createNewEvent, }, }), broadcastConventionAgain: makeBroadcastConventionAgain({ diff --git a/back/src/domains/inclusion-connected-users/use-cases/CreateUserForAgency.ts b/back/src/domains/inclusion-connected-users/use-cases/CreateUserForAgency.ts index 1e0f9931c1..698b41fd13 100644 --- a/back/src/domains/inclusion-connected-users/use-cases/CreateUserForAgency.ts +++ b/back/src/domains/inclusion-connected-users/use-cases/CreateUserForAgency.ts @@ -6,6 +6,8 @@ import { userCreateParamsForAgencySchema, } from "shared"; import { createTransactionalUseCase } from "../../core/UseCase"; +import { DomainEvent } from "../../core/events/events"; +import { CreateNewEvent } from "../../core/events/ports/EventBus"; import { TimeGateway } from "../../core/time-gateway/ports/TimeGateway"; import { throwIfNotAdmin } from "../helpers/throwIfIcUserNotBackofficeAdmin"; @@ -15,50 +17,61 @@ export const makeCreateUserForAgency = createTransactionalUseCase< UserCreateParamsForAgency, void, InclusionConnectedUser, - { timeGateway: TimeGateway } + { timeGateway: TimeGateway; createNewEvent: CreateNewEvent } >( { name: "CreateUserForAgency", inputSchema: userCreateParamsForAgencySchema, }, - async ({ - inputParams: { agencyId, email, isNotifiedByEmail, roles, userId }, - uow, - currentUser, - deps, - }) => { + async ({ inputParams, uow, currentUser, deps }) => { throwIfNotAdmin(currentUser); - const agency = await uow.agencyRepository.getById(agencyId); - if (!agency) throw errors.agency.notFound({ agencyId }); + const agency = await uow.agencyRepository.getById(inputParams.agencyId); + if (!agency) + throw errors.agency.notFound({ agencyId: inputParams.agencyId }); - if (agency.refersToAgencyId && roles.includes("validator")) + if (agency.refersToAgencyId && inputParams.roles.includes("validator")) throw errors.agency.invalidRoleUpdateForAgencyWithRefersTo({ agencyId: agency.id, role: "validator", }); - const existingUser = await uow.userRepository.getById(userId); + const existingUser = await uow.userRepository.getById(inputParams.userId); if (!existingUser) { await uow.userRepository.save({ createdAt: deps.timeGateway.now().toISOString(), - email, + email: inputParams.email, externalId: null, firstName: "", - id: userId, + id: inputParams.userId, lastName: "", }); } const existingUserAgencyRights = existingUser?.agencyRights ?? []; const agencyRight: AgencyRight = { - roles, - isNotifiedByEmail: isNotifiedByEmail, + roles: inputParams.roles, + isNotifiedByEmail: inputParams.isNotifiedByEmail, agency, }; - await uow.userRepository.updateAgencyRights({ - userId: userId, - agencyRights: [...existingUserAgencyRights, agencyRight], + + const event: DomainEvent = deps.createNewEvent({ + topic: "IcUserAgencyRightChanged", + payload: { + ...inputParams, + triggeredBy: { + kind: "inclusion-connected", + userId: currentUser.id, + }, + }, }); + + await Promise.all([ + uow.userRepository.updateAgencyRights({ + userId: inputParams.userId, + agencyRights: [...existingUserAgencyRights, agencyRight], + }), + uow.outboxRepository.save(event), + ]); }, ); diff --git a/back/src/domains/inclusion-connected-users/use-cases/CreateUserForAgency.unit.test.ts b/back/src/domains/inclusion-connected-users/use-cases/CreateUserForAgency.unit.test.ts index 013188f4e5..2df31c67f2 100644 --- a/back/src/domains/inclusion-connected-users/use-cases/CreateUserForAgency.unit.test.ts +++ b/back/src/domains/inclusion-connected-users/use-cases/CreateUserForAgency.unit.test.ts @@ -1,12 +1,18 @@ import { AgencyDtoBuilder, InclusionConnectedUserBuilder, + UserCreateParamsForAgency, errors, expectPromiseToFailWithError, expectToEqual, } from "shared"; import { InMemoryAgencyRepository } from "../../agency/adapters/InMemoryAgencyRepository"; import { InMemoryUserRepository } from "../../core/authentication/inclusion-connect/adapters/InMemoryUserRepository"; +import { InMemoryOutboxRepository } from "../../core/events/adapters/InMemoryOutboxRepository"; +import { + CreateNewEvent, + makeCreateNewEvent, +} from "../../core/events/ports/EventBus"; import { CustomTimeGateway } from "../../core/time-gateway/adapters/CustomTimeGateway"; import { TimeGateway } from "../../core/time-gateway/ports/TimeGateway"; import { InMemoryUowPerformer } from "../../core/unit-of-work/adapters/InMemoryUowPerformer"; @@ -39,12 +45,15 @@ describe("CreateUserForAgency", () => { let agencyRepository: InMemoryAgencyRepository; let timeGateway: TimeGateway; let uuidGenerator: UuidGenerator; + let outboxRepository: InMemoryOutboxRepository; + let createNewEvent: CreateNewEvent; beforeEach(() => { const uow = createInMemoryUow(); userRepository = uow.userRepository; agencyRepository = uow.agencyRepository; + outboxRepository = uow.outboxRepository; uowPerformer = new InMemoryUowPerformer(uow); userRepository.setInclusionConnectedUsers([ backofficeAdminUser, @@ -52,9 +61,13 @@ describe("CreateUserForAgency", () => { ]); timeGateway = new CustomTimeGateway(); uuidGenerator = new TestUuidGenerator(); + createNewEvent = makeCreateNewEvent({ + uuidGenerator, + timeGateway, + }); createUserForAgency = makeCreateUserForAgency({ uowPerformer, - deps: { timeGateway, uuidGenerator }, + deps: { timeGateway, createNewEvent }, }); agencyRepository.setAgencies([agency]); }); @@ -141,16 +154,15 @@ describe("CreateUserForAgency", () => { const newUserId = uuidGenerator.new(); userRepository.users = []; - await createUserForAgency.execute( - { - userId: newUserId, - agencyId: agency.id, - roles: ["counsellor"], - isNotifiedByEmail: false, - email: "new-user@email.fr", - }, - backofficeAdminUser, - ); + const icUserForAgency: UserCreateParamsForAgency = { + userId: newUserId, + agencyId: agency.id, + roles: ["counsellor"], + isNotifiedByEmail: false, + email: "new-user@email.fr", + }; + + await createUserForAgency.execute(icUserForAgency, backofficeAdminUser); expect(userRepository.users.length).toBe(1); expectToEqual(await userRepository.getById(newUserId), { @@ -168,6 +180,19 @@ describe("CreateUserForAgency", () => { establishments: {}, }, }); + + expectToEqual(outboxRepository.events, [ + createNewEvent({ + topic: "IcUserAgencyRightChanged", + payload: { + ...icUserForAgency, + triggeredBy: { + kind: "inclusion-connected", + userId: backofficeAdminUser.id, + }, + }, + }), + ]); }); it("add agency rights to an existing user", async () => { @@ -195,16 +220,15 @@ describe("CreateUserForAgency", () => { ], }); - await createUserForAgency.execute( - { - userId, - agencyId: anotherAgency.id, - roles: ["counsellor"], - isNotifiedByEmail: false, - email: "user@email.fr", - }, - backofficeAdminUser, - ); + const icUserForAgency: UserCreateParamsForAgency = { + userId, + agencyId: anotherAgency.id, + roles: ["counsellor"], + isNotifiedByEmail: false, + email: "user@email.fr", + }; + + await createUserForAgency.execute(icUserForAgency, backofficeAdminUser); expectToEqual(await userRepository.getById(userId), { createdAt: timeGateway.now().toISOString(), @@ -230,5 +254,17 @@ describe("CreateUserForAgency", () => { establishments: {}, }, }); + expectToEqual(outboxRepository.events, [ + createNewEvent({ + topic: "IcUserAgencyRightChanged", + payload: { + ...icUserForAgency, + triggeredBy: { + kind: "inclusion-connected", + userId: backofficeAdminUser.id, + }, + }, + }), + ]); }); });