Skip to content

Commit

Permalink
Move lcms related code from lib to src/shared
Browse files Browse the repository at this point in the history
Co-authored-by: Iris Benoît <[email protected]>
Co-authored-by: Jérémie Jadé <[email protected]>
  • Loading branch information
3 people committed Nov 15, 2024
1 parent 5e412e0 commit 95d472e
Show file tree
Hide file tree
Showing 11 changed files with 189 additions and 228 deletions.
25 changes: 0 additions & 25 deletions api/lib/application/cache/cache-controller.js

This file was deleted.

47 changes: 0 additions & 47 deletions api/lib/application/cache/index.js

This file was deleted.

2 changes: 0 additions & 2 deletions api/lib/routes.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import * as healthcheck from '../src/shared/application/healthcheck/index.js';
import * as authentication from './application/authentication/index.js';
import * as cache from './application/cache/index.js';
import * as campaignParticipations from './application/campaign-participations/index.js';
import * as certificationCenterInvitations from './application/certification-center-invitations/index.js';
import * as certificationCenterMemberships from './application/certification-center-memberships/index.js';
Expand All @@ -22,7 +21,6 @@ import * as users from './application/users/index.js';

const routes = [
authentication,
cache,
campaignParticipations,
certificationCenters,
certificationCenterInvitations,
Expand Down
37 changes: 37 additions & 0 deletions api/src/shared/application/lcms/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,43 @@ const register = async function (server) {
],
},
},
{
method: 'PATCH',
path: '/api/cache/{model}/{id}',
config: {
pre: [
{
method: securityPreHandlers.checkAdminMemberHasRoleSuperAdmin,
assign: 'hasRoleSuperAdmin',
},
],
handler: lcmsController.refreshCacheEntry,
tags: ['api', 'cache'],
notes: [
'Cette route est restreinte aux utilisateurs authentifiés avec le rôle Super Admin',
'Elle permet de mettre à jour une entrée du cache de l’application\n' +
'Attention : pour un état cohérent des objets stockés en cache, utiliser PATCH /api/cache',
],
},
},
{
method: 'PATCH',
path: '/api/cache',
config: {
pre: [
{
method: securityPreHandlers.checkAdminMemberHasRoleSuperAdmin,
assign: 'hasRoleSuperAdmin',
},
],
handler: lcmsController.refreshCacheEntries,
tags: ['api', 'cache'],
notes: [
'Cette route est restreinte aux utilisateurs authentifiés avec le rôle Super Admin',
'Elle permet de précharger les entrées du cache de l’application (les requêtes les plus longues)',
],
},
},
]);
};

Expand Down
21 changes: 20 additions & 1 deletion api/src/shared/application/lcms/lcms-controller.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import _ from 'lodash';

import { sharedUsecases as usecases } from '../../domain/usecases/index.js';
import * as LearningContentDatasources from '../../infrastructure/datasources/learning-content/index.js';
import { logger } from '../../infrastructure/utils/logger.js';

const createRelease = async function (request, h) {
Expand All @@ -13,6 +16,22 @@ const createRelease = async function (request, h) {
return h.response({}).code(204);
};

const lcmsController = { createRelease };
const refreshCacheEntries = async function (request, h) {
const { userId } = request.auth.credentials;

await usecases.refreshLearningContentCache({ userId });
return h.response({}).code(202);
};

const refreshCacheEntry = async function (request, h) {
const updatedRecord = request.payload;
const recordId = request.params.id;
const datasource =
LearningContentDatasources[_.findKey(LearningContentDatasources, { modelName: request.params.model })];
await datasource.refreshLearningContentCacheRecord(recordId, updatedRecord);
return h.response().code(204);
};

const lcmsController = { createRelease, refreshCacheEntries, refreshCacheEntry };

export { lcmsController };
4 changes: 2 additions & 2 deletions api/src/shared/domain/usecases/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ import { fileURLToPath } from 'node:url';

import * as complementaryCertificationBadgeRepository from '../../../certification/complementary-certification/infrastructure/repositories/complementary-certification-badge-repository.js';
import * as badgeRepository from '../../../evaluation/infrastructure/repositories/badge-repository.js';
import { injectDependencies } from '../../../shared/infrastructure/utils/dependency-injection.js';
import { importNamedExportsFromDirectory } from '../../../shared/infrastructure/utils/import-named-exports-from-directory.js';
import { lcmsRefreshCacheJobRepository } from '../../infrastructure/repositories/jobs/lcms-refresh-cache-job-repository.js';
import { injectDependencies } from '../../infrastructure/utils/dependency-injection.js';
import { importNamedExportsFromDirectory } from '../../infrastructure/utils/import-named-exports-from-directory.js';

const path = dirname(fileURLToPath(import.meta.url));

Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
import Redis from 'ioredis';

import { PIX_ADMIN } from '../../../../src/authorization/domain/constants.js';
import { LearningContentCache } from '../../../../src/shared/infrastructure/caches/learning-content-cache.js';
import { PIX_ADMIN } from '../../../../../src/authorization/domain/constants.js';
import { LearningContentCache } from '../../../../../src/shared/infrastructure/caches/learning-content-cache.js';
import {
createServer,
databaseBuilder,
expect,
generateValidRequestAuthorizationHeader,
mockLearningContent,
} from '../../../test-helper.js';
} from '../../../../test-helper.js';

