diff --git a/api/lib/application/error-manager.js b/api/lib/application/error-manager.js index 0ff97022258..937f5d0f1a3 100644 --- a/api/lib/application/error-manager.js +++ b/api/lib/application/error-manager.js @@ -198,9 +198,6 @@ function _mapToHttpError(error) { if (error instanceof DomainErrors.UserNotFoundError) { return new HttpErrors.NotFoundError(error.message); } - if (error instanceof DomainErrors.PasswordResetDemandNotFoundError) { - return new HttpErrors.NotFoundError(error.message); - } if (error instanceof DomainErrors.AlreadyRegisteredEmailAndUsernameError) { return new HttpErrors.BadRequestError(error.message); } diff --git a/api/lib/application/passwords/index.js b/api/lib/application/passwords/index.js index 5c181d67ea5..c44aeffe184 100644 --- a/api/lib/application/passwords/index.js +++ b/api/lib/application/passwords/index.js @@ -2,22 +2,12 @@ import Joi from 'joi'; import XRegExp from 'xregexp'; import { config } from '../../config.js'; +import { passwordController } from './password-controller.js'; const { passwordValidationPattern } = config.account; -import { passwordController } from './password-controller.js'; - const register = async function (server) { server.route([ - { - method: 'GET', - path: '/api/password-reset-demands/{temporaryKey}', - config: { - auth: false, - handler: passwordController.checkResetDemand, - tags: ['api', 'passwords'], - }, - }, { method: 'POST', path: '/api/expired-password-updates', diff --git a/api/lib/application/passwords/password-controller.js b/api/lib/application/passwords/password-controller.js index c385662623a..02d17f538d8 100644 --- a/api/lib/application/passwords/password-controller.js +++ b/api/lib/application/passwords/password-controller.js @@ -1,12 +1,5 @@ -import * as userSerializer from '../../../src/shared/infrastructure/serializers/jsonapi/user-serializer.js'; import { usecases } from '../../domain/usecases/index.js'; -const checkResetDemand = async function (request, h, dependencies = { userSerializer }) { - const temporaryKey = request.params.temporaryKey; - const user = await usecases.getUserByResetPasswordDemand({ temporaryKey }); - return dependencies.userSerializer.serialize(user); -}; - const updateExpiredPassword = async function (request, h) { const passwordResetToken = request.payload.data.attributes['password-reset-token']; const newPassword = request.payload.data.attributes['new-password']; @@ -24,6 +17,6 @@ const updateExpiredPassword = async function (request, h) { .created(); }; -const passwordController = { checkResetDemand, updateExpiredPassword }; +const passwordController = { updateExpiredPassword }; export { passwordController }; diff --git a/api/lib/domain/errors.js b/api/lib/domain/errors.js index b31f6cb5a44..5dec056034e 100644 --- a/api/lib/domain/errors.js +++ b/api/lib/domain/errors.js @@ -671,20 +671,6 @@ class FileValidationError extends DomainError { } } -class PasswordResetDemandNotFoundError extends DomainError { - constructor(message = "La demande de réinitialisation de mot de passe n'existe pas.") { - super(message); - } - - getErrorMessage() { - return { - data: { - temporaryKey: ['Cette demande de réinitialisation n’existe pas.'], - }, - }; - } -} - // FIXME: used ? class SessionWithIdAndInformationOnMassImportError extends DomainError { constructor(message = 'Merci de ne pas renseigner les informations de session') { @@ -709,6 +695,7 @@ class UserAlreadyLinkedToCandidateInSessionError extends DomainError { super(message); } } + class UserNotAuthorizedToUpdateEmailError extends DomainError { constructor(message = 'User is not authorized to update email') { super(message); @@ -1063,7 +1050,6 @@ export { OrganizationNotFoundError, OrganizationTagNotFound, OrganizationWithoutEmailError, - PasswordResetDemandNotFoundError, SendingEmailError, SendingEmailToInvalidDomainError, SendingEmailToInvalidEmailAddressError, diff --git a/api/lib/domain/usecases/get-user-by-reset-password-demand.js b/api/lib/domain/usecases/get-user-by-reset-password-demand.js deleted file mode 100644 index 641099ba446..00000000000 --- a/api/lib/domain/usecases/get-user-by-reset-password-demand.js +++ /dev/null @@ -1,13 +0,0 @@ -const getUserByResetPasswordDemand = async function ({ - temporaryKey, - resetPasswordService, - tokenService, - userRepository, - resetPasswordDemandRepository, -}) { - await tokenService.decodeIfValid(temporaryKey); - const { email } = await resetPasswordService.verifyDemand(temporaryKey, resetPasswordDemandRepository); - return userRepository.getByEmail(email); -}; - -export { getUserByResetPasswordDemand }; diff --git a/api/lib/domain/usecases/index.js b/api/lib/domain/usecases/index.js index 092124a965c..ffb3124692b 100644 --- a/api/lib/domain/usecases/index.js +++ b/api/lib/domain/usecases/index.js @@ -55,7 +55,7 @@ import { accountRecoveryDemandRepository } from '../../../src/identity-access-ma import * as authenticationMethodRepository from '../../../src/identity-access-management/infrastructure/repositories/authentication-method.repository.js'; import { emailValidationDemandRepository } from '../../../src/identity-access-management/infrastructure/repositories/email-validation-demand.repository.js'; import * as oidcProviderRepository from '../../../src/identity-access-management/infrastructure/repositories/oidc-provider-repository.js'; -import * as resetPasswordDemandRepository from '../../../src/identity-access-management/infrastructure/repositories/reset-password-demand.repository.js'; +import { resetPasswordDemandRepository } from '../../../src/identity-access-management/infrastructure/repositories/reset-password-demand.repository.js'; import * as userRepository from '../../../src/identity-access-management/infrastructure/repositories/user.repository.js'; import { userToCreateRepository } from '../../../src/identity-access-management/infrastructure/repositories/user-to-create.repository.js'; import { organizationForAdminRepository } from '../../../src/organizational-entities/infrastructure/repositories/organization-for-admin.repository.js'; diff --git a/api/src/identity-access-management/application/http-error-mapper-configuration.js b/api/src/identity-access-management/application/http-error-mapper-configuration.js index b767309d959..91c07fabb5a 100644 --- a/api/src/identity-access-management/application/http-error-mapper-configuration.js +++ b/api/src/identity-access-management/application/http-error-mapper-configuration.js @@ -6,6 +6,7 @@ import { MissingOrInvalidCredentialsError, MissingUserAccountError, PasswordNotMatching, + PasswordResetDemandNotFoundError, UserCantBeCreatedError, UserShouldChangePasswordError, } from '../domain/errors.js'; @@ -32,6 +33,10 @@ const authenticationDomainErrorMappingConfiguration = [ name: PasswordNotMatching.name, httpErrorFn: (error) => new HttpErrors.UnauthorizedError(error.message), }, + { + name: PasswordResetDemandNotFoundError.name, + httpErrorFn: (error) => new HttpErrors.NotFoundError(error.message), + }, { name: UserCantBeCreatedError.name, httpErrorFn: (error) => new HttpErrors.UnauthorizedError(error.message), diff --git a/api/src/identity-access-management/application/password/password.controller.js b/api/src/identity-access-management/application/password/password.controller.js index 16fea46c2ff..2d588f3bc4a 100644 --- a/api/src/identity-access-management/application/password/password.controller.js +++ b/api/src/identity-access-management/application/password/password.controller.js @@ -1,7 +1,13 @@ +import * as userSerializer from '../../../shared/infrastructure/serializers/jsonapi/user-serializer.js'; import { extractLocaleFromRequest } from '../../../shared/infrastructure/utils/request-response-utils.js'; import { usecases } from '../../domain/usecases/index.js'; import * as resetPasswordSerializer from '../../infrastructure/serializers/jsonapi/reset-password.serializer.js'; +const checkResetDemand = async function (request, h, dependencies = { userSerializer }) { + const temporaryKey = request.params.temporaryKey; + const user = await usecases.getUserByResetPasswordDemand({ temporaryKey }); + return dependencies.userSerializer.serialize(user); +}; const createResetPasswordDemand = async function (request, h, dependencies = { resetPasswordSerializer }) { const { email } = request.payload.data.attributes; const locale = extractLocaleFromRequest(request); @@ -15,4 +21,4 @@ const createResetPasswordDemand = async function (request, h, dependencies = { r return h.response(serializedPayload).created(); }; -export const passwordController = { createResetPasswordDemand }; +export const passwordController = { checkResetDemand, createResetPasswordDemand }; diff --git a/api/src/identity-access-management/application/password/password.route.js b/api/src/identity-access-management/application/password/password.route.js index 306a0a768f7..c25664d94cd 100644 --- a/api/src/identity-access-management/application/password/password.route.js +++ b/api/src/identity-access-management/application/password/password.route.js @@ -14,8 +14,6 @@ export const passwordRoutes = [ data: { attributes: { email: Joi.string().email().required(), - // TODO supprimer "temporary-key" car il est généré dans le usecase associé à cette route - 'temporary-key': [Joi.string(), null], }, type: Joi.string(), }, @@ -25,4 +23,17 @@ export const passwordRoutes = [ tags: ['identity-access-management', 'api', 'password'], }, }, + { + method: 'GET', + path: '/api/password-reset-demands/{temporaryKey}', + config: { + auth: false, + handler: (request, h) => passwordController.checkResetDemand(request, h), + notes: [ + 'Route publique', + 'Cette route permet la redirection vers le formulaire de reset de mot de passe si la demande est bien dans la liste', + ], + tags: ['api', 'passwords'], + }, + }, ]; diff --git a/api/src/identity-access-management/domain/errors.js b/api/src/identity-access-management/domain/errors.js index d206a806d15..6ff833c15fe 100644 --- a/api/src/identity-access-management/domain/errors.js +++ b/api/src/identity-access-management/domain/errors.js @@ -32,6 +32,20 @@ class PasswordNotMatching extends DomainError { } } +class PasswordResetDemandNotFoundError extends DomainError { + constructor(message = "La demande de réinitialisation de mot de passe n'existe pas.") { + super(message); + } + + getErrorMessage() { + return { + data: { + temporaryKey: ['Cette demande de réinitialisation n’existe pas.'], + }, + }; + } +} + class UserCantBeCreatedError extends DomainError { constructor(message = "L'utilisateur ne peut pas être créé") { super(message); @@ -51,6 +65,7 @@ export { MissingOrInvalidCredentialsError, MissingUserAccountError, PasswordNotMatching, + PasswordResetDemandNotFoundError, UserCantBeCreatedError, UserShouldChangePasswordError, }; diff --git a/api/src/identity-access-management/domain/services/reset-password.service.js b/api/src/identity-access-management/domain/services/reset-password.service.js index 4a5adf595f9..7c7e17ac25f 100644 --- a/api/src/identity-access-management/domain/services/reset-password.service.js +++ b/api/src/identity-access-management/domain/services/reset-password.service.js @@ -2,7 +2,6 @@ import jsonwebtoken from 'jsonwebtoken'; import { config } from '../../../shared/config.js'; import { cryptoService } from '../../../shared/domain/services/crypto-service.js'; -import * as passwordResetDemandRepository from '../../infrastructure/repositories/reset-password-demand.repository.js'; const generateTemporaryKey = async function () { const randomBytesBuffer = await cryptoService.randomBytes(16); @@ -16,14 +15,11 @@ const generateTemporaryKey = async function () { ); }; -const invalidateOldResetPasswordDemand = function ( - userEmail, - resetPasswordDemandRepository = passwordResetDemandRepository, -) { +const invalidateOldResetPasswordDemand = function (userEmail, resetPasswordDemandRepository) { return resetPasswordDemandRepository.markAsBeingUsed(userEmail); }; -const verifyDemand = function (temporaryKey, resetPasswordDemandRepository = passwordResetDemandRepository) { +const verifyDemand = function (temporaryKey, resetPasswordDemandRepository) { return resetPasswordDemandRepository.findByTemporaryKey(temporaryKey).then((fetchedDemand) => fetchedDemand.toJSON()); }; @@ -34,11 +30,7 @@ const verifyDemand = function (temporaryKey, resetPasswordDemandRepository = pas * @param {ResetPasswordDemandRepository} resetPasswordDemandRepository * @return {Promise<*>} */ -const hasUserAPasswordResetDemandInProgress = function ( - email, - temporaryKey, - resetPasswordDemandRepository = passwordResetDemandRepository, -) { +const hasUserAPasswordResetDemandInProgress = function (email, temporaryKey, resetPasswordDemandRepository) { return resetPasswordDemandRepository.findByUserEmail(email, temporaryKey); }; @@ -49,4 +41,10 @@ const hasUserAPasswordResetDemandInProgress = function ( * @property invalidateOldResetPasswordDemand * @property verifyDemand */ -export { generateTemporaryKey, hasUserAPasswordResetDemandInProgress, invalidateOldResetPasswordDemand, verifyDemand }; +const resetPasswordService = { + generateTemporaryKey, + hasUserAPasswordResetDemandInProgress, + invalidateOldResetPasswordDemand, + verifyDemand, +}; +export { resetPasswordService }; diff --git a/api/src/identity-access-management/domain/usecases/get-user-by-reset-password-demand.usecase.js b/api/src/identity-access-management/domain/usecases/get-user-by-reset-password-demand.usecase.js new file mode 100644 index 00000000000..9611ca11fae --- /dev/null +++ b/api/src/identity-access-management/domain/usecases/get-user-by-reset-password-demand.usecase.js @@ -0,0 +1,21 @@ +/** + * @typedef {function} getUserByResetPasswordDemandUseCase + * @param {Object} params + * @param {string} params.temporaryKey + * @param {ResetPasswordService} params.resetPasswordService + * @param {TokenService} params.tokenService + * @param {UserRepository} params.userRepository + * @param {resetPasswordDemandRepository} params.resetPasswordDemandRepository + * @returns {Promise} + */ +export const getUserByResetPasswordDemand = async function ({ + temporaryKey, + resetPasswordService, + tokenService, + userRepository, + resetPasswordDemandRepository, +}) { + await tokenService.decodeIfValid(temporaryKey); + const { email } = await resetPasswordService.verifyDemand(temporaryKey, resetPasswordDemandRepository); + return userRepository.getByEmail(email); +}; diff --git a/api/src/identity-access-management/domain/usecases/index.js b/api/src/identity-access-management/domain/usecases/index.js index c760a7c13c1..8c55283154e 100644 --- a/api/src/identity-access-management/domain/usecases/index.js +++ b/api/src/identity-access-management/domain/usecases/index.js @@ -24,13 +24,13 @@ import { accountRecoveryDemandRepository } from '../../infrastructure/repositori import * as authenticationMethodRepository from '../../infrastructure/repositories/authentication-method.repository.js'; import { emailValidationDemandRepository } from '../../infrastructure/repositories/email-validation-demand.repository.js'; import { oidcProviderRepository } from '../../infrastructure/repositories/oidc-provider-repository.js'; -import * as resetPasswordDemandRepository from '../../infrastructure/repositories/reset-password-demand.repository.js'; +import { resetPasswordDemandRepository } from '../../infrastructure/repositories/reset-password-demand.repository.js'; import * as userRepository from '../../infrastructure/repositories/user.repository.js'; import { userToCreateRepository } from '../../infrastructure/repositories/user-to-create.repository.js'; import { authenticationSessionService } from '../services/authentication-session.service.js'; import { pixAuthenticationService } from '../services/pix-authentication-service.js'; import { refreshTokenService } from '../services/refresh-token-service.js'; -import * as resetPasswordService from '../services/reset-password.service.js'; +import { resetPasswordService } from '../services/reset-password.service.js'; import { scoAccountRecoveryService } from '../services/sco-account-recovery.service.js'; import { addOidcProviderValidator } from '../validators/add-oidc-provider.validator.js'; diff --git a/api/src/identity-access-management/domain/usecases/update-user-password.usecase.js b/api/src/identity-access-management/domain/usecases/update-user-password.usecase.js index 7b7ad77d22c..3b0bd74e2ef 100644 --- a/api/src/identity-access-management/domain/usecases/update-user-password.usecase.js +++ b/api/src/identity-access-management/domain/usecases/update-user-password.usecase.js @@ -9,6 +9,7 @@ import { UserNotAuthorizedToUpdatePasswordError } from '../../../shared/domain/e * resetPasswordService: ResetPasswordService, * authenticationMethodRepository: AuthenticationMethodRepository, * userRepository: UserRepository, + * resetPasswordDemandRepository: ResetPasswordDemandRepository, * }} params * @return {Promise} * @throws {UserNotAuthorizedToUpdatePasswordError} @@ -21,6 +22,7 @@ export const updateUserPassword = async function ({ resetPasswordService, authenticationMethodRepository, userRepository, + resetPasswordDemandRepository, }) { const hashedPassword = await cryptoService.hashPassword(password); const user = await userRepository.get(userId); @@ -29,13 +31,17 @@ export const updateUserPassword = async function ({ throw new UserNotAuthorizedToUpdatePasswordError(); } - await resetPasswordService.hasUserAPasswordResetDemandInProgress(user.email, temporaryKey); + await resetPasswordService.hasUserAPasswordResetDemandInProgress( + user.email, + temporaryKey, + resetPasswordDemandRepository, + ); await authenticationMethodRepository.updateChangedPassword({ userId: user.id, hashedPassword, }); - await resetPasswordService.invalidateOldResetPasswordDemand(user.email); + await resetPasswordService.invalidateOldResetPasswordDemand(user.email, resetPasswordDemandRepository); user.markEmailAsValid(); await userRepository.update(user.mapToDatabaseDto()); diff --git a/api/src/identity-access-management/infrastructure/repositories/reset-password-demand.repository.js b/api/src/identity-access-management/infrastructure/repositories/reset-password-demand.repository.js index ac2e40dc5a7..a3cd4ed6a9d 100644 --- a/api/src/identity-access-management/infrastructure/repositories/reset-password-demand.repository.js +++ b/api/src/identity-access-management/infrastructure/repositories/reset-password-demand.repository.js @@ -1,6 +1,6 @@ import { knex } from '../../../../db/knex-database-connection.js'; -import { PasswordResetDemandNotFoundError } from '../../../../lib/domain/errors.js'; import { ResetPasswordDemand } from '../../../../lib/infrastructure/orm-models/ResetPasswordDemand.js'; +import { PasswordResetDemandNotFoundError } from '../../domain/errors.js'; import { ResetPasswordDemand as ResetPasswordDemandModel } from '../../domain/models/ResetPasswordDemand.js'; const RESET_PASSWORD_DEMANDS_TABLE_NAME = 'reset-password-demands'; @@ -48,8 +48,14 @@ const findByUserEmail = function (email, temporaryKey) { /** * @typedef {Object} ResetPasswordDemandRepository + * @property {function} create + * @property {function} findByTemporaryKey + * @property {function} findByUserEmail + * @property {function} markAsBeingUsed */ -export { create, findByTemporaryKey, findByUserEmail, markAsBeingUsed }; +const resetPasswordDemandRepository = { create, findByTemporaryKey, findByUserEmail, markAsBeingUsed }; + +export { resetPasswordDemandRepository }; function _toDomain(data) { return new ResetPasswordDemandModel(data); diff --git a/api/tests/acceptance/application/passwords/password-controller_test.js b/api/tests/acceptance/application/passwords/password-controller_test.js index c11b97f2560..e0ce6fc6042 100644 --- a/api/tests/acceptance/application/passwords/password-controller_test.js +++ b/api/tests/acceptance/application/passwords/password-controller_test.js @@ -1,4 +1,4 @@ -import * as resetPasswordService from '../../../../src/identity-access-management/domain/services/reset-password.service.js'; +import { resetPasswordService } from '../../../../src/identity-access-management/domain/services/reset-password.service.js'; import { tokenService } from '../../../../src/shared/domain/services/token-service.js'; import { createServer, databaseBuilder, expect } from '../../../test-helper.js'; diff --git a/api/tests/identity-access-management/acceptance/application/password/password.route.test.js b/api/tests/identity-access-management/acceptance/application/password/password.route.test.js index f0c4fe266aa..700b61b7a94 100644 --- a/api/tests/identity-access-management/acceptance/application/password/password.route.test.js +++ b/api/tests/identity-access-management/acceptance/application/password/password.route.test.js @@ -1,3 +1,4 @@ +import { resetPasswordService } from '../../../../../src/identity-access-management/domain/services/reset-password.service.js'; import { config } from '../../../../../src/shared/config.js'; import { createServer, databaseBuilder, expect } from '../../../../test-helper.js'; @@ -53,4 +54,25 @@ describe('Acceptance | Identity Access Management | Application | Route | passwo }); }); }); + + describe('GET /api/password-reset-demands/{temporaryKey}', function () { + it('returns 200 http status code', async function () { + // given + const temporaryKey = await resetPasswordService.generateTemporaryKey(); + const options = { + method: 'GET', + url: `/api/password-reset-demands/${temporaryKey}`, + }; + const userId = databaseBuilder.factory.buildUser({ email }).id; + databaseBuilder.factory.buildAuthenticationMethod.withPixAsIdentityProviderAndHashedPassword({ userId }); + databaseBuilder.factory.buildResetPasswordDemand({ temporaryKey, email }); + await databaseBuilder.commit(); + + // when + const response = await server.inject(options); + + // then + expect(response.statusCode).to.equal(200); + }); + }); }); diff --git a/api/tests/identity-access-management/integration/application/password/password.controller.test.js b/api/tests/identity-access-management/integration/application/password/password.controller.test.js index 230bfe8eef7..8c53046fb71 100644 --- a/api/tests/identity-access-management/integration/application/password/password.controller.test.js +++ b/api/tests/identity-access-management/integration/application/password/password.controller.test.js @@ -1,6 +1,18 @@ import { UserNotFoundError } from '../../../../../lib/domain/errors.js'; import { passwordController } from '../../../../../src/identity-access-management/application/password/password.controller.js'; -import { catchErr, databaseBuilder, expect, hFake, sinon } from '../../../../test-helper.js'; +import { identityAccessManagementRoutes } from '../../../../../src/identity-access-management/application/routes.js'; +import { PasswordResetDemandNotFoundError } from '../../../../../src/identity-access-management/domain/errors.js'; +import { usecases } from '../../../../../src/identity-access-management/domain/usecases/index.js'; +import { InvalidTemporaryKeyError } from '../../../../../src/shared/domain/errors.js'; +import { + catchErr, + databaseBuilder, + domainBuilder, + expect, + hFake, + HttpTestServer, + sinon, +} from '../../../../test-helper.js'; describe('Integration | Identity Access Management | Application | Controller | password', function () { describe('#createResetPasswordDemand', function () { @@ -52,4 +64,72 @@ describe('Integration | Identity Access Management | Application | Controller | }); }); }); + + describe('#checkResetDemand', function () { + let routesUnderTest; + let httpTestServer; + let user; + const method = 'GET'; + const url = '/api/password-reset-demands/ABCDEF123'; + const email = 'user@example.net'; + + beforeEach(async function () { + sinon.stub(usecases, 'getUserByResetPasswordDemand'); + user = domainBuilder.buildUser({ email }); + routesUnderTest = identityAccessManagementRoutes[0]; + httpTestServer = new HttpTestServer(); + await httpTestServer.register(routesUnderTest); + }); + + context('Success cases', function () { + it('should return an HTTP response with status code 200', async function () { + // given + usecases.getUserByResetPasswordDemand.resolves(user); + + // when + const response = await httpTestServer.request(method, url); + + // then + expect(response.statusCode).to.equal(200); + expect(response.result.data.type).to.equal('users'); + expect(response.result.data.id).to.equal(user.id.toString()); + expect(response.result.data.attributes.email).to.equal(email); + }); + }); + + context('Error cases', function () { + it('should respond an HTTP response with status code 401 when InvalidTemporaryKeyError', async function () { + // given + usecases.getUserByResetPasswordDemand.rejects(new InvalidTemporaryKeyError()); + + // when + const response = await httpTestServer.request(method, url); + + // then + expect(response.statusCode).to.equal(401); + }); + + it('should respond an HTTP response with status code 404 when PasswordResetDemandNotFoundError', async function () { + // given + usecases.getUserByResetPasswordDemand.rejects(new PasswordResetDemandNotFoundError()); + + // when + const response = await httpTestServer.request(method, url); + + // then + expect(response.statusCode).to.equal(404); + }); + + it('should respond an HTTP response with status code 404 when UserNotFoundError', async function () { + // given + usecases.getUserByResetPasswordDemand.rejects(new UserNotFoundError()); + + // when + const response = await httpTestServer.request(method, url); + + // then + expect(response.statusCode).to.equal(404); + }); + }); + }); }); diff --git a/api/tests/identity-access-management/integration/application/password/password.route.test.js b/api/tests/identity-access-management/integration/application/password/password.route.test.js index e27d6ba1f6e..479de83ddf0 100644 --- a/api/tests/identity-access-management/integration/application/password/password.route.test.js +++ b/api/tests/identity-access-management/integration/application/password/password.route.test.js @@ -8,8 +8,6 @@ describe('Integration | Identity Access Management | Application | Route | passw let httpTestServer; beforeEach(async function () { - sinon.stub(passwordController, 'createResetPasswordDemand').callsFake((request, h) => h.response().created()); - httpTestServer = new HttpTestServer(); await httpTestServer.register(routesUnderTest); }); @@ -28,6 +26,9 @@ describe('Integration | Identity Access Management | Application | Route | passw }; it('returns 201 http status code', async function () { + // given + sinon.stub(passwordController, 'createResetPasswordDemand').callsFake((request, h) => h.response().created()); + // when const response = await httpTestServer.request(method, url, payload, null, headers); @@ -35,4 +36,20 @@ describe('Integration | Identity Access Management | Application | Route | passw expect(response.statusCode).to.equal(201); }); }); + + describe('GET /api/password-reset-demands/{temporaryKey}', function () { + const method = 'GET'; + const url = '/api/password-reset-demands/ABCDEF123'; + + it('returns 200 http status code', async function () { + // given + sinon.stub(passwordController, 'checkResetDemand').callsFake((request, h) => h.response().code(200)); + + // when + const response = await httpTestServer.request(method, url); + + // then + expect(response.statusCode).to.equal(200); + }); + }); }); diff --git a/api/tests/identity-access-management/integration/domain/services/reset-password.service.test.js b/api/tests/identity-access-management/integration/domain/services/reset-password.service.test.js index 99183a623c7..59da8f4a9d6 100644 --- a/api/tests/identity-access-management/integration/domain/services/reset-password.service.test.js +++ b/api/tests/identity-access-management/integration/domain/services/reset-password.service.test.js @@ -1,4 +1,4 @@ -import * as resetPasswordService from '../../../../../src/identity-access-management/domain/services/reset-password.service.js'; +import { resetPasswordService } from '../../../../../src/identity-access-management/domain/services/reset-password.service.js'; import { expect } from '../../../../test-helper.js'; describe('Integration | Identity Access Management | Domain | Service | reset-password', function () { diff --git a/api/tests/identity-access-management/integration/domain/usecases/create-reset-password-demand.usecase.test.js b/api/tests/identity-access-management/integration/domain/usecases/create-reset-password-demand.usecase.test.js index 467731d9332..5a2d15a962f 100644 --- a/api/tests/identity-access-management/integration/domain/usecases/create-reset-password-demand.usecase.test.js +++ b/api/tests/identity-access-management/integration/domain/usecases/create-reset-password-demand.usecase.test.js @@ -1,8 +1,8 @@ import { UserNotFoundError } from '../../../../../lib/domain/errors.js'; import * as mailService from '../../../../../lib/domain/services/mail-service.js'; -import * as resetPasswordService from '../../../../../src/identity-access-management/domain/services/reset-password.service.js'; +import { resetPasswordService } from '../../../../../src/identity-access-management/domain/services/reset-password.service.js'; import { createResetPasswordDemand } from '../../../../../src/identity-access-management/domain/usecases/create-reset-password-demand.usecase.js'; -import * as resetPasswordDemandRepository from '../../../../../src/identity-access-management/infrastructure/repositories/reset-password-demand.repository.js'; +import { resetPasswordDemandRepository } from '../../../../../src/identity-access-management/infrastructure/repositories/reset-password-demand.repository.js'; import * as userRepository from '../../../../../src/identity-access-management/infrastructure/repositories/user.repository.js'; import { catchErr, databaseBuilder, expect } from '../../../../test-helper.js'; diff --git a/api/tests/integration/domain/usecases/get-user-by-reset-password-demand_test.js b/api/tests/identity-access-management/integration/domain/usecases/get-user-by-reset-password-demand.usecase.test.js similarity index 60% rename from api/tests/integration/domain/usecases/get-user-by-reset-password-demand_test.js rename to api/tests/identity-access-management/integration/domain/usecases/get-user-by-reset-password-demand.usecase.test.js index 08f3db87739..a13bc0cbe5a 100644 --- a/api/tests/integration/domain/usecases/get-user-by-reset-password-demand_test.js +++ b/api/tests/identity-access-management/integration/domain/usecases/get-user-by-reset-password-demand.usecase.test.js @@ -1,13 +1,15 @@ -import { PasswordResetDemandNotFoundError, UserNotFoundError } from '../../../../lib/domain/errors.js'; -import { getUserByResetPasswordDemand } from '../../../../lib/domain/usecases/get-user-by-reset-password-demand.js'; -import { User } from '../../../../src/identity-access-management/domain/models/User.js'; -import * as resetPasswordService from '../../../../src/identity-access-management/domain/services/reset-password.service.js'; -import * as userRepository from '../../../../src/identity-access-management/infrastructure/repositories/user.repository.js'; -import { InvalidTemporaryKeyError } from '../../../../src/shared/domain/errors.js'; -import { tokenService } from '../../../../src/shared/domain/services/token-service.js'; -import { catchErr, databaseBuilder, expect } from '../../../test-helper.js'; +import { UserNotFoundError } from '../../../../../lib/domain/errors.js'; +import { PasswordResetDemandNotFoundError } from '../../../../../src/identity-access-management/domain/errors.js'; +import { User } from '../../../../../src/identity-access-management/domain/models/User.js'; +import { resetPasswordService } from '../../../../../src/identity-access-management/domain/services/reset-password.service.js'; +import { getUserByResetPasswordDemand } from '../../../../../src/identity-access-management/domain/usecases/get-user-by-reset-password-demand.usecase.js'; +import { resetPasswordDemandRepository } from '../../../../../src/identity-access-management/infrastructure/repositories/reset-password-demand.repository.js'; +import * as userRepository from '../../../../../src/identity-access-management/infrastructure/repositories/user.repository.js'; +import { InvalidTemporaryKeyError } from '../../../../../src/shared/domain/errors.js'; +import { tokenService } from '../../../../../src/shared/domain/services/token-service.js'; +import { catchErr, databaseBuilder, expect } from '../../../../test-helper.js'; -describe('Integration | UseCases | get-user-by-reset-password-demand', function () { +describe('Integration | Identity Access Management | Domain | UseCase | getUserByResetPasswordDemand', function () { const email = 'user@example.net'; let temporaryKey; @@ -29,6 +31,7 @@ describe('Integration | UseCases | get-user-by-reset-password-demand', function resetPasswordService, tokenService, userRepository, + resetPasswordDemandRepository, }); // then @@ -43,6 +46,7 @@ describe('Integration | UseCases | get-user-by-reset-password-demand', function resetPasswordService, tokenService, userRepository, + resetPasswordDemandRepository, }); // then @@ -59,6 +63,7 @@ describe('Integration | UseCases | get-user-by-reset-password-demand', function resetPasswordService, tokenService, userRepository, + resetPasswordDemandRepository, }); // then @@ -78,6 +83,7 @@ describe('Integration | UseCases | get-user-by-reset-password-demand', function resetPasswordService, tokenService, userRepository, + resetPasswordDemandRepository, }); // then diff --git a/api/tests/identity-access-management/integration/infrastructure/repositories/reset-password-demand.repository.test.js b/api/tests/identity-access-management/integration/infrastructure/repositories/reset-password-demand.repository.test.js index 6ca9b0aaff6..2276f123b71 100644 --- a/api/tests/identity-access-management/integration/infrastructure/repositories/reset-password-demand.repository.test.js +++ b/api/tests/identity-access-management/integration/infrastructure/repositories/reset-password-demand.repository.test.js @@ -1,6 +1,6 @@ -import { PasswordResetDemandNotFoundError } from '../../../../../lib/domain/errors.js'; +import { PasswordResetDemandNotFoundError } from '../../../../../src/identity-access-management/domain/errors.js'; import { ResetPasswordDemand } from '../../../../../src/identity-access-management/domain/models/ResetPasswordDemand.js'; -import * as resetPasswordDemandRepository from '../../../../../src/identity-access-management/infrastructure/repositories/reset-password-demand.repository.js'; +import { resetPasswordDemandRepository } from '../../../../../src/identity-access-management/infrastructure/repositories/reset-password-demand.repository.js'; import { catchErr, databaseBuilder, expect, knex } from '../../../../test-helper.js'; describe('Integration | Identity Access Management | Infrastructure | Repository | reset-password-demand', function () { diff --git a/api/tests/identity-access-management/unit/application/http-error-mapper-configuration_test.js b/api/tests/identity-access-management/unit/application/http-error-mapper-configuration_test.js index 8a264a4ca4d..4e0daabce37 100644 --- a/api/tests/identity-access-management/unit/application/http-error-mapper-configuration_test.js +++ b/api/tests/identity-access-management/unit/application/http-error-mapper-configuration_test.js @@ -5,6 +5,7 @@ import { MissingOrInvalidCredentialsError, MissingUserAccountError, PasswordNotMatching, + PasswordResetDemandNotFoundError, UserCantBeCreatedError, UserShouldChangePasswordError, } from '../../../../src/identity-access-management/domain/errors.js'; @@ -99,6 +100,23 @@ describe('Unit | Identity Access Management | Application | HttpErrorMapperConfi }); }); + context('when mapping "PasswordResetDemandNotFoundError"', function () { + it('returns a NotFoundError Http Error', function () { + //given + const httpErrorMapper = authenticationDomainErrorMappingConfiguration.find( + (httpErrorMapper) => httpErrorMapper.name === PasswordResetDemandNotFoundError.name, + ); + const message = 'Test message error'; + + //when + const error = httpErrorMapper.httpErrorFn(new PasswordResetDemandNotFoundError(message)); + + //then + expect(error).to.be.instanceOf(HttpErrors.NotFoundError); + expect(error.message).to.equal(message); + }); + }); + context('when mapping "UserCantBeCreatedError"', function () { it('returns an UnauthorizedError Http Error', function () { //given diff --git a/api/tests/identity-access-management/unit/application/password/password.controller.test.js b/api/tests/identity-access-management/unit/application/password/password.controller.test.js index 8321f761321..5f0b637ece2 100644 --- a/api/tests/identity-access-management/unit/application/password/password.controller.test.js +++ b/api/tests/identity-access-management/unit/application/password/password.controller.test.js @@ -3,6 +3,36 @@ import { usecases } from '../../../../../src/identity-access-management/domain/u import { expect, hFake, sinon } from '../../../../test-helper.js'; describe('Unit | Identity Access Management | Application | Controller | password', function () { + describe('#checkResetDemand', function () { + const email = 'user@example.net'; + const temporaryKey = 'ABCDEF123'; + + const request = { + params: { temporaryKey }, + }; + let dependencies; + + beforeEach(function () { + sinon.stub(usecases, 'getUserByResetPasswordDemand'); + const userSerializerStub = { + serialize: sinon.stub(), + }; + dependencies = { + userSerializer: userSerializerStub, + }; + usecases.getUserByResetPasswordDemand.resolves({ email }); + }); + + it('should return serialized user', async function () { + // when + await passwordController.checkResetDemand(request, hFake, dependencies); + + // then + expect(usecases.getUserByResetPasswordDemand).to.have.been.calledWithExactly({ temporaryKey }); + expect(dependencies.userSerializer.serialize).to.have.been.calledWithExactly({ email }); + }); + }); + describe('#createResetPasswordDemand', function () { const email = 'user@example.net'; const locale = 'fr'; diff --git a/api/tests/identity-access-management/unit/application/password/password.route.test.js b/api/tests/identity-access-management/unit/application/password/password.route.test.js index afcaa5959e1..6bdc0d1c248 100644 --- a/api/tests/identity-access-management/unit/application/password/password.route.test.js +++ b/api/tests/identity-access-management/unit/application/password/password.route.test.js @@ -19,7 +19,6 @@ describe('Unit | Identity Access Management | Application | Route | password', f data: { attributes: { email: 'uzinagaz@example.net', - 'temporary-key': 'clé', }, type: 'password-reset', }, diff --git a/api/tests/identity-access-management/unit/domain/errors.test.js b/api/tests/identity-access-management/unit/domain/errors.test.js new file mode 100644 index 00000000000..21e264cd7d4 --- /dev/null +++ b/api/tests/identity-access-management/unit/domain/errors.test.js @@ -0,0 +1,20 @@ +import { PasswordResetDemandNotFoundError } from '../../../../src/identity-access-management/domain/errors.js'; +import { expect } from '../../../test-helper.js'; + +describe('Unit | Identity Access Management | Domain | Errors', function () { + describe('#PasswordResetDemandNotFoundError', function () { + it('has a getErrorMessage method', function () { + // given + const expectedErrorMessage = { + data: { + temporaryKey: ['Cette demande de réinitialisation n’existe pas.'], + }, + }; + + // then + const error = new PasswordResetDemandNotFoundError(); + expect(error.getErrorMessage).to.be.a('function'); + expect(error.getErrorMessage()).to.eql(expectedErrorMessage); + }); + }); +}); diff --git a/api/tests/identity-access-management/unit/domain/services/reset-password.service.test.js b/api/tests/identity-access-management/unit/domain/services/reset-password.service.test.js index e28530e8e7d..f72801b6ce8 100644 --- a/api/tests/identity-access-management/unit/domain/services/reset-password.service.test.js +++ b/api/tests/identity-access-management/unit/domain/services/reset-password.service.test.js @@ -1,6 +1,6 @@ import jsonwebtoken from 'jsonwebtoken'; -import * as resetPasswordService from '../../../../../src/identity-access-management/domain/services/reset-password.service.js'; +import { resetPasswordService } from '../../../../../src/identity-access-management/domain/services/reset-password.service.js'; import { config as settings } from '../../../../../src/shared/config.js'; import { cryptoService } from '../../../../../src/shared/domain/services/crypto-service.js'; import { expect, sinon } from '../../../../test-helper.js'; diff --git a/api/tests/unit/domain/usecases/get-user-by-reset-password-demand_test.js b/api/tests/identity-access-management/unit/domain/usecases/get-user-by-reset-password-demand.usecase.test.js similarity index 80% rename from api/tests/unit/domain/usecases/get-user-by-reset-password-demand_test.js rename to api/tests/identity-access-management/unit/domain/usecases/get-user-by-reset-password-demand.usecase.test.js index 2e379bc92ce..ce0568e8c5f 100644 --- a/api/tests/unit/domain/usecases/get-user-by-reset-password-demand_test.js +++ b/api/tests/identity-access-management/unit/domain/usecases/get-user-by-reset-password-demand.usecase.test.js @@ -1,10 +1,11 @@ -import { PasswordResetDemandNotFoundError, UserNotFoundError } from '../../../../lib/domain/errors.js'; -import { getUserByResetPasswordDemand } from '../../../../lib/domain/usecases/get-user-by-reset-password-demand.js'; -import { User } from '../../../../src/identity-access-management/domain/models/User.js'; -import { InvalidTemporaryKeyError } from '../../../../src/shared/domain/errors.js'; -import { catchErr, domainBuilder, expect, sinon } from '../../../test-helper.js'; - -describe('Unit | UseCase | get-user-by-reset-password-demand', function () { +import { UserNotFoundError } from '../../../../../lib/domain/errors.js'; +import { PasswordResetDemandNotFoundError } from '../../../../../src/identity-access-management/domain/errors.js'; +import { User } from '../../../../../src/identity-access-management/domain/models/User.js'; +import { getUserByResetPasswordDemand } from '../../../../../src/identity-access-management/domain/usecases/get-user-by-reset-password-demand.usecase.js'; +import { InvalidTemporaryKeyError } from '../../../../../src/shared/domain/errors.js'; +import { catchErr, domainBuilder, expect, sinon } from '../../../../test-helper.js'; + +describe('Unit | Identity Access Management | Domain | UseCase | get-user-by-reset-password-demand', function () { const temporaryKey = 'ABCDEF123'; const email = 'user@example.net'; diff --git a/api/tests/identity-access-management/unit/domain/usecases/update-user-password.usecase.test.js b/api/tests/identity-access-management/unit/domain/usecases/update-user-password.usecase.test.js index de729c96c50..b338d1961a7 100644 --- a/api/tests/identity-access-management/unit/domain/usecases/update-user-password.usecase.test.js +++ b/api/tests/identity-access-management/unit/domain/usecases/update-user-password.usecase.test.js @@ -1,4 +1,4 @@ -import { PasswordResetDemandNotFoundError } from '../../../../../lib/domain/errors.js'; +import { PasswordResetDemandNotFoundError } from '../../../../../src/identity-access-management/domain/errors.js'; import { User } from '../../../../../src/identity-access-management/domain/models/User.js'; import { updateUserPassword } from '../../../../../src/identity-access-management/domain/usecases/update-user-password.usecase.js'; import { UserNotAuthorizedToUpdatePasswordError } from '../../../../../src/shared/domain/errors.js'; @@ -17,6 +17,7 @@ describe('Unit | Identity Access Management | Domain | UseCase | update-user-pas let resetPasswordService; let authenticationMethodRepository; let userRepository; + let resetPasswordDemandRepository; beforeEach(function () { cryptoService = { @@ -34,6 +35,11 @@ describe('Unit | Identity Access Management | Domain | UseCase | update-user-pas update: sinon.stub(), }; + resetPasswordDemandRepository = { + hasUserAPasswordResetDemandInProgress: sinon.stub(), + invalidateOldResetPasswordDemand: sinon.stub(), + }; + cryptoService.hashPassword.resolves(); resetPasswordService.hasUserAPasswordResetDemandInProgress.withArgs(user.email, temporaryKey).resolves(); resetPasswordService.invalidateOldResetPasswordDemand.resolves(); @@ -89,12 +95,14 @@ describe('Unit | Identity Access Management | Domain | UseCase | update-user-pas resetPasswordService, authenticationMethodRepository, userRepository, + resetPasswordDemandRepository, }); // then expect(resetPasswordService.hasUserAPasswordResetDemandInProgress).to.have.been.calledWithExactly( user.email, temporaryKey, + resetPasswordDemandRepository, ); }); @@ -131,10 +139,14 @@ describe('Unit | Identity Access Management | Domain | UseCase | update-user-pas resetPasswordService, authenticationMethodRepository, userRepository, + resetPasswordDemandRepository, }); // then - expect(resetPasswordService.invalidateOldResetPasswordDemand).to.have.been.calledWithExactly(user.email); + expect(resetPasswordService.invalidateOldResetPasswordDemand).to.have.been.calledWithExactly( + user.email, + resetPasswordDemandRepository, + ); }); context('When user has not a current password reset demand', function () { @@ -153,6 +165,7 @@ describe('Unit | Identity Access Management | Domain | UseCase | update-user-pas resetPasswordService, authenticationMethodRepository, userRepository, + resetPasswordDemandRepository, }); // then @@ -174,6 +187,7 @@ describe('Unit | Identity Access Management | Domain | UseCase | update-user-pas resetPasswordService, authenticationMethodRepository, userRepository, + resetPasswordDemandRepository, }); // then diff --git a/api/tests/integration/application/error-manager_test.js b/api/tests/integration/application/error-manager_test.js index b1c6267d850..188d9e42345 100644 --- a/api/tests/integration/application/error-manager_test.js +++ b/api/tests/integration/application/error-manager_test.js @@ -215,18 +215,6 @@ describe('Integration | API | Controller Error', function () { expect(response.statusCode).to.equal(NOT_FOUND_ERROR); expect(responseDetail(response)).to.equal('Ce compte est introuvable.'); }); - - it('responds Not Found when a PasswordResetDemandNotFoundError error occurs', async function () { - routeHandler.throws( - new DomainErrors.PasswordResetDemandNotFoundError( - "La demande de réinitialisation de mot de passe n'existe pas.", - ), - ); - const response = await server.requestObject(request); - - expect(response.statusCode).to.equal(NOT_FOUND_ERROR); - expect(responseDetail(response)).to.equal("La demande de réinitialisation de mot de passe n'existe pas."); - }); }); context('409 Conflict', function () { diff --git a/api/tests/integration/application/passwords/index_test.js b/api/tests/integration/application/passwords/index_test.js index cb0a01f7056..5a097c5cf6a 100644 --- a/api/tests/integration/application/passwords/index_test.js +++ b/api/tests/integration/application/passwords/index_test.js @@ -6,26 +6,12 @@ describe('Integration | Application | Password | Routes', function () { let httpTestServer; beforeEach(async function () { - sinon.stub(passwordController, 'checkResetDemand').resolves('ok'); sinon.stub(passwordController, 'updateExpiredPassword').callsFake((request, h) => h.response().created()); httpTestServer = new HttpTestServer(); await httpTestServer.register(moduleUnderTest); }); - describe('GET /api/password-reset-demands/{temporaryKey}', function () { - const method = 'GET'; - const url = '/api/password-reset-demands/ABCDEF123'; - - it('should return 200 http status code', async function () { - // when - const response = await httpTestServer.request(method, url); - - // then - expect(response.statusCode).to.equal(200); - }); - }); - describe('POST /api/expired-password-updates', function () { it('should return 201 http status code', async function () { // given diff --git a/api/tests/integration/application/passwords/password-controller_test.js b/api/tests/integration/application/passwords/password-controller_test.js index 0c64bd20f21..866010a3160 100644 --- a/api/tests/integration/application/passwords/password-controller_test.js +++ b/api/tests/integration/application/passwords/password-controller_test.js @@ -1,82 +1,19 @@ import * as moduleUnderTest from '../../../../lib/application/passwords/index.js'; -import { PasswordResetDemandNotFoundError, UserNotFoundError } from '../../../../lib/domain/errors.js'; +import { UserNotFoundError } from '../../../../lib/domain/errors.js'; import { usecases } from '../../../../lib/domain/usecases/index.js'; -import { ForbiddenAccess, InvalidTemporaryKeyError } from '../../../../src/shared/domain/errors.js'; -import { domainBuilder, expect, HttpTestServer, sinon } from '../../../test-helper.js'; +import { ForbiddenAccess } from '../../../../src/shared/domain/errors.js'; +import { expect, HttpTestServer, sinon } from '../../../test-helper.js'; describe('Integration | Application | Passwords | password-controller', function () { let httpTestServer; beforeEach(async function () { - sinon.stub(usecases, 'getUserByResetPasswordDemand'); sinon.stub(usecases, 'updateExpiredPassword'); httpTestServer = new HttpTestServer(); await httpTestServer.register(moduleUnderTest); }); - describe('#checkResetDemand', function () { - const method = 'GET'; - const url = '/api/password-reset-demands/ABCDEF123'; - - const email = 'user@example.net'; - - // TODO: Fix this the next time the file is edited. - // eslint-disable-next-line mocha/no-setup-in-describe - const user = domainBuilder.buildUser({ email }); - - context('Success cases', function () { - it('should return an HTTP response with status code 200', async function () { - // given - usecases.getUserByResetPasswordDemand.resolves(user); - - // when - const response = await httpTestServer.request(method, url); - - // then - expect(response.statusCode).to.equal(200); - expect(response.result.data.type).to.equal('users'); - expect(response.result.data.id).to.equal(user.id.toString()); - expect(response.result.data.attributes.email).to.equal(email); - }); - }); - - context('Error cases', function () { - it('should respond an HTTP response with status code 401 when InvalidTemporaryKeyError', async function () { - // given - usecases.getUserByResetPasswordDemand.rejects(new InvalidTemporaryKeyError()); - - // when - const response = await httpTestServer.request(method, url); - - // then - expect(response.statusCode).to.equal(401); - }); - - it('should respond an HTTP response with status code 404 when PasswordResetDemandNotFoundError', async function () { - // given - usecases.getUserByResetPasswordDemand.rejects(new PasswordResetDemandNotFoundError()); - - // when - const response = await httpTestServer.request(method, url); - - // then - expect(response.statusCode).to.equal(404); - }); - - it('should respond an HTTP response with status code 404 when UserNotFoundError', async function () { - // given - usecases.getUserByResetPasswordDemand.rejects(new UserNotFoundError()); - - // when - const response = await httpTestServer.request(method, url); - - // then - expect(response.statusCode).to.equal(404); - }); - }); - }); - describe('#updateExpiredPassword', function () { const method = 'POST'; const url = '/api/expired-password-updates'; diff --git a/api/tests/unit/application/passwords/index_test.js b/api/tests/unit/application/passwords/index_test.js index 4967b18e0fa..56a321f92ce 100644 --- a/api/tests/unit/application/passwords/index_test.js +++ b/api/tests/unit/application/passwords/index_test.js @@ -3,24 +3,6 @@ import { passwordController } from '../../../../lib/application/passwords/passwo import { expect, HttpTestServer, sinon } from '../../../test-helper.js'; describe('Unit | Router | Password router', function () { - describe('GET /api/password-reset-demands/{temporaryKey}', function () { - const method = 'GET'; - const url = '/api/password-reset-demands/ABCDEF123'; - - it('should return 201 http status code', async function () { - // given - sinon.stub(passwordController, 'checkResetDemand').resolves('ok'); - const httpTestServer = new HttpTestServer(); - await httpTestServer.register(moduleUnderTest); - - // when - const response = await httpTestServer.request(method, url); - - // then - expect(response.statusCode).to.equal(200); - }); - }); - describe('POST /api/expired-password-updates', function () { const method = 'POST'; const url = '/api/expired-password-updates'; diff --git a/api/tests/unit/application/passwords/password-controller_test.js b/api/tests/unit/application/passwords/password-controller_test.js index 76c4f1ad135..fe5a09aea9a 100644 --- a/api/tests/unit/application/passwords/password-controller_test.js +++ b/api/tests/unit/application/passwords/password-controller_test.js @@ -3,36 +3,6 @@ import { usecases } from '../../../../lib/domain/usecases/index.js'; import { expect, hFake, sinon } from '../../../test-helper.js'; describe('Unit | Controller | PasswordController', function () { - describe('#checkResetDemand', function () { - const email = 'user@example.net'; - const temporaryKey = 'ABCDEF123'; - - const request = { - params: { temporaryKey }, - }; - let dependencies; - - beforeEach(function () { - sinon.stub(usecases, 'getUserByResetPasswordDemand'); - const userSerializerStub = { - serialize: sinon.stub(), - }; - dependencies = { - userSerializer: userSerializerStub, - }; - usecases.getUserByResetPasswordDemand.resolves({ email }); - }); - - it('should return serialized user', async function () { - // when - await passwordController.checkResetDemand(request, hFake, dependencies); - - // then - expect(usecases.getUserByResetPasswordDemand).to.have.been.calledWithExactly({ temporaryKey }); - expect(dependencies.userSerializer.serialize).to.have.been.calledWithExactly({ email }); - }); - }); - describe('#updateExpiredPassword', function () { it('should return 201 http status code', async function () { // given diff --git a/api/tests/unit/domain/errors_test.js b/api/tests/unit/domain/errors_test.js index 3b476f59bb6..73d43e3a74f 100644 --- a/api/tests/unit/domain/errors_test.js +++ b/api/tests/unit/domain/errors_test.js @@ -93,26 +93,6 @@ describe('Unit | Domain | Errors', function () { }); }); - describe('#PasswordResetDemandNotFoundError', function () { - it('should export a PasswordResetDemandNotFoundError', function () { - expect(errors.PasswordResetDemandNotFoundError).to.exist; - }); - - it('should have a getErrorMessage method', function () { - // given - const expectedErrorMessage = { - data: { - temporaryKey: ['Cette demande de réinitialisation n’existe pas.'], - }, - }; - - // then - const error = new errors.PasswordResetDemandNotFoundError(); - expect(error.getErrorMessage).to.be.a('function'); - expect(error.getErrorMessage()).to.eql(expectedErrorMessage); - }); - }); - it('should export a TargetProfileInvalidError', function () { expect(errors.TargetProfileInvalidError).to.exist; });