Skip to content

Commit

Permalink
Merge pull request #1432 from govuk-one-login/BAU/add-tests-to-verify…
Browse files Browse the repository at this point in the history
…-code-controller

Bugfix: Do not redirect to password reset intervention when on password reset journey in verfiy code controller
  • Loading branch information
BeckaL authored Mar 6, 2024
2 parents 5e9b7ac + d834a46 commit 2f23892
Show file tree
Hide file tree
Showing 2 changed files with 248 additions and 1 deletion.
245 changes: 245 additions & 0 deletions src/components/common/verify-code/tests/verify-code-controller.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,245 @@
import { expect } from "chai";
import { describe } from "mocha";
import { sinon } from "../../../../../test/utils/test-utils";

import { Request, Response } from "express";
import {
mockRequest,
mockResponse,
RequestOutput,
ResponseOutput,
} from "mock-req-res";
import { fakeVerifyCodeServiceHelper } from "../../../../../test/helpers/verify-code-helpers";
import { verifyCodePost } from "../verify-code-controller";
import { accountInterventionsFakeHelper } from "../../../../../test/helpers/account-interventions-helpers";
import {
JOURNEY_TYPE,
NOTIFICATION_TYPE,
PATH_NAMES,
} from "../../../../app.constants";
import { ERROR_CODES } from "../../constants";

