Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(EMS-895): no PDF - CRON - Abandoned application access #2433

Merged
merged 7 commits into from
May 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/infrastructure.yml
Original file line number Diff line number Diff line change
Expand Up @@ -649,6 +649,8 @@ jobs:
JWT_SIGNING_KEY='${{ secrets.JWT_SIGNING_KEY }}' \
UNDERWRITING_TEAM_EMAIL='${{ secrets.UNDERWRITING_TEAM_EMAIL }}' \
FEEDBACK_EMAIL_RECIPIENT='${{ secrets.FEEDBACK_EMAIL_RECIPIENT }}'
CRON_SCHEDULE_UNVERIFIED_ACCOUNT='${{ secrets.CRON_SCHEDULE_UNVERIFIED_ACCOUNT }}'
CRON_SCHEDULE_INACTIVE_APPLICATION='${{ secrets.CRON_SCHEDULE_INACTIVE_APPLICATION }}'

- name: Extension ➕
uses: azure/cli@v1.0.9
Expand Down
30 changes: 30 additions & 0 deletions e2e-tests/commands/api/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,18 @@ const queryStrings = {
}
}
`,
createAnAbandonedApplication: () => gql`
mutation createAnAbandonedApplication($accountId: String!, $eligibilityAnswers: ApplicationEligibility!, $company: CompanyInput!, $sectionReview: SectionReviewInput!) {
createAnAbandonedApplication(accountId: $accountId, eligibilityAnswers: $eligibilityAnswers, company: $company, sectionReview: $sectionReview) {
referenceNumber
}
}
`,
createApplications: () => gql`
mutation createApplications($data: [ApplicationCreateInput!]!) {
createApplications(data: $data) {
id
referenceNumber
}
}
`,
Expand Down Expand Up @@ -236,6 +244,27 @@ const createAnApplication = (accountId, eligibilityAnswers, company, sectionRevi
context: APOLLO_CONTEXT,
}).then((response) => response.data.createAnApplication);

/**
* createAnApplication
* Create an application
* @param {String} Account/application owner ID
* @param {Object} Eligibility answers
* @param {Object} Company object (obtained from eligibility companies house call)
* @param {Object} sectionReview object (with eligibility set to true)
* @returns {Object} Created application
*/
const createAnAbandonedApplication = (accountId, eligibilityAnswers, company, sectionReview) =>
apollo.query({
query: queryStrings.createAnAbandonedApplication(),
variables: {
accountId,
eligibilityAnswers,
company,
sectionReview,
},
context: APOLLO_CONTEXT,
}).then((response) => response.data.createAnAbandonedApplication);

/**
* createApplications
* Create multiple applications
Expand Down Expand Up @@ -559,6 +588,7 @@ const api = {
createAnAccount,
createBuyer,
createAnApplication,
createAnAbandonedApplication,
createApplications,
getAccountByEmail,
updateAccount,
Expand Down
43 changes: 43 additions & 0 deletions e2e-tests/commands/insurance/create-an-abandoned-application.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import api from '../api';
import mockApplication from '../../fixtures/application';

const { ELIGIBILITY: mockEligibilityAnswers, COMPANY: mockCompany } = mockApplication;

/**
* createAnAbandonedApplication
* Create an abandoned application directly via the API
* 1) Create company from mock company
* 2) Create section review
* 3) Call API to create abandoned application
* @param {String} Account ID for the application owner
* @returns {Object} Created application
*/
const createAnAbandonedApplication = (accountId) => {
if (accountId) {
try {
/**
* Create initial company object from mockCompany/fixtures.
*/
const { financialYearEndDate, ...companyFields } = mockCompany;
const company = companyFields;

/**
* pass sectionReview for eligibility to API
* has to be set to true for eligibility
*/
const sectionReview = {
eligibility: true,
};

return api.createAnAbandonedApplication(accountId, mockEligibilityAnswers, company, sectionReview).then((application) => application);
} catch (err) {
console.error('Creating an abandoned application', err);

return err;
}
}

return null;
};

export default createAnAbandonedApplication;
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { APPLICATION } from '../../constants';
import dashboardPage from '../../pages/insurance/dashboard';

const { IN_PROGRESS } = APPLICATION.STATUS;

/**
* assertAllDashboardApplicationStatusesAreInProgress
* asserts that all applications on dashboard page are IN_PROGRESS
*/
const assertAllDashboardApplicationStatusesAreInProgress = () => {
dashboardPage.table.body.firstColumn().each(($el) => {
expect($el.text().trim()).to.eq(IN_PROGRESS);
});
};

export default assertAllDashboardApplicationStatusesAreInProgress;
4 changes: 4 additions & 0 deletions e2e-tests/commands/shared-commands/assertions/pagination.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,7 @@ Cypress.Commands.add('assertPaginationItemEllipsis', require('../../pagination/a
Cypress.Commands.add('assertPaginationNextLink', require('../../pagination/assert-pagination-next-link'));
Cypress.Commands.add('assertPaginationPreviousLink', require('../../pagination/assert-pagination-previous-link'));
Cypress.Commands.add('assertPaginationState', require('../../pagination/assert-pagination-state'));
Cypress.Commands.add(
'assertAllDashboardApplicationStatusesAreInProgress',
require('../../pagination/assert-all-dashboard-application-statuses-are-in-progress'),
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { INSURANCE_ROUTES } from '../../../../../constants/routes/insurance';
import { APPLICATION } from '../../../../../constants/application';
import dashboardPage from '../../../../../pages/insurance/dashboard';

const { IN_PROGRESS, ABANDONED } = APPLICATION.STATUS;

const { DASHBOARD } = INSURANCE_ROUTES;

const baseUrl = Cypress.config('baseUrl');

const totalExpectedApplications = 1;

const dashboardUrl = `${baseUrl}${DASHBOARD}`;

const { table } = dashboardPage;

context(`Insurance - Dashboard - pagination - 1 ${IN_PROGRESS} application and 1 ${ABANDONED} application`, () => {
let applications;
let abandonedApplication;

before(() => {
cy.completeSignInAndGoToDashboard().then(({ accountId }) => {
cy.createApplications(accountId, totalExpectedApplications).then((createdApplications) => {
applications = createdApplications;
});

cy.createAnAbandonedApplication(accountId).then((createdApplication) => {
abandonedApplication = createdApplication;
});

cy.navigateToUrl(dashboardUrl);
});
});

beforeEach(() => {
cy.saveSession();
});

after(() => {
cy.deleteApplications(applications);
cy.deleteApplication(abandonedApplication.referenceNumber);
});

it(`should render 1 ${IN_PROGRESS} application on the dashboard`, () => {
cy.assertLength(table.body.rows(), totalExpectedApplications);
cy.checkText(dashboardPage.table.body.row(applications[0].referenceNumber).status(), IN_PROGRESS);
Zainzzkk marked this conversation as resolved.
Show resolved Hide resolved
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import pagination from '../../../../../../partials/pagination';
import dashboardPage from '../../../../../../pages/insurance/dashboard';
import { MAX_APPLICATIONS_PER_PAGE, APPLICATION } from '../../../../../../constants';
import { INSURANCE_ROUTES } from '../../../../../../constants/routes/insurance';

const { DASHBOARD } = INSURANCE_ROUTES;

const baseUrl = Cypress.config('baseUrl');

const totalApplications = MAX_APPLICATIONS_PER_PAGE + 1;
const totalPages = 2;

const dashboardUrl = `${baseUrl}${DASHBOARD}`;

const { table } = dashboardPage;

const { ABANDONED } = APPLICATION.STATUS;

context(`Insurance - Dashboard - pagination - ${totalApplications} applications and 1 ${ABANDONED} application`, () => {
let applications;
let abandonedApplication;

before(() => {
cy.completeSignInAndGoToDashboard().then(({ accountId }) => {
cy.createApplications(accountId, totalApplications).then((createdApplications) => {
applications = createdApplications;
});

cy.createAnAbandonedApplication(accountId).then((createdApplication) => {
abandonedApplication = createdApplication;
});

cy.navigateToUrl(dashboardUrl);
});
});

beforeEach(() => {
cy.saveSession();
});

after(() => {
cy.deleteApplications(applications);
cy.deleteApplication(abandonedApplication.referenceNumber);
});

describe('page tests', () => {
beforeEach(() => {
cy.navigateToUrl(dashboardUrl);
});

it('should render 2 pagination list items with links', () => {
cy.assertLength(pagination.listItems(), totalPages);

cy.assertPaginationItemLink({ index: 0 });
cy.assertPaginationItemLink({ index: 1 });
});

it('should have the correct pagination state', () => {
cy.assertPaginationState({
totalPages,
index: 0,
expectedPageNumber: 1,
previousLinkShouldExist: false,
expectedUrl: `${baseUrl}${DASHBOARD}`,
});
});

it(`should have no ${ABANDONED} applications`, () => {
cy.assertAllDashboardApplicationStatusesAreInProgress();
});
});
Zainzzkk marked this conversation as resolved.
Show resolved Hide resolved

describe('when clicking on the `next` pagination link', () => {
beforeEach(() => {
cy.navigateToUrl(dashboardUrl);

pagination.nextLink().click();
});

it('should have the correct pagination state', () => {
cy.assertPaginationState({
totalPages,
index: 2,
expectedPageNumber: 2,
nextLinkShouldExist: false,
});
});

it(`should have 1 application on the dashboard (and not the ${ABANDONED} application)`, () => {
cy.assertLength(table.body.rows(), 1);
cy.assertAllDashboardApplicationStatusesAreInProgress();
});
ttbarnes marked this conversation as resolved.
Show resolved Hide resolved
});

describe('when clicking on page 2 pagination link', () => {
it('should have the correct pagination state', () => {
cy.navigateToUrl(dashboardUrl);

pagination.listItemLink(1).click();

cy.assertPaginationState({
totalPages,
index: 2,
expectedPageNumber: 2,
nextLinkShouldExist: false,
});
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { INSURANCE_ROUTES } from '../../../../../constants/routes/insurance';
import { APPLICATION } from '../../../../../constants/application';

const { ABANDONED } = APPLICATION.STATUS;

const {
ROOT,
ALL_SECTIONS,
NO_ACCESS_TO_APPLICATION,
} = INSURANCE_ROUTES;

const baseUrl = Cypress.config('baseUrl');

context('Insurance - no access to application page - Abandoned application - to ensure that the system should automatically marks applications as abandoned where the application has not been submitted 30 days after it was started', () => {
let refNumber;
let allSectionsUrl;

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

cy.completeSignInAndGoToDashboard().then(({ accountId }) => {
cy.createAnAbandonedApplication(accountId).then((createdApplication) => {
allSectionsUrl = `${baseUrl}${ROOT}/${createdApplication.referenceNumber}${ALL_SECTIONS}`;
refNumber = createdApplication.referenceNumber;
});
});
});

after(() => {
cy.deleteApplication(refNumber);
});

describe(`when trying to access an ${ABANDONED} application`, () => {
beforeEach(() => {
cy.navigateToUrl(allSectionsUrl);
});

it(`should redirect to ${NO_ACCESS_TO_APPLICATION}`, () => {
const expectedUrl = `${baseUrl}${NO_ACCESS_TO_APPLICATION}`;

cy.assertUrl(expectedUrl);
});
});
});
1 change: 1 addition & 0 deletions e2e-tests/insurance/cypress/support/application/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import './policy';

Cypress.Commands.add('createAnApplication', require('../../../../commands/insurance/create-an-application'));
Cypress.Commands.add('createApplications', require('../../../../commands/insurance/create-applications'));
Cypress.Commands.add('createAnAbandonedApplication', require('../../../../commands/insurance/create-an-abandoned-application'));

Cypress.Commands.add('deleteApplication', require('../../../../commands/insurance/delete-application'));
Cypress.Commands.add('deleteApplications', require('../../../../commands/insurance/delete-applications'));
Expand Down
1 change: 1 addition & 0 deletions e2e-tests/pages/insurance/dashboard/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const dashboardPage = {
},
body: {
rows: () => cy.get('table tbody tr'),
firstColumn: () => cy.get('table tbody tr td:first'),
row: (referenceNumber) => ({
status: () => cy.get(`[data-cy="ref-${referenceNumber}-status"]`),
buyerLocation: () => cy.get(`[data-cy="ref-${referenceNumber}-buyerLocation"]`),
Expand Down
Loading
Loading