Skip to content

Commit 8a61914

Browse files
AndreiaPenaSteph0HEYGULalexandrecoin
committed
🚚 api: move generate-results-download-link to results certification context
Co-authored-by: Steph0 <Steph0@users.noreply.github.com> Co-authored-by: GUL <guillaume.lagorce@pix.fr> Co-authored-by: Alexandre Coin <alexandre.coin@pix.fr>
1 parent ff0054f commit 8a61914

File tree

10 files changed

+144
-137
lines changed

10 files changed

+144
-137
lines changed

‎api/lib/application/sessions/index.js

-31
Original file line numberDiff line numberDiff line change
@@ -37,37 +37,6 @@ const register = async function (server) {
3737
],
3838
},
3939
},
40-
{
41-
method: 'GET',
42-
path: '/api/admin/sessions/{id}/generate-results-download-link',
43-
config: {
44-
validate: {
45-
params: Joi.object({
46-
id: identifiersType.sessionId,
47-
}),
48-
query: Joi.object({
49-
lang: Joi.string().optional().valid('fr', 'en'),
50-
}),
51-
},
52-
pre: [
53-
{
54-
method: (request, h) =>
55-
securityPreHandlers.hasAtLeastOneAccessOf([
56-
securityPreHandlers.checkAdminMemberHasRoleSuperAdmin,
57-
securityPreHandlers.checkAdminMemberHasRoleCertif,
58-
securityPreHandlers.checkAdminMemberHasRoleSupport,
59-
])(request, h),
60-
assign: 'hasAuthorizationToAccessAdminScope',
61-
},
62-
],
63-
handler: sessionController.generateSessionResultsDownloadLink,
64-
tags: ['api', 'sessions'],
65-
notes: [
66-
"Cette route est restreinte aux utilisateurs ayant les droits d'accès",
67-
"Elle permet de générer un lien permettant de télécharger tous les résultats de certification d'une session",
68-
],
69-
},
70-
},
7140
{
7241
method: 'PATCH',
7342
path: '/api/admin/sessions/{id}/publish',

‎api/lib/application/sessions/session-controller.js

-10
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import * as juryCertificationSummaryRepository from '../../../src/certification/
22
import * as sessionManagementSerializer from '../../../src/certification/session-management/infrastructure/serializers/session-serializer.js';
33
import { SessionPublicationBatchError } from '../../../src/shared/application/http-errors.js';
44
import { logger } from '../../../src/shared/infrastructure/utils/logger.js';
5-
import * as sessionResultsLinkService from '../../domain/services/session-results-link-service.js';
65
import { usecases } from '../../domain/usecases/index.js';
76
import * as juryCertificationSummarySerializer from '../../infrastructure/serializers/jsonapi/jury-certification-summary-serializer.js';
87

@@ -25,14 +24,6 @@ const getJuryCertificationSummaries = async function (
2524
return dependencies.juryCertificationSummarySerializer.serialize(juryCertificationSummaries, pagination);
2625
};
2726

28-
const generateSessionResultsDownloadLink = async function (request, h, dependencies = { sessionResultsLinkService }) {
29-
const sessionId = request.params.id;
30-
const i18n = request.i18n;
31-
const sessionResultsLink = dependencies.sessionResultsLinkService.generateResultsLink({ sessionId, i18n });
32-
33-
return h.response({ sessionResultsLink });
34-
};
35-
3627
const publish = async function (request, h, dependencies = { sessionManagementSerializer }) {
3728
const sessionId = request.params.id;
3829
const i18n = request.i18n;
@@ -74,7 +65,6 @@ const flagResultsAsSentToPrescriber = async function (request, h, dependencies =
7465

7566
const sessionController = {
7667
getJuryCertificationSummaries,
77-
generateSessionResultsDownloadLink,
7868
publish,
7969
publishInBatch,
8070
unpublish,

‎api/src/certification/results/application/certification-results-controller.js

+10
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import dayjs from 'dayjs';
22

33
import { tokenService } from '../../../shared/domain/services/token-service.js';
4+
import * as sessionResultsLinkService from '../domain/services/session-results-link-service.js';
45
import { usecases } from '../domain/usecases/index.js';
56
import * as certifiedProfileRepository from '../infrastructure/repositories/certified-profile-repository.js';
67
import * as certifiedProfileSerializer from '../infrastructure/serializers/certified-profile-serializer.js';
@@ -102,12 +103,21 @@ const getCertifiedProfile = async function (
102103
return dependencies.certifiedProfileSerializer.serialize(certifiedProfile);
103104
};
104105

106+
const generateSessionResultsDownloadLink = async function (request, h, dependencies = { sessionResultsLinkService }) {
107+
const sessionId = request.params.sessionId;
108+
const i18n = request.i18n;
109+
const sessionResultsLink = dependencies.sessionResultsLinkService.generateResultsLink({ sessionId, i18n });
110+
111+
return h.response({ sessionResultsLink });
112+
};
113+
105114
const certificationResultsController = {
106115
getCleaCertifiedCandidateDataCsv,
107116
getSessionResultsByRecipientEmail,
108117
getSessionResultsToDownload,
109118
postSessionResultsToDownload,
110119
getCertifiedProfile,
120+
generateSessionResultsDownloadLink,
111121
};
112122

113123
export { certificationResultsController };

‎api/src/certification/results/application/certification-results-route.js

+31
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,37 @@ const register = async function (server) {
112112
],
113113
},
114114
},
115+
{
116+
method: 'GET',
117+
path: '/api/admin/sessions/{sessionId}/generate-results-download-link',
118+
config: {
119+
validate: {
120+
params: Joi.object({
121+
sessionId: identifiersType.sessionId,
122+
}),
123+
query: Joi.object({
124+
lang: Joi.string().optional().valid(LOCALE.FRENCH_SPOKEN, LOCALE.ENGLISH_SPOKEN),
125+
}),
126+
},
127+
pre: [
128+
{
129+
method: (request, h) =>
130+
securityPreHandlers.hasAtLeastOneAccessOf([
131+
securityPreHandlers.checkAdminMemberHasRoleSuperAdmin,
132+
securityPreHandlers.checkAdminMemberHasRoleCertif,
133+
securityPreHandlers.checkAdminMemberHasRoleSupport,
134+
])(request, h),
135+
assign: 'hasAuthorizationToAccessAdminScope',
136+
},
137+
],
138+
handler: certificationResultsController.generateSessionResultsDownloadLink,
139+
tags: ['api', 'sessions', 'results'],
140+
notes: [
141+
"Cette route est restreinte aux utilisateurs ayant les droits d'accès",
142+
"Elle permet de générer un lien permettant de télécharger tous les résultats de certification d'une session",
143+
],
144+
},
145+
},
115146
]);
116147
};
117148

