diff --git a/back/src/domains/inclusion-connected-users/use-cases/RemoveUserFromAgency.ts b/back/src/domains/inclusion-connected-users/use-cases/RemoveUserFromAgency.ts index f62e4729e..dfab9ef32 100644 --- a/back/src/domains/inclusion-connected-users/use-cases/RemoveUserFromAgency.ts +++ b/back/src/domains/inclusion-connected-users/use-cases/RemoveUserFromAgency.ts @@ -1,6 +1,6 @@ import { - AgencyDto, AgencyId, + AgencyRight, InclusionConnectedUser, OAuthGatewayProvider, RemoveAgencyUserParams, @@ -33,7 +33,7 @@ const getUserAndThrowIfNotFound = async ( const getUserAgencyRightsAndThrowIfUserHasNoAgencyRight = ( user: InclusionConnectedUser, agencyId: AgencyId, -): AgencyDto => { +): AgencyRight => { const userRight = user.agencyRights.find( (agencyRight) => agencyRight.agency.id === agencyId, ); @@ -44,7 +44,17 @@ const getUserAgencyRightsAndThrowIfUserHasNoAgencyRight = ( userId: user.id, }); - return userRight.agency; + return userRight; +}; + +const throwIfUserIsValidatorAndAgencyHasRefersTo = ( + agencyRight: AgencyRight, +) => { + const agency = agencyRight.agency; + + if (agency.refersToAgencyId && agencyRight.roles.includes("validator")) { + throw errors.agency.invalidUserRemovalWhenAgencyWithRefersTo(agency.id); + } }; export const makeRemoveUserFromAgency = createTransactionalUseCase< @@ -64,10 +74,13 @@ export const makeRemoveUserFromAgency = createTransactionalUseCase< inputParams.userId, provider, ); - const agency = getUserAgencyRightsAndThrowIfUserHasNoAgencyRight( + const agencyRight = getUserAgencyRightsAndThrowIfUserHasNoAgencyRight( requestedUser, inputParams.agencyId, ); + const agency = agencyRight.agency; + + throwIfUserIsValidatorAndAgencyHasRefersTo(agencyRight); await throwIfAgencyDontHaveOtherValidatorsReceivingNotifications( uow, agency, diff --git a/back/src/domains/inclusion-connected-users/use-cases/RemoveUserFromAgency.unit.test.ts b/back/src/domains/inclusion-connected-users/use-cases/RemoveUserFromAgency.unit.test.ts index ac7d216d1..d981829de 100644 --- a/back/src/domains/inclusion-connected-users/use-cases/RemoveUserFromAgency.unit.test.ts +++ b/back/src/domains/inclusion-connected-users/use-cases/RemoveUserFromAgency.unit.test.ts @@ -94,24 +94,17 @@ describe("RemoveUserFromAgency", () => { ); }); - it("throws forbidden if user to delete has not rights on agency", async () => { - const inputParams: RemoveAgencyUserParams = { - agencyId: agency.id, - userId: notAdminUser.id, - }; - - expectPromiseToFailWithError( - removeUserFromAgency.execute(inputParams, backofficeAdminUser), - errors.user.expectedRightsOnAgency(inputParams), - ); - }); - - it("throws forbidden if user to delete is the last validator receiving notifications", async () => { + it("throws bad request if user attempts to delete validator when agency has refersTo", async () => { + const agencyWithRefersTo = new AgencyDtoBuilder() + .withId("agency-with-refers-to-id") + .withRefersToAgencyId(agency.id) + .withCounsellorEmails([notAdminUser.email]) + .build(); const initialAgencyRights: AgencyRight[] = [ { - agency, + agency: agencyWithRefersTo, roles: ["validator"], - isNotifiedByEmail: true, + isNotifiedByEmail: false, }, ]; const user: InclusionConnectedUser = { @@ -122,7 +115,23 @@ describe("RemoveUserFromAgency", () => { establishments: {}, }, }; + agencyRepository.insert(agencyWithRefersTo); userRepository.setInclusionConnectedUsers([user]); + + const inputParams: RemoveAgencyUserParams = { + agencyId: agencyWithRefersTo.id, + userId: user.id, + }; + + expectPromiseToFailWithError( + removeUserFromAgency.execute(inputParams, backofficeAdminUser), + errors.agency.invalidUserRemovalWhenAgencyWithRefersTo( + agencyWithRefersTo.id, + ), + ); + }); + + it("throws forbidden if user to delete has not rights on agency", async () => { const inputParams: RemoveAgencyUserParams = { agencyId: agency.id, userId: notAdminUser.id, @@ -130,7 +139,7 @@ describe("RemoveUserFromAgency", () => { expectPromiseToFailWithError( removeUserFromAgency.execute(inputParams, backofficeAdminUser), - errors.agency.notEnoughValidators(inputParams), + errors.user.expectedRightsOnAgency(inputParams), ); }); @@ -173,7 +182,7 @@ describe("RemoveUserFromAgency", () => { const initialAgencyRights: AgencyRight[] = [ { agency: agencyWithRefersTo, - roles: ["validator"], + roles: ["counsellor"], isNotifiedByEmail: true, }, ]; diff --git a/front/src/app/components/agency/AgencyUsers.tsx b/front/src/app/components/agency/AgencyUsers.tsx index 71cbe1382..3eda5a5cf 100644 --- a/front/src/app/components/agency/AgencyUsers.tsx +++ b/front/src/app/components/agency/AgencyUsers.tsx @@ -172,6 +172,11 @@ export const AgencyUsers = ({ agency }: AgencyUsersProperties) => { { children: "Supprimer", priority: "secondary", + disabled: + agency.refersToAgencyId !== null && + agencyUser.agencyRights[agency.id].roles[0].includes( + "validator", + ), id: `${domElementIds.admin.agencyTab.editAgencyRemoveUserButton}-${agency.id}-${index}`, onClick: () => { dispatch(feedbackSlice.actions.clearFeedbacksTriggered()); diff --git a/shared/src/errors/errors.ts b/shared/src/errors/errors.ts index ec17e0d61..698f764dc 100644 --- a/shared/src/errors/errors.ts +++ b/shared/src/errors/errors.ts @@ -309,6 +309,11 @@ export const errors = { new BadRequestError( `Le role "${role}" n'est pas autorisé pour l'agence "${agencyId}" car cette agence est une structure d'accompagnement.`, ), + + invalidUserRemovalWhenAgencyWithRefersTo: (agencyId: AgencyId) => + new BadRequestError( + `La suppression d'un valideur n'est pas autorisée pour l'agence "${agencyId}" car cette agence est une structure d'accompagnement.`, + ), }, user: { unauthorized: () => new UnauthorizedError(),