diff --git a/e2e-tests/constants/field-ids.js b/e2e-tests/constants/field-ids.js index 7ced5cf44c..ae01f6b05f 100644 --- a/e2e-tests/constants/field-ids.js +++ b/e2e-tests/constants/field-ids.js @@ -1,4 +1,5 @@ const FIELD_IDS = { + VALID_BUYER_BODY: 'validBuyerBody', VALID_COMPANY_BASE: 'validCompanyBase', BUYER_COUNTRY: 'buyerCountry', COUNTRY: 'country', diff --git a/e2e-tests/constants/routes/quote.js b/e2e-tests/constants/routes/quote.js index 31ad613482..096a1b144e 100644 --- a/e2e-tests/constants/routes/quote.js +++ b/e2e-tests/constants/routes/quote.js @@ -1,4 +1,6 @@ const QUOTE_ROUTES = { + BUYER_BODY: '/quote/type-of-buyer', + BUYER_COUNTRY: '/quote/buyer-country', BUYER_COUNTRY_CHANGE: '/quote/buyer-country/change', diff --git a/e2e-tests/constants/templates/quote.js b/e2e-tests/constants/templates/quote.js index b9a86c1a75..6e27d82b94 100644 --- a/e2e-tests/constants/templates/quote.js +++ b/e2e-tests/constants/templates/quote.js @@ -1,6 +1,7 @@ const QUOTE_TEMPLATES = { - COMPANY_BASED: 'quote/company-based.njk', + BUYER_BODY: 'quote/buyer-body.njk', BUYER_COUNTRY: 'quote/buyer-country.njk', + COMPANY_BASED: 'quote/company-based.njk', HAS_MINIMUM_UK_GOODS_OR_SERVICES: 'quote/uk-goods-or-services.njk', POLICY_TYPE: 'quote/policy-type.njk', TELL_US_ABOUT_YOUR_POLICY: 'quote/tell-us-about-your-policy.njk', diff --git a/e2e-tests/content-strings/error-messages.js b/e2e-tests/content-strings/error-messages.js index 7ff602fbc9..2d13234ef5 100644 --- a/e2e-tests/content-strings/error-messages.js +++ b/e2e-tests/content-strings/error-messages.js @@ -1,9 +1,10 @@ const FIELD_IDS = require('../constants/field-ids'); const ERROR_MESSAGES = { - [FIELD_IDS.VALID_COMPANY_BASE]: 'Select if your company is based in the UK, Channel Islands, Isle of Man or not', [FIELD_IDS.BUYER_COUNTRY]: 'Select where your buyer is based', [FIELD_IDS.COUNTRY]: 'Select where your buyer is based', + [FIELD_IDS.VALID_BUYER_BODY]: 'Select if your buyer is a government or public sector body', + [FIELD_IDS.VALID_COMPANY_BASE]: 'Select if your company is based in the UK, Channel Islands, Isle of Man or not', [FIELD_IDS.HAS_MINIMUM_UK_GOODS_OR_SERVICES]: { IS_EMPTY: 'Select whether at least 20% of your export contract value is made up from UK goods and services', }, diff --git a/e2e-tests/content-strings/pages.js b/e2e-tests/content-strings/pages.js index dd55e925e5..997a2006c8 100644 --- a/e2e-tests/content-strings/pages.js +++ b/e2e-tests/content-strings/pages.js @@ -1,15 +1,25 @@ const LINKS = require('./links'); -const COMPANY_BASED_PAGE = { - PAGE_TITLE: 'Is your company based inside the UK, Channel Islands or Isle of Man?', - HEADING: 'Is your company based inside the UK, Channel Islands or Isle of Man?', -}; - const BUYER_COUNTRY_PAGE = { PAGE_TITLE: 'Where is your buyer based?', HEADING: 'Where is your buyer based?', }; +const BUYER_BODY_PAGE = { + PAGE_TITLE: 'Is your buyer a government or public sector body?', + HEADING: 'Is your buyer a government or public sector body?', + DETAILS: { + INTRO: 'What counts as a government or public sector body?', + BODY_1: 'This means a formally established organisation that is, at least in part, publicly funded to deliver a public or government service.', + BODY_2: 'For example, a central government department, a local authority or a public utlity company.', + }, +}; + +const COMPANY_BASED_PAGE = { + PAGE_TITLE: 'Is your company based inside the UK, Channel Islands or Isle of Man?', + HEADING: 'Is your company based inside the UK, Channel Islands or Isle of Man?', +}; + const HAS_MINIMUM_UK_GOODS_OR_SERVICES_PAGE = { PAGE_TITLE: 'Is at least 20% of your export contract value made up from UK goods or services?', HEADING: 'Is at least 20% of your export contract value made up from UK goods or services?', @@ -124,8 +134,10 @@ const GET_A_QUOTE_BY_EMAIL_PAGE = { PAGE_TITLE: 'You need to get a quote by email', HEADING: 'You need to get a quote by email', REASON: { - BODY_1: 'We cannot give you a quote online because of the country where your buyer is based.', - BODY_2: "We can still give you a quote but may need extra information from you to assess the risks around your buyer's country first.", + BUYER_BODY: 'We cannot give you a quote online because your buyer is a government or public sector body.', + BUYER_BODY_DESCRIPTION: "We can still give you a quote but may need extra information from you to assess the risks around your buyer first.", + BUYER_COUNTRY: 'We cannot give you a quote online because of the country where your buyer is based.', + BUYER_COUNTRY_DESCRIPTION: "We can still give you a quote but may need extra information from you to assess the risks around your buyer's country first.", }, ACTION: [ [ @@ -269,8 +281,9 @@ const PROBLEM_WITH_SERVICE_PAGE = { }; module.exports = { - COMPANY_BASED_PAGE, BUYER_COUNTRY_PAGE, + BUYER_BODY_PAGE, + COMPANY_BASED_PAGE, HAS_MINIMUM_UK_GOODS_OR_SERVICES_PAGE, POLICY_TYPE_PAGE, TELL_US_ABOUT_YOUR_POLICY_PAGE, diff --git a/e2e-tests/cypress/e2e/journeys/quote/buyer-body/buyer-body-answer-yes.spec.js b/e2e-tests/cypress/e2e/journeys/quote/buyer-body/buyer-body-answer-yes.spec.js new file mode 100644 index 0000000000..115c1c7ac9 --- /dev/null +++ b/e2e-tests/cypress/e2e/journeys/quote/buyer-body/buyer-body-answer-yes.spec.js @@ -0,0 +1,61 @@ +import { + buyerBodyPage, + getAQuoteByEmailPage, +} from '../../../pages/quote'; +import partials from '../../../partials'; +import { PAGES } from '../../../../../content-strings'; +import CONSTANTS from '../../../../../constants'; +import { completeAndSubmitBuyerCountryForm } from '../../../../support/quote/forms'; + +const CONTENT_STRINGS = PAGES.BUYER_BODY_PAGE; +const { ROUTES, FIELD_IDS } = CONSTANTS; + +context('Buyer body page - as an exporter, I want to check if I can get an EXIP online quote for my buyers country - submit `buyer is a government or public sector body`', () => { + before(() => { + cy.login(); + completeAndSubmitBuyerCountryForm(); + + cy.url().should('include', ROUTES.QUOTE.BUYER_BODY); + + buyerBodyPage[FIELD_IDS.VALID_BUYER_BODY].yes().click(); + buyerBodyPage.submitButton().click(); + }); + + beforeEach(() => { + Cypress.Cookies.preserveOnce('_csrf'); + Cypress.Cookies.preserveOnce('connect.sid'); + }); + + it('redirects to exit page', () => { + cy.url().should('include', ROUTES.QUOTE.GET_A_QUOTE_BY_EMAIL); + }); + + it('renders a back link with correct url', () => { + partials.backLink().should('exist'); + + partials.backLink().should('have.attr', 'href', ROUTES.QUOTE.BUYER_BODY); + }); + + it('renders a specific reason and description', () => { + getAQuoteByEmailPage.reason().invoke('text').then((text) => { + const expected = PAGES.GET_A_QUOTE_BY_EMAIL_PAGE.REASON.BUYER_BODY; + + expect(text.trim()).equal(expected); + }); + + getAQuoteByEmailPage.description().invoke('text').then((text) => { + const expected = PAGES.GET_A_QUOTE_BY_EMAIL_PAGE.REASON.BUYER_BODY_DESCRIPTION; + + expect(text.trim()).equal(expected); + }); + }); + + describe('navigating back to the buyer body page', () => { + it('auto checks the previously submitted answer', () => { + partials.backLink().click(); + + const yesRadio = buyerBodyPage[FIELD_IDS.VALID_BUYER_BODY].yesInput(); + yesRadio.should('be.checked'); + }); + }); +}); diff --git a/e2e-tests/cypress/e2e/journeys/quote/buyer-body/buyer-body.spec.js b/e2e-tests/cypress/e2e/journeys/quote/buyer-body/buyer-body.spec.js new file mode 100644 index 0000000000..54df7309fc --- /dev/null +++ b/e2e-tests/cypress/e2e/journeys/quote/buyer-body/buyer-body.spec.js @@ -0,0 +1,118 @@ +import { buyerBodyPage } from '../../../pages/quote'; +import partials from '../../../partials'; +import { + BUTTONS, + ERROR_MESSAGES, + FIELDS, + LINKS, + ORGANISATION, + PAGES, +} from '../../../../../content-strings'; +import CONSTANTS from '../../../../../constants'; +import { completeAndSubmitBuyerCountryForm } from '../../../../support/quote/forms'; + +const CONTENT_STRINGS = PAGES.BUYER_BODY_PAGE; +const { ROUTES, FIELD_IDS } = CONSTANTS; + +context('Buyer body page - as an exporter, I want to check if I can get an EXIP online quote for my buyers country', () => { + beforeEach(() => { + cy.login(); + completeAndSubmitBuyerCountryForm(); + + cy.url().should('include', ROUTES.QUOTE.BUYER_BODY); + }); + + it('passes the audits', () => { + cy.lighthouse({ + accessibility: 100, + performance: 80, + 'best-practices': 100, + seo: 60, + }); + }); + + it('renders a phase banner', () => { + cy.checkPhaseBanner(); + }); + + it('renders a back link with correct url', () => { + partials.backLink().should('exist'); + partials.backLink().invoke('text').then((text) => { + expect(text.trim()).equal(LINKS.BACK); + }); + + const expected = `${Cypress.config('baseUrl')}${ROUTES.QUOTE.BUYER_COUNTRY}`; + partials.backLink().should('have.attr', 'href', expected); + }); + + it('renders a page title and heading', () => { + const expectedPageTitle = `${CONTENT_STRINGS.PAGE_TITLE} - ${ORGANISATION}`; + cy.title().should('eq', expectedPageTitle); + + buyerBodyPage.heading().invoke('text').then((text) => { + expect(text.trim()).equal(CONTENT_STRINGS.HEADING); + }); + }); + + it('renders yes and no radio buttons', () => { + const yesRadio = buyerBodyPage[FIELD_IDS.VALID_BUYER_BODY].yes(); + yesRadio.should('exist'); + + yesRadio.invoke('text').then((text) => { + expect(text.trim()).equal('Yes'); + }); + + const noRadio = buyerBodyPage[FIELD_IDS.VALID_BUYER_BODY].no(); + noRadio.should('exist'); + + noRadio.invoke('text').then((text) => { + expect(text.trim()).equal('No'); + }); + }); + + it('renders a submit button', () => { + const button = buyerBodyPage.submitButton(); + button.should('exist'); + + button.invoke('text').then((text) => { + expect(text.trim()).equal(BUTTONS.CONTINUE); + }); + }); + + describe('form submission', () => { + describe('when submitting an empty form', () => { + it('should render validation errors', () => { + buyerBodyPage.submitButton().click(); + + partials.errorSummaryListItems().should('exist'); + partials.errorSummaryListItems().should('have.length', 1); + + const expectedMessage = ERROR_MESSAGES[FIELD_IDS.VALID_BUYER_BODY]; + + partials.errorSummaryListItems().first().invoke('text').then((text) => { + expect(text.trim()).equal(expectedMessage); + }); + + buyerBodyPage[FIELD_IDS.VALID_BUYER_BODY].errorMessage().invoke('text').then((text) => { + expect(text.trim()).includes(expectedMessage); + }); + }); + + it('should focus on input when clicking summary error message', () => { + buyerBodyPage.submitButton().click(); + + partials.errorSummaryListItemLinks().eq(0).click(); + buyerBodyPage[FIELD_IDS.VALID_BUYER_BODY].yesInput().should('have.focus'); + }); + }); + + describe('when submitting the answer as `no`', () => { + it(`should redirect to ${ROUTES.QUOTE.COMPANY_BASED}`, () => { + buyerBodyPage[FIELD_IDS.VALID_BUYER_BODY].no().click(); + buyerBodyPage.submitButton().click(); + + cy.url().should('include', ROUTES.QUOTE.COMPANY_BASED); + }); + }); + }); +}); diff --git a/e2e-tests/cypress/e2e/journeys/quote/buyer-country/buyer-country-get-quote-by-email.spec.js b/e2e-tests/cypress/e2e/journeys/quote/buyer-country/buyer-country-country-only-get-a-quote-by-email.spec.js similarity index 88% rename from e2e-tests/cypress/e2e/journeys/quote/buyer-country/buyer-country-get-quote-by-email.spec.js rename to e2e-tests/cypress/e2e/journeys/quote/buyer-country/buyer-country-country-only-get-a-quote-by-email.spec.js index ff7bf1ecf0..fefd38583f 100644 --- a/e2e-tests/cypress/e2e/journeys/quote/buyer-country/buyer-country-get-quote-by-email.spec.js +++ b/e2e-tests/cypress/e2e/journeys/quote/buyer-country/buyer-country-country-only-get-a-quote-by-email.spec.js @@ -1,7 +1,4 @@ -import { - buyerCountryPage, - cannotObtainCoverPage, -} from '../../../pages/quote'; +import { buyerCountryPage } from '../../../pages/quote'; import partials from '../../../partials'; import { PAGES } from '../../../../../content-strings'; import CONSTANTS from '../../../../../constants'; @@ -36,7 +33,7 @@ context('Buyer country page - as an exporter, I want to check if UKEF issue expo it('renders a back link with correct url', () => { partials.backLink().should('exist'); - const expected = `${Cypress.config('baseUrl')}${ROUTES.QUOTE.BUYER_COUNTRY}`; + const expected = ROUTES.QUOTE.BUYER_COUNTRY; partials.backLink().should('have.attr', 'href', expected); }); diff --git a/e2e-tests/cypress/e2e/journeys/quote/buyer-country/buyer-country.spec.js b/e2e-tests/cypress/e2e/journeys/quote/buyer-country/buyer-country.spec.js index da140eb366..22cd8775cb 100644 --- a/e2e-tests/cypress/e2e/journeys/quote/buyer-country/buyer-country.spec.js +++ b/e2e-tests/cypress/e2e/journeys/quote/buyer-country/buyer-country.spec.js @@ -183,7 +183,7 @@ context('Buyer country page - as an exporter, I want to check if UKEF issue expo }); describe('when submitting with a supported country', () => { - it(`should redirect to ${ROUTES.QUOTE.COMPANY_BASED}`, () => { + it(`should redirect to ${ROUTES.QUOTE.BUYER_BODY}`, () => { buyerCountryPage.searchInput().type('Algeria'); const results = buyerCountryPage.results(); @@ -191,7 +191,7 @@ context('Buyer country page - as an exporter, I want to check if UKEF issue expo buyerCountryPage.submitButton().click(); - cy.url().should('include', ROUTES.QUOTE.COMPANY_BASED); + cy.url().should('include', ROUTES.QUOTE.BUYER_BODY); }); }); }); diff --git a/e2e-tests/cypress/e2e/journeys/quote/cannot-obtain-cover-page.spec.js b/e2e-tests/cypress/e2e/journeys/quote/cannot-obtain-cover-page.spec.js index eb1324817d..db8b9de4d3 100644 --- a/e2e-tests/cypress/e2e/journeys/quote/cannot-obtain-cover-page.spec.js +++ b/e2e-tests/cypress/e2e/journeys/quote/cannot-obtain-cover-page.spec.js @@ -6,7 +6,7 @@ import { PAGES, } from '../../../../content-strings'; import CONSTANTS from '../../../../constants'; -import { completeAndSubmitBuyerForm, completeAndSubmitCompanyForm } from '../../../support/quote/forms'; +import { completeAndSubmitBuyerCountryForm, completeAndSubmitBuyerBodyForm, completeAndSubmitCompanyForm } from '../../../support/quote/forms'; const CONTENT_STRINGS = PAGES.CANNOT_OBTAIN_COVER_PAGE; const { FIELD_IDS, ROUTES } = CONSTANTS; @@ -14,7 +14,8 @@ const { FIELD_IDS, ROUTES } = CONSTANTS; context('Cannot obtain UKEF cover exit page', () => { beforeEach(() => { cy.login(); - completeAndSubmitBuyerForm(); + completeAndSubmitBuyerCountryForm(); + completeAndSubmitBuyerBodyForm(); completeAndSubmitCompanyForm(); cy.url().should('include', ROUTES.QUOTE.HAS_MINIMUM_UK_GOODS_OR_SERVICES); diff --git a/e2e-tests/cypress/e2e/journeys/quote/cannot-skip-flow/navigate-to-buyer-body-page-directly.spec.js b/e2e-tests/cypress/e2e/journeys/quote/cannot-skip-flow/navigate-to-buyer-body-page-directly.spec.js new file mode 100644 index 0000000000..be2f924504 --- /dev/null +++ b/e2e-tests/cypress/e2e/journeys/quote/cannot-skip-flow/navigate-to-buyer-body-page-directly.spec.js @@ -0,0 +1,17 @@ +import CONSTANTS from '../../../../../constants'; +const { ROUTES } = CONSTANTS; + +context('Manually going to the `Buyer body` via URL page without completing the previous forms', () => { + beforeEach(() => { + cy.visit(ROUTES.QUOTE.BUYER_BODY, { + auth: { + username: Cypress.config('basicAuthKey'), + password: Cypress.config('basicAuthSecret'), + }, + }); + }); + + it('should redirect to the `need to start again` exit page', () => { + cy.url().should('include', ROUTES.QUOTE.NEED_TO_START_AGAIN); + }); +}); diff --git a/e2e-tests/cypress/e2e/journeys/quote/change-your-answers/change-policy-type-multiple-times-via-back-button.spec.js b/e2e-tests/cypress/e2e/journeys/quote/change-your-answers/change-policy-type-multiple-times-via-back-button.spec.js index 39930a38c4..8c3fa7d983 100644 --- a/e2e-tests/cypress/e2e/journeys/quote/change-your-answers/change-policy-type-multiple-times-via-back-button.spec.js +++ b/e2e-tests/cypress/e2e/journeys/quote/change-your-answers/change-policy-type-multiple-times-via-back-button.spec.js @@ -5,7 +5,8 @@ import { import partials from '../../../partials'; import CONSTANTS from '../../../../../constants'; import { - completeAndSubmitBuyerForm, + completeAndSubmitBuyerCountryForm, + completeAndSubmitBuyerBodyForm, completeAndSubmitCompanyForm, completeAndSubmitUkContentForm, completeAndSubmitPolicyTypeSingleForm, @@ -27,10 +28,12 @@ context('Change your answers (policy type) - multiple times via back button - as before(() => { cy.login(); - completeAndSubmitBuyerForm(); + completeAndSubmitBuyerCountryForm(); + completeAndSubmitBuyerBodyForm(); completeAndSubmitCompanyForm(); completeAndSubmitUkContentForm(); completeAndSubmitPolicyTypeSingleForm(); + cy.url().should('include', ROUTES.QUOTE.TELL_US_ABOUT_YOUR_POLICY); }); diff --git a/e2e-tests/cypress/e2e/journeys/quote/company-based/company-based-answer-no.spec.js b/e2e-tests/cypress/e2e/journeys/quote/company-based/company-based-answer-no.spec.js index 413dc24815..571bc8fb66 100644 --- a/e2e-tests/cypress/e2e/journeys/quote/company-based/company-based-answer-no.spec.js +++ b/e2e-tests/cypress/e2e/journeys/quote/company-based/company-based-answer-no.spec.js @@ -5,7 +5,7 @@ import { import partials from '../../../partials'; import { PAGES } from '../../../../../content-strings'; import CONSTANTS from '../../../../../constants'; -import { completeAndSubmitBuyerForm } from '../../../../support/quote/forms'; +import { completeAndSubmitBuyerCountryForm, completeAndSubmitBuyerBodyForm } from '../../../../support/quote/forms'; const CONTENT_STRINGS = PAGES.CANNOT_OBTAIN_COVER_PAGE; const { ROUTES, FIELD_IDS } = CONSTANTS; @@ -13,7 +13,8 @@ const { ROUTES, FIELD_IDS } = CONSTANTS; context('Company based page - as an exporter, I want to check if my company can get UKEF issue export insurance cover - submit `not based inside the UK`', () => { before(() => { cy.login(); - completeAndSubmitBuyerForm(); + completeAndSubmitBuyerCountryForm(); + completeAndSubmitBuyerBodyForm(); cy.url().should('include', ROUTES.QUOTE.COMPANY_BASED); diff --git a/e2e-tests/cypress/e2e/journeys/quote/company-based/company-based.spec.js b/e2e-tests/cypress/e2e/journeys/quote/company-based/company-based.spec.js index 3f257e3b3d..568d21e407 100644 --- a/e2e-tests/cypress/e2e/journeys/quote/company-based/company-based.spec.js +++ b/e2e-tests/cypress/e2e/journeys/quote/company-based/company-based.spec.js @@ -11,7 +11,7 @@ import { ERROR_MESSAGES, } from '../../../../../content-strings'; import CONSTANTS from '../../../../../constants'; -import { completeAndSubmitBuyerForm } from '../../../../support/quote/forms'; +import { completeAndSubmitBuyerCountryForm, completeAndSubmitBuyerBodyForm } from '../../../../support/quote/forms'; const CONTENT_STRINGS = PAGES.COMPANY_BASED_PAGE; const { ROUTES, FIELD_IDS } = CONSTANTS; @@ -19,7 +19,8 @@ const { ROUTES, FIELD_IDS } = CONSTANTS; context('Company based page - as an exporter, I want to check if my company can get UKEF issue export insurance cover', () => { beforeEach(() => { cy.login(); - completeAndSubmitBuyerForm(); + completeAndSubmitBuyerCountryForm(); + completeAndSubmitBuyerBodyForm(); cy.url().should('include', ROUTES.QUOTE.COMPANY_BASED); }); @@ -45,7 +46,7 @@ context('Company based page - as an exporter, I want to check if my company can partials.backLink().click(); - cy.url().should('include', ROUTES.QUOTE.BUYER_COUNTRY); + cy.url().should('include', ROUTES.QUOTE.BUYER_BODY); }); it('renders a page title and heading', () => { diff --git a/e2e-tests/cypress/e2e/journeys/quote/get-a-quote-via-email.spec.js b/e2e-tests/cypress/e2e/journeys/quote/get-a-quote-via-email.spec.js index bcb7106974..8325b1e2f9 100644 --- a/e2e-tests/cypress/e2e/journeys/quote/get-a-quote-via-email.spec.js +++ b/e2e-tests/cypress/e2e/journeys/quote/get-a-quote-via-email.spec.js @@ -6,7 +6,7 @@ import { PAGES, } from '../../../../content-strings'; import CONSTANTS from '../../../../constants'; -import { completeAndSubmitBuyerForm, completeAndSubmitCompanyForm } from '../../../support/quote/forms'; +import { completeAndSubmitBuyerCountryForm, completeAndSubmitCompanyForm } from '../../../support/quote/forms'; const CONTENT_STRINGS = PAGES.GET_A_QUOTE_BY_EMAIL_PAGE; const { FIELD_IDS, ROUTES } = CONSTANTS; @@ -58,13 +58,13 @@ context('Get a quote via email exit page', () => { }); }); - it('renders a reason/body content ', () => { - getAQuoteByEmailPage.body1().invoke('text').then((text) => { - expect(text.trim()).equal(CONTENT_STRINGS.REASON.BODY_1); + it('renders a reason and description ', () => { + getAQuoteByEmailPage.reason().invoke('text').then((text) => { + expect(text.trim()).equal(CONTENT_STRINGS.REASON.BUYER_COUNTRY); }); - getAQuoteByEmailPage.body2().invoke('text').then((text) => { - expect(text.trim()).equal(CONTENT_STRINGS.REASON.BODY_2); + getAQuoteByEmailPage.description().invoke('text').then((text) => { + expect(text.trim()).equal(CONTENT_STRINGS.REASON.BUYER_COUNTRY_DESCRIPTION); }); }); diff --git a/e2e-tests/cypress/e2e/journeys/quote/need-to-start-again.spec.js b/e2e-tests/cypress/e2e/journeys/quote/need-to-start-again.spec.js index 6cbaf5bbc7..ef09b053de 100644 --- a/e2e-tests/cypress/e2e/journeys/quote/need-to-start-again.spec.js +++ b/e2e-tests/cypress/e2e/journeys/quote/need-to-start-again.spec.js @@ -7,27 +7,19 @@ import { PAGES, } from '../../../../content-strings'; import CONSTANTS from '../../../../constants'; +import { + completeAndSubmitBuyerCountryForm, + completeAndSubmitBuyerBodyForm, +} from '../../../support/quote/forms'; const CONTENT_STRINGS = PAGES.NEED_TO_START_AGAIN; const { FIELD_IDS, ROUTES } = CONSTANTS; context('Need to start again exit page', () => { beforeEach(() => { - cy.visit(ROUTES.QUOTE.BUYER_COUNTRY, { - auth: { - username: Cypress.config('basicAuthKey'), - password: Cypress.config('basicAuthSecret'), - }, - }); - - buyerCountryPage.searchInput().type('Algeria'); - - const results = buyerCountryPage.results(); - results.first().click(); - - buyerCountryPage.submitButton().click(); - - cy.url().should('include', ROUTES.QUOTE.COMPANY_BASED); + cy.login(); + completeAndSubmitBuyerCountryForm(); + completeAndSubmitBuyerBodyForm(); cy.visit(ROUTES.QUOTE.TELL_US_ABOUT_YOUR_POLICY, { auth: { diff --git a/e2e-tests/cypress/e2e/journeys/quote/policy-type/policy-type-validation.spec.js b/e2e-tests/cypress/e2e/journeys/quote/policy-type/policy-type-validation.spec.js index da51bef888..a9811a11b5 100644 --- a/e2e-tests/cypress/e2e/journeys/quote/policy-type/policy-type-validation.spec.js +++ b/e2e-tests/cypress/e2e/journeys/quote/policy-type/policy-type-validation.spec.js @@ -3,14 +3,15 @@ import partials from '../../../partials'; import { ERROR_MESSAGES } from '../../../../../content-strings'; import CONSTANTS from '../../../../../constants'; import checkText from '../../../helpers/check-text'; -import { completeAndSubmitBuyerForm, completeAndSubmitCompanyForm, completeAndSubmitUkContentForm } from '../../../../support/quote/forms'; +import { completeAndSubmitBuyerCountryForm, completeAndSubmitBuyerBodyForm, completeAndSubmitCompanyForm, completeAndSubmitUkContentForm } from '../../../../support/quote/forms'; const { ROUTES, FIELD_IDS } = CONSTANTS; context('Policy type page - policy type & length validation', () => { before(() => { cy.login(); - completeAndSubmitBuyerForm(); + completeAndSubmitBuyerCountryForm(); + completeAndSubmitBuyerBodyForm(); completeAndSubmitCompanyForm(); completeAndSubmitUkContentForm(); diff --git a/e2e-tests/cypress/e2e/journeys/quote/policy-type/policy-type.spec.js b/e2e-tests/cypress/e2e/journeys/quote/policy-type/policy-type.spec.js index 40193f9994..8cff53880f 100644 --- a/e2e-tests/cypress/e2e/journeys/quote/policy-type/policy-type.spec.js +++ b/e2e-tests/cypress/e2e/journeys/quote/policy-type/policy-type.spec.js @@ -1,5 +1,6 @@ import { - completeAndSubmitBuyerForm, + completeAndSubmitBuyerBodyForm, + completeAndSubmitBuyerCountryForm, completeAndSubmitCompanyForm, completeAndSubmitUkContentForm, } from '../../../../support/quote/forms'; @@ -25,7 +26,8 @@ context('Policy type page - as an exporter, I want to get UKEF export insurance before(() => { cy.login(); - completeAndSubmitBuyerForm(); + completeAndSubmitBuyerCountryForm(); + completeAndSubmitBuyerBodyForm(); completeAndSubmitCompanyForm(); completeAndSubmitUkContentForm(); diff --git a/e2e-tests/cypress/e2e/journeys/quote/tell-us-about-your-policy/tell-us-about-your-multi-policy-validation.spec.js b/e2e-tests/cypress/e2e/journeys/quote/tell-us-about-your-policy/tell-us-about-your-multi-policy-validation.spec.js index 3062f3037d..db0bc426c1 100644 --- a/e2e-tests/cypress/e2e/journeys/quote/tell-us-about-your-policy/tell-us-about-your-multi-policy-validation.spec.js +++ b/e2e-tests/cypress/e2e/journeys/quote/tell-us-about-your-policy/tell-us-about-your-multi-policy-validation.spec.js @@ -1,5 +1,6 @@ import { - completeAndSubmitBuyerForm, + completeAndSubmitBuyerCountryForm, + completeAndSubmitBuyerBodyForm, completeAndSubmitCompanyForm, completeAndSubmitUkContentForm, completeAndSubmitPolicyTypeMultiForm, @@ -22,7 +23,8 @@ context('Tell us about the multi policy you need - form validation', () => { before(() => { cy.login(); - completeAndSubmitBuyerForm(); + completeAndSubmitBuyerCountryForm(); + completeAndSubmitBuyerBodyForm(); completeAndSubmitCompanyForm(); completeAndSubmitUkContentForm(); completeAndSubmitPolicyTypeMultiForm(); diff --git a/e2e-tests/cypress/e2e/journeys/quote/tell-us-about-your-policy/tell-us-about-your-multi-policy.spec.js b/e2e-tests/cypress/e2e/journeys/quote/tell-us-about-your-policy/tell-us-about-your-multi-policy.spec.js index a9f7374c20..952e1bce94 100644 --- a/e2e-tests/cypress/e2e/journeys/quote/tell-us-about-your-policy/tell-us-about-your-multi-policy.spec.js +++ b/e2e-tests/cypress/e2e/journeys/quote/tell-us-about-your-policy/tell-us-about-your-multi-policy.spec.js @@ -1,5 +1,6 @@ import { - completeAndSubmitBuyerForm, + completeAndSubmitBuyerCountryForm, + completeAndSubmitBuyerBodyForm, completeAndSubmitCompanyForm, completeAndSubmitUkContentForm, completeAndSubmitPolicyTypeMultiForm, @@ -27,7 +28,8 @@ context('Tell us about your multi policy page - as an exporter, I want to provid before(() => { cy.login(); - completeAndSubmitBuyerForm(); + completeAndSubmitBuyerCountryForm(); + completeAndSubmitBuyerBodyForm(); completeAndSubmitCompanyForm(); completeAndSubmitUkContentForm(); completeAndSubmitPolicyTypeMultiForm(); diff --git a/e2e-tests/cypress/e2e/journeys/quote/tell-us-about-your-policy/tell-us-about-your-single-policy-validation.spec.js b/e2e-tests/cypress/e2e/journeys/quote/tell-us-about-your-policy/tell-us-about-your-single-policy-validation.spec.js index ef7b9d661e..c89eb070f1 100644 --- a/e2e-tests/cypress/e2e/journeys/quote/tell-us-about-your-policy/tell-us-about-your-single-policy-validation.spec.js +++ b/e2e-tests/cypress/e2e/journeys/quote/tell-us-about-your-policy/tell-us-about-your-single-policy-validation.spec.js @@ -1,5 +1,6 @@ import { - completeAndSubmitBuyerForm, + completeAndSubmitBuyerCountryForm, + completeAndSubmitBuyerBodyForm, completeAndSubmitCompanyForm, completeAndSubmitUkContentForm, completeAndSubmitPolicyTypeSingleForm, @@ -22,7 +23,8 @@ context('Tell us about the policy you need page - form validation', () => { before(() => { cy.login(); - completeAndSubmitBuyerForm(); + completeAndSubmitBuyerCountryForm(); + completeAndSubmitBuyerBodyForm(); completeAndSubmitCompanyForm(); completeAndSubmitUkContentForm(); completeAndSubmitPolicyTypeSingleForm(); diff --git a/e2e-tests/cypress/e2e/journeys/quote/tell-us-about-your-policy/tell-us-about-your-single-policy.spec.js b/e2e-tests/cypress/e2e/journeys/quote/tell-us-about-your-policy/tell-us-about-your-single-policy.spec.js index 3fdf290ff6..87337b55ff 100644 --- a/e2e-tests/cypress/e2e/journeys/quote/tell-us-about-your-policy/tell-us-about-your-single-policy.spec.js +++ b/e2e-tests/cypress/e2e/journeys/quote/tell-us-about-your-policy/tell-us-about-your-single-policy.spec.js @@ -1,5 +1,6 @@ import { - completeAndSubmitBuyerForm, + completeAndSubmitBuyerCountryForm, + completeAndSubmitBuyerBodyForm, completeAndSubmitCompanyForm, completeAndSubmitUkContentForm, completeAndSubmitPolicyTypeSingleForm, @@ -27,7 +28,8 @@ context('Tell us about your single policy page - as an exporter, I want to provi before(() => { cy.login(); - completeAndSubmitBuyerForm(); + completeAndSubmitBuyerCountryForm(); + completeAndSubmitBuyerBodyForm(); completeAndSubmitCompanyForm(); completeAndSubmitUkContentForm(); completeAndSubmitPolicyTypeSingleForm(); diff --git a/e2e-tests/cypress/e2e/journeys/quote/uk-goods-or-services/uk-goods-or-services-answer-no.spec.js b/e2e-tests/cypress/e2e/journeys/quote/uk-goods-or-services/uk-goods-or-services-answer-no.spec.js index ef3e7c2b5e..3fdb46bc0c 100644 --- a/e2e-tests/cypress/e2e/journeys/quote/uk-goods-or-services/uk-goods-or-services-answer-no.spec.js +++ b/e2e-tests/cypress/e2e/journeys/quote/uk-goods-or-services/uk-goods-or-services-answer-no.spec.js @@ -7,7 +7,7 @@ import { PAGES, } from '../../../../../content-strings'; import CONSTANTS from '../../../../../constants'; -import { completeAndSubmitBuyerForm, completeAndSubmitCompanyForm } from '../../../../support/quote/forms'; +import { completeAndSubmitBuyerCountryForm, completeAndSubmitBuyerBodyForm, completeAndSubmitCompanyForm } from '../../../../support/quote/forms'; const CONTENT_STRINGS = PAGES.CANNOT_OBTAIN_COVER_PAGE; const { ROUTES } = CONSTANTS; @@ -15,7 +15,8 @@ const { ROUTES } = CONSTANTS; context('UK goods or services page - as an exporter, I want to check if my export value is eligible for UKEF export insurance cover - submit `no - UK goods/services is below the minimum`', () => { beforeEach(() => { cy.login(); - completeAndSubmitBuyerForm(); + completeAndSubmitBuyerCountryForm(); + completeAndSubmitBuyerBodyForm(); completeAndSubmitCompanyForm(); cy.url().should('include', ROUTES.QUOTE.HAS_MINIMUM_UK_GOODS_OR_SERVICES); diff --git a/e2e-tests/cypress/e2e/journeys/quote/uk-goods-or-services/uk-goods-or-services.spec.js b/e2e-tests/cypress/e2e/journeys/quote/uk-goods-or-services/uk-goods-or-services.spec.js index 0acac60c36..402accb11b 100644 --- a/e2e-tests/cypress/e2e/journeys/quote/uk-goods-or-services/uk-goods-or-services.spec.js +++ b/e2e-tests/cypress/e2e/journeys/quote/uk-goods-or-services/uk-goods-or-services.spec.js @@ -11,7 +11,7 @@ import { ERROR_MESSAGES, } from '../../../../../content-strings'; import CONSTANTS from '../../../../../constants'; -import { completeAndSubmitBuyerForm, completeAndSubmitCompanyForm } from '../../../../support/quote/forms'; +import { completeAndSubmitBuyerCountryForm, completeAndSubmitBuyerBodyForm, completeAndSubmitCompanyForm } from '../../../../support/quote/forms'; const CONTENT_STRINGS = PAGES.HAS_MINIMUM_UK_GOODS_OR_SERVICES_PAGE; const { ROUTES, FIELD_IDS } = CONSTANTS; @@ -19,7 +19,8 @@ const { ROUTES, FIELD_IDS } = CONSTANTS; context('UK goods or services page - as an exporter, I want to check if my export value is eligible for UKEF export insurance cover', () => { before(() => { cy.login(); - completeAndSubmitBuyerForm(); + completeAndSubmitBuyerCountryForm(); + completeAndSubmitBuyerBodyForm(); completeAndSubmitCompanyForm(); cy.url().should('include', ROUTES.QUOTE.HAS_MINIMUM_UK_GOODS_OR_SERVICES); diff --git a/e2e-tests/cypress/e2e/journeys/quote/your-quote/your-quote-kenya-single-policy-USD.spec.js b/e2e-tests/cypress/e2e/journeys/quote/your-quote/your-quote-kenya-single-policy-USD.spec.js index 01c65f5b33..f6281a0bb1 100644 --- a/e2e-tests/cypress/e2e/journeys/quote/your-quote/your-quote-kenya-single-policy-USD.spec.js +++ b/e2e-tests/cypress/e2e/journeys/quote/your-quote/your-quote-kenya-single-policy-USD.spec.js @@ -1,5 +1,6 @@ import { - completeAndSubmitBuyerForm, + completeAndSubmitBuyerCountryForm, + completeAndSubmitBuyerBodyForm, completeAndSubmitCompanyForm, completeAndSubmitUkContentForm, completeAndSubmitPolicyTypeSingleForm, @@ -31,9 +32,9 @@ context('Get a quote/your quote page (single policy, Kenya, USD) - as an exporte results.first().click(); buyerCountryPage.submitButton().click(); + completeAndSubmitBuyerBodyForm(); completeAndSubmitCompanyForm(); completeAndSubmitUkContentForm(); - // completeAndSubmitPolicyTypeSingleForm(); policyTypePage[POLICY_TYPE].single.input().click(); policyTypePage[SINGLE_POLICY_LENGTH].input().type('18'); diff --git a/e2e-tests/cypress/e2e/journeys/quote/your-quote/your-quote-large-contract-value.spec.js b/e2e-tests/cypress/e2e/journeys/quote/your-quote/your-quote-large-contract-value.spec.js index 4f7910b21e..fa89bb490d 100644 --- a/e2e-tests/cypress/e2e/journeys/quote/your-quote/your-quote-large-contract-value.spec.js +++ b/e2e-tests/cypress/e2e/journeys/quote/your-quote/your-quote-large-contract-value.spec.js @@ -1,5 +1,6 @@ import { - completeAndSubmitBuyerForm, + completeAndSubmitBuyerCountryForm, + completeAndSubmitBuyerBodyForm, completeAndSubmitCompanyForm, completeAndSubmitUkContentForm, completeAndSubmitPolicyTypeSingleForm, @@ -22,7 +23,8 @@ context('Get a quote/your quote page (large contract value) - as an exporter, I before(() => { cy.login(); - completeAndSubmitBuyerForm(); + completeAndSubmitBuyerCountryForm(); + completeAndSubmitBuyerBodyForm(); completeAndSubmitCompanyForm(); completeAndSubmitUkContentForm(); completeAndSubmitPolicyTypeSingleForm(); diff --git a/e2e-tests/cypress/e2e/pages/quote/buyerBody.js b/e2e-tests/cypress/e2e/pages/quote/buyerBody.js new file mode 100644 index 0000000000..9f69f7e5ac --- /dev/null +++ b/e2e-tests/cypress/e2e/pages/quote/buyerBody.js @@ -0,0 +1,14 @@ +import { FIELD_IDS } from '../../../../constants'; + +const buyerBodyPage = { + heading: () => cy.get('[data-cy="heading"]'), + [FIELD_IDS.VALID_BUYER_BODY]: { + yes: () => cy.get(`[data-cy="${FIELD_IDS.VALID_BUYER_BODY}-yes"]`), + no: () => cy.get(`[data-cy="${FIELD_IDS.VALID_BUYER_BODY}-no"]`), + yesInput: () => cy.get(`[data-cy="${FIELD_IDS.VALID_BUYER_BODY}-yes-input"]`), + errorMessage: () => cy.get(`[data-cy="${FIELD_IDS.VALID_BUYER_BODY}-error-message"]`), + }, + submitButton: () => cy.get('[data-cy="submit-button"]'), +}; + +export default buyerBodyPage; diff --git a/e2e-tests/cypress/e2e/pages/quote/getAQuoteByEmail.js b/e2e-tests/cypress/e2e/pages/quote/getAQuoteByEmail.js index bfdf5906b0..ff043fe36d 100644 --- a/e2e-tests/cypress/e2e/pages/quote/getAQuoteByEmail.js +++ b/e2e-tests/cypress/e2e/pages/quote/getAQuoteByEmail.js @@ -1,7 +1,7 @@ const getAQuoteByEmailPage = { heading: () => cy.get('[data-cy="heading"]'), - body1: () => cy.get('[data-cy="body-1"]'), - body2: () => cy.get('[data-cy="body-2"]'), + reason: () => cy.get('[data-cy="reason"]'), + description: () => cy.get('[data-cy="description"]'), action: { text: () => cy.get('[data-cy="details-1"]'), link1: () => cy.get('[data-cy="details-1"] a').eq(0), diff --git a/e2e-tests/cypress/e2e/pages/quote/index.js b/e2e-tests/cypress/e2e/pages/quote/index.js index 906b696c70..a0642b29ba 100644 --- a/e2e-tests/cypress/e2e/pages/quote/index.js +++ b/e2e-tests/cypress/e2e/pages/quote/index.js @@ -1,5 +1,6 @@ -const companyBasedPage = require('./companyBased'); const buyerCountryPage = require('./buyerCountry'); +const buyerBodyPage = require('./buyerBody'); +const companyBasedPage = require('./companyBased'); const ukGoodsOrServicesPage = require('./ukGoodsOrServices'); const policyTypePage = require('./policyTypePage'); const tellUsAboutYourPolicyPage = require('./tellUsAboutYourPolicy'); @@ -11,8 +12,9 @@ const needToStartAgainPage = require('./needToStartAgain'); module.exports = { - companyBasedPage, buyerCountryPage, + buyerBodyPage, + companyBasedPage, ukGoodsOrServicesPage, policyTypePage, tellUsAboutYourPolicyPage, diff --git a/e2e-tests/cypress/support/quote/forms.js b/e2e-tests/cypress/support/quote/forms.js index e7a71b98e5..523e4ae3c0 100644 --- a/e2e-tests/cypress/support/quote/forms.js +++ b/e2e-tests/cypress/support/quote/forms.js @@ -1,6 +1,7 @@ import { - companyBasedPage, buyerCountryPage, + buyerBodyPage, + companyBasedPage, ukGoodsOrServicesPage, policyTypePage, tellUsAboutYourPolicyPage, @@ -19,13 +20,18 @@ const { VALID_COMPANY_BASE, } = FIELD_IDS; -export const completeAndSubmitBuyerForm = () => { +export const completeAndSubmitBuyerCountryForm = () => { buyerCountryPage.searchInput().type('Alg'); const results = buyerCountryPage.results(); results.first().click(); buyerCountryPage.submitButton().click(); }; +export const completeAndSubmitBuyerBodyForm = () => { + buyerBodyPage[FIELD_IDS.VALID_BUYER_BODY].no().click(); + buyerBodyPage.submitButton().click(); +}; + export const completeAndSubmitCompanyForm = () => { companyBasedPage[VALID_COMPANY_BASE].yes().click(); companyBasedPage.submitButton().click(); diff --git a/e2e-tests/cypress/support/quote/submit-answers-happy-path-multi-policy.js b/e2e-tests/cypress/support/quote/submit-answers-happy-path-multi-policy.js index d6d60a35b7..8590f03a07 100644 --- a/e2e-tests/cypress/support/quote/submit-answers-happy-path-multi-policy.js +++ b/e2e-tests/cypress/support/quote/submit-answers-happy-path-multi-policy.js @@ -1,5 +1,6 @@ import { - completeAndSubmitBuyerForm, + completeAndSubmitBuyerCountryForm, + completeAndSubmitBuyerBodyForm, completeAndSubmitCompanyForm, completeAndSubmitUkContentForm, completeAndSubmitPolicyTypeMultiForm, @@ -7,7 +8,8 @@ import { } from './forms'; export default () => { - completeAndSubmitBuyerForm(); + completeAndSubmitBuyerCountryForm(); + completeAndSubmitBuyerBodyForm(); completeAndSubmitCompanyForm(); completeAndSubmitUkContentForm(); completeAndSubmitPolicyTypeMultiForm(); diff --git a/e2e-tests/cypress/support/quote/submit-answers-happy-path-single-policy.js b/e2e-tests/cypress/support/quote/submit-answers-happy-path-single-policy.js index 2d007ccda8..5442ccafef 100644 --- a/e2e-tests/cypress/support/quote/submit-answers-happy-path-single-policy.js +++ b/e2e-tests/cypress/support/quote/submit-answers-happy-path-single-policy.js @@ -1,5 +1,6 @@ import { - completeAndSubmitBuyerForm, + completeAndSubmitBuyerCountryForm, + completeAndSubmitBuyerBodyForm, completeAndSubmitCompanyForm, completeAndSubmitUkContentForm, completeAndSubmitPolicyTypeSingleForm, @@ -7,7 +8,8 @@ import { } from './forms'; export default () => { - completeAndSubmitBuyerForm(); + completeAndSubmitBuyerCountryForm(); + completeAndSubmitBuyerBodyForm(); completeAndSubmitCompanyForm(); completeAndSubmitUkContentForm(); completeAndSubmitPolicyTypeSingleForm(); diff --git a/src/ui/server/constants/field-ids.ts b/src/ui/server/constants/field-ids.ts index e931136dcb..e46a7d34af 100644 --- a/src/ui/server/constants/field-ids.ts +++ b/src/ui/server/constants/field-ids.ts @@ -1,4 +1,5 @@ export const FIELD_IDS = { + VALID_BUYER_BODY: 'validBuyerBody', VALID_COMPANY_BASE: 'validCompanyBase', BUYER_COUNTRY: 'buyerCountry', COUNTRY: 'country', diff --git a/src/ui/server/constants/routes/quote.ts b/src/ui/server/constants/routes/quote.ts index 071f4b7bb9..46c81526f4 100644 --- a/src/ui/server/constants/routes/quote.ts +++ b/src/ui/server/constants/routes/quote.ts @@ -1,4 +1,6 @@ export const QUOTE_ROUTES = { + BUYER_BODY: '/quote/type-of-buyer', + BUYER_COUNTRY: '/quote/buyer-country', BUYER_COUNTRY_CHANGE: '/quote/buyer-country/change', diff --git a/src/ui/server/constants/templates/quote.ts b/src/ui/server/constants/templates/quote.ts index 6e5515a2a3..cf456d2d9f 100644 --- a/src/ui/server/constants/templates/quote.ts +++ b/src/ui/server/constants/templates/quote.ts @@ -1,6 +1,7 @@ export const QUOTE_TEMPLATES = { - COMPANY_BASED: 'quote/company-based.njk', + BUYER_BODY: 'quote/buyer-body.njk', BUYER_COUNTRY: 'quote/buyer-country.njk', + COMPANY_BASED: 'quote/company-based.njk', HAS_MINIMUM_UK_GOODS_OR_SERVICES: 'quote/uk-goods-or-services.njk', POLICY_TYPE: 'quote/policy-type.njk', TELL_US_ABOUT_YOUR_POLICY: 'quote/tell-us-about-your-policy.njk', diff --git a/src/ui/server/content-strings/error-messages.ts b/src/ui/server/content-strings/error-messages.ts index cfe3cc31d7..c5fa46de9c 100644 --- a/src/ui/server/content-strings/error-messages.ts +++ b/src/ui/server/content-strings/error-messages.ts @@ -5,9 +5,10 @@ type ErrorMessage = { }; export const ERROR_MESSAGES = { - [FIELD_IDS.VALID_COMPANY_BASE]: 'Select if your company is based in the UK, Channel Islands, Isle of Man or not', [FIELD_IDS.BUYER_COUNTRY]: 'Select where your buyer is based', [FIELD_IDS.COUNTRY]: 'Select where your buyer is based', + [FIELD_IDS.VALID_BUYER_BODY]: 'Select if your buyer is a government or public sector body', + [FIELD_IDS.VALID_COMPANY_BASE]: 'Select if your company is based in the UK, Channel Islands, Isle of Man or not', [FIELD_IDS.HAS_MINIMUM_UK_GOODS_OR_SERVICES]: { IS_EMPTY: 'Select whether at least 20% of your export contract value is made up from UK goods and services', }, diff --git a/src/ui/server/content-strings/pages.ts b/src/ui/server/content-strings/pages.ts index 3f5cc40339..6fbd54e7de 100644 --- a/src/ui/server/content-strings/pages.ts +++ b/src/ui/server/content-strings/pages.ts @@ -1,15 +1,25 @@ import { LINKS } from './links'; -const COMPANY_BASED_PAGE = { - PAGE_TITLE: 'Is your company based inside the UK, Channel Islands or Isle of Man?', - HEADING: 'Is your company based inside the UK, Channel Islands or Isle of Man?', -}; - const BUYER_COUNTRY_PAGE = { PAGE_TITLE: 'Where is your buyer based?', HEADING: 'Where is your buyer based?', }; +const BUYER_BODY_PAGE = { + PAGE_TITLE: 'Is your buyer a government or public sector body?', + HEADING: 'Is your buyer a government or public sector body?', + DETAILS: { + INTRO: 'What counts as a government or public sector body?', + BODY_1: 'This means a formally established organisation that is, at least in part, publicly funded to deliver a public or government service.', + BODY_2: 'For example, a central government department, a local authority or a public utlity company.', + }, +}; + +const COMPANY_BASED_PAGE = { + PAGE_TITLE: 'Is your company based inside the UK, Channel Islands or Isle of Man?', + HEADING: 'Is your company based inside the UK, Channel Islands or Isle of Man?', +}; + const HAS_MINIMUM_UK_GOODS_OR_SERVICES_PAGE = { PAGE_TITLE: 'Is at least 20% of your export contract value made up from UK goods or services?', HEADING: 'Is at least 20% of your export contract value made up from UK goods or services?', @@ -124,8 +134,10 @@ const GET_A_QUOTE_BY_EMAIL_PAGE = { PAGE_TITLE: 'You need to get a quote by email', HEADING: 'You need to get a quote by email', REASON: { - BODY_1: 'We cannot give you a quote online because of the country where your buyer is based.', - BODY_2: "We can still give you a quote but may need extra information from you to assess the risks around your buyer's country first.", + BUYER_BODY: 'We cannot give you a quote online because your buyer is a government or public sector body.', + BUYER_BODY_DESCRIPTION: 'We can still give you a quote but may need extra information from you to assess the risks around your buyer first.', + BUYER_COUNTRY: 'We cannot give you a quote online because of the country where your buyer is based.', + BUYER_COUNTRY_DESCRIPTION: "We can still give you a quote but may need extra information from you to assess the risks around your buyer's country first.", }, ACTION: [ [ @@ -269,8 +281,9 @@ const PROBLEM_WITH_SERVICE_PAGE = { }; export const PAGES = { - COMPANY_BASED_PAGE, BUYER_COUNTRY_PAGE, + BUYER_BODY_PAGE, + COMPANY_BASED_PAGE, HAS_MINIMUM_UK_GOODS_OR_SERVICES_PAGE, POLICY_TYPE_PAGE, TELL_US_ABOUT_YOUR_POLICY_PAGE, diff --git a/src/ui/server/controllers/quote/buyer-body/index.test.ts b/src/ui/server/controllers/quote/buyer-body/index.test.ts new file mode 100644 index 0000000000..913caaab4c --- /dev/null +++ b/src/ui/server/controllers/quote/buyer-body/index.test.ts @@ -0,0 +1,135 @@ +import { PAGE_VARIABLES, mapAnswer, get, post } from '.'; +import { PAGES } from '../../../content-strings'; +import { FIELD_IDS, ROUTES, TEMPLATES } from '../../../constants'; +import singleInputPageVariables from '../../../helpers/single-input-page-variables'; +import generateValidationErrors from './validation'; +import { updateSubmittedData } from '../../../helpers/update-submitted-data'; +import { mockReq, mockRes } from '../../../test-mocks'; +import { Request, Response } from '../../../../types'; + +describe('controllers/buyer-body', () => { + let req: Request; + let res: Response; + + const mockFlash = jest.fn(); + + beforeEach(() => { + req = mockReq(); + req.flash = mockFlash; + + res = mockRes(); + }); + + afterAll(() => { + jest.resetAllMocks(); + }); + + describe('PAGE_VARIABLES', () => { + it('should have correct properties', () => { + const expected = { + FIELD_ID: FIELD_IDS.VALID_BUYER_BODY, + PAGE_CONTENT_STRINGS: PAGES.BUYER_BODY_PAGE, + }; + + expect(PAGE_VARIABLES).toEqual(expected); + }); + }); + + describe('mapAnswer', () => { + describe('when the answer is `false`', () => { + it('should return true', () => { + const result = mapAnswer('false'); + + expect(result).toEqual(true); + }); + }); + + describe('when the answer is `true`', () => { + it('should return false', () => { + const result = mapAnswer('true'); + + expect(result).toEqual(false); + }); + }); + }); + + describe('get', () => { + it('should render template', async () => { + await get(req, res); + + const expectedVariables = { + ...singleInputPageVariables(PAGE_VARIABLES), + BACK_LINK: req.headers.referer, + submittedValues: req.session.submittedData, + }; + + expect(res.render).toHaveBeenCalledWith(TEMPLATES.QUOTE.BUYER_BODY, expectedVariables); + }); + }); + + describe('post', () => { + describe('when there are validation errors', () => { + it('should render template with validation errors', async () => { + await post(req, res); + + expect(res.render).toHaveBeenCalledWith(TEMPLATES.QUOTE.BUYER_BODY, { + ...singleInputPageVariables(PAGE_VARIABLES), + BACK_LINK: req.headers.referer, + validationErrors: generateValidationErrors(req.body), + }); + }); + }); + + describe('when the submitted answer is `yes`', () => { + beforeEach(() => { + req.body[FIELD_IDS.VALID_BUYER_BODY] = 'true'; + }); + + it('should add previousRoute, exitReason and exitDescription to req.flash', async () => { + await post(req, res); + + expect(mockFlash).toHaveBeenCalledTimes(3); + + expect(mockFlash.mock.calls[0]).toEqual(['previousRoute', ROUTES.QUOTE.BUYER_BODY]); + + const { GET_A_QUOTE_BY_EMAIL_PAGE } = PAGES; + const { REASON } = GET_A_QUOTE_BY_EMAIL_PAGE; + + expect(mockFlash.mock.calls[1]).toEqual(['exitReason', REASON.BUYER_BODY]); + expect(mockFlash.mock.calls[2]).toEqual(['exitDescription', REASON.BUYER_BODY_DESCRIPTION]); + }); + + it(`should redirect to ${ROUTES.QUOTE.GET_A_QUOTE_BY_EMAIL}`, async () => { + await post(req, res); + + expect(res.redirect).toHaveBeenCalledWith(ROUTES.QUOTE.GET_A_QUOTE_BY_EMAIL); + }); + }); + + describe('when there are no validation errors', () => { + const validBody = { + [FIELD_IDS.VALID_BUYER_BODY]: 'false', + }; + + beforeEach(() => { + req.body = validBody; + }); + + it('should update the session with submitted data, popluated with mapped buyer body answer', async () => { + await post(req, res); + + const expectedMappedAnswer = mapAnswer(req.body[FIELD_IDS.VALID_BUYER_BODY]); + + const expected = updateSubmittedData({ [FIELD_IDS.VALID_BUYER_BODY]: expectedMappedAnswer }, req.session.submittedData); + + expect(req.session.submittedData).toEqual(expected); + }); + + it(`should redirect to ${ROUTES.QUOTE.COMPANY_BASED}`, async () => { + await post(req, res); + + expect(res.redirect).toHaveBeenCalledWith(ROUTES.QUOTE.COMPANY_BASED); + }); + }); + }); +}); diff --git a/src/ui/server/controllers/quote/buyer-body/index.ts b/src/ui/server/controllers/quote/buyer-body/index.ts new file mode 100644 index 0000000000..e4151737e3 --- /dev/null +++ b/src/ui/server/controllers/quote/buyer-body/index.ts @@ -0,0 +1,68 @@ +import { PAGES } from '../../../content-strings'; +import { FIELD_IDS, ROUTES, TEMPLATES } from '../../../constants'; +import singleInputPageVariables from '../../../helpers/single-input-page-variables'; +import generateValidationErrors from './validation'; +import { updateSubmittedData } from '../../../helpers/update-submitted-data'; +import { Request, Response } from '../../../../types'; + +const PAGE_VARIABLES = { + FIELD_ID: FIELD_IDS.VALID_BUYER_BODY, + PAGE_CONTENT_STRINGS: PAGES.BUYER_BODY_PAGE, +}; + +/** + * mapAnswer + * Map yes/no answer to true/false boolean. + * The saved field ID includes 'valid' so we need to reverse the answer to save it correctly. + * If the answer is 'false', the 'buyer body' is valid. Return true. + * If the answer is 'true', the 'buyer body' is invalid. Return false. + * @returns {boolean} + */ +const mapAnswer = (answer: string) => { + if (answer === 'false') { + return true; + } + + return false; +}; + +const get = (req: Request, res: Response) => + res.render(TEMPLATES.QUOTE.BUYER_BODY, { + ...singleInputPageVariables(PAGE_VARIABLES), + BACK_LINK: req.headers.referer, + submittedValues: req.session.submittedData, + }); + +const post = (req: Request, res: Response) => { + const validationErrors = generateValidationErrors(req.body); + + if (validationErrors) { + return res.render(TEMPLATES.QUOTE.BUYER_BODY, { + ...singleInputPageVariables(PAGE_VARIABLES), + BACK_LINK: req.headers.referer, + validationErrors, + }); + } + + const answer = req.body[FIELD_IDS.VALID_BUYER_BODY]; + + const mappedAnswer = mapAnswer(req.body[FIELD_IDS.VALID_BUYER_BODY]); + + req.session.submittedData = updateSubmittedData({ [FIELD_IDS.VALID_BUYER_BODY]: mappedAnswer }, req.session.submittedData); + + if (answer === 'true') { + req.flash('previousRoute', ROUTES.QUOTE.BUYER_BODY); + + const { GET_A_QUOTE_BY_EMAIL_PAGE } = PAGES; + const { REASON } = GET_A_QUOTE_BY_EMAIL_PAGE; + + req.flash('exitReason', REASON.BUYER_BODY); + req.flash('exitDescription', REASON.BUYER_BODY_DESCRIPTION); + + return res.redirect(ROUTES.QUOTE.GET_A_QUOTE_BY_EMAIL); + } + + return res.redirect(ROUTES.QUOTE.COMPANY_BASED); +}; + +export { PAGE_VARIABLES, mapAnswer, get, post }; diff --git a/src/ui/server/controllers/quote/buyer-body/validation.test.ts b/src/ui/server/controllers/quote/buyer-body/validation.test.ts new file mode 100644 index 0000000000..bc527feabd --- /dev/null +++ b/src/ui/server/controllers/quote/buyer-body/validation.test.ts @@ -0,0 +1,34 @@ +import validation from './validation'; +import { FIELD_IDS } from '../../../constants'; +import { ERROR_MESSAGES } from '../../../content-strings'; +import generateValidationErrors from '../../../helpers/validation'; + +describe('controllers/buyer-body/validation', () => { + describe('when no values are provided', () => { + it('should return validation errors', () => { + const result = validation({}); + + const expected = generateValidationErrors(FIELD_IDS.VALID_BUYER_BODY, ERROR_MESSAGES[FIELD_IDS.VALID_BUYER_BODY]); + + expect(result).toEqual(expected); + }); + }); + + describe(`when ${FIELD_IDS.VALID_BUYER_BODY} is not provided`, () => { + it('should return validation errors', () => { + const result = validation({}); + + const expected = generateValidationErrors(FIELD_IDS.VALID_BUYER_BODY, ERROR_MESSAGES[FIELD_IDS.VALID_BUYER_BODY]); + + expect(result).toEqual(expected); + }); + }); + + describe('when there are no errors', () => { + it('should return null', () => { + const result = validation({ [FIELD_IDS.VALID_BUYER_BODY]: true }); + + expect(result).toEqual(null); + }); + }); +}); diff --git a/src/ui/server/controllers/quote/buyer-body/validation.ts b/src/ui/server/controllers/quote/buyer-body/validation.ts new file mode 100644 index 0000000000..d6d95fa393 --- /dev/null +++ b/src/ui/server/controllers/quote/buyer-body/validation.ts @@ -0,0 +1,21 @@ +import { FIELD_IDS } from '../../../constants'; +import { ERROR_MESSAGES } from '../../../content-strings'; +import generateValidationErrors from '../../../helpers/validation'; +import { objectHasValues, objectHasProperty } from '../../../helpers/object'; +import { RequestBody } from '../../../../types'; + +const validation = (formBody: RequestBody) => { + let errors; + + const hasErrors = !objectHasValues(formBody) || !objectHasProperty(formBody, FIELD_IDS.VALID_BUYER_BODY); + + if (hasErrors) { + errors = generateValidationErrors(FIELD_IDS.VALID_BUYER_BODY, ERROR_MESSAGES[FIELD_IDS.VALID_BUYER_BODY]); + + return errors; + } + + return null; +}; + +export default validation; diff --git a/src/ui/server/controllers/quote/buyer-country/index.test.ts b/src/ui/server/controllers/quote/buyer-country/index.test.ts index f4dfd37361..e717674f5a 100644 --- a/src/ui/server/controllers/quote/buyer-country/index.test.ts +++ b/src/ui/server/controllers/quote/buyer-country/index.test.ts @@ -42,8 +42,12 @@ describe('controllers/buyer-country', () => { const countryUnsupported = mockCountriesResponse[0]; const countrySupportedViaEmailOnly = mockCountriesResponse[2]; + const mockFlash = jest.fn(); + beforeEach(() => { req = mockReq(); + req.flash = mockFlash; + res = mockRes(); }); @@ -185,6 +189,20 @@ describe('controllers/buyer-country', () => { req.body[FIELD_IDS.BUYER_COUNTRY] = countrySupportedViaEmailOnly.marketName; }); + it('should add previousRoute, exitReason and exitDescription to req.flash', async () => { + await post(req, res); + + expect(mockFlash).toHaveBeenCalledTimes(3); + + expect(mockFlash.mock.calls[0]).toEqual(['previousRoute', ROUTES.QUOTE.BUYER_COUNTRY]); + + const { GET_A_QUOTE_BY_EMAIL_PAGE } = PAGES; + const { REASON } = GET_A_QUOTE_BY_EMAIL_PAGE; + + expect(mockFlash.mock.calls[1]).toEqual(['exitReason', REASON.BUYER_COUNTRY]); + expect(mockFlash.mock.calls[2]).toEqual(['exitDescription', REASON.BUYER_COUNTRY_DESCRIPTION]); + }); + it(`should redirect to ${ROUTES.QUOTE.GET_A_QUOTE_BY_EMAIL}`, async () => { await post(req, res); @@ -209,12 +227,6 @@ describe('controllers/buyer-country', () => { req.body[FIELD_IDS.BUYER_COUNTRY] = countryUnsupported.marketName; }); - it(`should redirect to ${ROUTES.QUOTE.CANNOT_OBTAIN_COVER}`, async () => { - await post(req, res); - - expect(res.redirect).toHaveBeenCalledWith(ROUTES.QUOTE.CANNOT_OBTAIN_COVER); - }); - it('should add previousRoute and exitReason to req.flash', async () => { await post(req, res); @@ -229,6 +241,12 @@ describe('controllers/buyer-country', () => { expect(req.flash).toHaveBeenCalledWith('exitReason', expectedReason); }); + + it(`should redirect to ${ROUTES.QUOTE.CANNOT_OBTAIN_COVER}`, async () => { + await post(req, res); + + expect(res.redirect).toHaveBeenCalledWith(ROUTES.QUOTE.CANNOT_OBTAIN_COVER); + }); }); describe('when the country is supported for an online quote and there are no validation errors', () => { @@ -262,10 +280,10 @@ describe('controllers/buyer-country', () => { expect(req.session.submittedData).toEqual(expected); }); - it(`should redirect to ${ROUTES.QUOTE.COMPANY_BASED}`, async () => { + it(`should redirect to ${ROUTES.QUOTE.BUYER_BODY}`, async () => { await post(req, res); - expect(res.redirect).toHaveBeenCalledWith(ROUTES.QUOTE.COMPANY_BASED); + expect(res.redirect).toHaveBeenCalledWith(ROUTES.QUOTE.BUYER_BODY); }); describe("when the url's last substring is `change`", () => { diff --git a/src/ui/server/controllers/quote/buyer-country/index.ts b/src/ui/server/controllers/quote/buyer-country/index.ts index cf3d565ead..372f3fe366 100644 --- a/src/ui/server/controllers/quote/buyer-country/index.ts +++ b/src/ui/server/controllers/quote/buyer-country/index.ts @@ -115,10 +115,18 @@ export const post = async (req: Request, res: Response) => { return res.redirect(ROUTES.QUOTE.CHECK_YOUR_ANSWERS); } - return res.redirect(ROUTES.QUOTE.COMPANY_BASED); + return res.redirect(ROUTES.QUOTE.BUYER_BODY); } if (canGetAQuoteByEmail(country)) { + req.flash('previousRoute', ROUTES.QUOTE.BUYER_COUNTRY); + + const { GET_A_QUOTE_BY_EMAIL_PAGE } = PAGES; + const { REASON } = GET_A_QUOTE_BY_EMAIL_PAGE; + + req.flash('exitReason', REASON.BUYER_COUNTRY); + req.flash('exitDescription', REASON.BUYER_COUNTRY_DESCRIPTION); + return res.redirect(ROUTES.QUOTE.GET_A_QUOTE_BY_EMAIL); } diff --git a/src/ui/server/controllers/quote/get-a-quote-by-email/index.test.ts b/src/ui/server/controllers/quote/get-a-quote-by-email/index.test.ts index 4179338757..d796363fee 100644 --- a/src/ui/server/controllers/quote/get-a-quote-by-email/index.test.ts +++ b/src/ui/server/controllers/quote/get-a-quote-by-email/index.test.ts @@ -7,9 +7,21 @@ import { Request, Response } from '../../../../types'; describe('controllers/get-a-quote-by-email', () => { let req: Request; let res: Response; + const mockExitReason = 'mock'; + const mockPreviousRoute = '/test'; beforeEach(() => { req = mockReq(); + + req.flash = (property: string) => { + const obj = { + exitReason: mockExitReason, + previousRoute: mockPreviousRoute, + }; + + return obj[property]; + }; + res = mockRes(); }); @@ -23,7 +35,8 @@ describe('controllers/get-a-quote-by-email', () => { LINKS, ...PAGES.GET_A_QUOTE_BY_EMAIL_PAGE, }, - BACK_LINK: req.headers.referer, + BACK_LINK: mockPreviousRoute, + EXIT_REASON: mockExitReason, }); }); }); diff --git a/src/ui/server/controllers/quote/get-a-quote-by-email/index.ts b/src/ui/server/controllers/quote/get-a-quote-by-email/index.ts index 5b4b5dfbf6..b882a8266a 100644 --- a/src/ui/server/controllers/quote/get-a-quote-by-email/index.ts +++ b/src/ui/server/controllers/quote/get-a-quote-by-email/index.ts @@ -2,15 +2,22 @@ import { FOOTER, LINKS, PAGES, PRODUCT } from '../../../content-strings'; import { TEMPLATES } from '../../../constants'; import { Request, Response } from '../../../../types'; -const get = (req: Request, res: Response) => - res.render(TEMPLATES.QUOTE.GET_A_QUOTE_BY_EMAIL, { +const get = (req: Request, res: Response) => { + const previousRoute = req.flash('previousRoute'); + const EXIT_REASON = req.flash('exitReason'); + const EXIT_DESCRIPTION = req.flash('exitDescription'); + + return res.render(TEMPLATES.QUOTE.GET_A_QUOTE_BY_EMAIL, { CONTENT_STRINGS: { PRODUCT, FOOTER, LINKS, ...PAGES.GET_A_QUOTE_BY_EMAIL_PAGE, }, - BACK_LINK: req.headers.referer, + BACK_LINK: previousRoute, + EXIT_REASON, + EXIT_DESCRIPTION, }); +}; export default get; diff --git a/src/ui/server/middleware/required-data-provided.test.ts b/src/ui/server/middleware/required-data-provided.test.ts index 4398e783fe..31999d2a1e 100644 --- a/src/ui/server/middleware/required-data-provided.test.ts +++ b/src/ui/server/middleware/required-data-provided.test.ts @@ -6,6 +6,7 @@ import { Request, Response } from '../../types'; const { ROOT, COOKIES, PROBLEM_WITH_SERVICE, QUOTE } = ROUTES; const { + BUYER_BODY, BUYER_COUNTRY, BUYER_COUNTRY_CHANGE, CHECK_YOUR_ANSWERS, @@ -77,13 +78,23 @@ describe('middleware/required-data-provided', () => { const expected = { [BUYER_COUNTRY]: [], - [COMPANY_BASED]: [FIELD_IDS.BUYER_COUNTRY], - [HAS_MINIMUM_UK_GOODS_OR_SERVICES]: [FIELD_IDS.BUYER_COUNTRY, FIELD_IDS.VALID_COMPANY_BASE], - [POLICY_TYPE]: [FIELD_IDS.BUYER_COUNTRY, FIELD_IDS.VALID_COMPANY_BASE], - [TELL_US_ABOUT_YOUR_POLICY]: [FIELD_IDS.BUYER_COUNTRY, FIELD_IDS.VALID_COMPANY_BASE, FIELD_IDS.POLICY_TYPE, FIELD_IDS.POLICY_LENGTH], + [BUYER_BODY]: [FIELD_IDS.BUYER_COUNTRY], + [COMPANY_BASED]: [FIELD_IDS.BUYER_COUNTRY, FIELD_IDS.VALID_BUYER_BODY], + [HAS_MINIMUM_UK_GOODS_OR_SERVICES]: [FIELD_IDS.BUYER_COUNTRY, FIELD_IDS.VALID_BUYER_BODY, FIELD_IDS.VALID_COMPANY_BASE], + [POLICY_TYPE]: [FIELD_IDS.BUYER_COUNTRY, FIELD_IDS.VALID_BUYER_BODY, FIELD_IDS.VALID_COMPANY_BASE, FIELD_IDS.HAS_MINIMUM_UK_GOODS_OR_SERVICES], + [TELL_US_ABOUT_YOUR_POLICY]: [ + FIELD_IDS.BUYER_COUNTRY, + FIELD_IDS.VALID_BUYER_BODY, + FIELD_IDS.VALID_COMPANY_BASE, + FIELD_IDS.HAS_MINIMUM_UK_GOODS_OR_SERVICES, + FIELD_IDS.POLICY_TYPE, + FIELD_IDS.POLICY_LENGTH, + ], [CHECK_YOUR_ANSWERS]: [ FIELD_IDS.BUYER_COUNTRY, + FIELD_IDS.VALID_BUYER_BODY, FIELD_IDS.VALID_COMPANY_BASE, + FIELD_IDS.HAS_MINIMUM_UK_GOODS_OR_SERVICES, FIELD_IDS.POLICY_TYPE, FIELD_IDS.POLICY_LENGTH, FIELD_IDS.CURRENCY, @@ -92,7 +103,9 @@ describe('middleware/required-data-provided', () => { ], [YOUR_QUOTE]: [ FIELD_IDS.BUYER_COUNTRY, + FIELD_IDS.VALID_BUYER_BODY, FIELD_IDS.VALID_COMPANY_BASE, + FIELD_IDS.HAS_MINIMUM_UK_GOODS_OR_SERVICES, FIELD_IDS.POLICY_TYPE, FIELD_IDS.POLICY_LENGTH, FIELD_IDS.CURRENCY, @@ -115,13 +128,23 @@ describe('middleware/required-data-provided', () => { const expected = { [BUYER_COUNTRY]: [], - [COMPANY_BASED]: [FIELD_IDS.BUYER_COUNTRY], - [HAS_MINIMUM_UK_GOODS_OR_SERVICES]: [FIELD_IDS.BUYER_COUNTRY, FIELD_IDS.VALID_COMPANY_BASE], - [POLICY_TYPE]: [FIELD_IDS.BUYER_COUNTRY, FIELD_IDS.VALID_COMPANY_BASE], - [TELL_US_ABOUT_YOUR_POLICY]: [FIELD_IDS.BUYER_COUNTRY, FIELD_IDS.VALID_COMPANY_BASE, FIELD_IDS.POLICY_TYPE, FIELD_IDS.POLICY_LENGTH], + [BUYER_BODY]: [FIELD_IDS.BUYER_COUNTRY], + [COMPANY_BASED]: [FIELD_IDS.BUYER_COUNTRY, FIELD_IDS.VALID_BUYER_BODY], + [HAS_MINIMUM_UK_GOODS_OR_SERVICES]: [FIELD_IDS.BUYER_COUNTRY, FIELD_IDS.VALID_BUYER_BODY, FIELD_IDS.VALID_COMPANY_BASE], + [POLICY_TYPE]: [FIELD_IDS.BUYER_COUNTRY, FIELD_IDS.VALID_BUYER_BODY, FIELD_IDS.VALID_COMPANY_BASE, FIELD_IDS.HAS_MINIMUM_UK_GOODS_OR_SERVICES], + [TELL_US_ABOUT_YOUR_POLICY]: [ + FIELD_IDS.BUYER_COUNTRY, + FIELD_IDS.VALID_BUYER_BODY, + FIELD_IDS.VALID_COMPANY_BASE, + FIELD_IDS.HAS_MINIMUM_UK_GOODS_OR_SERVICES, + FIELD_IDS.POLICY_TYPE, + FIELD_IDS.POLICY_LENGTH, + ], [CHECK_YOUR_ANSWERS]: [ FIELD_IDS.BUYER_COUNTRY, + FIELD_IDS.VALID_BUYER_BODY, FIELD_IDS.VALID_COMPANY_BASE, + FIELD_IDS.HAS_MINIMUM_UK_GOODS_OR_SERVICES, FIELD_IDS.POLICY_TYPE, FIELD_IDS.POLICY_LENGTH, FIELD_IDS.CURRENCY, @@ -131,7 +154,9 @@ describe('middleware/required-data-provided', () => { ], [YOUR_QUOTE]: [ FIELD_IDS.BUYER_COUNTRY, + FIELD_IDS.VALID_BUYER_BODY, FIELD_IDS.VALID_COMPANY_BASE, + FIELD_IDS.HAS_MINIMUM_UK_GOODS_OR_SERVICES, FIELD_IDS.POLICY_TYPE, FIELD_IDS.POLICY_LENGTH, FIELD_IDS.CURRENCY, @@ -153,6 +178,7 @@ describe('middleware/required-data-provided', () => { const expected = { [BUYER_COUNTRY]: allRequiredData({})[BUYER_COUNTRY], [BUYER_COUNTRY_CHANGE]: allRequiredData({})[BUYER_COUNTRY], + [BUYER_BODY]: allRequiredData({})[BUYER_BODY], [COMPANY_BASED]: allRequiredData({})[COMPANY_BASED], [COMPANY_BASED_CHANGE]: allRequiredData({})[COMPANY_BASED], [HAS_MINIMUM_UK_GOODS_OR_SERVICES]: allRequiredData({})[HAS_MINIMUM_UK_GOODS_OR_SERVICES], diff --git a/src/ui/server/middleware/required-data-provided.ts b/src/ui/server/middleware/required-data-provided.ts index 30cd20f551..3a689ecf88 100644 --- a/src/ui/server/middleware/required-data-provided.ts +++ b/src/ui/server/middleware/required-data-provided.ts @@ -5,6 +5,7 @@ import { isSinglePolicyType, isMultiPolicyType } from '../helpers/policy-type'; const { ROOT, COOKIES, PROBLEM_WITH_SERVICE, QUOTE } = ROUTES; const { + BUYER_BODY, BUYER_COUNTRY, BUYER_COUNTRY_CHANGE, CANNOT_OBTAIN_COVER, @@ -63,11 +64,13 @@ export const allRequiredData = (submittedData: SubmittedData): RequiredDataState requiredDataState[BUYER_COUNTRY] = []; - requiredDataState[COMPANY_BASED] = [FIELD_IDS.BUYER_COUNTRY]; + requiredDataState[BUYER_BODY] = [FIELD_IDS.BUYER_COUNTRY]; + + requiredDataState[COMPANY_BASED] = [...requiredDataState[BUYER_BODY], FIELD_IDS.VALID_BUYER_BODY]; requiredDataState[HAS_MINIMUM_UK_GOODS_OR_SERVICES] = [...requiredDataState[COMPANY_BASED], FIELD_IDS.VALID_COMPANY_BASE]; - requiredDataState[POLICY_TYPE] = [...requiredDataState[HAS_MINIMUM_UK_GOODS_OR_SERVICES]]; + requiredDataState[POLICY_TYPE] = [...requiredDataState[HAS_MINIMUM_UK_GOODS_OR_SERVICES], FIELD_IDS.HAS_MINIMUM_UK_GOODS_OR_SERVICES]; requiredDataState[TELL_US_ABOUT_YOUR_POLICY] = [...requiredDataState[POLICY_TYPE], FIELD_IDS.POLICY_TYPE, FIELD_IDS.POLICY_LENGTH]; @@ -93,6 +96,7 @@ export const generateRequiredDataState = (submittedData: SubmittedData): Require requiredDataState[BUYER_COUNTRY] = required[BUYER_COUNTRY]; requiredDataState[BUYER_COUNTRY_CHANGE] = required[BUYER_COUNTRY]; + requiredDataState[BUYER_BODY] = required[BUYER_BODY]; requiredDataState[COMPANY_BASED] = required[COMPANY_BASED]; requiredDataState[COMPANY_BASED_CHANGE] = required[COMPANY_BASED]; requiredDataState[HAS_MINIMUM_UK_GOODS_OR_SERVICES] = required[HAS_MINIMUM_UK_GOODS_OR_SERVICES]; diff --git a/src/ui/server/routes/quote/index.test.ts b/src/ui/server/routes/quote/index.test.ts index 44ebf3321f..8038eac7da 100644 --- a/src/ui/server/routes/quote/index.test.ts +++ b/src/ui/server/routes/quote/index.test.ts @@ -1,6 +1,7 @@ import { get, post } from '../../test-mocks/mock-router'; import { ROUTES } from '../../constants'; import { get as buyerBasedGet, post as buyerBasedPost } from '../../controllers/quote/buyer-country'; +import { get as buyerBodyGet, post as buyerBodyPost } from '../../controllers/quote/buyer-body'; import { get as companyBasedGet, post as companyBasedPost } from '../../controllers/quote/company-based'; import { get as ukGoodsOrServicesGet, post as ukGoodsOrServicesPost } from '../../controllers/quote/uk-goods-or-services'; import { get as policyTypeGet, post as policyTypePost } from '../../controllers/quote/policy-type'; @@ -21,14 +22,17 @@ describe('routes/index', () => { }); it('should setup all routes', () => { - expect(get).toHaveBeenCalledTimes(15); - expect(post).toHaveBeenCalledTimes(12); + expect(get).toHaveBeenCalledTimes(16); + expect(post).toHaveBeenCalledTimes(13); expect(get).toHaveBeenCalledWith(ROUTES.QUOTE.BUYER_COUNTRY, buyerBasedGet); expect(post).toHaveBeenCalledWith(ROUTES.QUOTE.BUYER_COUNTRY, buyerBasedPost); expect(get).toHaveBeenCalledWith(ROUTES.QUOTE.BUYER_COUNTRY_CHANGE, buyerBasedGet); expect(post).toHaveBeenCalledWith(ROUTES.QUOTE.BUYER_COUNTRY_CHANGE, buyerBasedPost); + expect(get).toHaveBeenCalledWith(ROUTES.QUOTE.BUYER_BODY, buyerBodyGet); + expect(post).toHaveBeenCalledWith(ROUTES.QUOTE.BUYER_BODY, buyerBodyPost); + expect(get).toHaveBeenCalledWith(ROUTES.QUOTE.COMPANY_BASED, companyBasedGet); expect(post).toHaveBeenCalledWith(ROUTES.QUOTE.COMPANY_BASED, companyBasedPost); expect(get).toHaveBeenCalledWith(ROUTES.QUOTE.COMPANY_BASED_CHANGE, companyBasedGet); diff --git a/src/ui/server/routes/quote/index.ts b/src/ui/server/routes/quote/index.ts index b08c538db2..b84d3cb9f4 100644 --- a/src/ui/server/routes/quote/index.ts +++ b/src/ui/server/routes/quote/index.ts @@ -1,6 +1,7 @@ import express from 'express'; import { ROUTES } from '../../constants'; import { get as buyerBasedGet, post as buyerBasedPost } from '../../controllers/quote/buyer-country/index'; +import { get as buyerBodyGet, post as buyerBodyPost } from '../../controllers/quote/buyer-body/index'; import { get as companyBasedGet, post as companyBasedPost } from '../../controllers/quote/company-based'; import { get as ukGoodsOrServicesGet, post as ukGoodsOrServicesPost } from '../../controllers/quote/uk-goods-or-services'; import { get as policyTypeGet, post as policyTypePost } from '../../controllers/quote/policy-type'; @@ -21,6 +22,9 @@ quoteRouter.post(ROUTES.QUOTE.BUYER_COUNTRY, buyerBasedPost); quoteRouter.get(ROUTES.QUOTE.BUYER_COUNTRY_CHANGE, buyerBasedGet); quoteRouter.post(ROUTES.QUOTE.BUYER_COUNTRY_CHANGE, buyerBasedPost); +quoteRouter.get(ROUTES.QUOTE.BUYER_BODY, buyerBodyGet); +quoteRouter.post(ROUTES.QUOTE.BUYER_BODY, buyerBodyPost); + quoteRouter.get(ROUTES.QUOTE.COMPANY_BASED, companyBasedGet); quoteRouter.post(ROUTES.QUOTE.COMPANY_BASED, companyBasedPost); quoteRouter.get(ROUTES.QUOTE.COMPANY_BASED_CHANGE, companyBasedGet); diff --git a/src/ui/server/test-mocks/mock-answers.ts b/src/ui/server/test-mocks/mock-answers.ts index d0de91af38..0e297c64e5 100644 --- a/src/ui/server/test-mocks/mock-answers.ts +++ b/src/ui/server/test-mocks/mock-answers.ts @@ -2,6 +2,7 @@ import { FIELD_IDS, FIELD_VALUES } from '../constants'; import { SubmittedData } from '../../types'; const { + VALID_BUYER_BODY, VALID_COMPANY_BASE, BUYER_COUNTRY, HAS_MINIMUM_UK_GOODS_OR_SERVICES, @@ -14,6 +15,7 @@ const { } = FIELD_IDS; const mockAnswers = { + [VALID_BUYER_BODY]: true, [VALID_COMPANY_BASE]: true, [BUYER_COUNTRY]: 'Algeria', [HAS_MINIMUM_UK_GOODS_OR_SERVICES]: true, diff --git a/src/ui/templates/quote/buyer-body.njk b/src/ui/templates/quote/buyer-body.njk new file mode 100644 index 0000000000..04338eb185 --- /dev/null +++ b/src/ui/templates/quote/buyer-body.njk @@ -0,0 +1,107 @@ +{% extends 'index.njk' %} +{% from "govuk/components/back-link/macro.njk" import govukBackLink %} +{% from 'govuk/components/error-summary/macro.njk' import govukErrorSummary %} +{% from 'govuk/components/radios/macro.njk' import govukRadios %} +{% from "govuk/components/details/macro.njk" import govukDetails %} +{% from 'govuk/components/button/macro.njk' import govukButton %} + +{% block pageTitle %} + {{ CONTENT_STRINGS.PAGE_TITLE }} +{% endblock %} + +{% block content %} + + {{ govukBackLink({ + text: CONTENT_STRINGS.LINKS.BACK, + href: BACK_LINK, + attributes: { + "data-cy": "back-link" + } + }) }} + + {% if validationErrors.summary %} + {{ govukErrorSummary({ + titleText: "There is a problem", + errorList: validationErrors.summary + }) }} + {% endif %} + +
+ +{% endblock %} diff --git a/src/ui/templates/quote/get-a-quote-by-email.njk b/src/ui/templates/quote/get-a-quote-by-email.njk index 598ea9e32c..62b68e1af1 100644 --- a/src/ui/templates/quote/get-a-quote-by-email.njk +++ b/src/ui/templates/quote/get-a-quote-by-email.njk @@ -18,9 +18,13 @@{{ CONTENT_STRINGS.REASON.BODY_1 }}
+ {% if EXIT_REASON %} +{{ CONTENT_STRINGS.REASON.INTRO }} {{ EXIT_REASON }}
+ {% endif %} -{{ CONTENT_STRINGS.REASON.BODY_2 }}
+ {% if EXIT_DESCRIPTION %} +{{ EXIT_DESCRIPTION }}
+ {% endif %} {{detailsText.render({ items: CONTENT_STRINGS.ACTION diff --git a/src/ui/types/required-data-state.ts b/src/ui/types/required-data-state.ts index 48f5ab0950..67e78ff341 100644 --- a/src/ui/types/required-data-state.ts +++ b/src/ui/types/required-data-state.ts @@ -1,6 +1,7 @@ type RequiredDataState = { 'buyer-country': Array