‎api/lib/domain/services/session-results-link-service.js ‎api/src/certification/results/domain/services/session-results-link-service.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { config } from '../../../src/shared/config.js';
2-
import { tokenService } from '../../../src/shared/domain/services/token-service.js';
1+
import { config } from '../../../../shared/config.js';
2+
import { tokenService } from '../../../../shared/domain/services/token-service.js';
33

44
const generateResultsLink = function ({ sessionId, i18n }) {
55
const daysBeforeExpiration = 30;

‎api/tests/acceptance/application/session/session-controller-generate-session-results-download-link_test.js

-61
This file was deleted.

‎api/tests/certification/results/acceptance/application/certification-results-route_test.js

+68
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
databaseBuilder,
99
expect,
1010
generateValidRequestAuthorizationHeader,
11+
insertUserWithRoleSuperAdmin,
1112
} from '../../../../test-helper.js';
1213

1314
describe('Certification | Results | Acceptance | Application | Routes | certification results', function () {
@@ -267,4 +268,71 @@ describe('Certification | Results | Acceptance | Application | Routes | certific
267268
});
268269
});
269270
});
271+
272+
describe('GET /api/admin/sessions/{sessionId}/generate-results-download-link', function () {
273+
context('when user is Super Admin', function () {
274+
it('should return a 200 status code response', async function () {
275+
// given
276+
const sessionId = 121;
277+
const options = {
278+
method: 'GET',
279+
url: `/api/admin/sessions/${sessionId}/generate-results-download-link`,
280+
payload: {},
281+
};
282+
const server = await createServer();
283+
await insertUserWithRoleSuperAdmin();
284+
databaseBuilder.factory.buildSession({ id: 121 });
285+
await databaseBuilder.commit();
286+
287+
// when
288+
options.headers = { authorization: generateValidRequestAuthorizationHeader() };
289+
const response = await server.inject(options);
290+
291+
// then
292+
expect(response.statusCode).to.equal(200);
293+
});
294+
});
295+
296+
context('when user is not SuperAdmin', function () {
297+
it('should return 403 HTTP status code', async function () {
298+
// given
299+
const sessionId = 121;
300+
const options = {
301+
method: 'GET',
302+
url: `/api/admin/sessions/${sessionId}/generate-results-download-link`,
303+
payload: {},
304+
};
305+
const server = await createServer();
306+
await insertUserWithRoleSuperAdmin();
307+
308+
// when
309+
options.headers = { authorization: generateValidRequestAuthorizationHeader(1111) };
310+
const response = await server.inject(options);
311+
312+
// then
313+
expect(response.statusCode).to.equal(403);
314+
});
315+
});
316+
317+
context('when user is not connected', function () {
318+
it('should return 401 HTTP status code if user is not authenticated', async function () {
319+
// given
320+
const sessionId = 121;
321+
const options = {
322+
method: 'GET',
323+
url: `/api/admin/sessions/${sessionId}/generate-results-download-link`,
324+
payload: {},
325+
};
326+
const server = await createServer();
327+
await insertUserWithRoleSuperAdmin();
328+
329+
// when
330+
options.headers = {};
331+
const response = await server.inject(options);
332+
333+
// then
334+
expect(response.statusCode).to.equal(401);
335+
});
336+
});
337+
});
270338
});

