Skip to content

Commit

Permalink
[FEATURE] Modifier l’API permettant d’accepter les CGU afin de foncti…
Browse files Browse the repository at this point in the history
…onner avec le nouveau modèle (PIX-15588)

 #10894
  • Loading branch information
pix-service-auto-merge authored Jan 7, 2025
2 parents eae265d + a4f2316 commit 8301a94
Show file tree
Hide file tree
Showing 15 changed files with 99 additions and 95 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,14 @@ const acceptPixLastTermsOfService = async function (request, h, dependencies = {
* }} dependencies
* @return {Promise<*>}
*/
const acceptPixOrgaTermsOfService = async function (request, h, dependencies = { userSerializer }) {
const acceptPixOrgaTermsOfService = async function (request, h) {
const authenticatedUserId = request.auth.credentials.userId;

const updatedUser = await usecases.acceptPixOrgaTermsOfService({
await usecases.acceptPixOrgaTermsOfService({
userId: authenticatedUserId,
});

return dependencies.userSerializer.serialize(updatedUser);
return h.response().code(204);
};

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
/**
* @param {{
* userId: string,
* userRepository: UserRepository
* legalDocumentApiRepository: legalDocumentApiRepository
* }} params
* @return {Promise<User>}
* @return {Promise<void>}
*/
export const acceptPixOrgaTermsOfService = function ({ userId, userRepository }) {
return userRepository.updatePixOrgaTermsOfServiceAcceptedToTrue(userId);
export const acceptPixOrgaTermsOfService = function ({ userId, legalDocumentApiRepository }) {
return legalDocumentApiRepository.acceptPixOrgaTos({ userId });
};
2 changes: 2 additions & 0 deletions api/src/identity-access-management/domain/usecases/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import { emailValidationDemandRepository } from '../../infrastructure/repositori
import { eventLoggingJobRepository } from '../../infrastructure/repositories/jobs/event-logging-job.repository.js';
import { garAnonymizedBatchEventsLoggingJobRepository } from '../../infrastructure/repositories/jobs/gar-anonymized-batch-events-logging-job-repository.js';
import { userAnonymizedEventLoggingJobRepository } from '../../infrastructure/repositories/jobs/user-anonymized-event-logging-job-repository.js';
import { legalDocumentApiRepository } from '../../infrastructure/repositories/legal-document-api.repository.js';
import { oidcProviderRepository } from '../../infrastructure/repositories/oidc-provider-repository.js';
import * as privacyUsersApiRepository from '../../infrastructure/repositories/privacy-users-api.repository.js';
import { refreshTokenRepository } from '../../infrastructure/repositories/refresh-token.repository.js';
Expand Down Expand Up @@ -61,6 +62,7 @@ const repositories = {
emailValidationDemandRepository,
emailRepository,
eventLoggingJobRepository,
legalDocumentApiRepository,
membershipRepository,
oidcProviderRepository,
organizationLearnerRepository,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import * as legalDocumentApi from '../../../legal-documents/application/api/legal-documents-api.js';

const acceptPixOrgaTos = async ({ userId, dependencies = { legalDocumentApi } }) => {
return dependencies.legalDocumentApi.acceptLegalDocumentByUserId({ userId, service: 'pix-orga', type: 'TOS' });
};

const legalDocumentApiRepository = { acceptPixOrgaTos };

export { legalDocumentApiRepository };
Original file line number Diff line number Diff line change
Expand Up @@ -338,17 +338,6 @@ const acceptPixLastTermsOfService = async function (id) {
return new User(user);
};

const updatePixOrgaTermsOfServiceAcceptedToTrue = async function (id) {
const now = new Date();

const [user] = await knex('users')
.where({ id })
.update({ pixOrgaTermsOfServiceAccepted: true, lastPixOrgaTermsOfServiceValidatedAt: now, updatedAt: now })
.returning('*');

return new User(user);
};

const updatePixCertifTermsOfServiceAcceptedToTrue = async function (id) {
const now = new Date();

Expand Down Expand Up @@ -448,7 +437,6 @@ const updateLastDataProtectionPolicySeenAt = async function ({ userId }) {
* @property {function} updateHasSeenNewDashboardInfoToTrue
* @property {function} updateLastDataProtectionPolicySeenAt
* @property {function} updatePixCertifTermsOfServiceAcceptedToTrue
* @property {function} updatePixOrgaTermsOfServiceAcceptedToTrue
* @property {function} updateUserDetailsForAdministration
* @property {function} updateUsername
* @property {function} updateWithEmailConfirmed
Expand Down Expand Up @@ -481,7 +469,6 @@ export {
updateHasSeenNewDashboardInfoToTrue,
updateLastDataProtectionPolicySeenAt,
updatePixCertifTermsOfServiceAcceptedToTrue,
updatePixOrgaTermsOfServiceAcceptedToTrue,
updateUserDetailsForAdministration,
updateUsername,
updateWithEmailConfirmed,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { withTransaction } from '../../../shared/domain/DomainTransaction.js';
import { LegalDocumentService } from '../models/LegalDocumentService.js';
import { LegalDocumentType } from '../models/LegalDocumentType.js';

Expand All @@ -13,31 +14,25 @@ const { TOS } = LegalDocumentType.VALUES;
* @param {string} params.type - The type of the legal document.
* @returns {Promise<void>} A promise that resolves when the operation is complete.
*/
const acceptLegalDocumentByUserId = async ({
userId,
service,
type,
userRepository,
legalDocumentRepository,
userAcceptanceRepository,
logger,
}) => {
LegalDocumentType.assert(type);
LegalDocumentService.assert(service);
const acceptLegalDocumentByUserId = withTransaction(
async ({ userId, service, type, userRepository, legalDocumentRepository, userAcceptanceRepository, logger }) => {
LegalDocumentType.assert(type);
LegalDocumentService.assert(service);

// legacy document acceptance
if (type === TOS && service === PIX_ORGA) {
await userRepository.setPixOrgaCguByUserId(userId);
}
// legacy document acceptance
if (type === TOS && service === PIX_ORGA) {
await userRepository.setPixOrgaCguByUserId(userId);
}

// new document acceptance
const legalDocument = await legalDocumentRepository.findLastVersionByTypeAndService({ service, type });
if (!legalDocument) {
logger.warn(`No legal document found for service: ${service} and type: ${type}`);
return;
}
// new document acceptance
const legalDocument = await legalDocumentRepository.findLastVersionByTypeAndService({ service, type });
if (!legalDocument) {
logger.warn(`No legal document found for service: ${service} and type: ${type}`);
return;
}

await userAcceptanceRepository.create({ userId, legalDocumentVersionId: legalDocument.id });
};
await userAcceptanceRepository.create({ userId, legalDocumentVersionId: legalDocument.id });
},
);

export { acceptLegalDocumentByUserId };
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { withTransaction } from '../../../shared/domain/DomainTransaction.js';
import { LegalDocumentInvalidDateError } from '../errors.js';
import { LegalDocumentService } from '../models/LegalDocumentService.js';
import { LegalDocumentType } from '../models/LegalDocumentType.js';
Expand All @@ -11,7 +12,7 @@ import { LegalDocumentType } from '../models/LegalDocumentType.js';
* @param {string} params.versionAt - Version date of the new legal document.
* @returns {Promise<LegalDocument>} A promise that resolves the new legal document.
*/
const createLegalDocument = async ({ service, type, versionAt, legalDocumentRepository }) => {
const createLegalDocument = withTransaction(async ({ service, type, versionAt, legalDocumentRepository }) => {
LegalDocumentService.assert(service);
LegalDocumentType.assert(type);

Expand All @@ -22,6 +23,6 @@ const createLegalDocument = async ({ service, type, versionAt, legalDocumentRepo
}

return legalDocumentRepository.create({ service, type, versionAt });
};
});

export { createLegalDocument };
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { DomainTransaction } from '../../../shared/domain/DomainTransaction.js';

const TABLE_NAME = 'users';

/**
* Updates the Pix terms of service acceptance status for a user.
*
Expand All @@ -8,7 +10,7 @@ import { DomainTransaction } from '../../../shared/domain/DomainTransaction.js';
*/
const setPixOrgaCguByUserId = async (userId) => {
const knexConnection = DomainTransaction.getConnection();
await knexConnection('users').where('id', userId).update({
await knexConnection(TABLE_NAME).where('id', userId).update({
pixOrgaTermsOfServiceAccepted: true,
lastPixOrgaTermsOfServiceValidatedAt: new Date(),
});
Expand All @@ -22,7 +24,7 @@ const setPixOrgaCguByUserId = async (userId) => {
*/
const findPixOrgaCgusByUserId = async (userId) => {
const knexConnection = DomainTransaction.getConnection();
const userPixOrgaCgus = await knexConnection('users')
const userPixOrgaCgus = await knexConnection(TABLE_NAME)
.select('pixOrgaTermsOfServiceAccepted', 'lastPixOrgaTermsOfServiceValidatedAt')
.where('id', userId)
.first();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,7 @@ describe('Acceptance | Identity Access Management | Application | Route | User',
});

context('when password is updated', function () {
it('replies with 200 status code', async function () {
it('replies with 204 status code', async function () {
// when
const response = await server.inject(options);

Expand Down Expand Up @@ -499,13 +499,12 @@ describe('Acceptance | Identity Access Management | Application | Route | User',
});

describe('Success case', function () {
it('returns the user with pixOrgaTermsOfServiceAccepted', async function () {
it('replies with 204 status code', async function () {
// when
const response = await server.inject(options);

// then
expect(response.statusCode).to.equal(200);
expect(response.result.data.attributes['pix-orga-terms-of-service-accepted']).to.be.true;
expect(response.statusCode).to.equal(204);
});
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1665,37 +1665,6 @@ describe('Integration | Identity Access Management | Infrastructure | Repository
});
});

describe('#updatePixOrgaTermsOfServiceAcceptedToTrue', function () {
it('returns the model with pixOrgaTermsOfServiceAccepted flag updated to true', async function () {
// given
const userId = databaseBuilder.factory.buildUser({ pixOrgaTermsOfServiceAccepted: false }).id;
await databaseBuilder.commit();

// when
const result = await userRepository.updatePixOrgaTermsOfServiceAcceptedToTrue(userId);

// then
expect(result).to.be.an.instanceof(User);
expect(result.pixOrgaTermsOfServiceAccepted).to.be.true;
});

it('updates the lastPixOrgaTermsOfServiceValidatedAt', async function () {
// given
const user = databaseBuilder.factory.buildUser({
pixOrgaTermsOfServiceAccepted: true,
lastPixOrgaTermsOfServiceValidatedAt: new Date('2020-01-01T00:00:00Z'),
});
await databaseBuilder.commit();

// when
const result = await userRepository.updatePixOrgaTermsOfServiceAcceptedToTrue(user.id);

// then
expect(result.lastPixOrgaTermsOfServiceValidatedAt).to.deep.equal(now);
expect(result.updatedAt).to.deep.equal(now);
});
});

describe('#updatePixCertifTermsOfServiceAcceptedToTrue', function () {
it('returns the model with pixCertifTermsOfServiceAccepted flag updated to true', async function () {
// given
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,14 +77,13 @@ describe('Unit | Identity Access Management | Application | Controller | User',

it('accepts pix orga terms of service', async function () {
// given
usecases.acceptPixOrgaTermsOfService.withArgs({ userId }).resolves({});
userSerializer.serialize.withArgs({}).returns('ok');
usecases.acceptPixOrgaTermsOfService.withArgs({ userId }).resolves();

// when
const response = await userController.acceptPixOrgaTermsOfService(request, hFake, { userSerializer });
const response = await userController.acceptPixOrgaTermsOfService(request, hFake);

// then
expect(response).to.be.equal('ok');
expect(response.statusCode).to.equal(204);
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,21 @@ import { acceptPixOrgaTermsOfService } from '../../../../../src/identity-access-
import { expect, sinon } from '../../../../test-helper.js';

describe('Unit | Identity Access Management | Domain | UseCase | accept-pix-orga-terms-of-service', function () {
let userRepository;
let legalDocumentApiRepository;

beforeEach(function () {
userRepository = { updatePixOrgaTermsOfServiceAcceptedToTrue: sinon.stub() };
legalDocumentApiRepository = { acceptPixOrgaTos: sinon.stub() };
});

it('accepts terms of service of pix-orga', async function () {
// given
const userId = Symbol('userId');
const updatedUser = Symbol('updateduser');
userRepository.updatePixOrgaTermsOfServiceAcceptedToTrue.resolves(updatedUser);
legalDocumentApiRepository.acceptPixOrgaTos.resolves();

// when
const actualUpdatedUser = await acceptPixOrgaTermsOfService({ userId, userRepository });
await acceptPixOrgaTermsOfService({ userId, legalDocumentApiRepository });

// then
expect(userRepository.updatePixOrgaTermsOfServiceAcceptedToTrue).to.have.been.calledWithExactly(userId);
expect(actualUpdatedUser).to.equal(updatedUser);
expect(legalDocumentApiRepository.acceptPixOrgaTos).to.have.been.calledWithExactly({ userId });
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { legalDocumentApiRepository } from '../../../../../src/identity-access-management/infrastructure/repositories/legal-document-api.repository.js';
import { expect, sinon } from '../../../../test-helper.js';

describe('Unit | Identity Access Management | Infrastructure | Repositories | legal-document-api', function () {
describe('#acceptPixOrgaTos', function () {
it('accepts terms of service', async function () {
// given
const dependencies = {
legalDocumentApi: {
acceptLegalDocumentByUserId: sinon.stub().resolves(),
},
};

const userId = Symbol('userId');

// when
await legalDocumentApiRepository.acceptPixOrgaTos({ userId, dependencies });

// then
expect(dependencies.legalDocumentApi.acceptLegalDocumentByUserId).to.have.been.calledWithExactly({
userId,
service: 'pix-orga',
type: 'TOS',
});
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,20 @@ import Joi from 'joi';
import { LegalDocumentService } from '../../../../../src/legal-documents/domain/models/LegalDocumentService.js';
import { LegalDocumentType } from '../../../../../src/legal-documents/domain/models/LegalDocumentType.js';
import { usecases } from '../../../../../src/legal-documents/domain/usecases/index.js';
import { expect } from '../../../../test-helper.js';
import { DomainTransaction } from '../../../../../src/shared/domain/DomainTransaction.js';
import { expect, sinon } from '../../../../test-helper.js';

const { PIX_ORGA } = LegalDocumentService.VALUES;
const { TOS } = LegalDocumentType.VALUES;

describe('Unit | Legal documents | Domain | Use case | accept-legal-document-by-user-id', function () {
beforeEach(function () {
sinon.stub(DomainTransaction, 'execute');
DomainTransaction.execute.callsFake((fn) => {
return fn({});
});
});

context('when the legal document type is invalid', function () {
it('throws an error', async function () {
// given
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,20 @@ import Joi from 'joi';
import { LegalDocumentService } from '../../../../../src/legal-documents/domain/models/LegalDocumentService.js';
import { LegalDocumentType } from '../../../../../src/legal-documents/domain/models/LegalDocumentType.js';
import { usecases } from '../../../../../src/legal-documents/domain/usecases/index.js';
import { expect } from '../../../../test-helper.js';
import { DomainTransaction } from '../../../../../src/shared/domain/DomainTransaction.js';
import { expect, sinon } from '../../../../test-helper.js';

const { PIX_ORGA } = LegalDocumentService.VALUES;
const { TOS } = LegalDocumentType.VALUES;

describe('Unit | Legal documents | Domain | Use case | create-legal-document', function () {
beforeEach(function () {
sinon.stub(DomainTransaction, 'execute');
DomainTransaction.execute.callsFake((fn) => {
return fn({});
});
});

context('when the legal document type is invalid', function () {
it('throws an error', async function () {
// given
Expand Down

0 comments on commit 8301a94

Please sign in to comment.