Skip to content

Commit

Permalink
feat(EMS-1696-1697): Reactivate an account (#527)
Browse files Browse the repository at this point in the history
* chore(tech): fix typo

* chore(tech): fix typo

* feat(EMS-1694): account suspension - initial reactivation journey

* feat(EMS-1694-1695): account reactivation - send reactivate email

* chore(tech): improve constants documentation

* feat(EMS-1694-1695): account sign in - revert accountId type to be optional

* feat(EMS-1694-1695): update DB dump

* fix typo

* feat(EMS-1694-1695): add E2E test descriptions

* feat(EMS-1694-1695): fix/update unit test

* feat(EMS-1694-1695): update account suspensions to have insurance route

* chore(tech): fix issue with api DATE_24_HOURS_FROM_NOW constant after merge

* feat(EMS-1696-1697): account reactivation - ability to reactivate an account

* feat(EMS-1696-1697): account reactivation - E2E test coverage

* feat(EMS-1696-1697): reactivate account - link expired page

* feat(EMS-1696-1697): account reactivation - createAnAccountAndBecomeBlocked cypress command

* fix typo

* feat(EMS-1696-1697): fix/update API unit test

* feat(EMS-1696-1697): account reactivation - improve E2E test coverage

* chore(tech): add missing async/await to UI unit test

* update README

* chore(deps): bump cypress

* chore(tech): add delete account command to E2E test

* feat(EMS-1696-1697): fix/update E2E test

* feat(EMS-1696-1697): fix/update E2E test
  • Loading branch information
ttbarnes authored Jun 8, 2023
1 parent 8d86f42 commit bf889c3
Show file tree
Hide file tree
Showing 53 changed files with 1,199 additions and 62 deletions.
4 changes: 4 additions & 0 deletions e2e-tests/constants/field-ids/insurance/account/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ export const ACCOUNT = {
PASSWORD: 'password',
SECURITY_CODE: 'securityCode',
VERIFICATION_HASH: 'verificationHash',
IS_VERIFIED: 'isVerified',
IS_BLOCKED: 'isBlocked',
PASSWORD_RESET_HASH: 'passwordResetHash',
PASSWORD_RESET_EXPIRY: 'passwordResetExpiry',
REACTIVATION_HASH: 'reactivationHash',
REACTIVATION_EXPIRY: 'reactivationExpiry',
};
5 changes: 2 additions & 3 deletions e2e-tests/constants/routes/insurance/account.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ const CREATE_ROOT = '/create-account';
const SIGN_IN_ROOT = '/sign-in';
const PASSWORD_RESET_ROOT = '/password-reset';
const SUSPENDED_ROOT = `${INSURANCE_ROOT}/account-suspended`;
const REACTIVATED_ROOT = `${INSURANCE_ROOT}/account-reactivated`;

const CREATE = {
ROOT: CREATE_ROOT,
Expand Down Expand Up @@ -41,8 +42,6 @@ const SUSPENDED = {
VERIFY_EMAIL_LINK_EXPIRED: `${SUSPENDED_ROOT}/link-expired`,
};

const REACTIVATED = `${INSURANCE_ROOT}/account-reactivated`;

export const ACCOUNT = {
CREATE,
SIGN_IN,
Expand All @@ -51,5 +50,5 @@ export const ACCOUNT = {
SIGN_OUT,
SIGNED_OUT,
SUSPENDED,
REACTIVATED,
REACTIVATED_ROOT,
};
7 changes: 7 additions & 0 deletions e2e-tests/content-strings/pages/insurance/account/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,13 @@ const ACCOUNT = {
CHECK_YOUR_EMAIL: 'Check your email and follow the link to confirm your email address and reactivate your account.',
HAVING_PROBLEMS: 'Having problems?',
},
VERIFY_EMAIL_LINK_EXPIRED: {
PAGE_TITLE: 'Your link has expired',
},
},
REACTIVATED: {
PAGE_TITLE: 'Your account has been reactivated',
THANK_YOU: 'Thank you for confirming your email address. Your account has been reactivated and you can now sign in.',
},
};

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { INSURANCE_ROUTES as ROUTES } from '../../../../../../constants/routes/insurance';
import { BUTTONS, PAGES } from '../../../../../../content-strings';
import reactivatedPage from '../../../../pages/insurance/account/reactivated';
import api from '../../../../../support/api';

const CONTENT_STRINGS = PAGES.INSURANCE.ACCOUNT.REACTIVATED;

const {
ACCOUNT: {
SUSPENDED: { VERIFY_EMAIL },
REACTIVATED_ROOT,
SIGN_IN: {
ROOT: SIGN_IN_ROOT,
},
},
} = ROUTES;

const accountEmail = Cypress.env('GOV_NOTIFY_EMAIL_RECIPIENT_1');

context('Insurance - Account - Reactivated page', () => {
const baseUrl = Cypress.config('baseUrl');
const accountReactivatedUrl = `${baseUrl}${REACTIVATED_ROOT}`;

let account;

before(() => {
cy.createAnAccountAndBecomeBlocked({ startReactivationJourney: true });
});

after(() => {
cy.deleteAccount();
});

describe(`when visting ${VERIFY_EMAIL} with a valid token`, () => {
before(() => {
/**
* Get the reactivation hash directly from the API,
* so that we can navigate to the VERIFY_EMAIL URL with a valid token
*/
api.getAccountByEmail(accountEmail).then((response) => {
const { data } = response.body;

const [firstAccount] = data.accounts;
account = firstAccount;

const verifyEmailUrl = `${baseUrl}${VERIFY_EMAIL}?token=${account.reactivationHash}`;

cy.navigateToUrl(verifyEmailUrl);

cy.assertUrl(accountReactivatedUrl);
});
});

it('renders core page elements, `thank you` copy and a button link', () => {
cy.corePageChecks({
pageTitle: CONTENT_STRINGS.PAGE_TITLE,
currentHref: REACTIVATED_ROOT,
assertBackLink: false,
assertAuthenticatedHeader: false,
assertSubmitButton: false,
});

cy.checkText(
reactivatedPage.thankYou(),
CONTENT_STRINGS.THANK_YOU,
);

cy.checkLink(
reactivatedPage.continue(),
SIGN_IN_ROOT,
BUTTONS.CONTINUE,
);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,6 @@ context('Insurance - Account - Sign in - Submitting the form with invalid creden
cy.assertUrl(signInUrl);
});

// after(() => {
// cy.deleteAccount();
// });

describe('when attempting sign in multiple times and reaching the maximum retries threshold', () => {
beforeEach(() => {
cy.saveSession();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { INSURANCE_ROUTES as ROUTES } from '../../../../../../../constants/routes/insurance';
import reactivatedPage from '../../../../../pages/insurance/account/reactivated';

import api from '../../../../../../support/api';

const {
ACCOUNT: {
SUSPENDED: { VERIFY_EMAIL },
REACTIVATED_ROOT,
SIGN_IN: { ENTER_CODE },
},
DASHBOARD,
} = ROUTES;

const accountEmail = Cypress.env('GOV_NOTIFY_EMAIL_RECIPIENT_1');

context('Insurance - Account - Sign in - after account has been blocked and reactivated', () => {
const baseUrl = Cypress.config('baseUrl');
const accountReactivatedUrl = `${baseUrl}${REACTIVATED_ROOT}`;
const enterCodeUrl = `${baseUrl}${ENTER_CODE}`;
const dashboardUrl = `${baseUrl}${DASHBOARD}`;

let account;

before(() => {
cy.createAnAccountAndBecomeBlocked({ startReactivationJourney: true });
});

after(() => {
cy.deleteAccount();
});

describe(`when visting ${VERIFY_EMAIL} with a valid token`, () => {
before(() => {
/**
* Get the reactivation hash directly from the API,
* so that we can navigate to the VERIFY_EMAIL URL with a valid token
*/
api.getAccountByEmail(accountEmail).then((response) => {
const { data } = response.body;

const [firstAccount] = data.accounts;
account = firstAccount;

const verifyEmailUrl = `${baseUrl}${VERIFY_EMAIL}?token=${account.reactivationHash}`;

cy.navigateToUrl(verifyEmailUrl);

cy.assertUrl(accountReactivatedUrl);

// click the "continue" link button in the reactivated page
reactivatedPage.continue().click();

// submit the sign in form
cy.completeAndSubmitSignInAccountForm({});
});
});

describe('when submitting the sign in form and entering a valid security code', () => {
let validSecurityCode;

before(() => {
// create and get an OTP for the exporter's account
cy.accountAddAndGetOTP().then((securityCode) => {
validSecurityCode = securityCode;
});
});

it(`should redirect to ${DASHBOARD}`, () => {
cy.navigateToUrl(enterCodeUrl);

cy.completeAndSubmitEnterCodeAccountForm(validSecurityCode);

cy.assertUrl(dashboardUrl);
});
});
});
});
Original file line number Diff line number Diff line change
@@ -1,32 +1,24 @@
import { suspendedPage } from '../../../../pages/insurance/account/suspended';
import { BUTTONS, PAGES } from '../../../../../../content-strings';
import { PAGES } from '../../../../../../content-strings';
import { INSURANCE_ROUTES as ROUTES } from '../../../../../../constants/routes/insurance';
import api from '../../../../../support/api';

const CONTENT_STRINGS = PAGES.INSURANCE.ACCOUNT.SUSPENDED.ROOT;

const {
ACCOUNT: {
SIGN_IN: { ROOT: SIGN_IN_ROOT },
SUSPENDED: { ROOT: SUSPENDED_ROOT },
},
} = ROUTES;

context('Insurance - Account - Suspended page - As an Exporter, I want to reactivate my suspended digital service account, So that I can securely access my account and applications with UKEF', () => {
const baseUrl = Cypress.config('baseUrl');
const signInUrl = `${baseUrl}${SIGN_IN_ROOT}`;
const accountSuspendedUrl = `${baseUrl}${SUSPENDED_ROOT}`;

let account;

before(() => {
cy.deleteAccount();

cy.completeAndSubmitCreateAccountForm({ navigateToAccountCreationPage: true });

cy.verifyAccountEmail();

cy.assertUrl(signInUrl);
cy.createAnAccountAndBecomeBlocked({});
});

after(() => {
Expand All @@ -47,8 +39,6 @@ context('Insurance - Account - Suspended page - As an Exporter, I want to reacti
const [firstAccount] = data.accounts;
account = firstAccount;

cy.completeAndSubmitSignInAccountFormMaximumRetries({});

const expectedUrl = `${accountSuspendedUrl}?id=${account.id}`;

cy.assertUrl(expectedUrl);
Expand All @@ -62,7 +52,6 @@ context('Insurance - Account - Suspended page - As an Exporter, I want to reacti
assertBackLink: false,
assertAuthenticatedHeader: false,
assertSubmitButton: false,
submitButtonCopy: BUTTONS.REACTIVATE_ACCOUNT,
});

cy.checkText(suspendedPage.body(), CONTENT_STRINGS.BODY);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,15 @@ const {

const accountEmail = Cypress.env('GOV_NOTIFY_EMAIL_RECIPIENT_1');

context('Insurance - Account - Suspended - Email sent page - As an Exporter, I want to reactivate my suspended digital service account , So that I can securely access my account and applications with UKEF', () => {
context('Insurance - Account - Suspended - Email sent page - As an Exporter, I want to reactivate my suspended digital service account, So that I can securely access my account and applications with UKEF', () => {
const baseUrl = Cypress.config('baseUrl');
const accountSuspendedUrl = `${baseUrl}${SUSPENDED_ROOT}`;
const accountSuspendedEmailSentUrl = `${baseUrl}${EMAIL_SENT}`;

let account;

before(() => {
cy.deleteAccount();

cy.completeAndSubmitCreateAccountForm({ navigateToAccountCreationPage: true });

cy.verifyAccountEmail();
cy.createAnAccountAndBecomeBlocked({ startReactivationJourney: true });
});

after(() => {
Expand All @@ -47,12 +43,6 @@ context('Insurance - Account - Suspended - Email sent page - As an Exporter, I w

const [firstAccount] = data.accounts;
account = firstAccount;

cy.completeAndSubmitSignInAccountFormMaximumRetries({});

submitButton().click();

cy.assertUrl(accountSuspendedEmailSentUrl);
});
});

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import { INSURANCE_ROUTES as ROUTES } from '../../../../../../../constants/routes/insurance';
import { INSURANCE_FIELD_IDS } from '../../../../../../../constants/field-ids/insurance';
import { PAGES } from '../../../../../../../content-strings';
import api from '../../../../../../support/api';

const {
ACCOUNT: {
SUSPENDED: {
VERIFY_EMAIL,
VERIFY_EMAIL_LINK_EXPIRED,
},
},
} = ROUTES;

const {
ACCOUNT: { REACTIVATION_EXPIRY, REACTIVATION_HASH },
} = INSURANCE_FIELD_IDS;

const CONTENT_STRINGS = PAGES.INSURANCE.ACCOUNT.SUSPENDED.VERIFY_EMAIL_LINK_EXPIRED;

context('Insurance - Account - Suspended - Verify email - Visit with an expired token query param', () => {
const baseUrl = Cypress.config('baseUrl');
const verifyEmailUrl = `${baseUrl}${VERIFY_EMAIL}`;
const verifyEmailLinkExpiredUrl = `${baseUrl}${VERIFY_EMAIL_LINK_EXPIRED}`;

before(() => {
cy.createAnAccountAndBecomeBlocked({ startReactivationJourney: true });
});

after(() => {
cy.deleteAccount();
});

describe(`when a reactivation token has expired and the useer navigates to ${VERIFY_EMAIL} with the expired token`, () => {
let updatedAccount;

beforeEach(async () => {
/**
* Get the account so that we can use the ID
* to update the reactivation verification period.
*/
const accountEmail = Cypress.env('GOV_NOTIFY_EMAIL_RECIPIENT_1');

const accountsResponse = await api.getAccountByEmail(accountEmail);

const { data } = accountsResponse.body;

const [firstAccount] = data.accounts;
const account = firstAccount;

/**
* Update the account's reactivation expiry date via the API,
* so that we can mimic missing the verification period.
*/
const now = new Date();

const MS_PER_MINUTE = 60000;
const oneMinuteAgo = new Date(now.getTime() - 1 * MS_PER_MINUTE);

const updateObj = {
[REACTIVATION_EXPIRY]: oneMinuteAgo,
};

updatedAccount = await api.updateAccount(account.id, updateObj);
});

it(`should redirect to ${VERIFY_EMAIL_LINK_EXPIRED} and render core page elements`, () => {
cy.navigateToUrl(`${verifyEmailUrl}?token=${updatedAccount[REACTIVATION_HASH]}`);

cy.assertUrl(verifyEmailLinkExpiredUrl);

cy.corePageChecks({
pageTitle: CONTENT_STRINGS.PAGE_TITLE,
currentHref: verifyEmailUrl,
assertBackLink: false,
assertAuthenticatedHeader: false,
assertSubmitButton: false,
});
});
});
});
Loading

0 comments on commit bf889c3

Please sign in to comment.