From 0d3e234a1172bd30e6eeb77933042dc84bd300a8 Mon Sep 17 00:00:00 2001 From: Robert Parkinson Date: Thu, 18 Jan 2024 10:24:20 +0000 Subject: [PATCH 1/4] Add warning text to view licence page https://eaflood.atlassian.net/browse/WATER-4325 As part of the work to migrate the summary page from the old UI to the new one we need to display a warning when a licence has been revoke, expired or lapsed. From d222fd1143c3ff97cabbbf7bfa8f36d20494096e Mon Sep 17 00:00:00 2001 From: Robert Parkinson Date: Mon, 22 Jan 2024 10:29:44 +0000 Subject: [PATCH 2/4] add function to determine which warning message if any to show --- app/controllers/licences.controller.js | 1 + .../licences/view-licence.presenter.js | 88 +++++- app/views/licences/view.njk | 9 +- .../licences/view-licence.service.test.js | 251 ++++++++++++++++-- 4 files changed, 327 insertions(+), 22 deletions(-) diff --git a/app/controllers/licences.controller.js b/app/controllers/licences.controller.js index d1a477950f..c06a53ebb7 100644 --- a/app/controllers/licences.controller.js +++ b/app/controllers/licences.controller.js @@ -28,6 +28,7 @@ async function view (request, h) { const { id } = request.params const data = await ViewLicenceService.go(id) + console.log(data) return h.view('licences/view.njk', { activeNavBar: 'search', diff --git a/app/presenters/licences/view-licence.presenter.js b/app/presenters/licences/view-licence.presenter.js index b58658a92d..587b69024b 100644 --- a/app/presenters/licences/view-licence.presenter.js +++ b/app/presenters/licences/view-licence.presenter.js @@ -15,22 +15,46 @@ const { formatLongDate } = require('../base.presenter.js') * @returns {Object} The data formatted for the view template */ function go (licence) { - const { expiredDate, id, licenceRef, region, startDate } = licence + const { expiredDate, id, lapsedDate, licenceRef, region, revokedDate, startDate } = licence + const warning = _generateWarningMessage(expiredDate, lapsedDate, revokedDate) return { id, endDate: _endDate(expiredDate), licenceRef, region: region.displayName, - startDate: formatLongDate(startDate) + startDate: formatLongDate(startDate), + warning } } /** - * Formats the expired date of the licence as the end date for the view + * Compares two end dates and chooses the correct one to return + * + * @param {date} firstEndDate - The first date to compare + * + * @param {date} secondEndDate - The second date to compare * * @module ViewLicencePresenter */ +function _compareEndDates (firstEndDate, secondEndDate) { + if (firstEndDate.date.getTime() === secondEndDate.date.getTime()) { + if (firstEndDate.name === 'revoked') return firstEndDate + if (secondEndDate.name === 'revoked') return secondEndDate + if (firstEndDate.name === 'lapsed') return firstEndDate + } else if (firstEndDate.date < secondEndDate.date) { + return firstEndDate + } + return secondEndDate +} + +/** + * Formats the expired date of the licence as the end date for the view + * + * @param {date} expiredDate - The expired date to be formatted if it is in the past + * + * @module ViewLicencePresenter +*/ function _endDate (expiredDate) { if (!expiredDate || expiredDate < Date.now()) { return null @@ -39,6 +63,64 @@ function _endDate (expiredDate) { return formatLongDate(expiredDate) } +/** + * When given up to three possible end dates for a licence this function will determine the correct one to show + * and return it formatted in the standard way + * + * @module ViewLicencePresenter + * + * @param {date} expiredDate - The expired date or null if not present + * + * @param {date} lapsedDate - The lapsed date or null if not present + * + * @param {date} revokedDate - The revoked date or null if not present + * + * @returns {string} The warning message formatted for the view template + */ +function _generateWarningMessage (expiredDate, lapsedDate, revokedDate) { + const endDates = [] + + if (lapsedDate) { + endDates.push({ + name: 'lapsed', + message: `This licence lapsed on ${formatLongDate(lapsedDate)}`, + date: lapsedDate + }) + } + + if (expiredDate) { + endDates.push({ + name: 'expired', + message: `This licence expired on ${formatLongDate(expiredDate)}`, + date: expiredDate + }) + } + + if (revokedDate) { + endDates.push({ + name: 'revoked', + message: `This licence was revoked on ${formatLongDate(revokedDate)}`, + date: revokedDate + }) + } + + if (endDates.length === 0) { + return null + } + + if (endDates.length === 1) { + return endDates[0].message + } + + if (endDates.length > 1) { + return endDates.reduce((result, endDate) => { + return _compareEndDates(result, endDate) + }).message + } + + return null +} + module.exports = { go } diff --git a/app/views/licences/view.njk b/app/views/licences/view.njk index de7d82d4c6..a0b6db3874 100644 --- a/app/views/licences/view.njk +++ b/app/views/licences/view.njk @@ -1,6 +1,7 @@ {% extends 'layout.njk' %} {% from "govuk/components/back-link/macro.njk" import govukBackLink %} {% from "govuk/components/tabs/macro.njk" import govukTabs %} +{% from "govuk/components/warning-text/macro.njk" import govukWarningText %} {% block breadcrumbs %} {{ @@ -31,7 +32,13 @@ {% endset %} {% block content %} -