const { ROLES } = PIX_ADMIN;

describe('Acceptance | Controller | cache-controller', function () {
describe('Acceptance | Controller | lcms-controller', function () {
let server;

beforeEach(async function () {
Expand Down
26 changes: 25 additions & 1 deletion api/tests/shared/unit/application/lcms/index_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ describe('Unit | Router | lcms-router', function () {

beforeEach(function () {
sinon.stub(securityPreHandlers, 'checkAdminMemberHasRoleSuperAdmin').callsFake((request, h) => h.response(true));
sinon.stub(lcmsController, 'refreshCacheEntry').callsFake((request, h) => h.response().code(204));
sinon.stub(lcmsController, 'createRelease').callsFake((request, h) => h.response().code(204));

sinon.stub(lcmsController, 'refreshCacheEntries').callsFake((request, h) => h.response().code(204));
httpTestServer = new HttpTestServer();
httpTestServer.register(moduleUnderTest);
});
Expand All @@ -24,4 +25,27 @@ describe('Unit | Router | lcms-router', function () {
expect(lcmsController.createRelease).to.have.been.called;
});
});

describe('PATCH /api/cache/{model}/{id}', function () {
it('should exist', async function () {
//given
const updatedRecord = { id: 'recId', param: 'updatedValue' };

// when
const response = await httpTestServer.request('PATCH', '/api/cache/table/recXYZ1234', updatedRecord);

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

describe('PATCH /api/cache', function () {
it('should exist', async function () {
// when
const response = await httpTestServer.request('PATCH', '/api/cache');

// then
expect(response.statusCode).to.equal(204);
});
});
});
101 changes: 101 additions & 0 deletions api/tests/shared/unit/application/lcms/lcms-controller_test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { lcmsController } from '../../../../../src/shared/application/lcms/lcms-controller.js';
import { sharedUsecases as usecases } from '../../../../../src/shared/domain/usecases/index.js';
import * as learningContentDatasources from '../../../../../src/shared/infrastructure/datasources/learning-content/index.js';
import { expect, hFake, sinon } from '../../../../test-helper.js';

describe('Unit | Controller | lcms-controller', function () {
Expand All @@ -16,4 +17,104 @@ describe('Unit | Controller | lcms-controller', function () {
expect(usecases.createLcmsRelease).to.have.been.called;
});
});

describe('#refreshCacheEntry', function () {
const request = {
params: {
model: 'challenges',
id: 'recId',
},
payload: {
property: 'updatedValue',
},
};

for (const entity of [
'area',
'challenge',
'competence',
'course',
'framework',
'skill',
'thematic',
'tube',
'tutorial',
]) {
it(`should reply 204 when patching ${entity}`, async function () {
// given

// eslint-disable-next-line import/namespace
sinon.stub(learningContentDatasources[`${entity}Datasource`], 'refreshLearningContentCacheRecord').resolves();
const request = {
params: {
model: `${entity}s`,
id: 'recId',
},
payload: {
property: 'updatedValue',
},
};

// when
const response = await lcmsController.refreshCacheEntry(request, hFake);

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

it('should reply with null when the cache key exists', async function () {
// given
sinon.stub(learningContentDatasources.challengeDatasource, 'refreshLearningContentCacheRecord').resolves();

// when
const response = await lcmsController.refreshCacheEntry(request, hFake);

// then
expect(
learningContentDatasources.challengeDatasource.refreshLearningContentCacheRecord,
).to.have.been.calledWithExactly('recId', { property: 'updatedValue' });
expect(response.statusCode).to.equal(204);
});

it('should reply with null when the cache key does not exist', async function () {
// given
sinon.stub(learningContentDatasources.challengeDatasource, 'refreshLearningContentCacheRecord').resolves();

// when
const response = await lcmsController.refreshCacheEntry(request, hFake);

// Then
expect(
learningContentDatasources.challengeDatasource.refreshLearningContentCacheRecord,
).to.have.been.calledWithExactly('recId', { property: 'updatedValue' });
expect(response.statusCode).to.equal(204);
});
});

describe('#refreshCacheEntries', function () {
context('nominal case', function () {
it('should reply with http status 202', async function () {
// given
sinon.stub(usecases, 'refreshLearningContentCache').resolves();

// when
const response = await lcmsController.refreshCacheEntries(
{
auth: {
credentials: {
userId: 123,
},
},
},
hFake,
);

// then
expect(usecases.refreshLearningContentCache).to.have.been.calledOnce;
expect(usecases.refreshLearningContentCache).to.have.been.calledWithExactly({ userId: 123 });
expect(response.statusCode).to.equal(202);
});
});
});
});
Loading

0 comments on commit 95d472e

Please sign in to comment.