From c5ac54569a595f97b49569f73e33cd6860c130dd Mon Sep 17 00:00:00 2001 From: LEGO Technix <109212476+lego-technix@users.noreply.github.com> Date: Fri, 27 Dec 2024 16:21:19 +0100 Subject: [PATCH 1/8] refactor(api): deduplicate code --- api/src/team/domain/usecases/get-prescriber.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/api/src/team/domain/usecases/get-prescriber.js b/api/src/team/domain/usecases/get-prescriber.js index 2d8d4586f25..5e9df92c594 100644 --- a/api/src/team/domain/usecases/get-prescriber.js +++ b/api/src/team/domain/usecases/get-prescriber.js @@ -28,10 +28,7 @@ export const getPrescriber = async function ({ if (_.isEmpty(userOrgaSettings)) { await userOrgaSettingsRepository.create(userId, firstOrganization.id); - return prescriberRepository.getPrescriber(userId); - } - - if (!_isCurrentOrganizationInMemberships(userOrgaSettings, memberships)) { + } else if (!_isCurrentOrganizationInMemberships(userOrgaSettings, memberships)) { await userOrgaSettingsRepository.update(userId, firstOrganization.id); } From 394bb0afa8e10b24bfe4f5022904b43d88302164 Mon Sep 17 00:00:00 2001 From: LEGO Technix <109212476+lego-technix@users.noreply.github.com> Date: Fri, 3 Jan 2025 20:12:29 +0100 Subject: [PATCH 2/8] feat(api): add dependency injection in repositories of team context to be able to use the legalDocumentApiRepository in the prescriberRepository --- api/src/team/infrastructure/repositories/index.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 api/src/team/infrastructure/repositories/index.js diff --git a/api/src/team/infrastructure/repositories/index.js b/api/src/team/infrastructure/repositories/index.js new file mode 100644 index 00000000000..41e0860fe93 --- /dev/null +++ b/api/src/team/infrastructure/repositories/index.js @@ -0,0 +1,15 @@ +import { injectDependencies } from '../../../../src/shared/infrastructure/utils/dependency-injection.js'; +import * as legalDocumentApi from '../../../legal-documents/application/api/legal-documents-api.js'; +import { prescriberRepository } from './prescriber-repository.js'; + +const repositoriesWithoutInjectedDependencies = { + prescriberRepository, +}; + +const dependencies = { + legalDocumentApi, +}; + +const repositories = injectDependencies(repositoriesWithoutInjectedDependencies, dependencies); + +export { repositories }; From 7c50cfb7afe3797f3b35ffc8bd627aee150dd335 Mon Sep 17 00:00:00 2001 From: LEGO Technix <109212476+lego-technix@users.noreply.github.com> Date: Sat, 4 Jan 2025 19:36:52 +0100 Subject: [PATCH 3/8] feat(api): leverage the dependency-injected repositories in the dependency injection for usecases of team context to be able to use in usecases the prescriberRepository injected with the legalDocumentApiRepository --- api/src/team/domain/usecases/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/src/team/domain/usecases/index.js b/api/src/team/domain/usecases/index.js index a1e14bd43ab..783a8c01545 100644 --- a/api/src/team/domain/usecases/index.js +++ b/api/src/team/domain/usecases/index.js @@ -13,10 +13,10 @@ import { importNamedExportsFromDirectory } from '../../../shared/infrastructure/ import * as certificationCenterInvitationRepository from '../../infrastructure/repositories/certification-center-invitation-repository.js'; import { certificationCenterInvitedUserRepository } from '../../infrastructure/repositories/certification-center-invited-user.repository.js'; import { certificationCenterMembershipRepository } from '../../infrastructure/repositories/certification-center-membership.repository.js'; +import { repositories } from '../../infrastructure/repositories/index.js'; import * as membershipRepository from '../../infrastructure/repositories/membership.repository.js'; import { organizationInvitationRepository } from '../../infrastructure/repositories/organization-invitation.repository.js'; import { organizationInvitedUserRepository } from '../../infrastructure/repositories/organization-invited-user.repository.js'; -import { prescriberRepository } from '../../infrastructure/repositories/prescriber-repository.js'; import { userOrgaSettingsRepository } from '../../infrastructure/repositories/user-orga-settings-repository.js'; import * as certificationCenterInvitationService from '../services/certification-center-invitation-service.js'; import { organizationInvitationService } from '../services/organization-invitation.service.js'; @@ -29,7 +29,7 @@ const dependencies = { certificationCenterInvitedUserRepository, certificationCenterRepository, certificationCenterInvitationRepository, - prescriberRepository, + prescriberRepository: repositories.prescriberRepository, membershipRepository, userOrgaSettingsRepository, certificationCenterInvitationService, From 81c309d457ed8071179d20e665d17efafc1ecf3a Mon Sep 17 00:00:00 2001 From: LEGO Technix <109212476+lego-technix@users.noreply.github.com> Date: Sat, 4 Jan 2025 19:37:05 +0100 Subject: [PATCH 4/8] feat(api): use the dependency-injected usecases in integration tests to be able to use in usecases the prescriberRepository injected with the legalDocumentApiRepository --- .../team/integration/domain/usecases/get-prescriber_test.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/api/tests/team/integration/domain/usecases/get-prescriber_test.js b/api/tests/team/integration/domain/usecases/get-prescriber_test.js index 071ed7d5238..48a290d1a4e 100644 --- a/api/tests/team/integration/domain/usecases/get-prescriber_test.js +++ b/api/tests/team/integration/domain/usecases/get-prescriber_test.js @@ -1,9 +1,11 @@ import * as sharedMembershipRepository from '../../../../../src/shared/infrastructure/repositories/membership-repository.js'; -import { getPrescriber } from '../../../../../src/team/domain/usecases/get-prescriber.js'; +import { usecases } from '../../../../../src/team/domain/usecases/index.js'; import { prescriberRepository } from '../../../../../src/team/infrastructure/repositories/prescriber-repository.js'; import { userOrgaSettingsRepository } from '../../../../../src/team/infrastructure/repositories/user-orga-settings-repository.js'; import { databaseBuilder, expect, knex } from '../../../../test-helper.js'; +const getPrescriber = usecases.getPrescriber; + describe('Integration | Team | Domain | UseCases | get-prescriber', function () { context('When prescriber does not have a userOrgaSettings', function () { it("should create it with the first membership's organization", async function () { From edd051c369b9accbd3eb9166581bdab139cc82e8 Mon Sep 17 00:00:00 2001 From: LEGO Technix <109212476+lego-technix@users.noreply.github.com> Date: Fri, 3 Jan 2025 20:12:46 +0100 Subject: [PATCH 5/8] feat(api): use legalDocumentApi in team context --- .../team/domain/usecases/get-prescriber.js | 3 +- .../repositories/prescriber-repository.js | 20 ++++-- .../domain/usecases/get-prescriber_test.js | 3 +- .../prescriber-repository_test.js | 68 +++++++++++++------ .../domain/usecases/get-prescriber_test.js | 4 +- 5 files changed, 68 insertions(+), 30 deletions(-) diff --git a/api/src/team/domain/usecases/get-prescriber.js b/api/src/team/domain/usecases/get-prescriber.js index 5e9df92c594..48871531314 100644 --- a/api/src/team/domain/usecases/get-prescriber.js +++ b/api/src/team/domain/usecases/get-prescriber.js @@ -31,8 +31,7 @@ export const getPrescriber = async function ({ } else if (!_isCurrentOrganizationInMemberships(userOrgaSettings, memberships)) { await userOrgaSettingsRepository.update(userId, firstOrganization.id); } - - return prescriberRepository.getPrescriber(userId); + return prescriberRepository.getPrescriber({ userId }); }; function _isCurrentOrganizationInMemberships(userOrgaSettings, memberships) { diff --git a/api/src/team/infrastructure/repositories/prescriber-repository.js b/api/src/team/infrastructure/repositories/prescriber-repository.js index bd8617065f8..61f65fa005e 100644 --- a/api/src/team/infrastructure/repositories/prescriber-repository.js +++ b/api/src/team/infrastructure/repositories/prescriber-repository.js @@ -8,19 +8,27 @@ import { UserOrgaSettings } from '../../../shared/domain/models/UserOrgaSettings import { Prescriber } from '../../domain/read-models/Prescriber.js'; /** - * @param {string} userId + * @param {Object} params + * @property {string} params.userId + * @param {any} params.legalDocumentApi * @return {Promise} */ -const getPrescriber = async function (userId) { - const user = await knex('users') - .select('id', 'firstName', 'lastName', 'pixOrgaTermsOfServiceAccepted', 'lang') - .where({ id: userId }) - .first(); +const getPrescriber = async function ({ userId, legalDocumentApi }) { + const user = await knex('users').select('id', 'firstName', 'lastName', 'lang').where({ id: userId }).first(); if (!user) { throw new UserNotFoundError(`User not found for ID ${userId}`); } + const pixOrgaLegalDocumentStatus = await legalDocumentApi.getLegalDocumentStatusByUserId({ + userId, + service: 'pix-orga', + type: 'TOS', + }); + user.pixOrgaTermsOfServiceAccepted = pixOrgaLegalDocumentStatus.status == 'accepted'; + user.pixOrgaTermsOfServiceStatus = pixOrgaLegalDocumentStatus.status; + user.pixOrgaTermsOfServiceDocumentPath = pixOrgaLegalDocumentStatus.path; + const memberships = await knex('memberships').where({ userId, disabledAt: null }).orderBy('id'); if (memberships.length === 0) { diff --git a/api/tests/team/integration/domain/usecases/get-prescriber_test.js b/api/tests/team/integration/domain/usecases/get-prescriber_test.js index 48a290d1a4e..c39e1a633cc 100644 --- a/api/tests/team/integration/domain/usecases/get-prescriber_test.js +++ b/api/tests/team/integration/domain/usecases/get-prescriber_test.js @@ -1,10 +1,11 @@ import * as sharedMembershipRepository from '../../../../../src/shared/infrastructure/repositories/membership-repository.js'; import { usecases } from '../../../../../src/team/domain/usecases/index.js'; -import { prescriberRepository } from '../../../../../src/team/infrastructure/repositories/prescriber-repository.js'; +import { repositories } from '../../../../../src/team/infrastructure/repositories/index.js'; import { userOrgaSettingsRepository } from '../../../../../src/team/infrastructure/repositories/user-orga-settings-repository.js'; import { databaseBuilder, expect, knex } from '../../../../test-helper.js'; const getPrescriber = usecases.getPrescriber; +const prescriberRepository = repositories.prescriberRepository; describe('Integration | Team | Domain | UseCases | get-prescriber', function () { context('When prescriber does not have a userOrgaSettings', function () { diff --git a/api/tests/team/integration/infrastructure/repositories/prescriber-repository_test.js b/api/tests/team/integration/infrastructure/repositories/prescriber-repository_test.js index 2eae1b5c333..e5c62bd0805 100644 --- a/api/tests/team/integration/infrastructure/repositories/prescriber-repository_test.js +++ b/api/tests/team/integration/infrastructure/repositories/prescriber-repository_test.js @@ -9,9 +9,11 @@ import { ForbiddenAccess } from '../../../../../src/shared/domain/errors.js'; import { Membership } from '../../../../../src/shared/domain/models/Membership.js'; import { UserOrgaSettings } from '../../../../../src/shared/domain/models/UserOrgaSettings.js'; import { Prescriber } from '../../../../../src/team/domain/read-models/Prescriber.js'; -import { prescriberRepository } from '../../../../../src/team/infrastructure/repositories/prescriber-repository.js'; +import { repositories } from '../../../../../src/team/infrastructure/repositories/index.js'; import { catchErr, databaseBuilder, expect } from '../../../../test-helper.js'; +const prescriberRepository = repositories.prescriberRepository; + describe('Integration | Team | Infrastructure | Repository | Prescriber', function () { const userToInsert = { firstName: 'estelle', @@ -40,7 +42,9 @@ describe('Integration | Team | Infrastructure | Repository | Prescriber', functi await databaseBuilder.commit(); // when - const error = await catchErr(prescriberRepository.getPrescriber)(userId); + const error = await catchErr(prescriberRepository.getPrescriber)({ + userId: userId, + }); // then expect(error).to.be.an.instanceOf(ForbiddenAccess); @@ -74,7 +78,9 @@ describe('Integration | Team | Infrastructure | Repository | Prescriber', functi it('should return the found prescriber', async function () { // when - const foundPrescriber = await prescriberRepository.getPrescriber(user.id); + const foundPrescriber = await prescriberRepository.getPrescriber({ + userId: user.id, + }); // then expect(foundPrescriber).to.be.an.instanceOf(Prescriber); @@ -92,7 +98,9 @@ describe('Integration | Team | Infrastructure | Repository | Prescriber', functi const nonExistentUserId = 678; // when - const result = await catchErr(prescriberRepository.getPrescriber)(nonExistentUserId); + const result = await catchErr(prescriberRepository.getPrescriber)({ + userId: nonExistentUserId, + }); // then expect(result).to.be.instanceOf(UserNotFoundError); @@ -103,7 +111,9 @@ describe('Integration | Team | Infrastructure | Repository | Prescriber', functi expectedPrescriber.memberships = [membership]; // when - const foundPrescriber = await prescriberRepository.getPrescriber(user.id); + const foundPrescriber = await prescriberRepository.getPrescriber({ + userId: user.id, + }); // then const firstMembership = foundPrescriber.memberships[0]; @@ -126,7 +136,9 @@ describe('Integration | Team | Infrastructure | Repository | Prescriber', functi await databaseBuilder.commit(); // when - const foundPrescriber = await prescriberRepository.getPrescriber(user.id); + const foundPrescriber = await prescriberRepository.getPrescriber({ + userId: user.id, + }); // then expect(foundPrescriber.memberships[0].id).to.equal(3000000); @@ -138,7 +150,7 @@ describe('Integration | Team | Infrastructure | Repository | Prescriber', functi expectedPrescriber.userOrgaSettings = userOrgaSettings; // when - const foundUser = await prescriberRepository.getPrescriber(user.id); + const foundUser = await prescriberRepository.getPrescriber({ userId: user.id }); // then expect(foundUser.userOrgaSettings).to.be.an.instanceOf(UserOrgaSettings); @@ -153,7 +165,7 @@ describe('Integration | Team | Infrastructure | Repository | Prescriber', functi expectedPrescriber.userOrgaSettings = userOrgaSettings; const expectedOrganization = new Organization(organization); // when - const foundUser = await prescriberRepository.getPrescriber(user.id); + const foundUser = await prescriberRepository.getPrescriber({ userId: user.id }); // then expect(foundUser.userOrgaSettings.currentOrganization).to.be.an.instanceOf(Organization); @@ -171,7 +183,9 @@ describe('Integration | Team | Infrastructure | Repository | Prescriber', functi await databaseBuilder.commit(); // when - const foundPrescriber = await prescriberRepository.getPrescriber(user.id); + const foundPrescriber = await prescriberRepository.getPrescriber({ + userId: user.id, + }); // then expect(foundPrescriber.userOrgaSettings.currentOrganization.tags.map((tag) => tag.name)).to.have.members([ @@ -192,7 +206,9 @@ describe('Integration | Team | Infrastructure | Repository | Prescriber', functi await databaseBuilder.commit(); // when - const foundPrescriber = await prescriberRepository.getPrescriber(user.id); + const foundPrescriber = await prescriberRepository.getPrescriber({ + userId: user.id, + }); // then const schoolMembership = foundPrescriber.memberships.find( @@ -210,7 +226,9 @@ describe('Integration | Team | Infrastructure | Repository | Prescriber', functi await databaseBuilder.commit(); // when - const foundPrescriber = await prescriberRepository.getPrescriber(user.id); + const foundPrescriber = await prescriberRepository.getPrescriber({ + userId: user.id, + }); // then expect(foundPrescriber.userOrgaSettings.currentOrganization.sessionExpirationDate).to.deep.equal( @@ -241,7 +259,7 @@ describe('Integration | Team | Infrastructure | Repository | Prescriber', functi await databaseBuilder.commit(); // when - const foundPrescriber = await prescriberRepository.getPrescriber(userId); + const foundPrescriber = await prescriberRepository.getPrescriber({ userId }); // then expect(foundPrescriber.areNewYearOrganizationLearnersImported).to.be.true; @@ -269,7 +287,7 @@ describe('Integration | Team | Infrastructure | Repository | Prescriber', functi await databaseBuilder.commit(); // when - const foundPrescriber = await prescriberRepository.getPrescriber(userId); + const foundPrescriber = await prescriberRepository.getPrescriber({ userId }); // then expect(foundPrescriber.areNewYearOrganizationLearnersImported).to.be.true; @@ -299,7 +317,9 @@ describe('Integration | Team | Infrastructure | Repository | Prescriber', functi await databaseBuilder.commit(); // when - const foundPrescriber = await prescriberRepository.getPrescriber(userId); + const foundPrescriber = await prescriberRepository.getPrescriber({ + userId: user.id, + }); // then expect(foundPrescriber.areNewYearOrganizationLearnersImported).to.be.false; @@ -318,7 +338,9 @@ describe('Integration | Team | Infrastructure | Repository | Prescriber', functi await databaseBuilder.commit(); // when - const foundPrescriber = await prescriberRepository.getPrescriber(user.id); + const foundPrescriber = await prescriberRepository.getPrescriber({ + userId: user.id, + }); // then expect(foundPrescriber.participantCount).to.equal(1); @@ -334,7 +356,9 @@ describe('Integration | Team | Infrastructure | Repository | Prescriber', functi await databaseBuilder.commit(); // when - const foundPrescriber = await prescriberRepository.getPrescriber(user.id); + const foundPrescriber = await prescriberRepository.getPrescriber({ + userId: user.id, + }); // then expect(foundPrescriber.participantCount).to.equal(0); @@ -349,7 +373,9 @@ describe('Integration | Team | Infrastructure | Repository | Prescriber', functi await databaseBuilder.commit(); // when - const foundPrescriber = await prescriberRepository.getPrescriber(user.id); + const foundPrescriber = await prescriberRepository.getPrescriber({ + userId: user.id, + }); // then expect(foundPrescriber.participantCount).to.equal(0); @@ -366,7 +392,9 @@ describe('Integration | Team | Infrastructure | Repository | Prescriber', functi await databaseBuilder.commit(); // when - const foundPrescriber = await prescriberRepository.getPrescriber(user.id); + const foundPrescriber = await prescriberRepository.getPrescriber({ + userId: user.id, + }); // then expect(foundPrescriber.participantCount).to.equal(2); @@ -393,7 +421,9 @@ describe('Integration | Team | Infrastructure | Repository | Prescriber', functi await databaseBuilder.commit(); // when - const foundPrescriber = await prescriberRepository.getPrescriber(user.id); + const foundPrescriber = await prescriberRepository.getPrescriber({ + userId: user.id, + }); // then expect(foundPrescriber.features).to.deep.equal({ diff --git a/api/tests/team/unit/domain/usecases/get-prescriber_test.js b/api/tests/team/unit/domain/usecases/get-prescriber_test.js index e1c6138ddc8..9a2b36b802e 100644 --- a/api/tests/team/unit/domain/usecases/get-prescriber_test.js +++ b/api/tests/team/unit/domain/usecases/get-prescriber_test.js @@ -62,7 +62,7 @@ describe('Unit | Team | Domain | UseCase | get-prescriber', function () { const membership = domainBuilder.buildMembership({ user }); sharedMembershipRepository.findByUserId.withArgs({ userId }).resolves([membership]); userOrgaSettingsRepository.findOneByUserId.withArgs(userId).resolves(null); - prescriberRepository.getPrescriber.withArgs(userId).resolves(expectedResult); + prescriberRepository.getPrescriber.withArgs({ userId }).resolves(expectedResult); // when const result = await getPrescriber({ @@ -111,7 +111,7 @@ describe('Unit | Team | Domain | UseCase | get-prescriber', function () { user: membership.user, }); userOrgaSettingsRepository.findOneByUserId.withArgs(userId).resolves(userOrgaSettings); - prescriberRepository.getPrescriber.withArgs(userId).resolves(expectedResult); + prescriberRepository.getPrescriber.withArgs({ userId }).resolves(expectedResult); // when const result = await getPrescriber({ From b0a798391b74265af531de86f85deda19e9fbf66 Mon Sep 17 00:00:00 2001 From: Emmanuelle Bonnemay Date: Tue, 7 Jan 2025 15:49:26 +0100 Subject: [PATCH 6/8] feat(api): add TOS related attributes to domain and serializer --- api/src/team/domain/read-models/Prescriber.js | 6 +++++ .../repositories/prescriber-repository.js | 27 +++++++++++++++---- .../jsonapi/prescriber-serializer.js | 2 ++ ...prescriber-informations.controller.test.js | 2 ++ .../prescriber-repository_test.js | 7 +++++ .../jsonapi/prescriber-serializer_test.js | 6 +++++ .../factory/build-prescriber.js | 4 +++ 7 files changed, 49 insertions(+), 5 deletions(-) diff --git a/api/src/team/domain/read-models/Prescriber.js b/api/src/team/domain/read-models/Prescriber.js index 10b0ad57e8f..620d8608797 100644 --- a/api/src/team/domain/read-models/Prescriber.js +++ b/api/src/team/domain/read-models/Prescriber.js @@ -5,6 +5,8 @@ class Prescriber { * firstName: string, * lastName: string, * pixOrgaTermsOfServiceAccepted: boolean, + * pixOrgaTermsOfServiceStatus: string, + * pixOrgaTermsOfServiceDocumentPath: string, * lang: string, * areNewYearOrganizationLearnersImported: boolean, * participantCount: number, @@ -18,6 +20,8 @@ class Prescriber { firstName, lastName, pixOrgaTermsOfServiceAccepted, + pixOrgaTermsOfServiceStatus, + pixOrgaTermsOfServiceDocumentPath, lang, areNewYearOrganizationLearnersImported, participantCount, @@ -29,6 +33,8 @@ class Prescriber { this.firstName = firstName; this.lastName = lastName; this.pixOrgaTermsOfServiceAccepted = pixOrgaTermsOfServiceAccepted; + this.pixOrgaTermsOfServiceStatus = pixOrgaTermsOfServiceStatus; + this.pixOrgaTermsOfServiceDocumentPath = pixOrgaTermsOfServiceDocumentPath; this.lang = lang; this.areNewYearOrganizationLearnersImported = areNewYearOrganizationLearnersImported; this.participantCount = participantCount; diff --git a/api/src/team/infrastructure/repositories/prescriber-repository.js b/api/src/team/infrastructure/repositories/prescriber-repository.js index 61f65fa005e..ecba2db6e36 100644 --- a/api/src/team/infrastructure/repositories/prescriber-repository.js +++ b/api/src/team/infrastructure/repositories/prescriber-repository.js @@ -25,9 +25,6 @@ const getPrescriber = async function ({ userId, legalDocumentApi }) { service: 'pix-orga', type: 'TOS', }); - user.pixOrgaTermsOfServiceAccepted = pixOrgaLegalDocumentStatus.status == 'accepted'; - user.pixOrgaTermsOfServiceStatus = pixOrgaLegalDocumentStatus.status; - user.pixOrgaTermsOfServiceDocumentPath = pixOrgaLegalDocumentStatus.path; const memberships = await knex('memberships').where({ userId, disabledAt: null }).orderBy('id'); @@ -44,7 +41,15 @@ const getPrescriber = async function ({ userId, legalDocumentApi }) { const schools = await knex('schools').whereIn('organizationId', organizationIds); - const prescriber = _toPrescriberDomain(user, userOrgaSettings, tags, memberships, organizations, schools); + const prescriber = _toPrescriberDomain({ + user, + pixOrgaLegalDocumentStatus, + userOrgaSettings, + tags, + memberships, + organizations, + schools, + }); const currentOrganizationId = prescriber.userOrgaSettings.currentOrganization.id; prescriber.areNewYearOrganizationLearnersImported = @@ -57,11 +62,23 @@ const getPrescriber = async function ({ userId, legalDocumentApi }) { export const prescriberRepository = { getPrescriber }; -function _toPrescriberDomain(user, userOrgaSettings, tags, memberships, organizations, schools) { +function _toPrescriberDomain({ + user, + pixOrgaLegalDocumentStatus, + userOrgaSettings, + tags, + memberships, + organizations, + schools, +}) { const currentSchool = schools.find((school) => school.organizationId === userOrgaSettings.currentOrganizationId); return new Prescriber({ ...user, + pixOrgaTermsOfServiceAccepted: pixOrgaLegalDocumentStatus.status === 'accepted', + pixOrgaTermsOfServiceStatus: pixOrgaLegalDocumentStatus.status, + pixOrgaTermsOfServiceDocumentPath: pixOrgaLegalDocumentStatus.documentPath, + memberships: memberships.map( (membership) => new Membership({ diff --git a/api/src/team/infrastructure/serializers/jsonapi/prescriber-serializer.js b/api/src/team/infrastructure/serializers/jsonapi/prescriber-serializer.js index e4b3de04891..5e1817946c9 100644 --- a/api/src/team/infrastructure/serializers/jsonapi/prescriber-serializer.js +++ b/api/src/team/infrastructure/serializers/jsonapi/prescriber-serializer.js @@ -31,6 +31,8 @@ const serialize = function (prescriber) { 'firstName', 'lastName', 'pixOrgaTermsOfServiceAccepted', + 'pixOrgaTermsOfServiceStatus', + 'pixOrgaTermsOfServiceDocumentPath', 'areNewYearOrganizationLearnersImported', 'participantCount', 'lang', diff --git a/api/tests/team/acceptance/application/prescriber-informations.controller.test.js b/api/tests/team/acceptance/application/prescriber-informations.controller.test.js index d39684105b7..aa81e80e29d 100644 --- a/api/tests/team/acceptance/application/prescriber-informations.controller.test.js +++ b/api/tests/team/acceptance/application/prescriber-informations.controller.test.js @@ -28,6 +28,8 @@ describe('Acceptance | Team | Application | Controller | prescriber-informations 'first-name': user.firstName, 'last-name': user.lastName, 'pix-orga-terms-of-service-accepted': false, + 'pix-orga-terms-of-service-status': 'requested', + 'pix-orga-terms-of-service-document-path': 'pix-orga-tos-2024-01-02', 'are-new-year-organization-learners-imported': false, 'participant-count': 0, lang: user.lang, diff --git a/api/tests/team/integration/infrastructure/repositories/prescriber-repository_test.js b/api/tests/team/integration/infrastructure/repositories/prescriber-repository_test.js index e5c62bd0805..413c6a31674 100644 --- a/api/tests/team/integration/infrastructure/repositories/prescriber-repository_test.js +++ b/api/tests/team/integration/infrastructure/repositories/prescriber-repository_test.js @@ -72,6 +72,8 @@ describe('Integration | Team | Infrastructure | Repository | Prescriber', functi firstName: user.firstName, lastName: user.lastName, pixOrgaTermsOfServiceAccepted: user.pixOrgaTermsOfServiceAccepted, + pixOrgaTermsOfServiceStatus: 'requested', + pixOrgaTermsOfServiceDocumentPath: 'pix-orga-tos-2024-01-02', lang: user.lang, }; }); @@ -83,6 +85,7 @@ describe('Integration | Team | Infrastructure | Repository | Prescriber', functi }); // then + expect(foundPrescriber).to.be.an.instanceOf(Prescriber); expect(foundPrescriber.id).to.equal(expectedPrescriber.id); expect(foundPrescriber.firstName).to.equal(expectedPrescriber.firstName); @@ -90,6 +93,10 @@ describe('Integration | Team | Infrastructure | Repository | Prescriber', functi expect(foundPrescriber.pixOrgaTermsOfServiceAccepted).to.equal( expectedPrescriber.pixOrgaTermsOfServiceAccepted, ); + expect(foundPrescriber.pixOrgaTermsOfServiceStatus).to.equal(expectedPrescriber.pixOrgaTermsOfServiceStatus); + expect(foundPrescriber.pixOrgaTermsOfServiceDocumentPath).to.equal( + expectedPrescriber.pixOrgaTermsOfServiceDocumentPath, + ); expect(foundPrescriber.lang).to.equal(expectedPrescriber.lang); }); diff --git a/api/tests/team/unit/infrastructure/serializers/jsonapi/prescriber-serializer_test.js b/api/tests/team/unit/infrastructure/serializers/jsonapi/prescriber-serializer_test.js index e4e2db8c191..01d71bfa673 100644 --- a/api/tests/team/unit/infrastructure/serializers/jsonapi/prescriber-serializer_test.js +++ b/api/tests/team/unit/infrastructure/serializers/jsonapi/prescriber-serializer_test.js @@ -176,6 +176,8 @@ describe('Unit | Team | Infrastructure | Serializer | JSONAPI | prescriber', fun areNewYearOrganizationLearnersImported: false, participantCount: 0, pixOrgaTermsOfServiceAccepted: user.pixOrgaTermsOfServiceAccepted, + pixOrgaTermsOfServiceStatus: 'accepted', + pixOrgaTermsOfServiceDocumentPath: 'dummy', memberships: [membership], userOrgaSettings, features: { @@ -245,6 +247,8 @@ function createExpectedPrescriberSerializedWithOneMoreField({ 'first-name': prescriber.firstName, 'last-name': prescriber.lastName, 'pix-orga-terms-of-service-accepted': prescriber.pixOrgaTermsOfServiceAccepted, + 'pix-orga-terms-of-service-status': prescriber.pixOrgaTermsOfServiceStatus, + 'pix-orga-terms-of-service-document-path': prescriber.pixOrgaTermsOfServiceDocumentPath, 'are-new-year-organization-learners-imported': prescriber.areNewYearOrganizationLearnersImported, 'participant-count': prescriber.participantCount, lang: prescriber.lang, @@ -354,6 +358,8 @@ function createExpectedPrescriberSerialized({ prescriber, membership, userOrgaSe 'first-name': prescriber.firstName, 'last-name': prescriber.lastName, 'pix-orga-terms-of-service-accepted': prescriber.pixOrgaTermsOfServiceAccepted, + 'pix-orga-terms-of-service-status': prescriber.pixOrgaTermsOfServiceStatus, + 'pix-orga-terms-of-service-document-path': prescriber.pixOrgaTermsOfServiceDocumentPath, 'are-new-year-organization-learners-imported': prescriber.areNewYearOrganizationLearnersImported, 'participant-count': prescriber.participantCount, lang: prescriber.lang, diff --git a/api/tests/tooling/domain-builder/factory/build-prescriber.js b/api/tests/tooling/domain-builder/factory/build-prescriber.js index 610382e22a4..fa770eb7dee 100644 --- a/api/tests/tooling/domain-builder/factory/build-prescriber.js +++ b/api/tests/tooling/domain-builder/factory/build-prescriber.js @@ -49,6 +49,8 @@ const buildPrescriber = function ({ firstName = 'Jean', lastName = 'Forme', pixOrgaTermsOfServiceAccepted = false, + pixOrgaTermsOfServiceStatus = 'requested', + pixOrgaTermsOfServiceDocumentPath = 'pix-orga-tos-2024-01-02', lang = 'fr', areNewYearOrganizationLearnersImported = false, memberships = _buildMemberships(), @@ -60,6 +62,8 @@ const buildPrescriber = function ({ firstName, lastName, pixOrgaTermsOfServiceAccepted, + pixOrgaTermsOfServiceStatus, + pixOrgaTermsOfServiceDocumentPath, lang, areNewYearOrganizationLearnersImported, memberships, From f6c8b03ebb98aeb0620b6e6b8f99de52fe9ef20c Mon Sep 17 00:00:00 2001 From: LEGO Technix <109212476+lego-technix@users.noreply.github.com> Date: Mon, 6 Jan 2025 08:01:33 +0100 Subject: [PATCH 7/8] refactor(api): in /users/me remove unused pixOrgaTermsOfServiceAccepted, pixCertifTermsOfServiceAccepted properties --- .../serializers/jsonapi/user-with-activity.serializer.js | 2 -- .../acceptance/application/user/user.route.test.js | 2 -- .../serializers/jsonapi/user-with-activity.serializer.test.js | 2 -- 3 files changed, 6 deletions(-) diff --git a/api/src/identity-access-management/infrastructure/serializers/jsonapi/user-with-activity.serializer.js b/api/src/identity-access-management/infrastructure/serializers/jsonapi/user-with-activity.serializer.js index e0bdbd1c397..34aba163192 100644 --- a/api/src/identity-access-management/infrastructure/serializers/jsonapi/user-with-activity.serializer.js +++ b/api/src/identity-access-management/infrastructure/serializers/jsonapi/user-with-activity.serializer.js @@ -14,8 +14,6 @@ const serialize = function (users, meta) { 'lastTermsOfServiceValidatedAt', 'lastDataProtectionPolicySeenAt', 'mustValidateTermsOfService', - 'pixOrgaTermsOfServiceAccepted', - 'pixCertifTermsOfServiceAccepted', 'lang', 'isAnonymous', 'accountInfo', diff --git a/api/tests/identity-access-management/acceptance/application/user/user.route.test.js b/api/tests/identity-access-management/acceptance/application/user/user.route.test.js index 9de5f037d9c..f2272162fbd 100644 --- a/api/tests/identity-access-management/acceptance/application/user/user.route.test.js +++ b/api/tests/identity-access-management/acceptance/application/user/user.route.test.js @@ -220,8 +220,6 @@ describe('Acceptance | Identity Access Management | Application | Route | User', 'is-anonymous': false, 'last-terms-of-service-validated-at': user.lastTermsOfServiceValidatedAt, 'must-validate-terms-of-service': user.mustValidateTermsOfService, - 'pix-orga-terms-of-service-accepted': user.pixOrgaTermsOfServiceAccepted, - 'pix-certif-terms-of-service-accepted': user.pixCertifTermsOfServiceAccepted, 'has-seen-assessment-instructions': user.hasSeenAssessmentInstructions, 'has-seen-new-dashboard-info': user.hasSeenNewDashboardInfo, 'has-seen-focused-challenge-tooltip': user.hasSeenFocusedChallengeTooltip, diff --git a/api/tests/identity-access-management/unit/infrastructure/serializers/jsonapi/user-with-activity.serializer.test.js b/api/tests/identity-access-management/unit/infrastructure/serializers/jsonapi/user-with-activity.serializer.test.js index 50a9beea57b..13050a7dc95 100644 --- a/api/tests/identity-access-management/unit/infrastructure/serializers/jsonapi/user-with-activity.serializer.test.js +++ b/api/tests/identity-access-management/unit/infrastructure/serializers/jsonapi/user-with-activity.serializer.test.js @@ -51,8 +51,6 @@ describe('Unit | Identity Access Management | Infrastructure | Serializer | JSON 'is-anonymous': userModelObject.isAnonymous, 'last-terms-of-service-validated-at': userModelObject.lastTermsOfServiceValidatedAt, 'must-validate-terms-of-service': userModelObject.mustValidateTermsOfService, - 'pix-orga-terms-of-service-accepted': userModelObject.pixOrgaTermsOfServiceAccepted, - 'pix-certif-terms-of-service-accepted': userModelObject.pixCertifTermsOfServiceAccepted, 'has-seen-assessment-instructions': userModelObject.hasSeenAssessmentInstructions, 'has-seen-new-dashboard-info': userModelObject.hasSeenNewDashboardInfo, 'has-seen-focused-challenge-tooltip': userModelObject.hasSeenFocusedChallengeTooltip, From cf9c7cfefb3c02d888404a1413d6e62a5b16473c Mon Sep 17 00:00:00 2001 From: Emmanuelle Bonnemay Date: Tue, 7 Jan 2025 16:54:01 +0100 Subject: [PATCH 8/8] feat(api): handle Legal Document errors mapping --- api/config/server-setup-error-handling.js | 2 + .../http-error-mapper-configuration.js | 16 ++++++ .../http-error-mapper-configuration_test.js | 49 +++++++++++++++++++ 3 files changed, 67 insertions(+) create mode 100644 api/src/legal-documents/application/http-error-mapper-configuration.js create mode 100644 api/tests/legal-documents/unit/domain/application/http-error-mapper-configuration_test.js diff --git a/api/config/server-setup-error-handling.js b/api/config/server-setup-error-handling.js index dfb864c2e04..45bbb3b3925 100644 --- a/api/config/server-setup-error-handling.js +++ b/api/config/server-setup-error-handling.js @@ -2,6 +2,7 @@ import { certificationDomainErrorMappingConfiguration } from '../src/certificati import { devcompDomainErrorMappingConfiguration } from '../src/devcomp/application/http-error-mapper-configuration.js'; import { evaluationDomainErrorMappingConfiguration } from '../src/evaluation/application/http-error-mapper-configuration.js'; import { authenticationDomainErrorMappingConfiguration } from '../src/identity-access-management/application/http-error-mapper-configuration.js'; +import { legalDocumentsDomainErrorMappingConfiguration } from '../src/legal-documents/application/http-error-mapper-configuration.js'; import { organizationalEntitiesDomainErrorMappingConfiguration } from '../src/organizational-entities/application/http-error-mapper-configuration.js'; import { prescriptionDomainErrorMappingConfiguration } from '../src/prescription/shared/application/http-error-mapper-configuration.js'; import { profileDomainErrorMappingConfiguration } from '../src/profile/application/http-error-mapper-configuration.js'; @@ -18,6 +19,7 @@ const setupErrorHandling = function (server) { ...certificationDomainErrorMappingConfiguration, ...devcompDomainErrorMappingConfiguration, ...evaluationDomainErrorMappingConfiguration, + ...legalDocumentsDomainErrorMappingConfiguration, ...prescriptionDomainErrorMappingConfiguration, ...schoolDomainErrorMappingConfiguration, ...profileDomainErrorMappingConfiguration, diff --git a/api/src/legal-documents/application/http-error-mapper-configuration.js b/api/src/legal-documents/application/http-error-mapper-configuration.js new file mode 100644 index 00000000000..2d8b675820f --- /dev/null +++ b/api/src/legal-documents/application/http-error-mapper-configuration.js @@ -0,0 +1,16 @@ +import { HttpErrors } from '../../shared/application/http-errors.js'; +import { DomainErrorMappingConfiguration } from '../../shared/application/models/domain-error-mapping-configuration.js'; +import { LegalDocumentInvalidDateError, LegalDocumentVersionNotFoundError } from '../domain/errors.js'; + +const legalDocumentsDomainErrorMappingConfiguration = [ + { + name: LegalDocumentInvalidDateError.name, + httpErrorFn: (error) => new HttpErrors.UnprocessableEntityError(error.message, error.code, error.meta), + }, + { + name: LegalDocumentVersionNotFoundError.name, + httpErrorFn: (error) => new HttpErrors.NotFoundError(error.message, error.code, error.meta), + }, +].map((domainErrorMappingConfiguration) => new DomainErrorMappingConfiguration(domainErrorMappingConfiguration)); + +export { legalDocumentsDomainErrorMappingConfiguration }; diff --git a/api/tests/legal-documents/unit/domain/application/http-error-mapper-configuration_test.js b/api/tests/legal-documents/unit/domain/application/http-error-mapper-configuration_test.js new file mode 100644 index 00000000000..0dd2430efa6 --- /dev/null +++ b/api/tests/legal-documents/unit/domain/application/http-error-mapper-configuration_test.js @@ -0,0 +1,49 @@ +import { legalDocumentsDomainErrorMappingConfiguration } from '../../../../../src/legal-documents/application/http-error-mapper-configuration.js'; +import { + LegalDocumentInvalidDateError, + LegalDocumentVersionNotFoundError, +} from '../../../../../src/legal-documents/domain/errors.js'; +import { HttpErrors } from '../../../../../src/shared/application/http-errors.js'; +import { DomainErrorMappingConfiguration } from '../../../../../src/shared/application/models/domain-error-mapping-configuration.js'; +import { expect } from '../../../../test-helper.js'; + +describe('Unit | Legal Documents | Application | HttpErrorMapperConfiguration', function () { + it('contains a list of HttpErrorMapper instances', function () { + // given + // when + // then + legalDocumentsDomainErrorMappingConfiguration.forEach((domainErrorMappingConfiguration) => + expect(domainErrorMappingConfiguration).to.be.instanceOf(DomainErrorMappingConfiguration), + ); + }); + + context('when mapping "LegalDocumentInvalidDateError"', function () { + it('returns an UnprocessableEntity Http Error', function () { + //given + const httpErrorMapper = legalDocumentsDomainErrorMappingConfiguration.find( + (httpErrorMapper) => httpErrorMapper.name === LegalDocumentInvalidDateError.name, + ); + + //when + const error = httpErrorMapper.httpErrorFn(new LegalDocumentInvalidDateError()); + + //then + expect(error).to.be.instanceOf(HttpErrors.UnprocessableEntityError); + }); + }); + + context('when mapping "LegalDocumentVersionNotFoundError"', function () { + it('returns an NotFound Http Error', function () { + //given + const httpErrorMapper = legalDocumentsDomainErrorMappingConfiguration.find( + (httpErrorMapper) => httpErrorMapper.name === LegalDocumentVersionNotFoundError.name, + ); + + //when + const error = httpErrorMapper.httpErrorFn(new LegalDocumentVersionNotFoundError()); + + //then + expect(error).to.be.instanceOf(HttpErrors.NotFoundError); + }); + }); +});