Skip to content

Commit

Permalink
[TECH] Isoler la configuration du module i18n de l'api
Browse files Browse the repository at this point in the history
  • Loading branch information
pix-service-auto-merge authored Nov 12, 2024
2 parents 498e1de + 2279f21 commit ca94218
Show file tree
Hide file tree
Showing 57 changed files with 178 additions and 101 deletions.
2 changes: 1 addition & 1 deletion api/src/shared/domain/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const LOCALE = {
SPANISH_SPOKEN: 'es',
};

const SUPPORTED_LOCALES = ['en', 'es', 'fr', 'fr-BE', 'fr-FR', 'nl-BE'];
const SUPPORTED_LOCALES = ['en', 'es', 'fr', 'fr-BE', 'fr-FR', 'nl-BE', 'nl'];

const ORGANIZATION_FEATURE = {
MISSIONS_MANAGEMENT: {
Expand Down
54 changes: 54 additions & 0 deletions api/src/shared/infrastructure/i18n/i18n.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import path from 'node:path';

import { I18n } from 'i18n';

import { SUPPORTED_LOCALES } from '../../domain/constants.js';
import { logger } from '../utils/logger.js';

const __dirname = import.meta.dirname;
const translationsFolder = path.resolve(path.join(__dirname, '../../../../translations'));

const supportedLocales = SUPPORTED_LOCALES.map((supportedLocale) => supportedLocale.toLowerCase());

const DEFAULT_LOCALE = 'fr';

export const options = {
locales: ['en', 'fr', 'es', 'nl'],
fallbacks: { 'en-*': 'en', 'fr-*': 'fr', 'es-*': 'es', 'nl-*': 'nl' },
defaultLocale: DEFAULT_LOCALE,
directory: translationsFolder,
queryParameter: 'lang',
languageHeaderField: 'Accept-Language',
objectNotation: true,
updateFiles: false,
mustacheConfig: {
tags: ['{', '}'],
disable: false,
},
};

// This is an optimization to avoid settings a new instance each time
// we need to use i18n.
const i18nInstances = {};

/**
* @param {string} locale a locale (language or BCP 47 format)
* @returns i18n instance correctly setup with the language
*/
export function getI18n(locale) {
if (!locale || !supportedLocales.includes(locale?.toLowerCase())) {
return getI18n(DEFAULT_LOCALE);
}

if (!i18nInstances[locale]) {
const i18n = new I18n(options);
i18n.setLocale(locale);
// we freeze the setLocale to avoid changing i18n locale for an instance
i18n.setLocale = () => {
logger.warn('Cannot change i18n locale instance, use getI18n(locale) instead.');
};
i18nInstances[locale] = i18n;
}

return i18nInstances[locale];
}
19 changes: 3 additions & 16 deletions api/src/shared/infrastructure/plugins/i18n.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,7 @@
import * as url from 'node:url';

import hapiI18n from 'hapi-i18n';
const __dirname = url.fileURLToPath(new URL('.', import.meta.url));

import { options } from '../i18n/i18n.js';

const plugin = hapiI18n;
const options = {
locales: ['en', 'fr', 'es', 'nl'],
directory: __dirname + '../../../../translations',
defaultLocale: 'fr',
queryParameter: 'lang',
languageHeaderField: 'Accept-Language',
objectNotation: true,
updateFiles: false,
mustacheConfig: {
tags: ['{', '}'],
disable: false,
},
};

export { options, plugin };
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ import { CERTIFICATION_CANDIDATES_ERRORS } from '../../../../../../../src/certif
import { ComplementaryCertificationKeys } from '../../../../../../../src/certification/shared/domain/models/ComplementaryCertificationKeys.js';
import * as certificationCpfService from '../../../../../../../src/certification/shared/domain/services/certification-cpf-service.js';
import { CertificationCandidatesError } from '../../../../../../../src/shared/domain/errors.js';
import { getI18n } from '../../../../../../../src/shared/infrastructure/i18n/i18n.js';
import { catchErr, databaseBuilder, domainBuilder, expect, sinon } from '../../../../../../test-helper.js';
import { getI18n } from '../../../../../../tooling/i18n/i18n.js';

const { promises } = fs;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ import { fillCandidatesImportSheet } from '../../../../../../../src/certificatio
import * as readOdsUtils from '../../../../../../../src/certification/enrolment/infrastructure/utils/ods/read-ods-utils.js';
import { ComplementaryCertificationKeys } from '../../../../../../../src/certification/shared/domain/models/ComplementaryCertificationKeys.js';
import { CERTIFICATION_CENTER_TYPES } from '../../../../../../../src/shared/domain/constants.js';
import { getI18n } from '../../../../../../../src/shared/infrastructure/i18n/i18n.js';
import { databaseBuilder, expect } from '../../../../../../test-helper.js';
import { getI18n } from '../../../../../../tooling/i18n/i18n.js';
const __dirname = url.fileURLToPath(new URL('.', import.meta.url));

describe('Integration | Infrastructure | Utils | Ods | fillCandidatesImportSheet', function () {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ const { readFile } = promises;

import _ from 'lodash';

import { getI18n } from '../../../../../tooling/i18n/i18n.js';
const i18n = getI18n();

import * as url from 'node:url';
Expand All @@ -19,6 +18,7 @@ import {
validateOdsHeaders,
} from '../../../../../../src/certification/enrolment/infrastructure/utils/ods/read-ods-utils.js';
import { UnprocessableEntityError } from '../../../../../../src/shared/application/http-errors.js';
import { getI18n } from '../../../../../../src/shared/infrastructure/i18n/i18n.js';
import { catchErr, expect } from '../../../../../test-helper.js';
const __dirname = url.fileURLToPath(new URL('.', import.meta.url));

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { attendanceSheetController } from '../../../../../src/certification/enrolment/application/attendance-sheet-controller.js';
import { usecases } from '../../../../../src/certification/enrolment/domain/usecases/index.js';
import { getI18n } from '../../../../../src/shared/infrastructure/i18n/i18n.js';
import { expect, hFake, sinon } from '../../../../test-helper.js';
import { getI18n } from '../../../../tooling/i18n/i18n.js';

describe('Unit | Controller | attendance-sheet-controller', function () {
describe('#getAttendanceSheet', function () {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import { SUBSCRIPTION_TYPES } from '../../../../../../src/certification/shared/d
import { CERTIFICATION_CANDIDATES_ERRORS } from '../../../../../../src/certification/shared/domain/constants/certification-candidates-errors.js';
import { CertificationCandidatesError } from '../../../../../../src/shared/domain/errors.js';
import { CertificationCandidate } from '../../../../../../src/shared/domain/models/index.js';
import { getI18n } from '../../../../../../src/shared/infrastructure/i18n/i18n.js';
import { catchErr, catchErrSync, domainBuilder, expect } from '../../../../../test-helper.js';
import { getI18n } from '../../../../../tooling/i18n/i18n.js';
const FIRST_NAME_ERROR_CODE = CERTIFICATION_CANDIDATES_ERRORS.CANDIDATE_FIRST_NAME_REQUIRED.code;
const LAST_NAME_ERROR_CODE = CERTIFICATION_CANDIDATES_ERRORS.CANDIDATE_LAST_NAME_REQUIRED.code;
const BIRTHDATE_ERROR_CODE = CERTIFICATION_CANDIDATES_ERRORS.CANDIDATE_BIRTHDATE_REQUIRED.code;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ import { DomainTransaction } from '../../../../../../lib/infrastructure/DomainTr
import { importCertificationCandidatesFromCandidatesImportSheet } from '../../../../../../src/certification/enrolment/domain/usecases/import-certification-candidates-from-candidates-import-sheet.js';
import { CERTIFICATION_CENTER_TYPES } from '../../../../../../src/shared/domain/constants.js';
import { CandidateAlreadyLinkedToUserError } from '../../../../../../src/shared/domain/errors.js';
import { getI18n } from '../../../../../../src/shared/infrastructure/i18n/i18n.js';
import { catchErr, domainBuilder, expect, sinon } from '../../../../../test-helper.js';
import { getI18n } from '../../../../../tooling/i18n/i18n.js';

const i18n = getI18n();

describe('Unit | UseCase | import-certification-candidates-from-attendance-sheet', function () {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import { CERTIFICATION_SESSIONS_ERRORS } from '../../../../../../src/certificati
import { CpfBirthInformationValidation } from '../../../../../../src/certification/shared/domain/services/certification-cpf-service.js';
import { CERTIFICATION_CENTER_TYPES } from '../../../../../../src/shared/domain/constants.js';
import { CertificationCandidate } from '../../../../../../src/shared/domain/models/index.js';
import { getI18n } from '../../../../../../src/shared/infrastructure/i18n/i18n.js';
import { domainBuilder, expect, sinon } from '../../../../../test-helper.js';
import { getI18n } from '../../../../../tooling/i18n/i18n.js';

const userId = 1234;
const cachedValidatedSessionsKey = 'uuid';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ import dayjs from 'dayjs';

import { getDivisionCertificationResultsCsv } from '../../../../../../../../src/certification/results/infrastructure/utils/csv/certification-results/get-division-certification-results-csv.js';
import { AutoJuryCommentKeys } from '../../../../../../../../src/certification/shared/domain/models/JuryComment.js';
import { getI18n } from '../../../../../../../../src/shared/infrastructure/i18n/i18n.js';
import { domainBuilder, expect } from '../../../../../../../test-helper.js';
import { getI18n } from '../../../../../../../tooling/i18n/i18n.js';

const i18n = getI18n();
const translate = i18n.__;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { getSessionCertificationResultsCsv } from '../../../../../../../../src/certification/results/infrastructure/utils/csv/certification-results/get-session-certification-results-csv.js';
import { AutoJuryCommentKeys } from '../../../../../../../../src/certification/shared/domain/models/JuryComment.js';
import { getI18n } from '../../../../../../../../src/shared/infrastructure/i18n/i18n.js';
import { domainBuilder, expect } from '../../../../../../../test-helper.js';
import { getI18n } from '../../../../../../../tooling/i18n/i18n.js';

const i18n = getI18n();
const translate = i18n.__;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import pdfLibUtils from 'pdf-lib/cjs/utils/index.js';

import { getCertificationAttestationsPdfBuffer } from '../../../../../../../src/certification/results/infrastructure/utils/pdf/certification-attestation-pdf.js';
import { CertificationAttestationGenerationError } from '../../../../../../../src/shared/domain/errors.js';
import { getI18n } from '../../../../../../../src/shared/infrastructure/i18n/i18n.js';
import { catchErr, domainBuilder, expect, nock, sinon } from '../../../../../../test-helper.js';
import { isSameBinary } from '../../../../../../tooling/binary-comparator.js';
import { getI18n } from '../../../../../../tooling/i18n/i18n.js';

const __dirname = url.fileURLToPath(new URL('.', import.meta.url));

Expand Down Expand Up @@ -269,8 +269,7 @@ describe('Integration | Infrastructure | Utils | Pdf | Certification Attestation
certifiedBadges: [],
});
const referencePdfPath = 'EN-certification-confirmation-pdf_test.pdf';
const i18n = getI18n();
i18n.setLocale('en');
const i18n = getI18n('en');

// when
const { buffer } = await getCertificationAttestationsPdfBuffer({
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { certificationAttestationController } from '../../../../../src/certification/results/application/certification-attestation-controller.js';
import { usecases } from '../../../../../src/certification/results/domain/usecases/index.js';
import { LANGUAGES_CODE } from '../../../../../src/shared/domain/services/language-service.js';
import { getI18n } from '../../../../../src/shared/infrastructure/i18n/i18n.js';
import { domainBuilder, expect, hFake, sinon } from '../../../../test-helper.js';
import { getI18n } from '../../../../tooling/i18n/i18n.js';

const { FRENCH } = LANGUAGES_CODE;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { certificationController } from '../../../../../src/certification/results/application/certification-controller.js';
import { usecases } from '../../../../../src/certification/results/domain/usecases/index.js';
import { SESSIONS_VERSIONS } from '../../../../../src/certification/shared/domain/models/SessionVersion.js';
import { getI18n } from '../../../../../src/shared/infrastructure/i18n/i18n.js';
import { domainBuilder, expect, hFake, sinon } from '../../../../test-helper.js';
import { getI18n } from '../../../../tooling/i18n/i18n.js';

describe('Certification | Results | Unit | Application | certifications-controller', function () {
describe('#getCertificationByVerificationCode', function () {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { certificationResultsController } from '../../../../../src/certification/results/application/certification-results-controller.js';
import { usecases } from '../../../../../src/certification/results/domain/usecases/index.js';
import { getI18n } from '../../../../../src/shared/infrastructure/i18n/i18n.js';
import { domainBuilder, expect, hFake, sinon } from '../../../../test-helper.js';
import { getI18n } from '../../../../tooling/i18n/i18n.js';

describe('Certification | Results | Unit | Controller | certification results', function () {
describe('#getCleaCertifiedCandidateDataCsv', function () {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { organizationController } from '../../../../../src/certification/results/application/organization-controller.js';
import { usecases } from '../../../../../src/certification/results/domain/usecases/index.js';
import { getI18n } from '../../../../../src/shared/infrastructure/i18n/i18n.js';
import { domainBuilder, expect, hFake, sinon } from '../../../../test-helper.js';
import { getI18n } from '../../../../tooling/i18n/i18n.js';

describe('Certification | Course | Unit | Application | Organizations | organization-controller', function () {
describe('#downloadCertificationResults', function () {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import { ResultCompetenceTree } from '../../../../../../src/certification/result
import * as serializer from '../../../../../../src/certification/results/infrastructure/serializers/private-certificate-serializer.js';
import { AutoJuryCommentKeys } from '../../../../../../src/certification/shared/domain/models/JuryComment.js';
import { SESSIONS_VERSIONS } from '../../../../../../src/certification/shared/domain/models/SessionVersion.js';
import { getI18n } from '../../../../../../src/shared/infrastructure/i18n/i18n.js';
import { domainBuilder, expect } from '../../../../../test-helper.js';
import { getI18n } from '../../../../../tooling/i18n/i18n.js';

describe('Certification | Results | Unit | Infrastructure | Serializers | private-certificate-serializer', function () {
let translate;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { CertificationResultsCsvValues } from '../../../../../../../../src/certification/results/infrastructure/utils/csv/certification-results/CertificationResultsCsvValues.js';
import { AutoJuryCommentKeys } from '../../../../../../../../src/certification/shared/domain/models/JuryComment.js';
import { CertificationResult } from '../../../../../../../../src/shared/domain/models/index.js';
import { getI18n } from '../../../../../../../../src/shared/infrastructure/i18n/i18n.js';
import { domainBuilder, expect } from '../../../../../../../test-helper.js';
import { getI18n } from '../../../../../../../tooling/i18n/i18n.js';

describe('Unit | Infrastructure | Utils | Csv | CertificationResultsCsvValues', function () {
let i18n, translate;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import i18n from 'i18n';
import pdfLibUtils from 'pdf-lib/cjs/utils/index.js';

import { getAttendanceSheetPdfBuffer } from '../../../../../../../src/certification/enrolment/infrastructure/utils/pdf/attendance-sheet-pdf.js';
import { getI18n } from '../../../../../../../src/shared/infrastructure/i18n/i18n.js';
import { domainBuilder, expect, sinon } from '../../../../../../test-helper.js';
import { isSameBinary } from '../../../../../../tooling/binary-comparator.js';
import { getI18n } from '../../../../../../tooling/i18n/i18n.js';
const __dirname = url.fileURLToPath(new URL('.', import.meta.url));

const directory = path.resolve(path.join(__dirname, '../../../../../../../translations'));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { invigilatorKitController } from '../../../../../src/certification/session-management/application/invigilator-kit-controller.js';
import { usecases } from '../../../../../src/certification/session-management/domain/usecases/index.js';
import { LANGUAGES_CODE } from '../../../../../src/shared/domain/services/language-service.js';
import { getI18n } from '../../../../../src/shared/infrastructure/i18n/i18n.js';
import { domainBuilder, expect, hFake, sinon } from '../../../../test-helper.js';
import { getI18n } from '../../../../tooling/i18n/i18n.js';

describe('Certification | Session Management | Unit | Application | Controller | Invigilator Kit', function () {
describe('#getInvigilatorKitPdf', function () {
Expand All @@ -19,13 +19,12 @@ describe('Certification | Session Management | Unit | Application | Controller |
const sessionMainInfo = domainBuilder.certification.sessionManagement.buildSession({ id: 1 });
const invigilatorKitBuffer = 'binary string';
const userId = 1;
const i18n = getI18n();
const i18n = getI18n(lang);
const request = {
i18n,
auth: { credentials: { userId } },
params: { sessionId: sessionMainInfo.id },
};
i18n.setLocale(lang);

const invigilatorKitPdf = {
getInvigilatorKitPdfBuffer: sinon.stub(),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { juryCertificationController } from '../../../../../src/certification/session-management/application/jury-certification-controller.js';
import { usecases } from '../../../../../src/certification/session-management/domain/usecases/index.js';
import { getI18n } from '../../../../../src/shared/infrastructure/i18n/i18n.js';
import { domainBuilder, expect, hFake, sinon } from '../../../../test-helper.js';
import { getI18n } from '../../../../tooling/i18n/i18n.js';

describe('Certification | Session-management | Unit | Application | jury-certification-controller', function () {
describe('#getJuryCertification', function () {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as serializer from '../../../../../../src/certification/session-management/infrastructure/serializers/jury-certification-serializer.js';
import { AutoJuryCommentKeys } from '../../../../../../src/certification/shared/domain/models/JuryComment.js';
import { getI18n } from '../../../../../../src/shared/infrastructure/i18n/i18n.js';
import { domainBuilder, expect } from '../../../../../test-helper.js';
import { getI18n } from '../../../../../tooling/i18n/i18n.js';

describe('Certification | Session-management | Unit | Infrastructure | Serializers | jury-certification-serializer', function () {
let translate;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import {
JuryComment,
JuryCommentContexts,
} from '../../../../../../src/certification/shared/domain/models/JuryComment.js';
import { getI18n } from '../../../../../../src/shared/infrastructure/i18n/i18n.js';
import { expect } from '../../../../../test-helper.js';
import { getI18n } from '../../../../../tooling/i18n/i18n.js';

describe('Unit | Domain | Models | JuryComment', function () {
let translate;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { User } from '../../../../../src/identity-access-management/domain/models/User.js';
import { usecases } from '../../../../../src/identity-access-management/domain/usecases/index.js';
import { getI18n } from '../../../../../src/shared/infrastructure/i18n/i18n.js';
import { expect } from '../../../../test-helper.js';
import { getI18n } from '../../../../tooling/i18n/i18n.js';

describe('Integration | Identity Access Management | Domain | UseCase | create-user', function () {
it('returns the saved user', async function () {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { userController } from '../../../../../src/identity-access-management/application/user/user.controller.js';
import { User } from '../../../../../src/identity-access-management/domain/models/User.js';
import { usecases } from '../../../../../src/identity-access-management/domain/usecases/index.js';
import { getI18n } from '../../../../../src/shared/infrastructure/i18n/i18n.js';
import * as requestResponseUtils from '../../../../../src/shared/infrastructure/utils/request-response-utils.js';
import { domainBuilder, expect, hFake, sinon } from '../../../../test-helper.js';
import { getI18n } from '../../../../tooling/i18n/i18n.js';

describe('Unit | Identity Access Management | Application | Controller | User', function () {
let userSerializer;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import {
InvalidPasswordForUpdateEmailError,
UserNotAuthorizedToUpdateEmailError,
} from '../../../../../src/shared/domain/errors.js';
import { getI18n } from '../../../../../src/shared/infrastructure/i18n/i18n.js';
import { catchErr, domainBuilder, expect, sinon } from '../../../../test-helper.js';
import { getI18n } from '../../../../tooling/i18n/i18n.js';

describe('Unit | Identity Access Management | Domain | UseCase | send-verification-code', function () {
let authenticationMethodRepository;
Expand Down
Loading

0 comments on commit ca94218

Please sign in to comment.