From 78e09024f9171695e39c24834927cd2b1521744a Mon Sep 17 00:00:00 2001 From: Tedd Mason Date: Thu, 11 Jan 2024 14:58:26 +0000 Subject: [PATCH] adding some initial pages, and unit test framework for hapi server --- .jest/setup.js | 29 +++++++++ .vscode/launch.json | 16 ++++- package-lock.json | 1 + package.json | 9 ++- server/__test-helpers__/on-pre-auth.js | 19 ++++++ server/__test-helpers__/server-options.js | 15 +++++ server/__test-helpers__/server.js | 35 ++++++++++ server/plugins/views.js | 1 + server/routes/__tests__/home.spec.js | 12 ++++ server/routes/home.js | 2 +- .../{welcome.js => report-water-pollution.js} | 8 +-- server/utils/constants.js | 4 +- server/views/footer.html | 18 ++++++ server/views/layout.html | 32 ++-------- server/views/report-water-pollution.html | 46 +++++++++++++ server/views/welcome.html | 64 ------------------- 16 files changed, 211 insertions(+), 100 deletions(-) create mode 100644 .jest/setup.js create mode 100644 server/__test-helpers__/on-pre-auth.js create mode 100644 server/__test-helpers__/server-options.js create mode 100644 server/__test-helpers__/server.js create mode 100644 server/routes/__tests__/home.spec.js rename server/routes/{welcome.js => report-water-pollution.js} (58%) create mode 100644 server/views/footer.html create mode 100644 server/views/report-water-pollution.html delete mode 100644 server/views/welcome.html diff --git a/.jest/setup.js b/.jest/setup.js new file mode 100644 index 00000000..2827bd6f --- /dev/null +++ b/.jest/setup.js @@ -0,0 +1,29 @@ +import { createServer, init } from "../server/index.js" +import serverOptions from '../server/__test-helpers__/server-options.js' +const ORIGINAL_ENV = process.env + +let server, context + +beforeEach(async () => { + jest.resetAllMocks() + // add any common mockage here, eg json POSTs + server = await createServer(serverOptions) + await init(server) +}) + +afterEach(async () => { + try { + if (server) { + await server.stop() + } + } finally { + // reset environment variables after test + process.env = { ...ORIGINAL_ENV } + } +}) + +const getServer = () => server + +const getContext = () => context + +export { getServer, getContext } diff --git a/.vscode/launch.json b/.vscode/launch.json index d145e1ed..7e8a5384 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -18,7 +18,14 @@ "type": "node", "request": "launch", "name": "Jest All", - "program": "${workspaceFolder}/node_modules/.bin/jest" + "program": "${workspaceFolder}/node_modules/.bin/jest", + "args": [ + "--runInBand", + "--testTimeout", + "999999", + "--silent=false" + ], + "outputCapture": "std" }, { "type": "node", @@ -26,8 +33,13 @@ "name": "Jest Current File", "program": "${workspaceFolder}/node_modules/.bin/jest", "args": [ + "--runInBand", + "--testTimeout", + "999999", + "--silent=false", "${fileBasenameNoExtension}" - ] + ], + "outputCapture": "std" } ] } \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index cc451074..3dce1e27 100644 --- a/package-lock.json +++ b/package-lock.json @@ -39,6 +39,7 @@ }, "devDependencies": { "@babel/preset-env": "^7.23.8", + "@hapi/catbox-memory": "^6.0.1", "concurrently": "^8.2.2", "husky": "^8.0.3", "jest": "^29.7.0", diff --git a/package.json b/package.json index 0dff167f..5f143527 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "watch:nodejs": "nodemon --delay 1000ms --signal SIGTERM -r dotenv/config index.js", "dev": "concurrently 'npm:watch:css' 'npm:watch:nodejs'", "lint": "standard", - "unit-test": "jest --verbose", + "unit-test": "jest --runInBand --verbose", "test": "npm run lint && npm run unit-test", "prettier": "prettier-config-standard", "prepare": "husky install", @@ -64,6 +64,7 @@ }, "devDependencies": { "@babel/preset-env": "^7.23.8", + "@hapi/catbox-memory": "^6.0.1", "concurrently": "^8.2.2", "husky": "^8.0.3", "jest": "^29.7.0", @@ -107,6 +108,12 @@ ], "setupFiles": [ "./.jest/test.env.js" + ], + "setupFilesAfterEnv": [ + "./.jest/setup.js" + ], + "testPathIgnorePatterns": [ + "__test-helpers__" ] } } diff --git a/server/__test-helpers__/on-pre-auth.js b/server/__test-helpers__/on-pre-auth.js new file mode 100644 index 00000000..7a78c1df --- /dev/null +++ b/server/__test-helpers__/on-pre-auth.js @@ -0,0 +1,19 @@ +// import application from '../__mock-data__/test-application.js' + +// Adds pre auth functionality to server that loads session with mock application data or sessionData object provided from test. +// This should really be done in a pre handler but only one pre handler can be registered with a Hapi.js server. +const onPreAuth = (sessionData) => { + return { + plugin: { + name: 'on-pre-auth', + register: (server, _options) => { + server.ext('onPreAuth', function (request, h) { + // request.yar._store = sessionData || JSON.parse(application.dataString) + return h.continue + }) + } + } + } +} + +export default onPreAuth diff --git a/server/__test-helpers__/server-options.js b/server/__test-helpers__/server-options.js new file mode 100644 index 00000000..db9d3f73 --- /dev/null +++ b/server/__test-helpers__/server-options.js @@ -0,0 +1,15 @@ +import { Engine } from '@hapi/catbox-memory' + +// use catbox-memory cache strategy for testing +const serverOptions = { + cache: [ + { + name: 'redis_cache', + provider: { + constructor: Engine + } + } + ] +} + +export default serverOptions diff --git a/server/__test-helpers__/server.js b/server/__test-helpers__/server.js new file mode 100644 index 00000000..9fe001f9 --- /dev/null +++ b/server/__test-helpers__/server.js @@ -0,0 +1,35 @@ +import { getServer } from '../../.jest/setup.js' +import onPreAuth from './on-pre-auth.js' + +const submitGetRequest = async (options, expectedResponseCode = 200, sessionData) => { + // await addOnPreAuth(sessionData) + options.method = 'GET' + return submitRequest(options, expectedResponseCode) +} + +const submitPostRequest = async (options, expectedResponseCode = 302, sessionData) => { + if (sessionData && Object.keys(sessionData).length > 0) { + await addOnPreAuth(sessionData) + } + options.method = 'POST' + return submitRequest(options, expectedResponseCode) +} + +const submitRequest = async (options, expectedResponseCode) => { + const response = await getServer().inject(options) + expect(response.statusCode).toBe(expectedResponseCode) + return response +} + +const addOnPreAuth = async (sessionData) => { + // Add session injection using on pre auth functionality. + // This shoud be done using a pre handler but only one pre handler can be registered + // with a Hapi.js server. + // Using on pre auth functionaliy is acceptable for testing purposes. + await getServer().register(onPreAuth(sessionData)) +} + +export { + submitGetRequest, + submitPostRequest +} diff --git a/server/plugins/views.js b/server/plugins/views.js index c040bac2..3fff4f21 100644 --- a/server/plugins/views.js +++ b/server/plugins/views.js @@ -41,6 +41,7 @@ export default { serviceNameUrl: constants.urls.GOV_UK_SERVICE_HOME, serviceName: config.serviceName, pageTitle: `${config.serviceName} - GOV.UK`, + titleSuffix: ' - GOV.UK', analyticsAccount } } diff --git a/server/routes/__tests__/home.spec.js b/server/routes/__tests__/home.spec.js new file mode 100644 index 00000000..a24613f8 --- /dev/null +++ b/server/routes/__tests__/home.spec.js @@ -0,0 +1,12 @@ +import { submitGetRequest } from '../../__test-helpers__/server.js' +import constants from '../../utils/constants.js' +const url = '/' + +describe(url, () => { + describe('GET', () => { + it(`Should redirect to ${constants.routes.REPORT_WATER_POLLUTION}`, async () => { + await submitGetRequest({ url }, 302) + expect(true) + }) + }) +}) diff --git a/server/routes/home.js b/server/routes/home.js index c43841c9..0d96507d 100644 --- a/server/routes/home.js +++ b/server/routes/home.js @@ -1,7 +1,7 @@ import constants from '../utils/constants.js' const handlers = { - get: async (_request, h) => h.redirect(constants.routes.WELCOME) + get: async (_request, h) => h.redirect(constants.routes.REPORT_WATER_POLUTION) } export default [ diff --git a/server/routes/welcome.js b/server/routes/report-water-pollution.js similarity index 58% rename from server/routes/welcome.js rename to server/routes/report-water-pollution.js index 95f28f26..017a6037 100644 --- a/server/routes/welcome.js +++ b/server/routes/report-water-pollution.js @@ -1,9 +1,9 @@ import constants from '../utils/constants.js' const handlers = { - get: async (request, h) => { + get: async (_request, h) => { const context = _getContext() - return h.view(constants.views.WELCOME, { + return h.view(constants.views.REPORT_WATER_POLUTION, { ...context }) } @@ -11,7 +11,7 @@ const handlers = { const _getContext = () => { return { - pageTitle: 'Report an environmental incident', + pageHeading: 'Report water pollution in England', hideBackLink: true } } @@ -19,7 +19,7 @@ const _getContext = () => { export default [ { method: 'GET', - path: constants.routes.WELCOME, + path: constants.routes.REPORT_WATER_POLUTION, handler: handlers.get } ] diff --git a/server/utils/constants.js b/server/utils/constants.js index 17a061eb..890c4c7b 100644 --- a/server/utils/constants.js +++ b/server/utils/constants.js @@ -10,7 +10,7 @@ const COOKIES = 'notices/cookies' const PRIVACY = 'notices/privacy' const PUBLIC = 'public' -const WELCOME = 'welcome' +const REPORT_WATER_POLUTION = 'report-water-pollution' const HOME = 'home' const INCIDENT_TYPE = 'incident-type' const WATER_TYPE = 'water-quality/water-type' @@ -20,7 +20,7 @@ const routes = { COOKIES, PRIVACY, PUBLIC, - WELCOME, + REPORT_WATER_POLUTION, HOME, INCIDENT_TYPE, WATER_TYPE diff --git a/server/views/footer.html b/server/views/footer.html new file mode 100644 index 00000000..df930aea --- /dev/null +++ b/server/views/footer.html @@ -0,0 +1,18 @@ +{{ govukFooter({ + meta: { + items: [ + { + href: "/notices/privacy", + text: "Privacy notice" + }, + { + href: "/notices/cookies", + text: "Cookies" + }, + { + href: "/notices/accessibility", + text: "Accessibility statement" + } + ] + } +}) }} \ No newline at end of file diff --git a/server/views/layout.html b/server/views/layout.html index 0ec7801e..a9e6cfa2 100644 --- a/server/views/layout.html +++ b/server/views/layout.html @@ -6,6 +6,7 @@ + @@ -25,25 +26,21 @@ {% block header %} {{ govukHeader({ - homepageUrl: govUkHome, + homepageUrl: "/", containerClasses: "govuk-width-container", serviceName: serviceName, - serviceUrl: serviceNameUrl + serviceUrl: "/" }) }} {% endblock %} {% block pageTitle %} - {% if fieldErrors %} - Error: - {% endif %} - - {{ pageTitle }} - {{ serviceName }} – GOV.UK + {% if err %} Error: {% endif %} {{ pageHeading }} {{ titleSuffix }} {% endblock %} {% block beforeContent %} {{ govukPhaseBanner({ tag: { - text: "Alpha" + text: "beta" }, html: 'This is a new service – give feedback (opens new tab) to help us to improve it.' }) }} @@ -71,24 +68,7 @@

Default page template

{% endblock %} {% block footer %} - {{ govukFooter({ - meta: { - items: [ - { - href: "/notices/privacy", - text: "Privacy notice" - }, - { - href: "/notices/cookies", - text: "Cookies" - }, - { - href: "/notices/accessibility", - text: "Accessibility statement" - } - ] - } - }) }} + {% include "footer.html" %} {% endblock %} {% block bodyEnd %} diff --git a/server/views/report-water-pollution.html b/server/views/report-water-pollution.html new file mode 100644 index 00000000..7c3f7b2d --- /dev/null +++ b/server/views/report-water-pollution.html @@ -0,0 +1,46 @@ +{% extends 'form-layout.html' %} + +{% set pageHeading = 'Report water pollution in England' %} + +{% block content %} + +
+
+

+ Report water pollution +

+

Use this service to report pollution in the sea, lakes, reservoirs, rivers or other watercourses in England.

+

Pollution can include:

+
    +
  • sewage
  • +
  • 'run-off' from farms
  • +
  • discharges from industry
  • +
  • leaks from objects in the river, such as vehicles
  • +
+ +

Before you start

+

You need to be able to describe the location of the pollution or we will not be able to investigate it.

+
Do not use this service to report littering in rivers. Contact your local council instead.
+ {{ govukButton({ + text: "Start now", + isStartButton: true + }) }} +

If you cannot report online

+

You can report the problem to the Environment Agency over the phone.

+
+

Environment Agency incident hotline
+ Telephone: 0800 80 70 60
+ 24 hours

+
+

Other problems with your environment

+

How you report other problems affecting the environment depends on the type of problem it is and where it's happening. You may have to report it to: +

    +
  • the Environment Agency
  • +
  • your local council
  • +
  • your utilities company
  • +
+

Find out how to report other problems with your environment

+
+
+ +{% endblock %} diff --git a/server/views/welcome.html b/server/views/welcome.html deleted file mode 100644 index 9c8ed8b4..00000000 --- a/server/views/welcome.html +++ /dev/null @@ -1,64 +0,0 @@ -{% extends 'form-layout.html' %} -{% set pageName="Home" %} -{% block content %} - -
-
- -

- {{ serviceName }} -

-

Use this service to report:

- -
    -
  • dirty or polluted water
  • -
  • unusual or unpleasant smells
  • -
  • poaching or illegal fishing
  • -
  • flooding or risk of flooding from major rivers or the sea
  • -
-

You do not have to give any personal details if you do not want to.

- -
- Do not use this service to report fly-tipping - report fly-tipping to your local council.
- - {{ govukButton({ - text: "Start now", - href: "/incident-type", - isStartButton: true - }) }} -

Other environmental issues or reporting by phone

-

You can report the following issues to the Environment Agency over the phone, including:

-
    -
  • damage to major rivers or river banks
  • -
  • dead fish
  • -
  • flooding or risk of flooding from major rivers or the sea
  • -
  • people taking water illegally from the environment
  • -
  • incidents at waste sites
  • -
  • poaching or illegal fishing
  • -
  • pollution
  • -
  • changes in river levels or flow
  • -
-
-
    -
  • Environment Agency incident hotline
  • -
  • Telephone: 020 7946 0101
  • -
  • 24 hours
  • -
-
-

Other incidents

-

Report the following issues directly to your council or utilities company:

- -
-
- -{% endblock %}