From bf04bb7b8a249de0665b245cc4e67a3b1ab76d98 Mon Sep 17 00:00:00 2001 From: Jonathan Goulding <58443816+jonathangoulding@users.noreply.github.com> Date: Thu, 16 May 2024 15:41:41 +0100 Subject: [PATCH 1/4] View licence contact details title format (#1028) --- app/views/licences/tabs/contact-details.njk | 2 +- test/controllers/licences.controller.test.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/views/licences/tabs/contact-details.njk b/app/views/licences/tabs/contact-details.njk index 43a6aa90ae..d941427e2f 100644 --- a/app/views/licences/tabs/contact-details.njk +++ b/app/views/licences/tabs/contact-details.njk @@ -1,4 +1,4 @@ -

Contact Details

+

Contact details

{% if customerId %}

Go to customer contacts

diff --git a/test/controllers/licences.controller.test.js b/test/controllers/licences.controller.test.js index 3e9da1d040..28e225b11a 100644 --- a/test/controllers/licences.controller.test.js +++ b/test/controllers/licences.controller.test.js @@ -221,7 +221,7 @@ describe('Licences controller', () => { const response = await server.inject(options) expect(response.statusCode).to.equal(200) - expect(response.payload).to.contain('Contact Details') + expect(response.payload).to.contain('Contact details') // Table row titles expect(response.payload).to.contain('Name') expect(response.payload).to.contain('Communication type') @@ -242,7 +242,7 @@ describe('Licences controller', () => { const response = await server.inject(options) expect(response.statusCode).to.equal(200) - expect(response.payload).to.contain('Contact Details') + expect(response.payload).to.contain('Contact details') expect(response.payload).to.contain('No contacts found.') }) }) From dd92b8cc07de72f084ef7039709ae25a80b4e535 Mon Sep 17 00:00:00 2001 From: Roble Date: Thu, 16 May 2024 15:48:53 +0100 Subject: [PATCH 2/4] Remove returns requirements button on check page (#1021) * Remove returns requirements button on check page https://eaflood.atlassian.net/browse/WATER-4304 When setting up a requirement for returns, a user can now add multiple requirements. As a result of being able to add more requirements, errors can occur where unwanted requirements have been added for a return. Users need the flexibility to remove a single requirement on the check page without having to cancel the entire return through the [Cancel these return requirements] (https://eaflood.atlassian.net/browse/WATER-4302) button. Users must also be notified of the removed requirement when redirected to the check page. This PR expands on [Remove these return requirements] (https://eaflood.atlassian.net/browse/WATER-4304 ) and implements a button to redirect users to the remove page where requirements can be removed one by one. Yar notifications are also added in this PR to notify users of a successfully removed requirement. --- .../return-requirements.controller.js | 2 +- .../submit-remove.service.js | 11 ++++++++++- app/views/return-requirements/check.njk | 9 +++++++-- .../submit-remove.service.test.js | 17 ++++++++++++++++- 4 files changed, 34 insertions(+), 5 deletions(-) diff --git a/app/controllers/return-requirements.controller.js b/app/controllers/return-requirements.controller.js index f42e327551..cb651d0288 100644 --- a/app/controllers/return-requirements.controller.js +++ b/app/controllers/return-requirements.controller.js @@ -396,7 +396,7 @@ async function submitReason (request, h) { async function submitRemove (request, h) { const { requirementIndex, sessionId } = request.params - await SubmitRemoveService.go(sessionId, requirementIndex) + await SubmitRemoveService.go(sessionId, requirementIndex, request.yar) return h.redirect(`/system/return-requirements/${sessionId}/check`) } diff --git a/app/services/return-requirements/submit-remove.service.js b/app/services/return-requirements/submit-remove.service.js index 1eb7606179..39d21029f0 100644 --- a/app/services/return-requirements/submit-remove.service.js +++ b/app/services/return-requirements/submit-remove.service.js @@ -14,12 +14,21 @@ const SessionModel = require('../../models/session.model.js') * is deleted from the session in the database. * * @param {string} sessionId - The UUID for the return requirement setup session record + * @param {number} requirementIndex - The index of the requirement being removed + * @param {Object} yar - The Hapi `request.yar` session manager passed on by the controller * * @returns {Promise} the promise returned is not intended to resolve to any particular value */ -async function go (sessionId, requirementIndex) { +async function go (sessionId, requirementIndex, yar) { const session = await SessionModel.query().findById(sessionId) + const notification = { + title: 'Removed', + text: 'Requirement removed' + } + + yar.flash('notification', notification) + return _removeRequirementFromSession(session, requirementIndex) } diff --git a/app/views/return-requirements/check.njk b/app/views/return-requirements/check.njk index a63271bba9..6bdf0d60c1 100644 --- a/app/views/return-requirements/check.njk +++ b/app/views/return-requirements/check.njk @@ -113,8 +113,13 @@ {# Set an easier to use index #} {% set rowIndex = loop.index0 %}
-

{{requirement.siteDescription}}

-

Remove {{rowIndex}}

+

{{requirement.siteDescription}}

+ {{ govukButton({ + text: "Remove requirement", + classes: "govuk-button--warning", + preventDoubleClick: true, + href: "/system/return-requirements/" + sessionId + "/remove/" + rowIndex + }) }}
{% endfor %} diff --git a/test/services/return-requirements/submit-remove.service.test.js b/test/services/return-requirements/submit-remove.service.test.js index a964277ce2..b7b706d278 100644 --- a/test/services/return-requirements/submit-remove.service.test.js +++ b/test/services/return-requirements/submit-remove.service.test.js @@ -3,6 +3,7 @@ // Test framework dependencies const Lab = require('@hapi/lab') const Code = require('@hapi/code') +const Sinon = require('sinon') const { describe, it, beforeEach } = exports.lab = Lab.script() const { expect } = Code @@ -18,6 +19,7 @@ describe('Return Requirements - Submit Remove service', () => { const requirementIndex = 0 let session + let yarStub beforeEach(async () => { await DatabaseSupport.clean() @@ -60,15 +62,28 @@ describe('Return Requirements - Submit Remove service', () => { reason: 'major-change' } }) + + yarStub = { + flash: Sinon.stub() + } }) describe('when a user submits the return requirements to be removed', () => { it('deletes the selected requirement from the session data', async () => { - await SubmitRemoveService.go(session.id, requirementIndex) + await SubmitRemoveService.go(session.id, requirementIndex, yarStub) const refreshedSession = await session.$query() expect(refreshedSession.requirements[requirementIndex]).not.to.exist() }) + + it("sets the notification message to 'Requirements removed'", async () => { + await SubmitRemoveService.go(session.id, requirementIndex, yarStub) + + const [flashType, notification] = yarStub.flash.args[0] + + expect(flashType).to.equal('notification') + expect(notification).to.equal({ title: 'Removed', text: 'Requirement removed' }) + }) }) }) From 7dd4aee95b2ca01f22839edd726584654673b288 Mon Sep 17 00:00:00 2001 From: Robert Parkinson Date: Thu, 16 May 2024 16:10:24 +0100 Subject: [PATCH 3/4] Refactor to use computed error message (#1026) https://eaflood.atlassian.net/browse/WATER-4295 As part of our work to get the requirements for returns set up we need to know which of the points the user has selected in the manual journey so that we can then get the information later at the check your answers page. This PR refactors the error on the page to use the computed value from the validator --- app/views/return-requirements/points.njk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/return-requirements/points.njk b/app/views/return-requirements/points.njk index 9c384909b6..40ba4e9c74 100644 --- a/app/views/return-requirements/points.njk +++ b/app/views/return-requirements/points.njk @@ -21,7 +21,7 @@ titleText: "There is a problem", errorList: [ { - text: "Select any points for the return requirement", + text: error.text, href: "#points" } ] From 7bf5dae50ab3aafe306b8e350c431ca557c5f12f Mon Sep 17 00:00:00 2001 From: Jason Claxton <30830544+Jozzey@users.noreply.github.com> Date: Thu, 16 May 2024 16:21:06 +0100 Subject: [PATCH 4/4] Fix QA issues found with the review adjustment factors validation (#1027) https://eaflood.atlassian.net/browse/WATER-4439 During QA it was found that the error message for when a factor greater than 1 is entered was incorrect in the ticket & subsequently on the page. It used to read "factor must be less than 1". When it should have read "factor must be equal to or less than 1". Also the ticket originally specified that the Charge Adjustment should be validated to 2DP. This was incorrect, it should be validated to 15DP like the Aggregate factor. These two issues will be corrected in this ticket. --- ...ubmit-amended-adjustment-factor.service.js | 2 +- .../adjustment-factor.validator.js | 4 +- .../adjustment-factor.validator.test.js | 41 ++++++++----------- 3 files changed, 21 insertions(+), 26 deletions(-) diff --git a/app/services/bill-runs/two-part-tariff/submit-amended-adjustment-factor.service.js b/app/services/bill-runs/two-part-tariff/submit-amended-adjustment-factor.service.js index c94da98b6a..15406b97fe 100644 --- a/app/services/bill-runs/two-part-tariff/submit-amended-adjustment-factor.service.js +++ b/app/services/bill-runs/two-part-tariff/submit-amended-adjustment-factor.service.js @@ -63,7 +63,7 @@ async function _persistAmendedAdjustmentFactor (reviewChargeReferenceId, payload } function _validate (payload) { - const maxDecimalsForAggregateValue = 2 + const maxDecimalsForAggregateValue = 15 const maxDecimalsForChargeAdjustmentValue = 15 const aggregateValidation = AdjustmentFactorValidator.go( diff --git a/app/validators/bill-runs/two-part-tariff/adjustment-factor.validator.js b/app/validators/bill-runs/two-part-tariff/adjustment-factor.validator.js index e30427852b..2031b8024b 100644 --- a/app/validators/bill-runs/two-part-tariff/adjustment-factor.validator.js +++ b/app/validators/bill-runs/two-part-tariff/adjustment-factor.validator.js @@ -45,7 +45,7 @@ function _customValidation (quantity, helpers, maxNumberOfDecimals, validationTy } return helpers.message({ - custom: `The ${validationType} must contain no more than ${maxNumberOfDecimals} decimal places` + custom: `The ${validationType} factor must not have more than ${maxNumberOfDecimals} decimal places` }) } @@ -60,7 +60,7 @@ function _validate (quantity, maxNumberOfDecimals, validationType) { 'number.base': `The ${validationType} factor must be a number`, 'number.unsafe': `The ${validationType} factor must be a number`, 'number.min': `The ${validationType} factor must be greater than 0`, - 'number.max': `The ${validationType} factor must be less than 1`, + 'number.max': `The ${validationType} factor must be equal to or less than 1`, 'any.required': `Enter a ${validationType} factor` }) }) diff --git a/test/validators/bill-runs/two-part-tariff/adjustment-factor.validator.test.js b/test/validators/bill-runs/two-part-tariff/adjustment-factor.validator.test.js index 63cc4e6427..11c99cb588 100644 --- a/test/validators/bill-runs/two-part-tariff/adjustment-factor.validator.test.js +++ b/test/validators/bill-runs/two-part-tariff/adjustment-factor.validator.test.js @@ -11,8 +11,9 @@ const { expect } = Code const AdjustmentFactorValidator = require('../../../../app/validators/bill-runs/two-part-tariff/adjustment-factor.validator.js') describe('Adjustment Factor validator', () => { + const maxNumberOfDecimals = 15 + let payload - let maxNumberOfDecimals let validationType describe('when a valid payload is provided', () => { @@ -22,7 +23,6 @@ describe('Adjustment Factor validator', () => { amendedAggregateFactor: 0.5 } - maxNumberOfDecimals = 2 validationType = 'aggregate' }) @@ -39,12 +39,15 @@ describe('Adjustment Factor validator', () => { amendedChargeAdjustment: 0.5 } - maxNumberOfDecimals = 15 validationType = 'charge' }) it('confirms the payload is valid', () => { - const result = AdjustmentFactorValidator.go(payload.amendedChargeAdjustment, maxNumberOfDecimals, validationType) + const result = AdjustmentFactorValidator.go( + payload.amendedChargeAdjustment, + maxNumberOfDecimals, + validationType + ) expect(result.error).not.to.exist() }) @@ -56,7 +59,6 @@ describe('Adjustment Factor validator', () => { beforeEach(() => { payload = undefined - maxNumberOfDecimals = 2 validationType = 'aggregate' }) @@ -74,7 +76,6 @@ describe('Adjustment Factor validator', () => { amendedAggregateFactor: 'Hello World' } - maxNumberOfDecimals = 2 validationType = 'aggregate' }) @@ -89,18 +90,19 @@ describe('Adjustment Factor validator', () => { describe('because the user entered too many decimal places', () => { beforeEach(() => { payload = { - amendedAggregateFactor: 0.555 + amendedAggregateFactor: 0.1234567890123456 } - maxNumberOfDecimals = 2 validationType = 'aggregate' }) - it("fails the validation with the message 'The aggregate must contain no more than 2 decimal places'", () => { + it("fails the validation with the message 'The aggregate factor must not have more than 15 decimal places'", () => { const result = AdjustmentFactorValidator.go(payload.amendedAggregateFactor, maxNumberOfDecimals, validationType) expect(result.error).to.exist() - expect(result.error.details[0].message).to.equal('The aggregate must contain no more than 2 decimal places') + expect(result.error.details[0].message).to.equal( + 'The aggregate factor must not have more than 15 decimal places' + ) }) }) @@ -110,15 +112,14 @@ describe('Adjustment Factor validator', () => { amendedAggregateFactor: 1.1 } - maxNumberOfDecimals = 2 validationType = 'aggregate' }) - it("fails the validation with the message 'The aggregate factor must be less than 1'", () => { + it("fails the validation with the message 'The aggregate factor must be equal to or less than 1'", () => { const result = AdjustmentFactorValidator.go(payload.amendedAggregateFactor, maxNumberOfDecimals, validationType) expect(result.error).to.exist() - expect(result.error.details[0].message).to.equal('The aggregate factor must be less than 1') + expect(result.error.details[0].message).to.equal('The aggregate factor must be equal to or less than 1') }) }) @@ -128,7 +129,6 @@ describe('Adjustment Factor validator', () => { amendedAggregateFactor: -1 } - maxNumberOfDecimals = 2 validationType = 'aggregate' }) @@ -146,7 +146,6 @@ describe('Adjustment Factor validator', () => { beforeEach(() => { payload = undefined - maxNumberOfDecimals = 15 validationType = 'charge' }) @@ -164,7 +163,6 @@ describe('Adjustment Factor validator', () => { amendedChargeFactor: 'Hello World' } - maxNumberOfDecimals = 15 validationType = 'charge' }) @@ -182,15 +180,14 @@ describe('Adjustment Factor validator', () => { amendedChargeFactor: 0.5555555555555555 } - maxNumberOfDecimals = 15 validationType = 'charge' }) - it("fails the validation with the message 'The charge must contain no more than 2 decimal places'", () => { + it("fails the validation with the message 'The charge factor must not have more than 15 decimal places'", () => { const result = AdjustmentFactorValidator.go(payload.amendedChargeFactor, maxNumberOfDecimals, validationType) expect(result.error).to.exist() - expect(result.error.details[0].message).to.equal('The charge must contain no more than 15 decimal places') + expect(result.error.details[0].message).to.equal('The charge factor must not have more than 15 decimal places') }) }) @@ -200,15 +197,14 @@ describe('Adjustment Factor validator', () => { amendedChargeFactor: 1.1 } - maxNumberOfDecimals = 15 validationType = 'charge' }) - it("fails the validation with the message 'The charge factor must be less than 1'", () => { + it("fails the validation with the message 'The charge factor must be equal to or less than 1'", () => { const result = AdjustmentFactorValidator.go(payload.amendedChargeFactor, maxNumberOfDecimals, validationType) expect(result.error).to.exist() - expect(result.error.details[0].message).to.equal('The charge factor must be less than 1') + expect(result.error.details[0].message).to.equal('The charge factor must be equal to or less than 1') }) }) @@ -218,7 +214,6 @@ describe('Adjustment Factor validator', () => { amendedChargeFactor: -1 } - maxNumberOfDecimals = 15 validationType = 'charge' })