Skip to content

Commit

Permalink
[FEATURE] Modifier l'appel Pix Orga qui récupère le status des CGU (P…
Browse files Browse the repository at this point in the history
  • Loading branch information
pix-service-auto-merge authored Jan 8, 2025
2 parents 50117f5 + cf9c7cf commit 47f2edf
Show file tree
Hide file tree
Showing 18 changed files with 202 additions and 45 deletions.
2 changes: 2 additions & 0 deletions api/config/server-setup-error-handling.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -18,6 +19,7 @@ const setupErrorHandling = function (server) {
...certificationDomainErrorMappingConfiguration,
...devcompDomainErrorMappingConfiguration,
...evaluationDomainErrorMappingConfiguration,
...legalDocumentsDomainErrorMappingConfiguration,
...prescriptionDomainErrorMappingConfiguration,
...schoolDomainErrorMappingConfiguration,
...profileDomainErrorMappingConfiguration,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ const serialize = function (users, meta) {
'lastTermsOfServiceValidatedAt',
'lastDataProtectionPolicySeenAt',
'mustValidateTermsOfService',
'pixOrgaTermsOfServiceAccepted',
'pixCertifTermsOfServiceAccepted',
'lang',
'isAnonymous',
'accountInfo',
Expand Down
Original file line number Diff line number Diff line change
@@ -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 };
6 changes: 6 additions & 0 deletions api/src/team/domain/read-models/Prescriber.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ class Prescriber {
* firstName: string,
* lastName: string,
* pixOrgaTermsOfServiceAccepted: boolean,
* pixOrgaTermsOfServiceStatus: string,
* pixOrgaTermsOfServiceDocumentPath: string,
* lang: string,
* areNewYearOrganizationLearnersImported: boolean,
* participantCount: number,
Expand All @@ -18,6 +20,8 @@ class Prescriber {
firstName,
lastName,
pixOrgaTermsOfServiceAccepted,
pixOrgaTermsOfServiceStatus,
pixOrgaTermsOfServiceDocumentPath,
lang,
areNewYearOrganizationLearnersImported,
participantCount,
Expand All @@ -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;
Expand Down
8 changes: 2 additions & 6 deletions api/src/team/domain/usecases/get-prescriber.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,10 @@ 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);
}

return prescriberRepository.getPrescriber(userId);
return prescriberRepository.getPrescriber({ userId });
};

function _isCurrentOrganizationInMemberships(userOrgaSettings, memberships) {
Expand Down
4 changes: 2 additions & 2 deletions api/src/team/domain/usecases/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -29,7 +29,7 @@ const dependencies = {
certificationCenterInvitedUserRepository,
certificationCenterRepository,
certificationCenterInvitationRepository,
prescriberRepository,
prescriberRepository: repositories.prescriberRepository,
membershipRepository,
userOrgaSettingsRepository,
certificationCenterInvitationService,
Expand Down
15 changes: 15 additions & 0 deletions api/src/team/infrastructure/repositories/index.js
Original file line number Diff line number Diff line change
@@ -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 };
41 changes: 33 additions & 8 deletions api/src/team/infrastructure/repositories/prescriber-repository.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,24 @@ 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<Prescriber>}
*/
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',
});

const memberships = await knex('memberships').where({ userId, disabledAt: null }).orderBy('id');

if (memberships.length === 0) {
Expand All @@ -36,7 +41,15 @@ const getPrescriber = async function (userId) {

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 =
Expand All @@ -49,11 +62,23 @@ const getPrescriber = async function (userId) {

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({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ const serialize = function (prescriber) {
'firstName',
'lastName',
'pixOrgaTermsOfServiceAccepted',
'pixOrgaTermsOfServiceStatus',
'pixOrgaTermsOfServiceDocumentPath',
'areNewYearOrganizationLearnersImported',
'participantCount',
'lang',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
@@ -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);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import * as sharedMembershipRepository from '../../../../../src/shared/infrastructure/repositories/membership-repository.js';
import { getPrescriber } from '../../../../../src/team/domain/usecases/get-prescriber.js';
import { prescriberRepository } from '../../../../../src/team/infrastructure/repositories/prescriber-repository.js';
import { usecases } from '../../../../../src/team/domain/usecases/index.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 () {
it("should create it with the first membership's organization", async function () {
Expand Down
Loading

0 comments on commit 47f2edf

Please sign in to comment.