The frontend for the Digital Hub service using Node
Node >= v22
npm install
Create a .env file using the provided template
cp .env-template .env
The .env can then be configured to point to local or remote backend services as required and toggle application features
The application caches certain of the CMS queries in redis cache. To not use redis and instead use memory cache, set ENABLE_REDIS_CACHE=false in your .env file. Alternatively running docker-compose up will spin up a local redis instance.
To point to a locally running Drupal backend application that has been spun up using docker-compose.
Set HUB_API_ENDPOINT=http://localhost:11001 in your .env file.
Feedback uses a Postgres database connection which uses knexjs. If you wish to connect to a Cloud Platform hosted RDS instance follow these steps.
First grab the RDS secrets from the relevant namespace and add to your .env file for later use:
kubectl get secrets prisoner-feedback-rds -o json | jq '.data | map_values(@base64d)'
Create a port-forward pod and connect to it:
kubectl -n <namespace> run feedback-port-forward-pod --image=ministryofjustice/port-forward --port=5432 --env="REMOTE_HOST=<rds_instance_address>" --env="LOCAL_PORT=5432" --env="REMOTE_PORT=5432"
kubectl -n <namespace> port-forward feedback-port-forward-pod 5432:5432
Ensure you have a .env file with the relevant fields populated from the secret:
FEEDBACK_DATABASE_USERNAME=<from secret>
FEEDBACK_DATABASE_PASSWORD=<from secret>
FEEDBACK_DATABASE_URL=localhost
FEEDBACK_DATABASE_NAME=<from secret>
LOCAL_ENV=true
Next download the PEM file for SSL certification from https://truststore.pki.rds.amazonaws.com/global/global-bundle.pem and place in the root of the app folder.
To run this locally you first need to build the CSS and templates:
npm run build
You can then start the app in dev mode with:
npm run dev
The app now takes it's establishment name from the hostname of each request. In order for dev and staging sites to work we use a reg exp /-prisoner-content-hub.*$/g in order to only use the site name, i.e. production uses wayland. whereas staging uses wayland-prisoner-content-hub-staging.. The reg exp ensures wayland will be used in all cases.
When running locally, in order to access the application as if you were at a specific establishment, /etc/hosts will need to be configured so that 127.0.0.1 localhost includes one or more of the following:
bedford.prisoner-content-hub.localberwyn.prisoner-content-hub.localbristol.prisoner-content-hub.localbullingdon.prisoner-content-hub.localcardiff.prisoner-content-hub.localchelmsford.prisoner-content-hub.localcookhamwood.prisoner-content-hub.localetwoe.prisoner-content-hub.localerlestoke.prisoner-content-hub.localfelthama.prisoner-content-hub.localfelthamb.prisoner-content-hub.localgarth.prisoner-content-hub.locallindholme.prisoner-content-hub.localnewhall.prisoner-content-hub.localranby.prisoner-content-hub.localstokeheath.prisoner-content-hub.localstyal.prisoner-content-hub.localswaleside.prisoner-content-hub.localthemount.prisoner-content-hub.localthestudio.prisoner-content-hub.localwayland.prisoner-content-hub.localwerrington.prisoner-content-hub.localwetherby.prisoner-content-hub.localwoodhill.prisoner-content-hub.local
You can then access the application in the browser on http://wetherby.prisoner-content-hub.local:3000 for example.
Jest is used for unit and integration tests
npm run test
Playwright is used for E2E testing with BDD (Behavior-Driven Development) format.
All prison hostnames must be added to your /etc/hosts file (see hostname list above).
All tests (with server and wiremock):
cd e2e
npm run start-uiFeature tests only:
cd e2e
npm run test:featuresAll tests (headless):
cd e2e
npm testDebug mode:
cd e2e
npm run test:debugCI automatically runs all BDD feature tests across all 21 prison environments:
npm run test:e2e:ciThis runs:
- Health check tests (3 scenarios)
- My Prison page tests (5 scenarios)
- Multi-prison tests (63 scenarios across all 21 prisons)
Total: 71 BDD feature tests
The test suite supports all 21 prison environments. Tests automatically detect whether running locally or in CI and use the appropriate domain pattern:
- Local:
*.prisoner-content-hub.local - CI:
*.content-hub.localhost
See e2e/MULTI-PRISON-TESTING.md for detailed documentation.
The server > content > breadcrumbs.json file lists the href and link text for breadcrumb navigation links that are displayed in sections of the site that do not use content from Drupal.
The server > utils > breadcrumbs.js creates breadcrumbs structure for each path defined.
When breadcrumbs are required for a path it should be added within the switch statement in this file.
Import the createBreadcrumbs function into the router
const { createBreadcrumbs } = require('../utils/breadcrumbs');
Pass the breadcrumb data into the view within res.render
return res.render('pages/games/2048', {
...
data: {
breadcrumbs: createBreadcrumbs(req)
},
...
});