From 76fa362ef9a68fd33a5324ad5dcae99ac3e60ec5 Mon Sep 17 00:00:00 2001 From: Precious Onyenaucheya Date: Fri, 23 Aug 2024 07:55:01 +0100 Subject: [PATCH] refactor address input test --- src/components/address-input/_macro.spec.js | 387 ++++++++-------- .../address-input/autosuggest.address.spec.js | 425 +++++++++--------- 2 files changed, 405 insertions(+), 407 deletions(-) diff --git a/src/components/address-input/_macro.spec.js b/src/components/address-input/_macro.spec.js index 6498f09fb5..e1c5c49818 100644 --- a/src/components/address-input/_macro.spec.js +++ b/src/components/address-input/_macro.spec.js @@ -57,16 +57,20 @@ const EXAMPLE_MANUAL_INPUT_FIELDS = { }, }; -describe('macro: address-input', () => { - it('passes jest-axe checks', async () => { - const $ = cheerio.load(renderComponent('address-input', EXAMPLE_AUTOSUGGEST_ADDRESS_MINIMAL)); - - const results = await axe($.html()); - expect(results).toHaveNoViolations(); +describe('FOR: address-input', () => { + describe('GIVEN: Params: none', () => { + describe('WHEN: All params are at default state', () => { + const $ = cheerio.load(renderComponent('address-input', EXAMPLE_AUTOSUGGEST_ADDRESS_MINIMAL)); + + test('THEN: jest-axe tests pass', async () => { + const results = await axe($.html()); + expect(results).toHaveNoViolations(); + }); + }); }); - describe('manual entry of address', () => { - it('has class to hide input fields when automatic search is enabled', () => { + describe('GIVEN: manual entry of address', () => { + describe('WHEN: automatic search is enabled', () => { const $ = cheerio.load( renderComponent('address-input', { ...EXAMPLE_AUTOSUGGEST_ADDRESS_MINIMAL, @@ -75,10 +79,12 @@ describe('macro: address-input', () => { }), ); - expect($('.ons-js-address-input__manual').hasClass('ons-u-db-no-js_enabled')).toBe(true); + test('THEN: it has class to hide input fields', () => { + expect($('.ons-js-address-input__manual').hasClass('ons-u-db-no-js_enabled')).toBe(true); + }); }); - it('does not have class to hide input fields when automatic search is disabled', () => { + describe('WHEN: automatic search is disabled', () => { const $ = cheerio.load( renderComponent('address-input', { ...EXAMPLE_AUTOSUGGEST_ADDRESS_MINIMAL, @@ -87,56 +93,12 @@ describe('macro: address-input', () => { }), ); - expect($('.ons-js-address-input__manual').hasClass('ons-u-db-no-js_enabled')).toBe(false); - }); - - it('renders "organisation" input field with expected parameters', () => { - const faker = templateFaker(); - const inputSpy = faker.spy('input', { suppressOutput: true }); - - faker.renderComponent('address-input', { - ...EXAMPLE_AUTOSUGGEST_ADDRESS_MINIMAL, - ...EXAMPLE_MANUAL_INPUT_FIELDS, - isEditable: true, - }); - - expect(inputSpy.occurrences).toContainEqual({ - id: 'address-input-example-id-organisation', - name: 'address-input-example-id-organisation', - classes: 'ons-js-address-organisation', - label: { - text: 'Organisation name', - }, - value: 'Example Organisation', - width: '20@m', - error: { text: 'Server error: organisation name' }, - }); - }); - - it('renders "address line 1" input field with expected parameters', () => { - const faker = templateFaker(); - const inputSpy = faker.spy('input', { suppressOutput: true }); - - faker.renderComponent('address-input', { - ...EXAMPLE_AUTOSUGGEST_ADDRESS_MINIMAL, - ...EXAMPLE_MANUAL_INPUT_FIELDS, - isEditable: true, - }); - - expect(inputSpy.occurrences).toContainEqual({ - id: 'address-input-example-id-line1', - name: 'address-input-example-id-line1', - classes: 'ons-js-address-line1', - label: { - text: 'Address line 1', - }, - value: 'Flat 12345', - width: '20@m', - error: { text: 'Server error: address line 1' }, + test('THEN: does not have class to hide input fields', () => { + expect($('.ons-js-address-input__manual').hasClass('ons-u-db-no-js_enabled')).toBe(false); }); }); - it('renders "address line 2" input field with expected parameters', () => { + describe('WHEN: manual fields are provided', () => { const faker = templateFaker(); const inputSpy = faker.spy('input', { suppressOutput: true }); @@ -146,67 +108,79 @@ describe('macro: address-input', () => { isEditable: true, }); - expect(inputSpy.occurrences).toContainEqual({ - id: 'address-input-example-id-line2', - name: 'address-input-example-id-line2', - classes: 'ons-js-address-line2', - label: { - text: 'Address line 2', - }, - value: '12345 The Road', - width: '20@m', - error: { text: 'Server error: address line 2' }, + test('THEN: it renders "organisation" input field with expected parameters', () => { + expect(inputSpy.occurrences).toContainEqual({ + id: 'address-input-example-id-organisation', + name: 'address-input-example-id-organisation', + classes: 'ons-js-address-organisation', + label: { + text: 'Organisation name', + }, + value: 'Example Organisation', + width: '20@m', + error: { text: 'Server error: organisation name' }, + }); }); - }); - it('renders "town or city" input field with expected parameters', () => { - const faker = templateFaker(); - const inputSpy = faker.spy('input', { suppressOutput: true }); - - faker.renderComponent('address-input', { - ...EXAMPLE_AUTOSUGGEST_ADDRESS_MINIMAL, - ...EXAMPLE_MANUAL_INPUT_FIELDS, - isEditable: true, + test('THEN: it renders "address line 1" input field with expected parameters', () => { + expect(inputSpy.occurrences).toContainEqual({ + id: 'address-input-example-id-line1', + name: 'address-input-example-id-line1', + classes: 'ons-js-address-line1', + label: { + text: 'Address line 1', + }, + value: 'Flat 12345', + width: '20@m', + error: { text: 'Server error: address line 1' }, + }); }); - expect(inputSpy.occurrences).toContainEqual({ - id: 'address-input-example-id-town', - name: 'address-input-example-id-town', - classes: 'ons-js-address-town', - label: { - text: 'Town or city', - }, - value: 'The Town', - error: { text: 'Server error: town or city' }, + test('THEN: it renders "address line 2" input field with expected parameters', () => { + expect(inputSpy.occurrences).toContainEqual({ + id: 'address-input-example-id-line2', + name: 'address-input-example-id-line2', + classes: 'ons-js-address-line2', + label: { + text: 'Address line 2', + }, + value: '12345 The Road', + width: '20@m', + error: { text: 'Server error: address line 2' }, + }); }); - }); - - it('renders "postcode" input field with expected parameters', () => { - const faker = templateFaker(); - const inputSpy = faker.spy('input', { suppressOutput: true }); - faker.renderComponent('address-input', { - ...EXAMPLE_AUTOSUGGEST_ADDRESS_MINIMAL, - ...EXAMPLE_MANUAL_INPUT_FIELDS, - isEditable: true, + test('THEN: it renders "town or city" input field with expected parameters', () => { + expect(inputSpy.occurrences).toContainEqual({ + id: 'address-input-example-id-town', + name: 'address-input-example-id-town', + classes: 'ons-js-address-town', + label: { + text: 'Town or city', + }, + value: 'The Town', + error: { text: 'Server error: town or city' }, + }); }); - expect(inputSpy.occurrences).toContainEqual({ - id: 'address-input-example-id-postcode', - name: 'address-input-example-id-postcode', - classes: 'ons-js-address-postcode', - label: { - text: 'Postcode', - }, - value: 'PO57 6ODE', - width: '7', - error: { text: 'Server error: postcode' }, + test('THEN: it renders "postcode" input field with expected parameters', () => { + expect(inputSpy.occurrences).toContainEqual({ + id: 'address-input-example-id-postcode', + name: 'address-input-example-id-postcode', + classes: 'ons-js-address-postcode', + label: { + text: 'Postcode', + }, + value: 'PO57 6ODE', + width: '7', + error: { text: 'Server error: postcode' }, + }); }); }); }); - describe('search button for no-js', () => { - it('is not rendered when automatic search is disabled', () => { + describe('GIVEN: search button for no-js', () => { + describe('WHEN: automatic search is disabled', () => { const $ = cheerio.load( renderComponent('address-input', { ...EXAMPLE_AUTOSUGGEST_ADDRESS_MINIMAL, @@ -215,11 +189,12 @@ describe('macro: address-input', () => { searchButton: 'Search for address', }), ); - - expect($('.ons-js-address-search-btn').length).toBe(0); + test('THEN: it does not render', () => { + expect($('.ons-js-address-search-btn').length).toBe(0); + }); }); - it('marks field so that it is displayed only when there is no javascript', () => { + describe('WHEN: there is no javascript', () => { const $ = cheerio.load( renderComponent('address-input', { ...EXAMPLE_AUTOSUGGEST_ADDRESS_MINIMAL, @@ -228,39 +203,35 @@ describe('macro: address-input', () => { }), ); - expect($('.ons-js-address-search-btn').hasClass('ons-u-db-no-js_disabled')).toBe(true); - }); - - it('renders provided text for search button', () => { - const $ = cheerio.load( - renderComponent('address-input', { - ...EXAMPLE_AUTOSUGGEST_ADDRESS_MINIMAL, - isEditable: true, - searchButton: 'Search for address', - }), - ); + test('THEN: it marks field so that it is displayed', () => { + expect($('.ons-js-address-search-btn').hasClass('ons-u-db-no-js_disabled')).toBe(true); + }); - expect($('.ons-js-address-search-btn').text().trim()).toBe('Search for address'); + test('THEN: it renders provided text for search button', () => { + expect($('.ons-js-address-search-btn').text().trim()).toBe('Search for address'); + }); }); }); - describe('hidden field for uprn', () => { - it('renders hidden `input` component with expected parameters when `uprn.value` is not provided', () => { + describe('GIVEN: hidden field for uprn', () => { + describe('WHEN: `uprn.value` is not provided', () => { const faker = templateFaker(); const inputSpy = faker.spy('input', { suppressOutput: true }); faker.renderComponent('address-input', EXAMPLE_AUTOSUGGEST_ADDRESS_MINIMAL); - expect(inputSpy.occurrences).toContainEqual({ - id: 'address-input-example-id-uprn', - classes: 'ons-js-hidden-uprn ons-u-d-no', - type: 'hidden', - name: 'address-input-example-id-uprn', - value: '', + test('THEN: it renders hidden `input` component with expected parameters', () => { + expect(inputSpy.occurrences).toContainEqual({ + id: 'address-input-example-id-uprn', + classes: 'ons-js-hidden-uprn ons-u-d-no', + type: 'hidden', + name: 'address-input-example-id-uprn', + value: '', + }); }); }); - it('renders hidden `input` component with expected parameters when `uprn.value` is provided', () => { + describe('WHEN: `uprn.value` is provided', () => { const faker = templateFaker(); const inputSpy = faker.spy('input', { suppressOutput: true }); @@ -271,18 +242,20 @@ describe('macro: address-input', () => { }, }); - expect(inputSpy.occurrences).toContainEqual({ - id: 'address-input-example-id-uprn', - classes: 'ons-js-hidden-uprn ons-u-d-no', - type: 'hidden', - name: 'address-input-example-id-uprn', - value: '[params.uprn.value]', + test('THEN: it renders hidden `input` component with expected parameters', () => { + expect(inputSpy.occurrences).toContainEqual({ + id: 'address-input-example-id-uprn', + classes: 'ons-js-hidden-uprn ons-u-d-no', + type: 'hidden', + name: 'address-input-example-id-uprn', + value: '[params.uprn.value]', + }); }); }); }); - describe('autosuggest search field', () => { - it('is not shown when `manualEntry` is `true`', () => { + describe('GIVEN: autosuggest search field', () => { + describe('WHEN: `manualEntry` is `true`', () => { const faker = templateFaker(); const autosuggestSpy = faker.spy('autosuggest', { suppressOutput: true }); @@ -291,10 +264,12 @@ describe('macro: address-input', () => { manualEntry: true, }); - expect(autosuggestSpy.occurrences.length).toBe(0); + test('THEN: it is not shown', () => { + expect(autosuggestSpy.occurrences.length).toBe(0); + }); }); - it('renders `autosuggest` component with expected parameters', () => { + describe('WHEN: `manualEntry` is not set', () => { const faker = templateFaker(); const autosuggestSpy = faker.spy('autosuggest', { suppressOutput: true }); @@ -345,57 +320,59 @@ describe('macro: address-input', () => { manualLinkText: '[params.manualLinkText]', }); - expect(autosuggestSpy.occurrences[0]).toEqual({ - id: 'address-input-example-id-autosuggest', - classes: 'ons-address-input__autosuggest ons-u-mb-no', - input: { - width: '50', - label: { - text: '[params.label.text]', - id: '[params.label.id]', - classes: 'ons-js-autosuggest-label', + test('THEN: it renders `autosuggest` component with expected parameters', () => { + expect(autosuggestSpy.occurrences[0]).toEqual({ + id: 'address-input-example-id-autosuggest', + classes: 'ons-address-input__autosuggest ons-u-mb-no', + input: { + width: '50', + label: { + text: '[params.label.text]', + id: '[params.label.id]', + classes: 'ons-js-autosuggest-label', + }, + value: '[params.value]', + attributes: '[params.attributes]', + error: '[params.error]', + name: '[params.name]', + mutuallyExclusive: '[params.mutuallyExclusive]', }, - value: '[params.value]', - attributes: '[params.attributes]', - error: '[params.error]', - name: '[params.name]', - mutuallyExclusive: '[params.mutuallyExclusive]', - }, - externalInitialiser: true, - APIDomain: '[params.APIDomain]', - APIDomainBearerToken: '[params.APIDomainBearerToken]', - APIManualQueryParams: '[params.APIManualQueryParams]', - allowMultiple: '[params.allowMultiple]', - mandatory: '[params.mandatory]', - instructions: '[params.instructions]', - autocomplete: '[params.autocomplete]', - isEditable: '[params.isEditable]', - ariaYouHaveSelected: '[params.ariaYouHaveSelected]', - ariaMinChars: '[params.ariaMinChars]', - minChars: '[params.minChars]', - ariaOneResult: '[params.ariaOneResult]', - ariaNResults: '[params.ariaNResults]', - ariaLimitedResults: '[params.ariaLimitedResults]', - ariaGroupedResults: '[params.ariaGroupedResults]', - groupCount: '[params.groupCount]', - moreResults: '[params.moreResults]', - tooManyResults: '[params.tooManyResults]', - resultsTitle: '[params.resultsTitle]', - resultsTitleId: '[params.resultsTitleId]', - noResults: '[params.noResults]', - typeMore: '[params.typeMore]', - errorTitle: '[params.errorTitle]', - errorMessageEnter: '[params.errorMessageEnter]', - errorMessageSelect: '[params.errorMessageSelect]', - errorMessageAPI: '[params.errorMessageAPI]', - errorMessageAPILinkText: '[params.errorMessageAPILinkText]', - options: '[params.options]', - manualLink: '[params.manualLink]', - manualLinkText: '[params.manualLinkText]', + externalInitialiser: true, + APIDomain: '[params.APIDomain]', + APIDomainBearerToken: '[params.APIDomainBearerToken]', + APIManualQueryParams: '[params.APIManualQueryParams]', + allowMultiple: '[params.allowMultiple]', + mandatory: '[params.mandatory]', + instructions: '[params.instructions]', + autocomplete: '[params.autocomplete]', + isEditable: '[params.isEditable]', + ariaYouHaveSelected: '[params.ariaYouHaveSelected]', + ariaMinChars: '[params.ariaMinChars]', + minChars: '[params.minChars]', + ariaOneResult: '[params.ariaOneResult]', + ariaNResults: '[params.ariaNResults]', + ariaLimitedResults: '[params.ariaLimitedResults]', + ariaGroupedResults: '[params.ariaGroupedResults]', + groupCount: '[params.groupCount]', + moreResults: '[params.moreResults]', + tooManyResults: '[params.tooManyResults]', + resultsTitle: '[params.resultsTitle]', + resultsTitleId: '[params.resultsTitleId]', + noResults: '[params.noResults]', + typeMore: '[params.typeMore]', + errorTitle: '[params.errorTitle]', + errorMessageEnter: '[params.errorMessageEnter]', + errorMessageSelect: '[params.errorMessageSelect]', + errorMessageAPI: '[params.errorMessageAPI]', + errorMessageAPILinkText: '[params.errorMessageAPILinkText]', + options: '[params.options]', + manualLink: '[params.manualLink]', + manualLinkText: '[params.manualLinkText]', + }); }); }); - it('renders manualLinkText` when provided with a default value for `manualLink`', () => { + describe('WHEN: provided with a default value for `manualLink`', () => { const $ = cheerio.load( renderComponent('address-input', { ...EXAMPLE_AUTOSUGGEST_ADDRESS_MINIMAL, @@ -403,11 +380,13 @@ describe('macro: address-input', () => { }), ); - expect($('.ons-js-address-manual-btn').attr('href')).toBe('#0'); - expect($('.ons-js-address-manual-btn').text().trim()).toBe('Manually enter address'); + test('THEN: it renders manualLinkText', () => { + expect($('.ons-js-address-manual-btn').attr('href')).toBe('#0'); + expect($('.ons-js-address-manual-btn').text().trim()).toBe('Manually enter address'); + }); }); - it('renders `manualLinkText` with `manualLink` when provided', () => { + describe('WHEN: a value for `manualLink` is provided', () => { const $ = cheerio.load( renderComponent('address-input', { ...EXAMPLE_AUTOSUGGEST_ADDRESS_MINIMAL, @@ -416,13 +395,15 @@ describe('macro: address-input', () => { }), ); - expect($('.ons-js-address-manual-btn').attr('href')).toBe('https://example.com/edit-address'); - expect($('.ons-js-address-manual-btn').text().trim()).toBe('Manually enter address'); + test('THEN: renders `manualLinkText` with `manualLink`', () => { + expect($('.ons-js-address-manual-btn').attr('href')).toBe('https://example.com/edit-address'); + expect($('.ons-js-address-manual-btn').text().trim()).toBe('Manually enter address'); + }); }); }); - describe('fieldset', () => { - it('does not render `fieldset` component when `dontWrap` is `true`', () => { + describe('GIVEN: fieldset', () => { + describe('WHEN: `dontWrap` is `true`', () => { const faker = templateFaker(); const fieldsetSpy = faker.spy('fieldset', { suppressOutput: true }); @@ -431,10 +412,12 @@ describe('macro: address-input', () => { dontWrap: true, }); - expect(fieldsetSpy.occurrences.length).toBe(0); + test('THEN: it does not render `fieldset` component`', () => { + expect(fieldsetSpy.occurrences.length).toBe(0); + }); }); - it('renders `fieldset` component with expected parameters', () => { + describe('WHEN: `dontWrap` is not set', () => { const faker = templateFaker(); const fieldsetSpy = faker.spy('fieldset', { suppressOutput: true }); @@ -444,11 +427,13 @@ describe('macro: address-input', () => { legendClasses: 'extra-legend-class', }); - expect(fieldsetSpy.occurrences[0]).toEqual({ - id: 'address-input-example-id', - classes: 'extra-field-class', - legend: 'What is the address?', - legendClasses: 'extra-legend-class', + test('THEN: it renders `fieldset` component with expected parameters', () => { + expect(fieldsetSpy.occurrences[0]).toEqual({ + id: 'address-input-example-id', + classes: 'extra-field-class', + legend: 'What is the address?', + legendClasses: 'extra-legend-class', + }); }); }); }); diff --git a/src/components/address-input/autosuggest.address.spec.js b/src/components/address-input/autosuggest.address.spec.js index 065f3f273f..a7e738066f 100644 --- a/src/components/address-input/autosuggest.address.spec.js +++ b/src/components/address-input/autosuggest.address.spec.js @@ -62,7 +62,7 @@ const EXAMPLE_ADDRESS_INPUT_WITH_API = { externalInitialiser: true, }; -describe('script: address-input', () => { +describe('FOR: address-input', () => { const apiFaker = new PuppeteerEndpointFaker(EXAMPLE_ADDRESS_INPUT_WITH_API.APIDomain); apiFaker.setOverrides( @@ -180,85 +180,200 @@ describe('script: address-input', () => { beforeEach(async () => { await apiFaker.reset(); }); + describe('GIVEN: the component initializes', () => { + describe('WHEN: the component initializes without options', () => { + test('THEN: it checks api status by trying a request', async () => { + await setTestPage('/test', renderComponent('address-input', EXAMPLE_ADDRESS_INPUT_WITH_API)); + await page.waitForTimeout(50); - describe('When the component initializes', () => { - it('checks api status by trying a request', async () => { - await setTestPage('/test', renderComponent('address-input', EXAMPLE_ADDRESS_INPUT_WITH_API)); - await page.waitForTimeout(50); + expect(apiFaker.getRequestCount('/addresses/eq?input=cf142&limit=10')).toBe(1); + }); - expect(apiFaker.getRequestCount('/addresses/eq?input=cf142&limit=10')).toBe(1); - }); + describe('WHEN: api status is okay', () => { + beforeEach(async () => { + await setTestPage('/test', renderComponent('address-input', EXAMPLE_ADDRESS_INPUT_WITH_API)); + await page.waitForTimeout(50); + }); - describe('when api status is okay', () => { - beforeEach(async () => { - await setTestPage('/test', renderComponent('address-input', EXAMPLE_ADDRESS_INPUT_WITH_API)); - await page.waitForTimeout(50); + test('THEN: it does not switch to manual input', async () => { + const isManualElementHidden = await page.$eval('.ons-js-address-input__manual', (node) => + node.classList.contains('ons-u-db-no-js_enabled'), + ); + expect(isManualElementHidden).toBe(true); + const isSearchElementHidden = await page.$eval('.ons-js-address-input__search', (node) => + node.classList.contains('ons-u-d-no'), + ); + expect(isSearchElementHidden).toBe(false); + }); }); - it('does not switch to manual input', async () => { - const isManualElementHidden = await page.$eval('.ons-js-address-input__manual', (node) => - node.classList.contains('ons-u-db-no-js_enabled'), - ); - expect(isManualElementHidden).toBe(true); - const isSearchElementHidden = await page.$eval('.ons-js-address-input__search', (node) => - node.classList.contains('ons-u-d-no'), - ); - expect(isSearchElementHidden).toBe(false); + describe('WHEN: api status is not okay', () => { + beforeEach(async () => { + apiFaker.setTemporaryOverride('/addresses/eq?input=cf142&limit=10', { + data: { + status: { code: 401 }, + }, + }); + + await setTestPage('/test', renderComponent('address-input', EXAMPLE_ADDRESS_INPUT_WITH_API)); + await page.waitForTimeout(50); + }); + + test('THEN: it switches to manual input', async () => { + const isManualElementHidden = await page.$eval('.ons-js-address-input__manual', (node) => + node.classList.contains('ons-u-db-no-js_enabled'), + ); + expect(isManualElementHidden).toBe(false); + const isSearchElementHidden = await page.$eval('.ons-js-address-input__search', (node) => + node.classList.contains('ons-u-d-no'), + ); + expect(isSearchElementHidden).toBe(true); + }); + + test('THEN: it hides the search button', async () => { + const hassClass = await page.$eval('.ons-js-address-search-btn', (node) => node.classList.contains('ons-u-d-no')); + expect(hassClass).toBe(true); + }); }); }); - describe('when api status is not okay', () => { + describe.each([ + [ + 'english, epoch, workplace', + '/addresses/eq?input=196%20colle&limit=10&classificationfilter=workplace&eboost=10&epoch=75', + '/addresses/eq/uprn/100070332099?addresstype=paf&epoch=75', + 'en', + { + regionCode: 'gb-eng', + oneYearAgo: true, + addressType: 'workplace', + }, + ], + [ + 'ni, educational', + '/addresses/eq?input=196%20colle&limit=10&classificationfilter=educational&eboost=0&sboost=0&wboost=0', + '/addresses/eq/uprn/100070332099?addresstype=paf', + 'en', + { + regionCode: 'gb-nir', + addressType: 'educational', + }, + ], + [ + 'ni, workplace', + '/addresses/eq?input=196%20colle&limit=10&classificationfilter=workplace&nboost=10', + '/addresses/eq/uprn/100070332099?addresstype=paf', + 'en', + { + regionCode: 'gb-nir', + addressType: 'workplace', + }, + ], + [ + 'wales, workspace', + '/addresses/eq?input=196%20colle&limit=10&classificationfilter=workplace&wboost=10&favourwelsh=true', + '/addresses/eq/uprn/100070332099?addresstype=paf', + 'cy', + { + regionCode: 'gb-wls', + addressType: 'workplace', + }, + ], + ])('WHEN: the component initialises with options - %s', (_, searchEndpoint, uprnEndpoint, lang, options) => { beforeEach(async () => { - apiFaker.setTemporaryOverride('/addresses/eq?input=cf142&limit=10', { + apiFaker.setTemporaryOverride(searchEndpoint, { data: { - status: { code: 401 }, + status: { code: 200 }, + response: { + input: '196 colle', + limit: 10, + addresses: [ + { + uprn: '100070332099', + formattedAddress: '196 College Road, Birmingham, B44 8HF', + addressType: 'PAF', + }, + ], + }, }, }); - await setTestPage('/test', renderComponent('address-input', EXAMPLE_ADDRESS_INPUT_WITH_API)); - await page.waitForTimeout(50); + await setTestPage( + '/test', + renderComponent('address-input', { + ...EXAMPLE_ADDRESS_INPUT_WITH_API, + options, + }), + ); + + const setLangAttribute = (lang) => document.documentElement.setAttribute('lang', lang); + await page.evaluate(setLangAttribute, lang); }); - it('switches to manual input', async () => { - const isManualElementHidden = await page.$eval('.ons-js-address-input__manual', (node) => - node.classList.contains('ons-u-db-no-js_enabled'), - ); - expect(isManualElementHidden).toBe(false); - const isSearchElementHidden = await page.$eval('.ons-js-address-input__search', (node) => - node.classList.contains('ons-u-d-no'), - ); - expect(isSearchElementHidden).toBe(true); + test('THEN: it provides expected parameters to the address API', async () => { + await page.$eval('.ons-js-autosuggest-input', (node) => (node.value = '196 coll')); + await page.type('.ons-js-autosuggest-input', 'e'); + + expect(apiFaker.getRequestCount(searchEndpoint)).toBe(1); }); - it('hides the search button', async () => { - const hassClass = await page.$eval('.ons-js-address-search-btn', (node) => node.classList.contains('ons-u-d-no')); - expect(hassClass).toBe(true); + test('THEN: it requests further information for the selected address from the API with the expected parameters', async () => { + await page.$eval('.ons-js-autosuggest-input', (node) => (node.value = '196 coll')); + await page.type('.ons-js-autosuggest-input', 'e', { delay: 20 }); + await page.keyboard.press('ArrowDown'); + await page.keyboard.press('Enter'); + + await page.waitForTimeout(50); + + expect(apiFaker.getRequestCount(uprnEndpoint)).toBe(1); }); }); }); - describe('When the user inputs', () => { - it('navigates to the first suggestion with the "Down" arrow key', async () => { - await setTestPage('/test', renderComponent('address-input', EXAMPLE_ADDRESS_INPUT_WITH_API)); + describe('GIVEN: the user inputs', () => { + describe('WHEN: the "Down" arrow key is pressed', () => { + beforeEach(async () => { + await setTestPage('/test', renderComponent('address-input', EXAMPLE_ADDRESS_INPUT_WITH_API)); - await page.$eval('.ons-js-autosuggest-input', (node) => (node.value = 'CF14')); - await page.type('.ons-js-autosuggest-input', '2', { delay: 20 }); - await page.keyboard.press('ArrowDown'); + await page.$eval('.ons-js-autosuggest-input', (node) => (node.value = 'CF14')); + await page.type('.ons-js-autosuggest-input', '2', { delay: 20 }); + await page.keyboard.press('ArrowDown'); + }); - const selectedOption = await page.$eval('.ons-autosuggest__option--focused', (node) => node.textContent); - expect(selectedOption.trim()).toBe('196 College Road, Birmingham, B44 8HF'); + test('THEN: it navigates to the first suggestion', async () => { + const selectedOption = await page.$eval('.ons-autosuggest__option--focused', (node) => node.textContent); + expect(selectedOption.trim()).toBe('196 College Road, Birmingham, B44 8HF'); + }); }); - it('provides expected parameters to the address API', async () => { - await setTestPage('/test', renderComponent('address-input', EXAMPLE_ADDRESS_INPUT_WITH_API)); + describe('WHEN: a character is typed', () => { + beforeEach(async () => { + await setTestPage('/test', renderComponent('address-input', EXAMPLE_ADDRESS_INPUT_WITH_API)); + + await page.$eval('.ons-js-autosuggest-input', (node) => (node.value = '196 coll')); + await page.type('.ons-js-autosuggest-input', 'e'); + }); + + test('THEN: it provides expected parameters to the address API', async () => { + expect(apiFaker.getRequestCount('/addresses/eq?input=196%20colle&limit=10')).toBe(1); + }); + }); + + describe('WHEN: the language is Welsh', () => { + beforeEach(async () => { + await setTestPage('/test', renderComponent('address-input', EXAMPLE_ADDRESS_INPUT_WITH_API)); + await page.evaluate(() => document.documentElement.setAttribute('lang', 'cy')); + }); - await page.$eval('.ons-js-autosuggest-input', (node) => (node.value = '196 coll')); - await page.type('.ons-js-autosuggest-input', 'e'); + test('THEN: the fetch url should contain the favour Welsh parameter', async () => { + await page.$eval('.ons-js-autosuggest-input', (node) => (node.value = '196 coll')); + await page.type('.ons-js-autosuggest-input', 'e'); - expect(apiFaker.getRequestCount('/addresses/eq?input=196%20colle&limit=10')).toBe(1); + expect(apiFaker.getRequestCount('/addresses/eq?input=196%20colle&limit=10&favourwelsh=true')).toBe(1); + }); }); - describe('when the value is a full postcode', () => { + describe('WHEN: the value is a full postcode', () => { beforeEach(async () => { await setTestPage('/test', renderComponent('address-input', EXAMPLE_ADDRESS_INPUT_WITH_API)); @@ -266,17 +381,17 @@ describe('script: address-input', () => { await page.type('.ons-js-autosuggest-input', 'T'); }); - it('provides expected parameters to the address API where `limit` is 100', async () => { + test('THEN: it provides expected parameters to the address API where `limit` is 100', async () => { expect(apiFaker.getRequestCount('/addresses/eq?input=cf14%202nt&limit=100&groupfullpostcodes=combo')).toBe(1); }); - it('has expected suggestion entries', async () => { + test('THEN: it has expected suggestion entries', async () => { const suggestions = await page.$$eval('.ons-autosuggest__option', (nodes) => nodes.map((node) => node.textContent.trim())); expect(suggestions).toEqual(['196 College Road, Birmingham, B44 8HF', '196 College Road, Whitchurch, Cardiff, CF14 2NZ']); }); }); - describe('when the query not a partial postcode', () => { + describe('WHEN: the query not a partial postcode', () => { beforeEach(async () => { apiFaker.setTemporaryOverride( '/addresses/eq?input=penlline%20road%20whitchurch%20cardiff%20cf14%202nz&limit=100&groupfullpostcodes=combo', @@ -308,7 +423,7 @@ describe('script: address-input', () => { await page.waitForTimeout(100); }); - it('provides expected parameters to the address API', async () => { + test('THEN: itprovides expected parameters to the address API', async () => { expect( apiFaker.getRequestCount( '/addresses/eq?input=penlline%20road%20whitchurch%20cardiff%20cf14%202nz&limit=100&groupfullpostcodes=combo', @@ -316,7 +431,7 @@ describe('script: address-input', () => { ).toBe(1); }); - it('has expected suggestion entries', async () => { + test('THEN: it has expected suggestion entries', async () => { const suggestions = await page.$$eval('.ons-autosuggest__option', (nodes) => nodes.map((node) => node.textContent.trim())); expect(suggestions).toEqual([ '1 Penlline Road, Whitchurch, Cardiff, CF14 2NZ', @@ -324,18 +439,18 @@ describe('script: address-input', () => { ]); }); - describe('when a suggestion is selected', () => { + describe('WHEN: a suggestion is selected', () => { beforeEach(async () => { await page.keyboard.press('ArrowDown'); await page.keyboard.press('Enter'); await page.waitForTimeout(100); }); - it('makes expected request when a suggestion is selected', async () => { + test('THEN: it makes expected request when a suggestion is selected', async () => { expect(apiFaker.getRequestCount('/addresses/eq/uprn/100070332099?addresstype=paf')).toBe(1); }); - it('populates manual input fields with address from selection', async () => { + test('THEN: it populates manual input fields with address from selection', async () => { expect(await page.$eval('.ons-js-address-organisation', (node) => node.value)).toBe(''); expect(await page.$eval('.ons-js-address-line1', (node) => node.value)).toBe('196 College Road'); expect(await page.$eval('.ons-js-address-line2', (node) => node.value)).toBe('Whitchurch'); @@ -346,7 +461,7 @@ describe('script: address-input', () => { }); }); - describe('when the query is a partial postcode', () => { + describe('WHEN: the query is a partial postcode', () => { beforeEach(async () => { await setTestPage('/test', renderComponent('address-input', EXAMPLE_ADDRESS_INPUT_WITH_API)); @@ -355,11 +470,11 @@ describe('script: address-input', () => { await page.waitForTimeout(200); }); - it('provides expected parameters to the address API', async () => { + test('THEN it provides expected parameters to the address API', async () => { expect(apiFaker.getRequestCount('/addresses/eq?input=cf14%202&limit=10')).toBe(1); }); - it('has expected suggestion entries', async () => { + test('THEN: it has expected suggestion entries', async () => { const suggestions = await page.$$eval('.ons-autosuggest__option', (nodes) => nodes.map((node) => node.textContent.trim())); expect(suggestions).toEqual([ 'Penlline Road, Whitchurch, Cardiff, CF14 2AA (41 addresses)', @@ -367,14 +482,14 @@ describe('script: address-input', () => { ]); }); - describe('when a suggestion is selected', () => { + describe('WHEN: a suggestion is selected', () => { beforeEach(async () => { await page.keyboard.press('ArrowDown'); await page.keyboard.press('Enter'); await page.waitForTimeout(200); }); - it('makes expected request', async () => { + test('THEN: it makes expected request', async () => { expect( apiFaker.getRequestCount( '/addresses/eq/bucket?postcode=CF14%202AA&streetname=Penlline%20Road&townname=Whitchurch&groupfullpostcodes=combo', @@ -382,21 +497,21 @@ describe('script: address-input', () => { ).toBe(1); }); - it('has expected suggestion entries', async () => { + test('THEN: it has expected suggestion entries', async () => { const suggestions = await page.$$eval('.ons-autosuggest__option', (nodes) => nodes.map((node) => node.textContent.trim()), ); expect(suggestions).toEqual(['197 College Road, Whitchurch, Cardiff, CF14 2AB']); }); - describe('when an inner suggestion is selected', () => { + describe('WHEN: an inner suggestion is selected', () => { beforeEach(async () => { await page.keyboard.press('ArrowDown'); await page.keyboard.press('Enter'); await page.waitForTimeout(200); }); - it('populates manual input fields with address from selection', async () => { + test('THEN: it populates manual input fields with address from selection', async () => { expect(await page.$eval('.ons-js-address-organisation', (node) => node.value)).toBe(''); expect(await page.$eval('.ons-js-address-line1', (node) => node.value)).toBe('197 College Road'); expect(await page.$eval('.ons-js-address-line2', (node) => node.value)).toBe('Whitchurch'); @@ -408,8 +523,8 @@ describe('script: address-input', () => { }); }); - describe('when there is an error retrieving the address', () => { - it('switches to manual mode and hides search button', async () => { + describe('WHEN: there is an error retrieving the address', () => { + beforeEach(async () => { apiFaker.setTemporaryOverride('/addresses/eq?input=cf142&limit=10', { data: { status: { code: 200 }, @@ -438,7 +553,9 @@ describe('script: address-input', () => { await page.keyboard.press('ArrowDown'); await page.keyboard.press('Enter'); await page.waitForTimeout(100); + }); + test('THEN: it switches to manual mode and hides search button', async () => { const isManualElementHidden = await page.$eval('.ons-js-address-input__manual', (node) => node.classList.contains('ons-u-db-no-js_enabled'), ); @@ -456,9 +573,9 @@ describe('script: address-input', () => { }); }); - describe('when the form is submitted', () => { - describe('when the selected address is manually changed', () => { - it('clears the urpn field', async () => { + describe('WHEN: the form is submitted', () => { + describe('WHEN: the selected address is manually changed', () => { + test('THEN: clears the urpn field', async () => { await setTestPage( '/test', ` @@ -493,7 +610,7 @@ describe('script: address-input', () => { }); }); - describe('when the submit is invalid', () => { + describe('WHEN: the submit is invalid', () => { beforeEach(async () => { await setTestPage( '/test', @@ -517,18 +634,18 @@ describe('script: address-input', () => { await page.click('button[type=submit]'); }); - it('then an error summary panel should be added to the DOM', async () => { + test('THEN: an error summary panel should be added to the DOM', async () => { const panelExists = await page.$$eval('.ons-js-autosuggest-error-panel', (nodes) => nodes.length === 1); expect(panelExists).toBe(true); }); - it('then input should be wrapped in an error', async () => { + test('THEN: input should be wrapped in an error', async () => { const inputIsError = await page.$$eval('#autosuggest-input-error', (nodes) => nodes.length === 1); expect(inputIsError).toBe(true); }); - describe('when the mode is set to manual', () => { - it('then the error summary should be removed', async () => { + describe('WHEN: the mode is set to manual', () => { + test('THEN: the error summary should be removed', async () => { await page.click('.ons-js-address-manual-btn'); const panelExists = await page.$$eval('.ons-js-autosuggest-error-panel', (nodes) => nodes.length === 1); @@ -539,29 +656,31 @@ describe('script: address-input', () => { }); }); - describe('When the manual link is clicked', () => { + describe('GIVEN: When the manual link is clicked', () => { beforeEach(async () => { await setTestPage('/test', renderComponent('address-input', EXAMPLE_ADDRESS_INPUT_WITH_API)); await page.click('.ons-js-address-manual-btn'); }); - it('shows manual input fields', async () => { - const isManualElementHidden = await page.$eval('.ons-js-address-input__manual', (node) => - node.classList.contains('ons-u-db-no-js_enabled'), - ); - expect(isManualElementHidden).toBe(false); - const isSearchElementHidden = await page.$eval('.ons-js-address-input__search', (node) => - node.classList.contains('ons-u-d-no'), - ); - expect(isSearchElementHidden).toBe(true); - }); + describe('WHEN: the search link is not clicked', () => { + test('THEN: it shows manual input fields', async () => { + const isManualElementHidden = await page.$eval('.ons-js-address-input__manual', (node) => + node.classList.contains('ons-u-db-no-js_enabled'), + ); + expect(isManualElementHidden).toBe(false); + const isSearchElementHidden = await page.$eval('.ons-js-address-input__search', (node) => + node.classList.contains('ons-u-d-no'), + ); + expect(isSearchElementHidden).toBe(true); + }); - it('clears autosuggest input', async () => { - const value = await page.$eval('.ons-js-autosuggest-input', (node) => node.value); - expect(value).toBe(''); + test('THEN: it clears autosuggest input', async () => { + const value = await page.$eval('.ons-js-autosuggest-input', (node) => node.value); + expect(value).toBe(''); + }); }); - describe('and then the search link is clicked', () => { + describe('WHEN: the search link is clicked', () => { beforeEach(async () => { await page.$eval('.ons-js-address-organisation', (node) => (node.value = 'Test organisation')); await page.$eval('.ons-js-address-line1', (node) => (node.value = 'Test address line 1')); @@ -573,7 +692,7 @@ describe('script: address-input', () => { await page.click('.ons-js-address-search-btn'); }); - it('hides manual input fields', async () => { + test('THEN: it hides manual input fields', async () => { const isManualElementHidden = await page.$eval('.ons-js-address-input__manual', (node) => node.classList.contains('ons-u-db-no-js_enabled'), ); @@ -584,7 +703,7 @@ describe('script: address-input', () => { expect(isSearchElementHidden).toBe(false); }); - it('clears manual input fields', async () => { + test('THEN: it clears manual input fields', async () => { expect(await page.$eval('.ons-js-address-organisation', (node) => node.value)).toBe(''); expect(await page.$eval('.ons-js-address-line1', (node) => node.value)).toBe(''); expect(await page.$eval('.ons-js-address-line2', (node) => node.value)).toBe(''); @@ -595,22 +714,8 @@ describe('script: address-input', () => { }); }); - describe('When the language is Welsh', () => { - beforeEach(async () => { - await setTestPage('/test', renderComponent('address-input', EXAMPLE_ADDRESS_INPUT_WITH_API)); - await page.evaluate(() => document.documentElement.setAttribute('lang', 'cy')); - }); - - it('then the fetch url should contain the favour Welsh parameter', async () => { - await page.$eval('.ons-js-autosuggest-input', (node) => (node.value = '196 coll')); - await page.type('.ons-js-autosuggest-input', 'e'); - - expect(apiFaker.getRequestCount('/addresses/eq?input=196%20colle&limit=10&favourwelsh=true')).toBe(1); - }); - }); - - describe('When the component initialises a non-editable address lookup', () => { - describe('when a query is sent and address selected', () => { + describe('GIVEN: the component initialises a non-editable address lookup', () => { + describe('WHEN: a query is sent and address selected', () => { beforeEach(async () => { await setTestPage('/test', renderComponent('address-input', EXAMPLE_ADDRESS_INPUT_WITH_API)); @@ -622,13 +727,13 @@ describe('script: address-input', () => { await page.waitForTimeout(50); }); - it('then the retrieveAddress function will be called', async () => { + test('THEN: the retrieveAddress function will be called', () => { expect(apiFaker.getRequestCount('/addresses/eq/uprn/100070332099?addresstype=paf')).toBe(1); }); }); - describe('when the form is submitted', () => { - describe('when the input is empty', () => { + describe('WHEN: the form is submitted', () => { + describe('WHEN: the input is empty', () => { beforeEach(async () => { await setTestPage( '/test', @@ -645,103 +750,11 @@ describe('script: address-input', () => { await page.click('button[type=submit]'); }); - it('sets aria status message', async () => { + test('THEN: it sets aria status message', async () => { const statusMessage = await page.$eval('.ons-js-autosuggest-aria-status', (node) => node.textContent); expect(statusMessage).toBe('Enter 3 or more characters for suggestions.'); }); }); }); }); - - describe.each([ - [ - 'english, epoch, workplace', - '/addresses/eq?input=196%20colle&limit=10&classificationfilter=workplace&eboost=10&epoch=75', - '/addresses/eq/uprn/100070332099?addresstype=paf&epoch=75', - 'en', - { - regionCode: 'gb-eng', - oneYearAgo: true, - addressType: 'workplace', - }, - ], - [ - 'ni, educational', - '/addresses/eq?input=196%20colle&limit=10&classificationfilter=educational&eboost=0&sboost=0&wboost=0', - '/addresses/eq/uprn/100070332099?addresstype=paf', - 'en', - { - regionCode: 'gb-nir', - addressType: 'educational', - }, - ], - [ - 'ni, workplace', - '/addresses/eq?input=196%20colle&limit=10&classificationfilter=workplace&nboost=10', - '/addresses/eq/uprn/100070332099?addresstype=paf', - 'en', - { - regionCode: 'gb-nir', - addressType: 'workplace', - }, - ], - [ - 'wales, workspace', - '/addresses/eq?input=196%20colle&limit=10&classificationfilter=workplace&wboost=10&favourwelsh=true', - '/addresses/eq/uprn/100070332099?addresstype=paf', - 'cy', - { - regionCode: 'gb-wls', - addressType: 'workplace', - }, - ], - ])('When the component initialises with options - %s', (_, searchEndpoint, uprnEndpoint, lang, options) => { - beforeEach(async () => { - apiFaker.setTemporaryOverride(searchEndpoint, { - data: { - status: { code: 200 }, - response: { - input: '196 colle', - limit: 10, - addresses: [ - { - uprn: '100070332099', - formattedAddress: '196 College Road, Birmingham, B44 8HF', - addressType: 'PAF', - }, - ], - }, - }, - }); - - await setTestPage( - '/test', - renderComponent('address-input', { - ...EXAMPLE_ADDRESS_INPUT_WITH_API, - options, - }), - ); - - const setLangAttribute = (lang) => document.documentElement.setAttribute('lang', lang); - await page.evaluate(setLangAttribute, lang); - }); - - it('provides expected parameters to the address API', async () => { - await page.$eval('.ons-js-autosuggest-input', (node) => (node.value = '196 coll')); - await page.type('.ons-js-autosuggest-input', 'e'); - - expect(apiFaker.getRequestCount(searchEndpoint)).toBe(1); - }); - - it('requests further information for the selected address from the API with the expected parameters', async () => { - await page.$eval('.ons-js-autosuggest-input', (node) => (node.value = '196 coll')); - await page.type('.ons-js-autosuggest-input', 'e', { delay: 20 }); - await page.keyboard.press('ArrowDown'); - await page.keyboard.press('Enter'); - - await page.waitForTimeout(50); - - expect(apiFaker.getRequestCount(uprnEndpoint)).toBe(1); - }); - }); });