UNPKG

@defra-fish/gafl-webapp-service

Version:

The websales frontend for the GAFL service

352 lines (305 loc) • 13.6 kB
import pageHandler from '../page-handler.js' import journeyDefinition from '../../routes/journey-definition.js' import { addLanguageCodeToUri } from '../../processors/uri-helper.js' import { welshEnabledAndApplied } from '../../processors/page-language-helper.js' import GetDataRedirect from '../get-data-redirect.js' import { ANALYTICS } from '../../constants.js' import { AGREED, IDENTIFY, LICENCE_DETAILS, LICENCE_FOR, ORDER_COMPLETE, PAYMENT_CANCELLED, PAYMENT_FAILED } from '../../uri.js' import { trackGTM } from '../analytics-handler.js' jest.mock('../../routes/journey-definition.js', () => []) jest.mock('../../processors/uri-helper.js') jest.mock('../../processors/page-language-helper.js') jest.mock('../analytics-handler.js', () => ({ trackGTM: jest.fn() })) jest.mock('../../constants', () => ({ ANALYTICS: { selected: 'chosen-one', acceptTracking: 'you-may-watch-me', seenMessage: 'seen-it', omitPageFromAnalytics: 'no-tracky', pageSkipped: 'ignored-page' }, PAGE_STATE: { completed: true, error: false } })) jest.mock('../../uri.js', () => ({ AGREED: { uri: '/buy/agreed/page' }, LICENCE_DETAILS: { uri: '/buy/licence/details' }, ORDER_COMPLETE: { uri: '/buy/order/complete/page' }, PAYMENT_CANCELLED: { uri: '/buy/payment/cancelled/page' }, PAYMENT_FAILED: { uri: '/buy/payment/failed/page' }, PROCESS_ANALYTICS_PREFERENCES: { uri: '/buy/process/analytics/preferences/page' }, LICENCE_FOR: { uri: '/buy/licence-for' }, IDENTIFY: { uri: '/buy/renew/identify' } })) describe('The page handler function', () => { beforeEach(() => { jest.resetAllMocks() journeyDefinition.length = 0 }) it('the get method re-throws any exceptions which are not transaction errors ', async () => { const request = getMockRequest() const getData = async () => { throw new Error('Random exception') } try { await pageHandler(null, null, null, getData).get(request) } catch (err) { expect(err.message).toBe('Random exception') } }) it('the error method re-throws any exceptions which are not transaction errors ', async () => { const request = getMockRequest({ setCurrentPermission: () => { throw new Error('Random exception') } }) try { await pageHandler().error(request, null, { details: [] }) } catch (err) { expect(err.message).toBe('Random exception') } }) it.each([['/previous/page'], ['/last/page']])('get calls addLanguageCodeToUri with request and backLink', async previousPage => { const backLink = () => previousPage journeyDefinition.push({ current: { page: 'view' }, backLink }) const { get } = pageHandler(null, 'view', '/next/page') const request = getMockRequest(undefined, '/this/page') const toolkit = getMockToolkit() await get(request, toolkit) expect(addLanguageCodeToUri).toHaveBeenCalledWith(request, backLink()) }) it.each([[() => '/last/page'], ['previous/page']])( 'pageData.backRef from get uses value generated by addLanguageCodeToUri', async backLink => { journeyDefinition.push({ current: { page: 'view' }, backLink }) const { get } = pageHandler(null, 'view', '/next/page') const returnValue = Symbol('/previous/page') addLanguageCodeToUri.mockReturnValueOnce(returnValue) const toolkit = getMockToolkit() await get(getMockRequest(), toolkit) expect(toolkit.view).toHaveBeenCalledWith( expect.any(String), expect.objectContaining({ backRef: returnValue }) ) } ) it('pageData.backRef is null if backLink is null', async () => { const backLink = () => {} journeyDefinition.push({ current: { page: 'view' }, backLink }) const { get } = pageHandler(null, 'view', '/next/page') const returnValue = Symbol('/previous/page') addLanguageCodeToUri.mockReturnValueOnce(returnValue) const toolkit = getMockToolkit() await get(getMockRequest(), toolkit) expect(toolkit.view).toHaveBeenCalledWith( expect.any(String), expect.objectContaining({ backRef: null }) ) }) it('GetDataRedirect being thrown will redirectWithLanguageCode to the target', async () => { journeyDefinition.push({ current: { page: 'view' }, backLink: '/previous/page' }) const url = Symbol('/go/somewhere/else') const getData = () => { throw new GetDataRedirect(url) } const { get } = pageHandler(null, 'view', '/next/page', getData) const request = getMockRequest() const toolkit = getMockToolkit() await get(request, toolkit) expect(toolkit.redirectWithLanguageCode).toHaveBeenCalledWith(url) }) it.each([['/route/one'], ['/route/sixty-six']])('error redirects with language code', async url => { const { error } = pageHandler('', 'view') const request = getMockRequest(undefined, url) const toolkit = getMockToolkit() await error(request, toolkit, { details: [] }) expect(toolkit.redirectWithLanguageCode).toHaveBeenCalledWith() }) it('sets the value of pageData with displayAnalytics true', async () => { addLanguageCodeToUri.mockReturnValueOnce('/buy/process-analytics-preferences') welshEnabledAndApplied.mockReturnValueOnce(false) trackGTM.mockReturnValueOnce(false) const { get } = pageHandler('', 'view', '/next/page') const toolkit = getMockToolkit() await get(getMockRequest(), toolkit) expect(toolkit.view).toMatchSnapshot() }) it('sets the value of pageData with displayAnalytics false', async () => { addLanguageCodeToUri.mockReturnValueOnce('/buy/process-analytics-preferences') welshEnabledAndApplied.mockReturnValueOnce(false) trackGTM.mockReturnValueOnce(false) const { get } = pageHandler('', 'view', '/next/page') const toolkit = getMockToolkit() await get(getMockRequest({ path: '/we/are/here' }), toolkit) expect(toolkit.view).toMatchSnapshot() }) it('sets the value of gtmContainerId to the GTM_CONTAINER_ID env var', async () => { const expectedValue = 'expected' process.env.GTM_CONTAINER_ID = expectedValue const { get } = pageHandler('', 'view', '/next/page') const toolkit = getMockToolkit() await get(getMockRequest(), toolkit) expect(toolkit.view).toHaveBeenCalledWith( expect.any(String), expect.objectContaining({ gtmContainerId: expectedValue }) ) delete process.env.GTM_CONTAINER_ID }) it.each([false, true])('sets the value of approvedGTM as %s when trackGTM returns same', async gtm => { trackGTM.mockReturnValueOnce(gtm) const { get } = pageHandler('', 'view', '/next/page') const toolkit = getMockToolkit() await get(getMockRequest(), toolkit) expect(toolkit.view).toHaveBeenCalledWith( expect.any(String), expect.objectContaining({ approvedGTM: gtm }) ) delete process.env.GTM_CONTAINER_ID }) it.each([ ['payment cancelled', PAYMENT_CANCELLED.uri], ['payment failed', PAYMENT_FAILED.uri], ['agreed', AGREED.uri], ['order complete', ORDER_COMPLETE.uri], ['licence details', LICENCE_DETAILS.uri] ])('hides the analytics banner for %s page', async (_pageLabel, path) => { const { get } = pageHandler('', 'view', '/next/page') const toolkit = getMockToolkit() const mockRequest = getMockRequest({ path }) await get(mockRequest, toolkit) const pageData = toolkit.view.mock.calls[0][1] expect(pageData.displayAnalytics).toBeFalsy() }) it('sets analytics values to default values if analytics key is not set', async () => { const { get } = pageHandler('', 'view', '/next/page') const toolkit = getMockToolkit() const mockRequest = getMockRequest('/current/page', false) await get(mockRequest, toolkit) const pageData = toolkit.view.mock.calls[0][1] expect(pageData).toEqual( expect.objectContaining({ analyticsMessageDisplayed: false, analyticsSelected: false, acceptedTracking: false }) ) }) it.each([[PAYMENT_CANCELLED.uri], [PAYMENT_FAILED.uri], [AGREED.uri], [ORDER_COMPLETE.uri], [LICENCE_DETAILS.uri]])( 'sets journeyBeginning is not set if not on licence_for or identify page', async pageUri => { const { get } = pageHandler('', 'view', '/next/page') const toolkit = getMockToolkit() const mockRequest = getMockRequest(pageUri) await get(mockRequest, toolkit) const pageData = toolkit.view.mock.calls[0][1] expect(pageData).toEqual( expect.not.objectContaining({ journeyBeginning: true }) ) } ) it.each([[IDENTIFY.uri], [LICENCE_FOR.uri]])('sets journeyBeginning to true if on licence_for or identify page', async path => { const { get } = pageHandler('', 'view', '/next/page') const toolkit = getMockToolkit() const mockRequest = getMockRequest({ path }) await get(mockRequest, toolkit) const pageData = toolkit.view.mock.calls[0][1] expect(pageData).toEqual( expect.objectContaining({ journeyBeginning: true }) ) }) it.each([['/next/page'], ['/another/page']])( 'post method called redirectWithLanguageCode with completion value when completion is a string', async pageUri => { const { post } = pageHandler('', 'view', pageUri) const toolkit = getMockToolkit() const mockRequest = getMockRequest() await post(mockRequest, toolkit) expect(toolkit.redirectWithLanguageCode).toHaveBeenCalledWith(pageUri) } ) describe('omitPageFromAnalytics', () => { it.each` desc | values | result ${'undefined: omitPageFromAnalytics property is set to false'} | ${{}} | ${{ [ANALYTICS.omitPageFromAnalytics]: false }} ${'defined with pageSkip property not equal to true, seenMessage property equals true and omitPageFromAnalytics property not equal to true: omitPageFromAnalytics and pageSkipped property is set to true'} | ${{ [ANALYTICS.seenMessage]: 'seen-message' }} | ${{ [ANALYTICS.omitPageFromAnalytics]: true, [ANALYTICS.pageSkipped]: true }} ${'defined, pageSkip property equals true, seenMessage property equals true and omitPageFromAnalytics property not equal to true: omitPageFromAnalytics property is set to false'} | ${{ [ANALYTICS.omitPageFromAnalytics]: true, [ANALYTICS.seenMessage]: 'seen-message' }} | ${{ [ANALYTICS.omitPageFromAnalytics]: false }} ${'defined, pageSkip property not equal to true, seenMessage property not equal to true and omitPageFromAnalytics property not equal to true: omitPageFromAnalytics property is set to false'} | ${{ [ANALYTICS.seenMessage]: false }} | ${{ [ANALYTICS.omitPageFromAnalytics]: false }} ${'defined, pageSkip property not equal to true, seenMessage property equals true and omitPageFromAnalytics property equals true: omitPageFromAnalytics property is set to false'} | ${{ [ANALYTICS.seenMessage]: 'seen-message', [ANALYTICS.pageSkipped]: true }} | ${{ [ANALYTICS.omitPageFromAnalytics]: false }} `('when analytics cache is $desc', async ({ values, result }) => { const set = jest.fn() const analytics = getAnalytics(values) const { get } = pageHandler('', 'view', 'next-page') const toolkit = getMockToolkit() const mockRequest = getMockRequest({ analytics, set }) await get(mockRequest, toolkit) expect(set).toBeCalledWith(result) }) }) describe('pageLanguageSetToWelsh', () => { it('returns the value of welshEnabledAndApplied', async () => { const expectedValue = Symbol('expected') welshEnabledAndApplied.mockReturnValueOnce(expectedValue) const { get } = pageHandler('', 'view', '/next/page') const toolkit = getMockToolkit() await get(getMockRequest(), toolkit) expect(toolkit.view).toHaveBeenCalledWith( expect.any(String), expect.objectContaining({ pageLanguageSetToWelsh: expectedValue }) ) }) }) }) const getAnalytics = overides => ({ [ANALYTICS.acceptTracking]: 'accepted-tracking', [ANALYTICS.selected]: 'selected', ...overides }) const getMockRequest = ({ setCurrentPermission = () => {}, path = '/buy/we/are/here', analytics, set = () => {} } = {}) => ({ cache: () => ({ helpers: { page: { getCurrentPermission: () => ({}), setCurrentPermission }, status: { getCurrentPermission: () => ({}), setCurrentPermission: () => {} }, transaction: { getCurrentPermission: () => {} }, analytics: { get: async () => analytics, set } } }), i18n: { getCatalog: () => {}, getLocales: () => [], getLocale: () => '' }, path, url: { search: '' } }) const getMockToolkit = () => ({ redirectWithLanguageCode: jest.fn(() => ({ takeover: () => {} })), view: jest.fn() })