-
Notifications
You must be signed in to change notification settings - Fork 55
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[FEATURE] Permettre au surveillant de traiter un signalement d'extens…
- Loading branch information
Showing
34 changed files
with
1,171 additions
and
322 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
11 changes: 11 additions & 0 deletions
11
api/src/certification/session-management/application/companion-alert-controller.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import { usecases } from '../domain/usecases/index.js'; | ||
|
||
export const companionAlertController = { | ||
async clear(request, h) { | ||
const { sessionId, userId } = request.params; | ||
|
||
await usecases.clearCompanionAlert({ sessionId, userId }); | ||
|
||
return h.response().code(204); | ||
}, | ||
}; |
51 changes: 51 additions & 0 deletions
51
api/src/certification/session-management/application/companion-alert-route.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import Joi from 'joi'; | ||
|
||
import { identifiersType } from '../../../shared/domain/types/identifiers-type.js'; | ||
import { responseObjectErrorDoc } from '../../../shared/infrastructure/open-api-doc/response-object-error-doc.js'; | ||
import { assessmentSupervisorAuthorization } from '../../shared/application/pre-handlers/session-supervisor-authorization.js'; | ||
import { companionAlertController } from './companion-alert-controller.js'; | ||
|
||
export function register(server) { | ||
server.route([ | ||
{ | ||
method: 'PATCH', | ||
path: '/api/sessions/{sessionId}/users/{userId}/clear-companion-alert', | ||
config: { | ||
plugins: { | ||
'hapi-swagger': { | ||
produces: ['application/json'], | ||
consumes: ['application/json'], | ||
}, | ||
}, | ||
response: { | ||
failAction: 'log', | ||
status: { | ||
204: Joi.string.empty, | ||
401: responseObjectErrorDoc, | ||
403: responseObjectErrorDoc, | ||
}, | ||
}, | ||
validate: { | ||
params: Joi.object({ | ||
sessionId: identifiersType.sessionId, | ||
userId: identifiersType.userId, | ||
}), | ||
}, | ||
pre: [ | ||
{ | ||
method: assessmentSupervisorAuthorization.verifyBySessionId, | ||
assign: 'isSupervisorForSession', | ||
}, | ||
], | ||
handler: companionAlertController.clear, | ||
tags: ['api', 'sessions', 'liveAlerts'], | ||
notes: [ | ||
'Cette route est restreinte au surveillant', | ||
'Elle permet de lever une alerte d’extension non détectée', | ||
], | ||
}, | ||
}, | ||
]); | ||
} | ||
|
||
export const name = 'session-management-companion-alert-api'; |
18 changes: 18 additions & 0 deletions
18
api/src/certification/session-management/domain/usecases/clear-companion-alert.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import { withTransaction } from '../../../../shared/domain/DomainTransaction.js'; | ||
|
||
export const clearCompanionAlert = withTransaction( | ||
/** | ||
* @param {Object} params | ||
* @param {number} params.sessionId | ||
* @param {number} params.userId | ||
* @param {import('./index.js').CertificationCompanionAlertRepository} params.certificationCompanionAlertRepository | ||
*/ | ||
async function clearCompanionAlert({ sessionId, userId, certificationCompanionAlertRepository }) { | ||
const alert = await certificationCompanionAlertRepository.getOngoingAlert({ sessionId, userId }); | ||
if (!alert) return; | ||
|
||
alert.clear(); | ||
|
||
await certificationCompanionAlertRepository.update(alert); | ||
}, | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
58 changes: 58 additions & 0 deletions
58
...ession-management/infrastructure/repositories/certification-companion-alert-repository.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import { DomainTransaction } from '../../../../shared/domain/DomainTransaction.js'; | ||
import { | ||
CertificationCompanionLiveAlert, | ||
CertificationCompanionLiveAlertStatus, | ||
} from '../../../shared/domain/models/CertificationCompanionLiveAlert.js'; | ||
const TABLE_NAME = 'certification-companion-live-alerts'; | ||
|
||
/** | ||
* | ||
* @param {object} params | ||
* @param {number} params.sessionId | ||
* @param {number} params.userId | ||
* @param {object} options | ||
* @param {import('knex').Knex} options.knex | ||
*/ | ||
export async function getOngoingAlert({ sessionId, userId }, { knex = DomainTransaction.getConnection() } = {}) { | ||
const alert = await knex | ||
.select(`${TABLE_NAME}.*`) | ||
.first() | ||
.from('certification-courses') | ||
.join('assessments', function () { | ||
this.on('assessments.userId', '=', 'certification-courses.userId').andOn( | ||
'assessments.certificationCourseId', | ||
'=', | ||
'certification-courses.id', | ||
); | ||
}) | ||
.join(TABLE_NAME, function () { | ||
this.on(`${TABLE_NAME}.assessmentId`, '=', 'assessments.id').andOnVal( | ||
`${TABLE_NAME}.status`, | ||
'=', | ||
CertificationCompanionLiveAlertStatus.ONGOING, | ||
); | ||
}) | ||
.where('certification-courses.sessionId', '=', sessionId) | ||
.andWhere('certification-courses.userId', '=', userId) | ||
.forUpdate(TABLE_NAME); | ||
|
||
if (!alert) return null; | ||
|
||
return new CertificationCompanionLiveAlert(alert); | ||
} | ||
|
||
/** | ||
* @param {CertificationCompanionLiveAlert} | ||
* @param {object} options | ||
* @param {import('knex').Knex} options.knex | ||
*/ | ||
export async function update({ id, status }, { knex = DomainTransaction.getConnection() } = {}) { | ||
await knex(TABLE_NAME) | ||
.update({ | ||
status, | ||
updatedAt: knex.fn.now(), | ||
}) | ||
.where({ | ||
id, | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
7 changes: 6 additions & 1 deletion
7
api/src/certification/shared/domain/models/CertificationCompanionLiveAlert.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
91 changes: 91 additions & 0 deletions
91
...sts/certification/session-management/acceptance/application/companion-alert-route_test.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
import { CertificationCompanionLiveAlertStatus } from '../../../../../src/certification/shared/domain/models/CertificationCompanionLiveAlert.js'; | ||
import { Assessment } from '../../../../../src/shared/domain/models/Assessment.js'; | ||
import { | ||
createServer, | ||
databaseBuilder, | ||
expect, | ||
generateValidRequestAuthorizationHeader, | ||
knex, | ||
} from '../../../../test-helper.js'; | ||
|
||
describe('Certification | Session Management | Acceptance | Application | Routes | companion-alert', function () { | ||
let server; | ||
|
||
beforeEach(async function () { | ||
server = await createServer(); | ||
}); | ||
|
||
describe('PATCH /api/sessions/{sessionId}/users/{userId}/clear-companion-alert', function () { | ||
it('should return 204 no content and set alert status to CLEARED', async function () { | ||
// given | ||
const { id: certificationCenterId } = databaseBuilder.factory.buildCertificationCenter(); | ||
const { id: sessionId } = databaseBuilder.factory.buildSession({ certificationCenterId }); | ||
const { id: certificationCandidateId, userId } = databaseBuilder.factory.buildCertificationCandidate({ | ||
sessionId, | ||
}); | ||
databaseBuilder.factory.buildCoreSubscription({ certificationCandidateId }); | ||
const { id: certificationCourseId } = databaseBuilder.factory.buildCertificationCourse({ | ||
sessionId, | ||
userId, | ||
}); | ||
const { id: assessmentId } = databaseBuilder.factory.buildAssessment({ | ||
type: Assessment.types.CERTIFICATION, | ||
state: Assessment.states.STARTED, | ||
userId, | ||
certificationCourseId, | ||
}); | ||
|
||
databaseBuilder.factory.buildCertificationCompanionLiveAlert({ | ||
assessmentId, | ||
status: CertificationCompanionLiveAlertStatus.ONGOING, | ||
}); | ||
|
||
const { userId: supervisorId } = databaseBuilder.factory.buildSupervisorAccess({ sessionId }); | ||
|
||
await databaseBuilder.commit(); | ||
|
||
const headers = { authorization: generateValidRequestAuthorizationHeader(supervisorId, 'pix-certif') }; | ||
|
||
const options = { | ||
headers, | ||
method: 'PATCH', | ||
url: `/api/sessions/${sessionId}/users/${userId}/clear-companion-alert`, | ||
}; | ||
|
||
// when | ||
const response = await server.inject(options); | ||
|
||
// then | ||
expect(response.statusCode).to.equal(204); | ||
const alerts = await knex.select('assessmentId', 'status').from('certification-companion-live-alerts'); | ||
expect(alerts).to.deep.equal([{ assessmentId, status: CertificationCompanionLiveAlertStatus.CLEARED }]); | ||
}); | ||
|
||
describe('when user does NOT have supervisor access on session', function () { | ||
it('should return 401 unauthorized', async function () { | ||
// given | ||
const { id: certificationCenterId } = databaseBuilder.factory.buildCertificationCenter(); | ||
const { id: sessionId } = databaseBuilder.factory.buildSession({ certificationCenterId }); | ||
const { id: otherSessionId } = databaseBuilder.factory.buildSession({ certificationCenterId }); | ||
|
||
const { userId: supervisorId } = databaseBuilder.factory.buildSupervisorAccess({ sessionId: otherSessionId }); | ||
|
||
await databaseBuilder.commit(); | ||
|
||
const headers = { authorization: generateValidRequestAuthorizationHeader(supervisorId, 'pix-certif') }; | ||
|
||
const options = { | ||
headers, | ||
method: 'PATCH', | ||
url: `/api/sessions/${sessionId}/users/666/clear-companion-alert`, | ||
}; | ||
|
||
// when | ||
const response = await server.inject(options); | ||
|
||
// then | ||
expect(response.statusCode).to.equal(401); | ||
}); | ||
}); | ||
}); | ||
}); |
Oops, something went wrong.