From 34560c19e4e1dcc1ca3a3d4ea935ec6ea7e5e0cf Mon Sep 17 00:00:00 2001 From: Alan Cruikshanks Date: Tue, 12 Mar 2024 10:52:33 +0000 Subject: [PATCH 1/6] Add bill runs setup season page to journey https://eaflood.atlassian.net/browse/WATER-4375 > Part of a series of changes related to replacing the create bill run journey to incorporate changes for two-part tariff This adds the fourth and final page to the setup bill run journey; select the season. This like [Add bill runs setup financial year page to journey](https://github.com/DEFRA/water-abstraction-system/pull/805) is only needed temporarily. Two-part tariff bill runs were held during COVID then the SROC ones have been delayed whilst we build an SROC 2PT billing engine. This means we have a backlog so users need to be able to select the year they wish to create the bill run for. If they select a PRESROC year they then need to pick the season. Under PRESROC two-part tariff bill runs were based on whether a licence's abstraction was in summer, or winter and all-year. We need to know what season they wish to generate so we can tell the legacy engine. Once the backlogged PRESROC two-part tariff bill runs are dealt with this page will become redundant. Once all the backlogged two-part tariff bill runs have been dealt with both `/year` and `/season` can be dropped from the journey altogether. From 97470014e0c02b5b831eab25b4090b84c6278ec0 Mon Sep 17 00:00:00 2001 From: Alan Cruikshanks Date: Tue, 12 Mar 2024 11:58:42 +0000 Subject: [PATCH 2/6] Add the GET season page This is the route, controller and view plus supporting service and presenter for the GET `/bill-runs/setup/{id}/season` page. --- app/controllers/bill-runs-setup.controller.js | 14 +++++ .../bill-runs/setup/season.presenter.js | 24 +++++++ app/routes/bill-runs-setup.routes.js | 13 ++++ .../bill-runs/setup/season.service.js | 32 ++++++++++ app/views/bill-runs/setup/season.njk | 62 +++++++++++++++++++ .../bill-runs-setup.controller.test.js | 23 +++++++ .../bill-runs/setup/season.presenter.test.js | 50 +++++++++++++++ .../bill-runs/setup/season.service.test.js | 36 +++++++++++ 8 files changed, 254 insertions(+) create mode 100644 app/presenters/bill-runs/setup/season.presenter.js create mode 100644 app/services/bill-runs/setup/season.service.js create mode 100644 app/views/bill-runs/setup/season.njk create mode 100644 test/presenters/bill-runs/setup/season.presenter.test.js create mode 100644 test/services/bill-runs/setup/season.service.test.js diff --git a/app/controllers/bill-runs-setup.controller.js b/app/controllers/bill-runs-setup.controller.js index 0b56f97f5b..df4e6d0cb3 100644 --- a/app/controllers/bill-runs-setup.controller.js +++ b/app/controllers/bill-runs-setup.controller.js @@ -7,6 +7,7 @@ const InitiateSessionService = require('../services/bill-runs/setup/initiate-session.service.js') const RegionService = require('../services/bill-runs/setup/region.service.js') +const SeasonService = require('../services/bill-runs/setup/season.service.js') const SubmitRegionService = require('../services/bill-runs/setup/submit-region.service.js') const SubmitTypeService = require('../services/bill-runs/setup/submit-type.service.js') const SubmitYearService = require('../services/bill-runs/setup/submit-year.service.js') @@ -25,6 +26,18 @@ async function region (request, h) { }) } +async function season (request, h) { + const { sessionId } = request.params + + const pageData = await SeasonService.go(sessionId) + + return h.view('bill-runs/setup/season.njk', { + activeNavBar: 'bill-runs', + pageTitle: 'Select the season', + ...pageData + }) +} + async function setup (_request, h) { const session = await InitiateSessionService.go() @@ -113,6 +126,7 @@ async function year (request, h) { module.exports = { region, + season, setup, submitRegion, submitType, diff --git a/app/presenters/bill-runs/setup/season.presenter.js b/app/presenters/bill-runs/setup/season.presenter.js new file mode 100644 index 0000000000..5713498191 --- /dev/null +++ b/app/presenters/bill-runs/setup/season.presenter.js @@ -0,0 +1,24 @@ +'use strict' + +/** + * Formats data for the `/bill-runs/setup/{sessionId}/season` page + * @module SeasonPresenter + */ + +/** + * Formats data for the `/bill-runs/setup/{sessionId}/season` page + * + * @param {module:SessionModel} session - The session instance to format + * + * @returns {Object} - The data formatted for the view template + */ +function go (session) { + return { + sessionId: session.id, + selectedSeason: session.data.season ? session.data.season : null + } +} + +module.exports = { + go +} diff --git a/app/routes/bill-runs-setup.routes.js b/app/routes/bill-runs-setup.routes.js index 5fbcf169a5..4d71dc880b 100644 --- a/app/routes/bill-runs-setup.routes.js +++ b/app/routes/bill-runs-setup.routes.js @@ -29,6 +29,19 @@ const routes = [ description: 'Submit the region for the bill run' } }, + { + method: 'GET', + path: '/bill-runs/setup/{sessionId}/season', + handler: BillRunsSetupController.season, + options: { + auth: { + access: { + scope: ['billing'] + } + }, + description: 'Select the season for the bill run' + } + }, { method: 'GET', path: '/bill-runs/setup', diff --git a/app/services/bill-runs/setup/season.service.js b/app/services/bill-runs/setup/season.service.js new file mode 100644 index 0000000000..a61e13dd52 --- /dev/null +++ b/app/services/bill-runs/setup/season.service.js @@ -0,0 +1,32 @@ +'use strict' + +/** + * Orchestrates fetching and presenting the data for `/bill-runs/setup/{sessionId}/season` page + * @module BillRunsCreateSeasonService + */ + +const SessionModel = require('../../../models/session.model.js') +const SeasonPresenter = require('../../../presenters/bill-runs/setup/season.presenter.js') + +/** + * Orchestrates fetching and presenting the data for `/bill-runs/setup/{sessionId}/season` page + * + * Supports generating the data needed for the type page in the create bill run journey. It fetches the current + * session record and formats the data needed for the form. + * + * @param {string} sessionId - The UUID for setup bill run session record + * + * @returns {Promise} The view data for the season page + */ +async function go (sessionId) { + const session = await SessionModel.query().findById(sessionId) + const formattedData = SeasonPresenter.go(session) + + return { + ...formattedData + } +} + +module.exports = { + go +} diff --git a/app/views/bill-runs/setup/season.njk b/app/views/bill-runs/setup/season.njk new file mode 100644 index 0000000000..2bb0c0791c --- /dev/null +++ b/app/views/bill-runs/setup/season.njk @@ -0,0 +1,62 @@ +{% extends 'layout.njk' %} +{% from "govuk/components/back-link/macro.njk" import govukBackLink %} +{% from "govuk/components/button/macro.njk" import govukButton %} +{% from "govuk/components/error-summary/macro.njk" import govukErrorSummary %} +{% from "govuk/components/radios/macro.njk" import govukRadios %} + +{% block breadcrumbs %} + {# Back link #} + {{ + govukBackLink({ + text: 'Back', + href: '/system/bill-runs/setup/' + sessionId + '/year' + }) + }} +{% endblock %} + +{% block content %} + {% if error %} + {{ govukErrorSummary({ + titleText: 'There is a problem', + errorList: [ + { + text: error.text, + href: '#season-error' + } + ] + }) }} + {% endif %} + +
+
+ {{ govukRadios({ + attributes: { + 'data-test': 'bill-run-season' + }, + name: 'season', + errorMessage: error, + fieldset: { + legend: { + text: pageTitle, + isPageHeading: true, + classes: 'govuk-fieldset__legend--l govuk-!-margin-bottom-6' + } + }, + items: [ + { + text: 'Summer', + value: 'summer', + checked: 'summer' == selectedSeason + }, + { + text: 'Winter and All year', + value: 'winter_all_year', + checked: 'winter_all_year' == selectedSeason + } + ] + }) }} + + {{ govukButton({ text: 'Continue', preventDoubleClick: true }) }} +
+
+{% endblock %} diff --git a/test/controllers/bill-runs-setup.controller.test.js b/test/controllers/bill-runs-setup.controller.test.js index 7b6b6a77fb..0810b2db49 100644 --- a/test/controllers/bill-runs-setup.controller.test.js +++ b/test/controllers/bill-runs-setup.controller.test.js @@ -11,6 +11,7 @@ const { expect } = Code // Things we need to stub const InitiateSessionService = require('../../app/services/bill-runs/setup/initiate-session.service.js') const RegionService = require('../../app/services/bill-runs/setup/region.service.js') +const SeasonService = require('../../app/services/bill-runs/setup/season.service.js') const SubmitRegionService = require('../../app/services/bill-runs/setup/submit-region.service.js') const SubmitTypeService = require('../../app/services/bill-runs/setup/submit-type.service.js') const SubmitYearService = require('../../app/services/bill-runs/setup/submit-year.service.js') @@ -64,6 +65,28 @@ describe('Bill Runs Setup controller', () => { }) }) + describe('/bill-runs/setup/{sessionId}/season', () => { + describe('GET', () => { + beforeEach(async () => { + options = _getOptions('season') + + Sinon.stub(SeasonService, 'go').resolves({ + sessionId: 'e009b394-8405-4358-86af-1a9eb31298a5', + selectedSeason: null + }) + }) + + describe('when the request succeeds', () => { + it('returns the page successfully', async () => { + const response = await server.inject(options) + + expect(response.statusCode).to.equal(200) + expect(response.payload).to.contain('Select the season') + }) + }) + }) + }) + describe('/bill-runs/setup/{sessionId}/region', () => { describe('GET', () => { beforeEach(async () => { diff --git a/test/presenters/bill-runs/setup/season.presenter.test.js b/test/presenters/bill-runs/setup/season.presenter.test.js new file mode 100644 index 0000000000..fc5e0332bc --- /dev/null +++ b/test/presenters/bill-runs/setup/season.presenter.test.js @@ -0,0 +1,50 @@ +'use strict' + +// Test framework dependencies +const Lab = require('@hapi/lab') +const Code = require('@hapi/code') + +const { describe, it, beforeEach } = exports.lab = Lab.script() +const { expect } = Code + +// Thing under test +const SeasonPresenter = require('../../../../app/presenters/bill-runs/setup/season.presenter.js') + +describe('Bill Runs Setup Season presenter', () => { + let session + + describe('when provided with a bill run setup session record', () => { + beforeEach(() => { + session = { + id: '98ad3a1f-8e4f-490a-be05-0aece6755466', + data: {} + } + }) + + describe('where the user has not previously selected a season', () => { + it('correctly presents the data', () => { + const result = SeasonPresenter.go(session) + + expect(result).to.equal({ + sessionId: '98ad3a1f-8e4f-490a-be05-0aece6755466', + selectedSeason: null + }) + }) + }) + + describe('where the user has previously selected a season', () => { + beforeEach(() => { + session.data.season = 'summer' + }) + + it('correctly presents the data', () => { + const result = SeasonPresenter.go(session) + + expect(result).to.equal({ + sessionId: '98ad3a1f-8e4f-490a-be05-0aece6755466', + selectedSeason: 'summer' + }) + }) + }) + }) +}) diff --git a/test/services/bill-runs/setup/season.service.test.js b/test/services/bill-runs/setup/season.service.test.js new file mode 100644 index 0000000000..e109de25ad --- /dev/null +++ b/test/services/bill-runs/setup/season.service.test.js @@ -0,0 +1,36 @@ +'use strict' + +// Test framework dependencies +const Lab = require('@hapi/lab') +const Code = require('@hapi/code') + +const { describe, it, beforeEach } = exports.lab = Lab.script() +const { expect } = Code + +// Test helpers +const DatabaseSupport = require('../../../support/database.js') +const SessionHelper = require('../../../support/helpers/session.helper.js') + +// Thing under test +const SeasonService = require('../../../../app/services/bill-runs/setup/season.service.js') + +describe('Bill Runs Setup Type service', () => { + let session + + beforeEach(async () => { + await DatabaseSupport.clean() + + session = await SessionHelper.add({ data: { season: 'summer' } }) + }) + + describe('when called', () => { + it('returns page data for the view', async () => { + const result = await SeasonService.go(session.id) + + expect(result).to.equal({ + sessionId: session.id, + selectedSeason: 'summer' + }) + }) + }) +}) From 20d2164cce97871dcaf1cd80f1ba056599b81507 Mon Sep 17 00:00:00 2001 From: Alan Cruikshanks Date: Tue, 12 Mar 2024 12:13:39 +0000 Subject: [PATCH 3/6] Housekeeping - correct comment --- app/services/bill-runs/setup/submit-region.service.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/services/bill-runs/setup/submit-region.service.js b/app/services/bill-runs/setup/submit-region.service.js index d8f208ef0d..4360e3e480 100644 --- a/app/services/bill-runs/setup/submit-region.service.js +++ b/app/services/bill-runs/setup/submit-region.service.js @@ -1,7 +1,7 @@ 'use strict' /** - * Orchestrates validating the data for `/bill-runs/setup/{sessionId}/region` page + * Handles the user submission for the `/bill-runs/setup/{sessionId}/region` page * @module SubmitRegionService */ @@ -11,7 +11,7 @@ const RegionValidator = require('../../../validators/bill-runs/setup/region.vali const SessionModel = require('../../../models/session.model.js') /** - * Orchestrates validating the data for `/bill-runs/setup/{sessionId}/region` page + * Handles the user submission for the `/bill-runs/setup/{sessionId}/region` page * * It first retrieves the session instance for the setup bill run journey in progress. It then validates the payload of * the submitted request. From 03533e844d505164a843ddf1226eafaa96b2197e Mon Sep 17 00:00:00 2001 From: Alan Cruikshanks Date: Tue, 12 Mar 2024 12:13:58 +0000 Subject: [PATCH 4/6] Add season validator --- .../bill-runs/setup/season.validator.js | 40 +++++++++++++++++ .../bill-runs/setup/season.validator.test.js | 44 +++++++++++++++++++ 2 files changed, 84 insertions(+) create mode 100644 app/validators/bill-runs/setup/season.validator.js create mode 100644 test/validators/bill-runs/setup/season.validator.test.js diff --git a/app/validators/bill-runs/setup/season.validator.js b/app/validators/bill-runs/setup/season.validator.js new file mode 100644 index 0000000000..f2c725061a --- /dev/null +++ b/app/validators/bill-runs/setup/season.validator.js @@ -0,0 +1,40 @@ +'use strict' + +/** + * Validates data submitted for the `/bill-runs/setup/{sessionId}/season` page + * @module SeasonValidator + */ + +const Joi = require('joi') + +const VALID_VALUES = [ + 'summer', + 'winter_all_year' +] + +/** + * Validates data submitted for the `/bill-runs/setup/{sessionId}/season` page + * + * @param {Object} payload - The payload from the request to be validated + * + * @returns {Object} the result from calling Joi's schema.validate(). It will be an object with a `value:` property. If + * any errors are found the `error:` property will also exist detailing what the issues were + */ +function go (data) { + const schema = Joi.object({ + season: Joi.string() + .required() + .valid(...VALID_VALUES) + .messages({ + 'any.required': 'Select the season', + 'any.only': 'Select the season', + 'string.empty': 'Select the season' + }) + }) + + return schema.validate(data, { abortEarly: false }) +} + +module.exports = { + go +} diff --git a/test/validators/bill-runs/setup/season.validator.test.js b/test/validators/bill-runs/setup/season.validator.test.js new file mode 100644 index 0000000000..c0f565b869 --- /dev/null +++ b/test/validators/bill-runs/setup/season.validator.test.js @@ -0,0 +1,44 @@ +'use strict' + +// Test framework dependencies +const Lab = require('@hapi/lab') +const Code = require('@hapi/code') + +const { describe, it } = exports.lab = Lab.script() +const { expect } = Code + +// Thing under test +const SeasonValidator = require('../../../../app/validators/bill-runs/setup/season.validator.js') + +describe('Bill Runs Setup Season validator', () => { + describe('when valid data is provided', () => { + it('confirms the data is valid', () => { + const result = SeasonValidator.go({ season: 'summer' }) + + expect(result.value).to.exist() + expect(result.error).not.to.exist() + }) + }) + + describe('when invalid data is provided', () => { + describe("because no 'season' is given", () => { + it('fails validation', () => { + const result = SeasonValidator.go({ season: '' }) + + expect(result.value).to.exist() + expect(result.error).to.exist() + expect(result.error.details[0].message).to.equal('Select the season') + }) + }) + + describe("because an unknown 'season' is given", () => { + it('fails validation', () => { + const result = SeasonValidator.go({ type: 'spring' }) + + expect(result.value).to.exist() + expect(result.error).to.exist() + expect(result.error.details[0].message).to.equal('Select the season') + }) + }) + }) +}) From 363660660e0e8b90c13a34de86dfc3f03bb34f71 Mon Sep 17 00:00:00 2001 From: Alan Cruikshanks Date: Tue, 12 Mar 2024 12:14:21 +0000 Subject: [PATCH 5/6] Add service to handle season submission --- .../bill-runs/setup/submit-season.service.js | 74 +++++++++++++++++++ .../setup/submit-season.service.test.js | 70 ++++++++++++++++++ 2 files changed, 144 insertions(+) create mode 100644 app/services/bill-runs/setup/submit-season.service.js create mode 100644 test/services/bill-runs/setup/submit-season.service.test.js diff --git a/app/services/bill-runs/setup/submit-season.service.js b/app/services/bill-runs/setup/submit-season.service.js new file mode 100644 index 0000000000..bce40eac53 --- /dev/null +++ b/app/services/bill-runs/setup/submit-season.service.js @@ -0,0 +1,74 @@ +'use strict' + +/** + * Handles the user submission for the `/bill-runs/setup/{sessionId}/type` page + * @module SubmitSeasonService + */ + +const SessionModel = require('../../../models/session.model.js') +const SeasonPresenter = require('../../../presenters/bill-runs/setup/season.presenter.js') +const SeasonValidator = require('../../../validators/bill-runs/setup/season.validator.js') + +/** + * Handles the user submission for the `/bill-runs/setup/{sessionId}/type` page + * + * It first retrieves the session instance for the setup bill run journey in progress. It then validates the payload of + * the submitted request. + * + * If there is no validation error it will save the selected value to the session then return an empty object. This will + * indicate to the controller that the submission was successful triggering it to redirect to the next page in the + * journey. + * + * If there is a validation error it is combined with the output of the presenter to generate the page data needed to + * re-render the view with an error message. + * + * @param {string} sessionId - The UUID of the current session + * @param {Object} payload - The submitted form data + * + * @returns {Promise} An empty object if there are no errors else the page data for the type page including the + * validation error details + */ +async function go (sessionId, payload) { + const session = await SessionModel.query().findById(sessionId) + + const validationResult = _validate(payload) + + if (!validationResult) { + await _save(session, payload) + + return {} + } + + const formattedData = SeasonPresenter.go(session) + + return { + error: validationResult, + ...formattedData + } +} + +async function _save (session, payload) { + const currentData = session.data + + currentData.season = payload.season + + return session.$query().patch({ data: currentData }) +} + +function _validate (payload) { + const validation = SeasonValidator.go(payload) + + if (!validation.error) { + return null + } + + const { message } = validation.error.details[0] + + return { + text: message + } +} + +module.exports = { + go +} diff --git a/test/services/bill-runs/setup/submit-season.service.test.js b/test/services/bill-runs/setup/submit-season.service.test.js new file mode 100644 index 0000000000..aff5eb7e7c --- /dev/null +++ b/test/services/bill-runs/setup/submit-season.service.test.js @@ -0,0 +1,70 @@ +'use strict' + +// Test framework dependencies +const Lab = require('@hapi/lab') +const Code = require('@hapi/code') + +const { describe, it, beforeEach } = exports.lab = Lab.script() +const { expect } = Code + +// Test helpers +const DatabaseSupport = require('../../../support/database.js') +const SessionHelper = require('../../../support/helpers/session.helper.js') + +// Thing under test +const SubmitSeasonService = require('../../../../app/services/bill-runs/setup/submit-season.service.js') + +describe('Bill Runs Setup Submit Season service', () => { + let payload + let session + + beforeEach(async () => { + await DatabaseSupport.clean() + + session = await SessionHelper.add({ data: {} }) + }) + + describe('when called', () => { + describe('with a valid payload', () => { + beforeEach(() => { + payload = { + season: 'summer' + } + }) + + it('saves the submitted value', async () => { + await SubmitSeasonService.go(session.id, payload) + + const refreshedSession = await session.$query() + + expect(refreshedSession.data.season).to.equal('summer') + }) + + it('returns an empty object (no page data is needed for a redirect)', async () => { + const result = await SubmitSeasonService.go(session.id, payload) + + expect(result).to.equal({}) + }) + }) + + describe('with an invalid payload', () => { + describe('because the user has not selected anything', () => { + beforeEach(() => { + payload = {} + }) + + it('returns page data needed to re-render the view including the validation error', async () => { + const result = await SubmitSeasonService.go(session.id, payload) + + expect(result).to.equal({ + sessionId: session.id, + selectedSeason: null, + error: { + text: 'Select the season' + } + }) + }) + }) + }) + }) +}) From d71f6ca3d7330424b8e28e4991713a28beacfa19 Mon Sep 17 00:00:00 2001 From: Alan Cruikshanks Date: Tue, 12 Mar 2024 12:14:34 +0000 Subject: [PATCH 6/6] Add route and controller --- app/controllers/bill-runs-setup.controller.js | 18 ++++ app/routes/bill-runs-setup.routes.js | 13 +++ .../bill-runs-setup.controller.test.js | 82 ++++++++++++++----- 3 files changed, 91 insertions(+), 22 deletions(-) diff --git a/app/controllers/bill-runs-setup.controller.js b/app/controllers/bill-runs-setup.controller.js index df4e6d0cb3..051762fcfc 100644 --- a/app/controllers/bill-runs-setup.controller.js +++ b/app/controllers/bill-runs-setup.controller.js @@ -9,6 +9,7 @@ const InitiateSessionService = require('../services/bill-runs/setup/initiate-ses const RegionService = require('../services/bill-runs/setup/region.service.js') const SeasonService = require('../services/bill-runs/setup/season.service.js') const SubmitRegionService = require('../services/bill-runs/setup/submit-region.service.js') +const SubmitSeasonService = require('../services/bill-runs/setup/submit-season.service.js') const SubmitTypeService = require('../services/bill-runs/setup/submit-type.service.js') const SubmitYearService = require('../services/bill-runs/setup/submit-year.service.js') const TypeService = require('../services/bill-runs/setup/type.service.js') @@ -64,6 +65,22 @@ async function submitRegion (request, h) { return h.redirect(`/system/bill-runs/setup/${sessionId}/year`) } +async function submitSeason (request, h) { + const { sessionId } = request.params + + const pageData = await SubmitSeasonService.go(sessionId, request.payload) + + if (pageData.error) { + return h.view('bill-runs/setup/season.njk', { + activeNavBar: 'bill-runs', + pageTitle: 'Select the season', + ...pageData + }) + } + + return h.redirect(`/system/bill-runs/setup/${sessionId}/generate`) +} + async function submitType (request, h) { const { sessionId } = request.params @@ -129,6 +146,7 @@ module.exports = { season, setup, submitRegion, + submitSeason, submitType, submitYear, type, diff --git a/app/routes/bill-runs-setup.routes.js b/app/routes/bill-runs-setup.routes.js index 4d71dc880b..94cca42e45 100644 --- a/app/routes/bill-runs-setup.routes.js +++ b/app/routes/bill-runs-setup.routes.js @@ -42,6 +42,19 @@ const routes = [ description: 'Select the season for the bill run' } }, + { + method: 'POST', + path: '/bill-runs/setup/{sessionId}/season', + handler: BillRunsSetupController.submitSeason, + options: { + auth: { + access: { + scope: ['billing'] + } + }, + description: 'Submit the season for the bill run' + } + }, { method: 'GET', path: '/bill-runs/setup', diff --git a/test/controllers/bill-runs-setup.controller.test.js b/test/controllers/bill-runs-setup.controller.test.js index 0810b2db49..2716eabdf5 100644 --- a/test/controllers/bill-runs-setup.controller.test.js +++ b/test/controllers/bill-runs-setup.controller.test.js @@ -13,6 +13,7 @@ const InitiateSessionService = require('../../app/services/bill-runs/setup/initi const RegionService = require('../../app/services/bill-runs/setup/region.service.js') const SeasonService = require('../../app/services/bill-runs/setup/season.service.js') const SubmitRegionService = require('../../app/services/bill-runs/setup/submit-region.service.js') +const SubmitSeasonService = require('../../app/services/bill-runs/setup/submit-season.service.js') const SubmitTypeService = require('../../app/services/bill-runs/setup/submit-type.service.js') const SubmitYearService = require('../../app/services/bill-runs/setup/submit-year.service.js') const TypeService = require('../../app/services/bill-runs/setup/type.service.js') @@ -65,28 +66,6 @@ describe('Bill Runs Setup controller', () => { }) }) - describe('/bill-runs/setup/{sessionId}/season', () => { - describe('GET', () => { - beforeEach(async () => { - options = _getOptions('season') - - Sinon.stub(SeasonService, 'go').resolves({ - sessionId: 'e009b394-8405-4358-86af-1a9eb31298a5', - selectedSeason: null - }) - }) - - describe('when the request succeeds', () => { - it('returns the page successfully', async () => { - const response = await server.inject(options) - - expect(response.statusCode).to.equal(200) - expect(response.payload).to.contain('Select the season') - }) - }) - }) - }) - describe('/bill-runs/setup/{sessionId}/region', () => { describe('GET', () => { beforeEach(async () => { @@ -168,6 +147,65 @@ describe('Bill Runs Setup controller', () => { }) }) + describe('/bill-runs/setup/{sessionId}/season', () => { + describe('GET', () => { + beforeEach(async () => { + options = _getOptions('season') + + Sinon.stub(SeasonService, 'go').resolves({ + sessionId: 'e009b394-8405-4358-86af-1a9eb31298a5', + selectedSeason: null + }) + }) + + describe('when the request succeeds', () => { + it('returns the page successfully', async () => { + const response = await server.inject(options) + + expect(response.statusCode).to.equal(200) + expect(response.payload).to.contain('Select the season') + }) + }) + }) + + describe('POST', () => { + describe('when a request is valid', () => { + beforeEach(async () => { + options = _postOptions('season', { season: 'summer' }) + + Sinon.stub(SubmitSeasonService, 'go').resolves({}) + }) + + it('redirects to the generate bill run endpoint', async () => { + const response = await server.inject(options) + + expect(response.statusCode).to.equal(302) + expect(response.headers.location).to.equal('/system/bill-runs/setup/e009b394-8405-4358-86af-1a9eb31298a5/generate') + }) + }) + + describe('when a request is invalid', () => { + beforeEach(async () => { + options = _postOptions('season', { type: '' }) + + Sinon.stub(SubmitSeasonService, 'go').resolves({ + sessionId: 'e009b394-8405-4358-86af-1a9eb31298a5', + selectedSeason: null, + error: { text: 'Select the season' } + }) + }) + + it('re-renders the page with an error message', async () => { + const response = await server.inject(options) + + expect(response.statusCode).to.equal(200) + expect(response.payload).to.contain('Select the season') + expect(response.payload).to.contain('There is a problem') + }) + }) + }) + }) + describe('/bill-runs/setup/{sessionId}/type', () => { describe('GET', () => { beforeEach(async () => {