diff --git a/api/src/certification/configuration/domain/usecases/import-sco-whitelist.js b/api/src/certification/configuration/domain/usecases/import-sco-whitelist.js index 22a8ecf1ecb..f948b95b37c 100644 --- a/api/src/certification/configuration/domain/usecases/import-sco-whitelist.js +++ b/api/src/certification/configuration/domain/usecases/import-sco-whitelist.js @@ -11,6 +11,10 @@ export const importScoWhitelist = withTransaction( */ async ({ externalIds = [], centerRepository }) => { await centerRepository.resetWhitelist(); - return centerRepository.addToWhitelistByExternalIds({ externalIds }); + const numberOfUpdatedLines = await centerRepository.addToWhitelistByExternalIds({ externalIds }); + + if (externalIds.length !== numberOfUpdatedLines) { + throw new RangeError('Some externalIds are not valid, please verify whitelist'); + } }, ); diff --git a/api/src/certification/configuration/infrastructure/repositories/center-repository.js b/api/src/certification/configuration/infrastructure/repositories/center-repository.js index a9dd545a1f1..57441af7c76 100644 --- a/api/src/certification/configuration/infrastructure/repositories/center-repository.js +++ b/api/src/certification/configuration/infrastructure/repositories/center-repository.js @@ -5,14 +5,16 @@ import { CenterTypes } from '../../domain/models/CenterTypes.js'; /** * @param {Object} params * @param {Array} params.externalIds - * @returns {Promise} + * @returns {Promise} - number of rows affected */ export const addToWhitelistByExternalIds = async ({ externalIds }) => { const knexConn = DomainTransaction.getConnection(); - return knexConn('certification-centers') + const numberOfUpdatedLines = knexConn('certification-centers') .update({ isScoBlockedAccessWhitelist: true, updatedAt: knexConn.fn.now() }) .where({ type: CenterTypes.SCO }) .whereIn('externalId', externalIds); + + return numberOfUpdatedLines || 0; }; /** diff --git a/api/tests/certification/configuration/acceptance/application/sco-whitelist-route_test.js b/api/tests/certification/configuration/acceptance/application/sco-whitelist-route_test.js index 5e58a922f88..3a40dc32571 100644 --- a/api/tests/certification/configuration/acceptance/application/sco-whitelist-route_test.js +++ b/api/tests/certification/configuration/acceptance/application/sco-whitelist-route_test.js @@ -59,6 +59,50 @@ describe('Certification | Configuration | Acceptance | API | sco-whitelist-route .pluck('externalId'); expect(whitelist).to.deep.equal(['ext1', 'ext2']); }); + + it('should rollback if invalid whitelist given', async function () { + // given + const thisExternalIdCannotBeWhitelisted = 'NOT_A_SCO_EXTERNAL_ID'; + const superAdmin = await insertUserWithRoleSuperAdmin(); + const buffer = `externalId\next1\n${thisExternalIdCannotBeWhitelisted}`; + const options = { + method: 'POST', + url: '/api/admin/sco-whitelist', + headers: { + authorization: generateValidRequestAuthorizationHeader(superAdmin.id), + }, + payload: buffer, + }; + databaseBuilder.factory.buildCertificationCenter({ + isV3Pilot: true, + type: CERTIFICATION_CENTER_TYPES.SCO, + externalId: 'ext1', + isScoBlockedAccessWhitelist: false, + }); + databaseBuilder.factory.buildCertificationCenter({ + isV3Pilot: true, + type: CERTIFICATION_CENTER_TYPES.PRO, + externalId: thisExternalIdCannotBeWhitelisted, + isScoBlockedAccessWhitelist: false, + }); + const whitelistRollbackedToThis = databaseBuilder.factory.buildCertificationCenter({ + isV3Pilot: true, + type: CERTIFICATION_CENTER_TYPES.SCO, + externalId: 'ext3', + isScoBlockedAccessWhitelist: true, + }); + await databaseBuilder.commit(); + + // when + const response = await server.inject(options); + + // then + expect(response.statusCode).to.equal(500); + const whitelist = await knex('certification-centers') + .where({ isScoBlockedAccessWhitelist: true }) + .pluck('externalId'); + expect(whitelist).to.deep.equal([whitelistRollbackedToThis.externalId]); + }); }); describe('GET /api/admin/sco-whitelist', function () { diff --git a/api/tests/certification/configuration/integration/infrastructure/repositories/center-repository_test.js b/api/tests/certification/configuration/integration/infrastructure/repositories/center-repository_test.js index f82554b4828..32bc0f12b12 100644 --- a/api/tests/certification/configuration/integration/infrastructure/repositories/center-repository_test.js +++ b/api/tests/certification/configuration/integration/infrastructure/repositories/center-repository_test.js @@ -23,11 +23,12 @@ describe('Certification | Configuration | Integration | Repository | center-repo await databaseBuilder.commit(); // when - await centerRepository.addToWhitelistByExternalIds({ + const numberOfUpdatedLines = await centerRepository.addToWhitelistByExternalIds({ externalIds: [whitelistedExternalId1, whitelistedExternalId2], }); // then + expect(numberOfUpdatedLines).to.equal(2); const updatedCenter1 = await knex('certification-centers').where({ id: center1BeforeUpdate.id }).first(); expect(updatedCenter1.isScoBlockedAccessWhitelist).to.be.true; expect(updatedCenter1.updatedAt).to.be.above(center1BeforeUpdate.updatedAt); diff --git a/api/tests/certification/configuration/unit/domain/usecases/import-sco-whitelist_test.js b/api/tests/certification/configuration/unit/domain/usecases/import-sco-whitelist_test.js index 15bb25989e6..3f8c684bf3b 100644 --- a/api/tests/certification/configuration/unit/domain/usecases/import-sco-whitelist_test.js +++ b/api/tests/certification/configuration/unit/domain/usecases/import-sco-whitelist_test.js @@ -1,6 +1,6 @@ import { DomainTransaction } from '../../../../../../lib/infrastructure/DomainTransaction.js'; import { importScoWhitelist } from '../../../../../../src/certification/configuration/domain/usecases/import-sco-whitelist.js'; -import { expect, sinon } from '../../../../../test-helper.js'; +import { catchErr, expect, sinon } from '../../../../../test-helper.js'; describe('Certification | Configuration | Unit | UseCase | import-sco-whitelist', function () { let centerRepository; @@ -19,7 +19,7 @@ describe('Certification | Configuration | Unit | UseCase | import-sco-whitelist' it('should whitelist a center', async function () { // given centerRepository.resetWhitelist.resolves(); - centerRepository.addToWhitelistByExternalIds.resolves(); + centerRepository.addToWhitelistByExternalIds.resolves(1); // when await importScoWhitelist({ @@ -31,4 +31,22 @@ describe('Certification | Configuration | Unit | UseCase | import-sco-whitelist' expect(centerRepository.resetWhitelist).to.have.been.calledOnce; expect(centerRepository.addToWhitelistByExternalIds).to.have.been.calledOnceWithExactly({ externalIds: [12] }); }); + + it('should reject new whitelist when not valid', async function () { + // given + centerRepository.resetWhitelist.resolves(); + centerRepository.addToWhitelistByExternalIds.resolves(1); + + // when + const error = await catchErr((externalIds) => + importScoWhitelist({ + externalIds, + centerRepository, + }), + )([11, 12]); + + // then + expect(error).to.be.instanceOf(RangeError); + expect(error.message).to.equal('Some externalIds are not valid, please verify whitelist'); + }); });