describe("Verify code controller tests", () => {
let req: RequestOutput;
let res: ResponseOutput;

beforeEach(() => {
process.env.SUPPORT_ACCOUNT_INTERVENTIONS = "1";

res = mockResponse();
});

afterEach(() => {
delete process.env.SUPPORT_ACCOUNT_INTERVENTIONS;
});

it("if code is valid and NOTIFICATION_TYPE.EMAIL_CODE redirects to /enter-password without calling account interventions", async () => {
const verifyCodeService = fakeVerifyCodeServiceHelper(true);
const accountInterventionService = accountInterventionsFakeHelper(
"[email protected]",
false,
false,
false
);

req = mockRequest({
path: PATH_NAMES.ENTER_PASSWORD,
session: { client: {}, user: { email: "[email protected]" } },
log: { info: sinon.fake() },
});

await verifyCodePost(verifyCodeService, accountInterventionService, {
notificationType: NOTIFICATION_TYPE.VERIFY_EMAIL,
template: "check-your-email/index.njk",
validationKey: "pages.checkYourEmail.code.validationError.invalidCode",
validationErrorCode: ERROR_CODES.INVALID_VERIFY_EMAIL_CODE,
})(req as Request, res as Response);

expect(accountInterventionService.accountInterventionStatus).to.not.be
.called;

expect(res.redirect).to.have.calledWith("/enter-password");
});

describe("When code is valid and NOTIFICATION_TYPE.VERIFY_CHANGE_HOW_GET_SECURITY_CODES and code is valid", () => {
const verifyCodeService = fakeVerifyCodeServiceHelper(true);
beforeEach(() => {
req = mockRequest({
path: PATH_NAMES.CHECK_YOUR_EMAIL_CHANGE_SECURITY_CODES,
session: { client: {}, user: { email: "[email protected]" } },
log: { info: sinon.fake() },
});
});

it("if account is blocked, redirects to /unavailable-permanent", async () => {
const accountInterventionService = accountInterventionsFakeHelper(
"[email protected]",
false,
true,
false
);
await verifyCodePost(verifyCodeService, accountInterventionService, {
notificationType:
NOTIFICATION_TYPE.VERIFY_CHANGE_HOW_GET_SECURITY_CODES,
template: "check-your-email/index.njk",
validationKey: "pages.checkYourEmail.code.validationError.invalidCode",
validationErrorCode: ERROR_CODES.INVALID_VERIFY_EMAIL_CODE,
})(req as Request, res as Response);

expect(accountInterventionService.accountInterventionStatus).to.have.been
.called;
expect(res.redirect).to.have.calledWith("/unavailable-permanent");
});

it("if account is temporarily suspended only, redirects to /unavailable-temporary", async () => {
const accountInterventionService = accountInterventionsFakeHelper(
"[email protected]",
false,
false,
true
);
await verifyCodePost(verifyCodeService, accountInterventionService, {
notificationType:
NOTIFICATION_TYPE.VERIFY_CHANGE_HOW_GET_SECURITY_CODES,
template: "check-your-email/index.njk",
validationKey: "pages.checkYourEmail.code.validationError.invalidCode",
validationErrorCode: ERROR_CODES.INVALID_VERIFY_EMAIL_CODE,
})(req as Request, res as Response);

expect(accountInterventionService.accountInterventionStatus).to.have.been
.called;
expect(res.redirect).to.have.calledWith("/unavailable-temporary");
});

it("if account has has password reset required status, redirects to /password-reset-required", async () => {
const accountInterventionService = accountInterventionsFakeHelper(
"[email protected]",
true,
false,
true
);
await verifyCodePost(verifyCodeService, accountInterventionService, {
notificationType:
NOTIFICATION_TYPE.VERIFY_CHANGE_HOW_GET_SECURITY_CODES,
template: "check-your-email/index.njk",
validationKey: "pages.checkYourEmail.code.validationError.invalidCode",
validationErrorCode: ERROR_CODES.INVALID_VERIFY_EMAIL_CODE,
})(req as Request, res as Response);

expect(accountInterventionService.accountInterventionStatus).to.have.been
.called;
expect(res.redirect).to.have.calledWith("/password-reset-required");
});

it("if account has no AIS status, redirects to /get-security-codes", async () => {
const accountInterventionService = accountInterventionsFakeHelper(
"[email protected]",
false,
false,
false
);
await verifyCodePost(verifyCodeService, accountInterventionService, {
notificationType:
NOTIFICATION_TYPE.VERIFY_CHANGE_HOW_GET_SECURITY_CODES,
template: "check-your-email/index.njk",
validationKey: "pages.checkYourEmail.code.validationError.invalidCode",
validationErrorCode: ERROR_CODES.INVALID_VERIFY_EMAIL_CODE,
})(req as Request, res as Response);

expect(accountInterventionService.accountInterventionStatus).to.have.been
.called;
expect(res.redirect).to.have.calledWith("/get-security-codes");
});
});

describe("When code is valid and NOTIFICATION_TYPE.MFA_SMS", () => {
const verifyCodeService = fakeVerifyCodeServiceHelper(true);
beforeEach(() => {
req = mockRequest({
path: PATH_NAMES.RESET_PASSWORD_2FA_SMS,
session: { client: {}, user: { email: "[email protected]" } },
log: { info: sinon.fake() },
});
});

it("if account has no AIS status, redirects to reset password", async () => {
const accountInterventionService = accountInterventionsFakeHelper(
"[email protected]",
false,
false,
false
);
await verifyCodePost(verifyCodeService, accountInterventionService, {
notificationType: NOTIFICATION_TYPE.MFA_SMS,
template: "check-your-email/index.njk",
validationKey: "pages.checkYourEmail.code.validationError.invalidCode",
validationErrorCode: ERROR_CODES.INVALID_VERIFY_EMAIL_CODE,
journeyType: JOURNEY_TYPE.PASSWORD_RESET_MFA,
})(req as Request, res as Response);

expect(accountInterventionService.accountInterventionStatus).to.have.been
.called;
expect(res.redirect).to.have.calledWith("/reset-password");
});

it("if account has only temporary suspension status, redirects to /unavailable-temporary", async () => {
const accountInterventionService = accountInterventionsFakeHelper(
"[email protected]",
false,
false,
true
);
await verifyCodePost(verifyCodeService, accountInterventionService, {
notificationType: NOTIFICATION_TYPE.MFA_SMS,
template: "check-your-email/index.njk",
validationKey: "pages.checkYourEmail.code.validationError.invalidCode",
validationErrorCode: ERROR_CODES.INVALID_VERIFY_EMAIL_CODE,
journeyType: JOURNEY_TYPE.PASSWORD_RESET_MFA,
})(req as Request, res as Response);

expect(accountInterventionService.accountInterventionStatus).to.have.been
.called;
expect(res.redirect).to.have.calledWith("/unavailable-temporary");
});

it("if account has only permanent suspension status, redirects to /unavailable-permanent", async () => {
const accountInterventionService = accountInterventionsFakeHelper(
"[email protected]",
false,
true,
false
);
await verifyCodePost(verifyCodeService, accountInterventionService, {
notificationType: NOTIFICATION_TYPE.MFA_SMS,
template: "check-your-email/index.njk",
validationKey: "pages.checkYourEmail.code.validationError.invalidCode",
validationErrorCode: ERROR_CODES.INVALID_VERIFY_EMAIL_CODE,
journeyType: JOURNEY_TYPE.PASSWORD_RESET_MFA,
})(req as Request, res as Response);

expect(accountInterventionService.accountInterventionStatus).to.have.been
.called;
expect(res.redirect).to.have.calledWith("/unavailable-permanent");
});

it("if account has reset password and suspended status, redirects to reset password", async () => {
const accountInterventionService = accountInterventionsFakeHelper(
"[email protected]",
true,
false,
true
);
await verifyCodePost(verifyCodeService, accountInterventionService, {
notificationType: NOTIFICATION_TYPE.MFA_SMS,
template: "check-your-email/index.njk",
validationKey: "pages.checkYourEmail.code.validationError.invalidCode",
validationErrorCode: ERROR_CODES.INVALID_VERIFY_EMAIL_CODE,
journeyType: JOURNEY_TYPE.PASSWORD_RESET_MFA,
})(req as Request, res as Response);

expect(accountInterventionService.accountInterventionStatus).to.have.been
.called;
expect(res.redirect).to.have.calledWith("/reset-password");
});
});
});
4 changes: 3 additions & 1 deletion src/components/common/verify-code/verify-code-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,9 @@ export function verifyCodePost(
if (accountInterventionsResponse.data.blocked) {
nextEvent = USER_JOURNEY_EVENTS.PERMANENTLY_BLOCKED_INTERVENTION;
} else if (accountInterventionsResponse.data.passwordResetRequired) {
nextEvent = USER_JOURNEY_EVENTS.PASSWORD_RESET_INTERVENTION;
if (options.journeyType !== JOURNEY_TYPE.PASSWORD_RESET_MFA) {
nextEvent = USER_JOURNEY_EVENTS.PASSWORD_RESET_INTERVENTION;
}
} else if (accountInterventionsResponse.data.temporarilySuspended) {
nextEvent = USER_JOURNEY_EVENTS.TEMPORARILY_BLOCKED_INTERVENTION;
}
Expand Down

0 comments on commit 2f23892

Please sign in to comment.