‎api/tests/certification/results/unit/application/certification-results-route_test.js

+28
Original file line numberDiff line numberDiff line change
@@ -57,4 +57,32 @@ describe('Certification | Results | Unit | Application | Certification Results R
5757
});
5858
});
5959
});
60+
61+
describe('GET /api/admin/sessions/{sessionId}/generate-results-download-link', function () {
62+
it('return forbidden access if user has METIER role', async function () {
63+
// given
64+
sinon
65+
.stub(securityPreHandlers, 'hasAtLeastOneAccessOf')
66+
.withArgs([
67+
securityPreHandlers.checkAdminMemberHasRoleSuperAdmin,
68+
securityPreHandlers.checkAdminMemberHasRoleCertif,
69+
securityPreHandlers.checkAdminMemberHasRoleSupport,
70+
])
71+
.callsFake(
72+
() => (request, h) =>
73+
h
74+
.response({ errors: new Error('forbidden') })
75+
.code(403)
76+
.takeover(),
77+
);
78+
const httpTestServer = new HttpTestServer();
79+
await httpTestServer.register(moduleUnderTest);
80+
81+
// when
82+
const response = await httpTestServer.request('GET', '/api/admin/sessions/1/generate-results-download-link');
83+
84+
// then
85+
expect(response.statusCode).to.equal(403);
86+
});
87+
});
6088
});

‎api/tests/unit/domain/services/session-results-link-service_test.js ‎api/tests/certification/results/unit/domain/services/session-results-link-service_test.js

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
import * as sessionResultsLinkService from '../../../../lib/domain/services/session-results-link-service.js';
2-
import { tokenService } from '../../../../src/shared/domain/services/token-service.js';
3-
import { getI18n } from '../../../../src/shared/infrastructure/i18n/i18n.js';
4-
import { expect, sinon } from '../../../test-helper.js';
1+
import * as sessionResultsLinkService from '../../../../../../src/certification/results/domain/services/session-results-link-service.js';
2+
import { tokenService } from '../../../../../../src/shared/domain/services/token-service.js';
3+
import { getI18n } from '../../../../../../src/shared/infrastructure/i18n/i18n.js';
4+
import { expect, sinon } from '../../../../../test-helper.js';
55

6-
describe('Unit | Domain | Service | Session Results Link Service', function () {
6+
describe('Certification | Results | Unit | Domain | Service | Session Results Link Service', function () {
77
describe('#generateResultsLink', function () {
88
it('should return a valid download link', function () {
99
// given

‎api/tests/unit/application/session/index_test.js

-28
Original file line numberDiff line numberDiff line change
@@ -259,34 +259,6 @@ describe('Unit | Application | Sessions | Routes', function () {
259259
expect(response.statusCode).to.equal(403);
260260
});
261261
});
262-
263-
describe('GET /api/admin/sessions/{id}/generate-results-download-link', function () {
264-
it('return forbidden access if user has METIER role', async function () {
265-
// given
266-
sinon
267-
.stub(securityPreHandlers, 'hasAtLeastOneAccessOf')
268-
.withArgs([
269-
securityPreHandlers.checkAdminMemberHasRoleSuperAdmin,
270-
securityPreHandlers.checkAdminMemberHasRoleCertif,
271-
securityPreHandlers.checkAdminMemberHasRoleSupport,
272-
])
273-
.callsFake(
274-
() => (request, h) =>
275-
h
276-
.response({ errors: new Error('forbidden') })
277-
.code(403)
278-
.takeover(),
279-
);
280-
const httpTestServer = new HttpTestServer();
281-
await httpTestServer.register(moduleUnderTest);
282-
283-
// when
284-
const response = await httpTestServer.request('GET', '/api/admin/sessions/1/generate-results-download-link');
285-
286-
// then
287-
expect(response.statusCode).to.equal(403);
288-
});
289-
});
290262
});
291263

292264
describe('DELETE /api/sessions/{id}', function () {

0 commit comments

Comments
 (0)