Licence Number {{ licenceRef }}

+ {% if warning %} + {{ govukWarningText({ + text: warning, + iconFallbackText: "Warning" + }) }} + {% endif %} +

Licence number {{ licenceRef }}

{{ govukTabs({ items: [ diff --git a/test/services/licences/view-licence.service.test.js b/test/services/licences/view-licence.service.test.js index a71be1cc0e..f28fa76826 100644 --- a/test/services/licences/view-licence.service.test.js +++ b/test/services/licences/view-licence.service.test.js @@ -14,7 +14,7 @@ const FetchLicenceService = require('../../../app/services/licences/fetch-licenc // Thing under test const ViewLicenceService = require('../../../app/services/licences/view-licence.service.js') -describe('View Licence service', () => { +describe.only('View Licence service', () => { const testId = '2c80bd22-a005-4cf4-a2a2-73812a9861de' let fetchLicenceResult @@ -23,42 +23,257 @@ describe('View Licence service', () => { }) describe('when a licence with a matching ID exists', () => { - describe('and it has an expired date', () => { + describe('and it does not have an expired, lapsed, or revoke date', () => { beforeEach(() => { fetchLicenceResult = _licenceData() - fetchLicenceResult.expiredDate = new Date('2033-03-07') Sinon.stub(FetchLicenceService, 'go').resolves(fetchLicenceResult) }) it('will return the data and format it for use in the licence summary page', async () => { const result = await ViewLicenceService.go(testId) - expect(result).to.equal({ - id: testId, - licenceRef: '01/130/R01', - region: 'South West', - startDate: '7 March 2013', - endDate: '7 March 2033' - }) + expect(result.warning).to.equal(null) }) }) - describe('and it does not have an expired date', () => { + describe('and it has an expired date, revoked date and lapsed date all in the past on the same day', () => { beforeEach(() => { fetchLicenceResult = _licenceData() + fetchLicenceResult.expiredDate = new Date('2023-03-07') + fetchLicenceResult.lapsedDate = new Date('2023-03-07') + fetchLicenceResult.revokedDate = new Date('2023-03-07') Sinon.stub(FetchLicenceService, 'go').resolves(fetchLicenceResult) }) it('will return the data and format it for use in the licence summary page', async () => { const result = await ViewLicenceService.go(testId) - expect(result).to.equal({ - id: testId, - licenceRef: '01/130/R01', - region: 'South West', - startDate: '7 March 2013', - endDate: null - }) + expect(result.warning).to.equal('This licence was revoked on 7 March 2023') + }) + }) + + describe('and it has no expired date but revoked and lapsed dates are in the past on the same day', () => { + beforeEach(() => { + fetchLicenceResult = _licenceData() + fetchLicenceResult.lapsedDate = new Date('2023-03-07') + fetchLicenceResult.revokedDate = new Date('2023-03-07') + Sinon.stub(FetchLicenceService, 'go').resolves(fetchLicenceResult) + }) + + it('will return the data and format it for use in the licence summary page', async () => { + const result = await ViewLicenceService.go(testId) + + expect(result.warning).to.equal('This licence was revoked on 7 March 2023') + }) + }) + + describe('and it has no lapsed date but expired and revoked dates are in the past on the same day', () => { + beforeEach(() => { + fetchLicenceResult = _licenceData() + fetchLicenceResult.expiredDate = new Date('2023-03-07') + fetchLicenceResult.revokedDate = new Date('2023-03-07') + Sinon.stub(FetchLicenceService, 'go').resolves(fetchLicenceResult) + }) + + it('will return the data and format it for use in the licence summary page', async () => { + const result = await ViewLicenceService.go(testId) + + expect(result.warning).to.equal('This licence was revoked on 7 March 2023') + }) + }) + + describe('and it has no revoked date but expired and lapsed dates are in the past on the same day', () => { + beforeEach(() => { + fetchLicenceResult = _licenceData() + fetchLicenceResult.expiredDate = new Date('2023-03-07') + fetchLicenceResult.lapsedDate = new Date('2023-03-07') + Sinon.stub(FetchLicenceService, 'go').resolves(fetchLicenceResult) + }) + + it('will return the data and format it for use in the licence summary page', async () => { + const result = await ViewLicenceService.go(testId) + + expect(result.warning).to.equal('This licence lapsed on 7 March 2023') + }) + }) + + describe('and it only has an expired date', () => { + beforeEach(() => { + fetchLicenceResult = _licenceData() + fetchLicenceResult.expiredDate = new Date('2023-03-07') + Sinon.stub(FetchLicenceService, 'go').resolves(fetchLicenceResult) + }) + + it('will return the data and format it for use in the licence summary page', async () => { + const result = await ViewLicenceService.go(testId) + + expect(result.warning).to.equal('This licence expired on 7 March 2023') + }) + }) + + describe('and it only has a lapsed date', () => { + beforeEach(() => { + fetchLicenceResult = _licenceData() + fetchLicenceResult.lapsedDate = new Date('2023-03-07') + Sinon.stub(FetchLicenceService, 'go').resolves(fetchLicenceResult) + }) + + it('will return the data and format it for use in the licence summary page', async () => { + const result = await ViewLicenceService.go(testId) + + expect(result.warning).to.equal('This licence lapsed on 7 March 2023') + }) + }) + + describe('and it only has a revoked date', () => { + beforeEach(() => { + fetchLicenceResult = _licenceData() + fetchLicenceResult.revokedDate = new Date('2023-03-07') + Sinon.stub(FetchLicenceService, 'go').resolves(fetchLicenceResult) + }) + + it('will return the data and format it for use in the licence summary page', async () => { + const result = await ViewLicenceService.go(testId) + + expect(result.warning).to.equal('This licence was revoked on 7 March 2023') + }) + }) + + describe('and it has an expired and revoked date with expired being earlier', () => { + beforeEach(() => { + fetchLicenceResult = _licenceData() + fetchLicenceResult.revokedDate = new Date('2023-03-07') + fetchLicenceResult.expiredDate = new Date('2023-02-07') + Sinon.stub(FetchLicenceService, 'go').resolves(fetchLicenceResult) + }) + + it('will return the data and format it for use in the licence summary page', async () => { + const result = await ViewLicenceService.go(testId) + + expect(result.warning).to.equal('This licence expired on 7 February 2023') + }) + }) + + describe('and it has an expired and lapsed date with expired being earlier', () => { + beforeEach(() => { + fetchLicenceResult = _licenceData() + fetchLicenceResult.expiredDate = new Date('2023-02-07') + fetchLicenceResult.lapsedDate = new Date('2023-03-07') + Sinon.stub(FetchLicenceService, 'go').resolves(fetchLicenceResult) + }) + + it('will return the data and format it for use in the licence summary page', async () => { + const result = await ViewLicenceService.go(testId) + + expect(result.warning).to.equal('This licence expired on 7 February 2023') + }) + }) + + describe('and it has an expired and lapsed date with lapsed being earlier', () => { + beforeEach(() => { + fetchLicenceResult = _licenceData() + fetchLicenceResult.expiredDate = new Date('2023-03-07') + fetchLicenceResult.lapsedDate = new Date('2023-02-07') + Sinon.stub(FetchLicenceService, 'go').resolves(fetchLicenceResult) + }) + + it('will return the data and format it for use in the licence summary page', async () => { + const result = await ViewLicenceService.go(testId) + + expect(result.warning).to.equal('This licence lapsed on 7 February 2023') + }) + }) + + describe('and it has an expired and revoked date with revoked being earlier', () => { + beforeEach(() => { + fetchLicenceResult = _licenceData() + fetchLicenceResult.expiredDate = new Date('2023-03-07') + fetchLicenceResult.revokedDate = new Date('2023-02-07') + Sinon.stub(FetchLicenceService, 'go').resolves(fetchLicenceResult) + }) + + it('will return the data and format it for use in the licence summary page', async () => { + const result = await ViewLicenceService.go(testId) + + expect(result.warning).to.equal('This licence was revoked on 7 February 2023') + }) + }) + + describe('and it has a revoked and lapsed date with lapsed being earlier', () => { + beforeEach(() => { + fetchLicenceResult = _licenceData() + fetchLicenceResult.lapsedDate = new Date('2023-02-07') + fetchLicenceResult.revokedDate = new Date('2023-03-07') + Sinon.stub(FetchLicenceService, 'go').resolves(fetchLicenceResult) + }) + + it('will return the data and format it for use in the licence summary page', async () => { + const result = await ViewLicenceService.go(testId) + + expect(result.warning).to.equal('This licence lapsed on 7 February 2023') + }) + }) + + describe('and it has a revoked and lapsed date with revoked being earlier', () => { + beforeEach(() => { + fetchLicenceResult = _licenceData() + fetchLicenceResult.revokedDate = new Date('2023-02-07') + fetchLicenceResult.lapsedDate = new Date('2023-03-07') + Sinon.stub(FetchLicenceService, 'go').resolves(fetchLicenceResult) + }) + + it('will return the data and format it for use in the licence summary page', async () => { + const result = await ViewLicenceService.go(testId) + + expect(result.warning).to.equal('This licence was revoked on 7 February 2023') + }) + }) + + describe('and it has a revoked, expired and lapsed date with revoked being earlier', () => { + beforeEach(() => { + fetchLicenceResult = _licenceData() + fetchLicenceResult.revokedDate = new Date('2023-02-07') + fetchLicenceResult.lapsedDate = new Date('2023-03-07') + fetchLicenceResult.expiredDate = new Date('2023-03-07') + Sinon.stub(FetchLicenceService, 'go').resolves(fetchLicenceResult) + }) + + it('will return the data and format it for use in the licence summary page', async () => { + const result = await ViewLicenceService.go(testId) + + expect(result.warning).to.equal('This licence was revoked on 7 February 2023') + }) + }) + + describe('and it has a revoked, expired and lapsed date with expired being earlier', () => { + beforeEach(() => { + fetchLicenceResult = _licenceData() + fetchLicenceResult.revokedDate = new Date('2023-03-07') + fetchLicenceResult.lapsedDate = new Date('2023-03-07') + fetchLicenceResult.expiredDate = new Date('2023-02-07') + Sinon.stub(FetchLicenceService, 'go').resolves(fetchLicenceResult) + }) + + it('will return the data and format it for use in the licence summary page', async () => { + const result = await ViewLicenceService.go(testId) + + expect(result.warning).to.equal('This licence expired on 7 February 2023') + }) + }) + + describe('and it has a revoked, expired and lapsed date with lapsed being earlier', () => { + beforeEach(() => { + fetchLicenceResult = _licenceData() + fetchLicenceResult.revokedDate = new Date('2023-03-07') + fetchLicenceResult.lapsedDate = new Date('2023-02-07') + fetchLicenceResult.expiredDate = new Date('2023-03-07') + Sinon.stub(FetchLicenceService, 'go').resolves(fetchLicenceResult) + }) + + it('will return the data and format it for use in the licence summary page', async () => { + const result = await ViewLicenceService.go(testId) + + expect(result.warning).to.equal('This licence lapsed on 7 February 2023') }) }) }) From dd04c69b69f49bd263619b13c7953b2efa3d0a8e Mon Sep 17 00:00:00 2001 From: Robert Parkinson Date: Mon, 22 Jan 2024 10:35:06 +0000 Subject: [PATCH 3/4] remove .only --- test/services/licences/view-licence.service.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/services/licences/view-licence.service.test.js b/test/services/licences/view-licence.service.test.js index f28fa76826..5577a0b914 100644 --- a/test/services/licences/view-licence.service.test.js +++ b/test/services/licences/view-licence.service.test.js @@ -14,7 +14,7 @@ const FetchLicenceService = require('../../../app/services/licences/fetch-licenc // Thing under test const ViewLicenceService = require('../../../app/services/licences/view-licence.service.js') -describe.only('View Licence service', () => { +describe('View Licence service', () => { const testId = '2c80bd22-a005-4cf4-a2a2-73812a9861de' let fetchLicenceResult From 1e25bb1182d25a3336e0ce5c24b26a6175e795e0 Mon Sep 17 00:00:00 2001 From: Robert Parkinson Date: Mon, 22 Jan 2024 14:08:41 +0000 Subject: [PATCH 4/4] remove console log and jsdoc comments --- app/controllers/licences.controller.js | 1 - .../licences/view-licence.presenter.js | 40 ++----------------- 2 files changed, 4 insertions(+), 37 deletions(-) diff --git a/app/controllers/licences.controller.js b/app/controllers/licences.controller.js index c06a53ebb7..d1a477950f 100644 --- a/app/controllers/licences.controller.js +++ b/app/controllers/licences.controller.js @@ -28,7 +28,6 @@ async function view (request, h) { const { id } = request.params const data = await ViewLicenceService.go(id) - console.log(data) return h.view('licences/view.njk', { activeNavBar: 'search', diff --git a/app/presenters/licences/view-licence.presenter.js b/app/presenters/licences/view-licence.presenter.js index 587b69024b..da092b1e20 100644 --- a/app/presenters/licences/view-licence.presenter.js +++ b/app/presenters/licences/view-licence.presenter.js @@ -28,15 +28,6 @@ function go (licence) { } } -/** - * Compares two end dates and chooses the correct one to return - * - * @param {date} firstEndDate - The first date to compare - * - * @param {date} secondEndDate - The second date to compare - * - * @module ViewLicencePresenter - */ function _compareEndDates (firstEndDate, secondEndDate) { if (firstEndDate.date.getTime() === secondEndDate.date.getTime()) { if (firstEndDate.name === 'revoked') return firstEndDate @@ -48,13 +39,6 @@ function _compareEndDates (firstEndDate, secondEndDate) { return secondEndDate } -/** - * Formats the expired date of the licence as the end date for the view - * - * @param {date} expiredDate - The expired date to be formatted if it is in the past - * - * @module ViewLicencePresenter -*/ function _endDate (expiredDate) { if (!expiredDate || expiredDate < Date.now()) { return null @@ -63,20 +47,6 @@ function _endDate (expiredDate) { return formatLongDate(expiredDate) } -/** - * When given up to three possible end dates for a licence this function will determine the correct one to show - * and return it formatted in the standard way - * - * @module ViewLicencePresenter - * - * @param {date} expiredDate - The expired date or null if not present - * - * @param {date} lapsedDate - The lapsed date or null if not present - * - * @param {date} revokedDate - The revoked date or null if not present - * - * @returns {string} The warning message formatted for the view template - */ function _generateWarningMessage (expiredDate, lapsedDate, revokedDate) { const endDates = [] @@ -112,13 +82,11 @@ function _generateWarningMessage (expiredDate, lapsedDate, revokedDate) { return endDates[0].message } - if (endDates.length > 1) { - return endDates.reduce((result, endDate) => { - return _compareEndDates(result, endDate) - }).message - } + const earliestPriorityEndDate = endDates.reduce((result, endDate) => { + return _compareEndDates(result, endDate) + }) - return null + return earliestPriorityEndDate.message } module.exports = {