From 9703336e9b6bb485231d9c105648263af01de837 Mon Sep 17 00:00:00 2001 From: Rhodine Orleans-Lindsay <43888758+Rhodine-orleans-lindsay@users.noreply.github.com> Date: Tue, 13 Aug 2024 21:59:11 +0100 Subject: [PATCH] pr review fixes - fix typos/syntax issues - add JSDoc and try/catch block to session timeout warning component - add hof logger to session timeout warning component - remove beta version in package.json - - amend content for session timeout warning readme and move it out of components folder into main readme to make it easier for users to find - update yarn.lock --- README.md | 49 +++++++++++++++++- components/session-timeout-warning/Readme.md | 43 ---------------- components/session-timeout-warning/index.js | 28 ++++++++-- package.json | 2 +- .../session-timeout-warning.spec.js | 51 +++++++++---------- test/frontend/jest/sessionDialog.test.js | 3 +- yarn.lock | 6 +-- 7 files changed, 102 insertions(+), 80 deletions(-) delete mode 100644 components/session-timeout-warning/Readme.md diff --git a/README.md b/README.md index feb33c19..26d36405 100644 --- a/README.md +++ b/README.md @@ -945,7 +945,7 @@ Using the translation key `fields.field-name.label` will return different values # HOF Components -## Date Component +# Date Component A component for handling the rendering and processing of 3-input date fields used in HOF Applications. @@ -1255,6 +1255,53 @@ transportOptions: { Disables sending email. No options are required. +# Session Timeout Warning Component +HOF component for customising session timeout related pages +This feature allows you to customise the content related to the session timeout warning, including the messages displayed in the session timeout warning dialog and on the exit page after a user exits the form due to a session timeout. + +## Usage + +To enable and customize the session timeout behavior, you need to set the component in your project's `hof.settings.json` file: +```js + "behaviours": [ + "hof/components/session-timeout-warning" + ] +``` + +By default, the framework uses the standard content provided by HOF. If you wish to override this with custom content at the project level, you must set the following variables to `true` in `hof.settings.json`: + +```js + behaviours: [ + require('../').components.sessionTimeoutWarning + ], + sessionTimeoutWarningContent: true, + exitFormContent: true +``` + +## Customising content in `pages.json` +Once the variables are set, you can customize the session timeout warning and exit messages in your project's pages.json: + +```json +"exit": { + "message": "We have cleared your information to keep it secure. Your information has not been saved." +}, +"session-timeout-warning": { + "dialog-title": "Your application will close soon", + "dialog-text": "If that happens, your progress will not be saved.", + "timeout-continue-button": "Stay on this page", + "dialog-exit-link": "Exit this form" +} +``` + +## Editing content on the Exit Page Header and Title +To edit the exit page's header and title, create an `exit.json` file in your project and set the desired content: +```json +{ + "header": "You have left this form", + "title": "You have left this form" +} +``` + # UTILITIES # Autofill Utility diff --git a/components/session-timeout-warning/Readme.md b/components/session-timeout-warning/Readme.md deleted file mode 100644 index ee1e045f..00000000 --- a/components/session-timeout-warning/Readme.md +++ /dev/null @@ -1,43 +0,0 @@ -# Session Timeout Warning Behaviour - -## What this does -Makes the content related to the session timeout warning behaviour customisable. This includes the content in the session timeout warning dialog and on the exit page after the user clicks to exit the form from the session timeout warning dialog. - -The component should be set in the project's hof.settings.json -``` - "behaviours": [ - "hof/components/session-timeout-warning" - ] -``` - -By default,the default content from the hof framework. If you require customised content at a project level, the following variables must be set to true in hof.settings.json - -``` - behaviours: [ - require('../').components.sessionTimeoutWarning - ], - sessionTimeoutWarningContent: true, - exitFormContent: true -``` - -You can then set the content in the project's pages.json - -``` -"exit": { - "message": "We have cleared your information to keep it secure. Your information has not been saved." -}, -"session-timeout-warning": { - "dialog-title": "Your application will close soon", - "dialog-text": "If that happens, your progress will not be saved.", - "timeout-continue-button": "Stay on this page", - "dialog-exit-link": "Exit this form" -} -``` - -To customise the exit page's header and title, you can create an exit.json file and set the content: -``` -{ - "header": "You have left this form", - "title": "You have left this form" -} -``` diff --git a/components/session-timeout-warning/index.js b/components/session-timeout-warning/index.js index 6494dd2a..5c6a55ed 100644 --- a/components/session-timeout-warning/index.js +++ b/components/session-timeout-warning/index.js @@ -1,14 +1,34 @@ +/** + * + * @fileOverview + * Provides custom behavior for handling session timeout warnings and exit actions. This includes + * - Resetting the session if the user exits due to a session timeout. + * - Customizing the session timeout warning dialog content. + * - Setting custom content and titles on the exit page. + * + * @module SessionTimeoutBehavior + * @requires ../../config/hof-defaults + * @param {Class} superclass - The class to be extended. + * @returns {Class} - The extended class with session timeout handling functionality. + */ 'use strict'; const config = require('../../config/hof-defaults'); +const logger = require('../../lib/logger')(config); module.exports = superclass => class extends superclass { configure(req, res, next) { - // reset the session if user chooses to exit on session timeout warning - if (req.form.options.route === '/exit') { - req.sessionModel.reset(); + try { + // Reset the session if the user chooses to exit on session timeout warning + if (req.form.options.route === '/exit') { + req.sessionModel.reset(); + logger.log('info', 'Session has been reset on exit'); + } + return super.configure(req, res, next); + } catch (error) { + logger.error('Error during session reset:', error); + return next(error); // Pass the error to the next middleware for centralised handling } - return super.configure(req, res, next); } locals(req, res) { diff --git a/package.json b/package.json index 32cc40cb..2d361d76 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "hof", "description": "A bootstrap for HOF projects", - "version": "22.0.0-timeout-warning-beta.13", + "version": "22.0.0", "license": "MIT", "main": "index.js", "author": "HomeOffice", diff --git a/test/components/session-timeout-warning.spec.js b/test/components/session-timeout-warning.spec.js index 305e037f..5a16f464 100644 --- a/test/components/session-timeout-warning.spec.js +++ b/test/components/session-timeout-warning.spec.js @@ -1,6 +1,6 @@ 'use strict'; -const Component = require('../../components').sessionTimeoutWarning; +const { sessionTimeoutWarning: Component } = require('../../components'); const config = require('../../config/hof-defaults'); describe('session timeout warning component', () => { @@ -22,6 +22,7 @@ describe('session timeout warning component', () => { req.sessionModel.reset = resetStub; next = sinon.stub(); }); + describe("The 'configure' method ", () => { beforeEach(() => { sinon.stub(Base.prototype, 'configure').returns(req, res, next); @@ -50,7 +51,7 @@ describe('session timeout warning component', () => { afterEach(() => { - Base.prototype.configure.restore(); + sinon.restore(); }); }); @@ -64,26 +65,28 @@ describe('session timeout warning component', () => { res.locals = { sessionTimeoutWarningContent: true }; - instance.locals(req, res); - instance.locals(req, res).should.have.property('dialogTitle') - .and.deep.equal(true); - instance.locals(req, res).should.have.property('dialogText') - .and.deep.equal(true); - instance.locals(req, res).should.have.property('timeoutContinueButton') - .and.deep.equal(true); - instance.locals(req, res).should.have.property('dialogExitLink') - .and.deep.equal(true); + const locals = instance.locals(req, res); + const checkDialogProperties = expected => { + locals.should.have.property('dialogTitle').and.deep.equal(expected); + locals.should.have.property('dialogText').and.deep.equal(expected); + locals.should.have.property('timeoutContinueButton').and.deep.equal(expected); + locals.should.have.property('dialogExitLink').and.deep.equal(expected); + }; + checkDialogProperties(true); }); it('does not set the dialog content to true if locals.sessionTimeoutWarningContent is set to false', () => { res.locals = { sessionTimeoutWarningContent: false }; - instance.locals(req, res); - instance.locals(req, res).should.not.have.property('dialogTitle'); - instance.locals(req, res).should.not.have.property('dialogText'); - instance.locals(req, res).should.not.have.property('timeoutContinueButton'); - instance.locals(req, res).should.not.have.property('dialogExitLink'); + const locals = instance.locals(req, res); + const checkDialogProperties = () => { + locals.should.not.have.property('dialogTitle'); + locals.should.not.have.property('dialogText'); + locals.should.not.have.property('timeoutContinueButton'); + locals.should.not.have.property('dialogExitLink'); + }; + checkDialogProperties(); }); it('sets the custom content to true on the exit page if exitFormContent is set to true', () => { @@ -93,9 +96,8 @@ describe('session timeout warning component', () => { route: '/exit' } }; - instance.locals(req, res); - instance.locals(req, res).should.have.property('exitFormContent') - .and.deep.equal(true); + const locals = instance.locals(req, res); + locals.should.have.property('exitFormContent').and.deep.equal(true); }); it('does sets the default content on the exit page if exitFormContent is set to false', () => { @@ -105,13 +107,10 @@ describe('session timeout warning component', () => { route: '/exit' } }; - instance.locals(req, res); - instance.locals(req, res).should.have.property('header') - .and.deep.equal('exit.header'); - instance.locals(req, res).should.have.property('title') - .and.deep.equal('exit.title'); - instance.locals(req, res).should.have.property('message') - .and.deep.equal('exit.message'); + const locals = instance.locals(req, res); + locals.should.have.property('header').and.deep.equal('exit.header'); + locals.should.have.property('title').and.deep.equal('exit.title'); + locals.should.have.property('message').and.deep.equal('exit.message'); }); afterEach(() => { diff --git a/test/frontend/jest/sessionDialog.test.js b/test/frontend/jest/sessionDialog.test.js index 2eb65814..1a980b25 100644 --- a/test/frontend/jest/sessionDialog.test.js +++ b/test/frontend/jest/sessionDialog.test.js @@ -6,8 +6,7 @@ const fs = require('fs'); const path = require('path'); const sessionTimeoutWarningHtml = fs.readFileSync(path.resolve(__dirname, '../../../frontend/template-partials/views/partials/session-timeout-warning.html'), 'utf8'); -jest - .dontMock('fs'); +jest.dontMock('fs'); describe('sessionDialog', () => { let sessionDialog; diff --git a/yarn.lock b/yarn.lock index dbfa5e5b..dc67caa5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1766,9 +1766,9 @@ aws4@^1.8.0: integrity sha512-3AungXC4I8kKsS9PuS4JH2nc+0bVY/mjgrephHTIi8fpEeGsTHBUJeosp0Wc1myYMElmD0B3Oc4XL/HVJ4PV2g== axios@^1.5.1, axios@^1.6.1: - version "1.7.2" - resolved "https://registry.yarnpkg.com/axios/-/axios-1.7.2.tgz#b625db8a7051fbea61c35a3cbb3a1daa7b9c7621" - integrity sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw== + version "1.7.4" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.7.4.tgz#4c8ded1b43683c8dd362973c393f3ede24052aa2" + integrity sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw== dependencies: follow-redirects "^1.15.6" form-data "^4.0.0"