From 85c92d0f94b8993864d62177965e91143704fafb Mon Sep 17 00:00:00 2001 From: jonathangoulding Date: Thu, 18 Jul 2024 15:33:10 +0100 Subject: [PATCH 01/75] Import Licence versions We need to replace the import service logic to import a licence from NALD. We will leave the import service running to add the NALD data in the import tables, but we will slowly replace the import-licence functionality and move this into the system repo. https://eaflood.atlassian.net/browse/WATER-4575 This change will add the licence versions to the import logic. The licence versions rely on the created / existing licence id. This work needs to be done first to allow us to remove the licence and licence versions from the old import logic. --- app/controllers/import.controller.js | 14 ++--- .../fetch-licence-versions.service.js | 17 +++++- .../legacy-import/licence-versions.mapper.js | 52 +++++++++++++++++ app/services/import/legacy-licence.service.js | 10 +++- .../persist-licence-versions.service.js | 58 +++++++++++++++++++ 5 files changed, 141 insertions(+), 10 deletions(-) create mode 100644 app/services/import/legacy-import/licence-versions.mapper.js create mode 100644 app/services/import/persist-licence-versions.service.js diff --git a/app/controllers/import.controller.js b/app/controllers/import.controller.js index 368c658531..bb950c1d0e 100644 --- a/app/controllers/import.controller.js +++ b/app/controllers/import.controller.js @@ -8,15 +8,15 @@ const Boom = require('@hapi/boom') * @module ImportController */ async function licence (request, h) { - try { - const { licenceRef } = request.payload + // try { + const { licenceRef } = request.payload - await LegacyImportLicenceService.go(licenceRef) + await LegacyImportLicenceService.go(licenceRef) - return h.response().code(204) - } catch (error) { - return Boom.badImplementation(error.message) - } + return h.response().code(204) + // } catch (error) { + // return Boom.badImplementation(error.message) + // } } module.exports = { diff --git a/app/services/import/legacy-import/fetch-licence-versions.service.js b/app/services/import/legacy-import/fetch-licence-versions.service.js index 33ff4f66a0..c2466841f5 100644 --- a/app/services/import/legacy-import/fetch-licence-versions.service.js +++ b/app/services/import/legacy-import/fetch-licence-versions.service.js @@ -34,7 +34,14 @@ async function _getLicenceVersions (licenceId, regionCode) { function select (rows) { return rows.map((row) => { return { - EFF_ST_DATE: row.EFF_ST_DATE + EFF_END_DATE: row.EFF_END_DATE, + EFF_ST_DATE: row.EFF_ST_DATE, + INCR_NO: row.INCR_NO, + ISSUE_NO: row.ISSUE_NO, + STATUS: row.STATUS, + // can use region code from licence ? + FGAC_REGION_CODE: row.FGAC_REGION_CODE, + AABL_ID: row.AABL_ID } }) } @@ -47,7 +54,13 @@ module.exports = { * A legacy licence version * @typedef {Object} LegacyLicenceVersionsType * - * @property {string} EFF_ST_DATE - date in UK format | 'null' + * @property {string} EFF_END_DATE - date in UK format - can be 'null' + * @property {string} EFF_ST_DATE - date in UK format + * @property {string} INCR_NO - a number between 1 - 5 + * @property {string} ISSUE_NO - a number - linked to the purpose id ? + * @property {string} STATUS - enum - 'DRAFT', 'SUPER', 'CURR' (Draft will not be selected) + * @property {string} FGAC_REGION_CODE + * @property {string} AABL_ID */ /** diff --git a/app/services/import/legacy-import/licence-versions.mapper.js b/app/services/import/legacy-import/licence-versions.mapper.js new file mode 100644 index 0000000000..1c38edd663 --- /dev/null +++ b/app/services/import/legacy-import/licence-versions.mapper.js @@ -0,0 +1,52 @@ +'use strict' + +/** + * Maps the import licence versions data to the desired format + * @module LegacyImportLicenceVersionMapper + */ + +const { formatStandardDateToISO } = require('../../../lib/dates.lib.js') + +const statuses = { + CURR: 'current', + SUPER: 'superseded', + DRAFT: 'draft' +} + +const createExternalId = (licenceVersion) => { + const { FGAC_REGION_CODE, AABL_ID, ISSUE_NO, INCR_NO } = licenceVersion + + return `${FGAC_REGION_CODE}:${AABL_ID}:${ISSUE_NO}:${INCR_NO}` +} + +/** + * Maps the import licence versions data to the desired format + * + * @param {LegacyLicenceVersionsArray} licenceVersions + * @returns {} + */ +function go (licenceVersions, licenceId) { + return _mapLicenceVersions(licenceVersions) +} + +function _mapLicenceVersions (licenceVersions) { + return licenceVersions.map((licenceVersion) => { + const issue = licenceVersion.ISSUE_NO + const increment = licenceVersion.INCR_NO + + return { + createdAt: new Date().toISOString(), + endDate: formatStandardDateToISO(licenceVersion.EFF_END_DATE), + externalId: createExternalId(licenceVersion), + increment: Number(increment), + issue: Number(issue), + startDate: formatStandardDateToISO(licenceVersion.EFF_ST_DATE), + status: statuses[licenceVersion.STATUS], + updatedAt: new Date().toISOString() + } + }) +} + +module.exports = { + go +} diff --git a/app/services/import/legacy-licence.service.js b/app/services/import/legacy-licence.service.js index cf58199af2..e3d8a6e043 100644 --- a/app/services/import/legacy-licence.service.js +++ b/app/services/import/legacy-licence.service.js @@ -7,9 +7,11 @@ const FetchLegacyImportLicenceService = require('./legacy-import/fetch-licence.service.js') const FetchLegacyImportLicenceVersionsService = require('./legacy-import/fetch-licence-versions.service.js') -const LegacyImportLicenceMapper = require('./legacy-import/licence.mapper.js') const ImportLicenceValidatorService = require('./licence-validator.service.js') +const LegacyImportLicenceMapper = require('./legacy-import/licence.mapper.js') +const LegacyImportLicenceVersionMapper = require('./legacy-import/licence-versions.mapper.js') const PersistLicenceService = require('./persist-licence.service.js') +const PersistLicenceVersionsService = require('./persist-licence-versions.service.js') /** * Imports a licence from the legacy import tables. Maps and validates the data and then saves to the database. @@ -28,13 +30,19 @@ async function go (licenceRef) { const mappedLicenceData = await LegacyImportLicenceMapper.go(licenceData, licenceVersionsData) + const mappedLicenceVersionsData = await LegacyImportLicenceVersionMapper.go(licenceVersionsData) + console.debug('Mapped imported licence data: ', mappedLicenceData) + console.debug('Mapped imported licence versions data: ', mappedLicenceVersionsData) + ImportLicenceValidatorService.go(mappedLicenceData) const savedLicence = await PersistLicenceService.go(mappedLicenceData) + const savedLicenceVersions = await PersistLicenceVersionsService.go(mappedLicenceVersionsData, savedLicence.id) console.debug('Saved Licence: ', savedLicence) + console.debug('Saved Licence versions: ', savedLicenceVersions) return savedLicence } diff --git a/app/services/import/persist-licence-versions.service.js b/app/services/import/persist-licence-versions.service.js new file mode 100644 index 0000000000..6939fd3ef0 --- /dev/null +++ b/app/services/import/persist-licence-versions.service.js @@ -0,0 +1,58 @@ +'use strict' + +/** + * Persists the licence versions + * @module PersistLicenceVersionsService + */ + +const LicenceVersionModel = require('../../models/licence-version.model.js') + +/** + * Saves the licence versions + * + * @param {LegacyLicenceVersionsArray} licenceVersions + * @param {string} licenceId + */ +async function go (licenceVersions, licenceId) { + const data = licenceVersions.map((version) => { + return { + ...version, + licenceId + } + }) + + return LicenceVersionModel.query() + .insert(data) + .onConflict('externalId') + .merge([ + 'licenceId', + 'status', + 'startDate', + 'endDate', + 'updatedAt' + ]) +} + +module.exports = { + go +} + +// old code + +// const createLicenceVersion = `insert into water.licence_versions ( +// licence_id, +// issue, +// increment, +// status, +// start_date, +// end_date, +// external_id, +// date_created, +// date_updated +// ) values ($1, $2, $3, $4, $5, $6, $7, now(), now()) on conflict (external_id) do update set +// licence_id = excluded.licence_id, +// status = excluded.status, +// start_date = excluded.start_date, +// end_date = excluded.end_date, +// date_updated = now() +// returning licence_version_id;` From 502daf96e57426cf15dec9de64a3ff02385dda4a Mon Sep 17 00:00:00 2001 From: jonathangoulding Date: Thu, 18 Jul 2024 15:34:12 +0100 Subject: [PATCH 02/75] chore: remove unused comment --- .../persist-licence-versions.service.js | 20 ------------------- 1 file changed, 20 deletions(-) diff --git a/app/services/import/persist-licence-versions.service.js b/app/services/import/persist-licence-versions.service.js index 6939fd3ef0..502bf54749 100644 --- a/app/services/import/persist-licence-versions.service.js +++ b/app/services/import/persist-licence-versions.service.js @@ -36,23 +36,3 @@ async function go (licenceVersions, licenceId) { module.exports = { go } - -// old code - -// const createLicenceVersion = `insert into water.licence_versions ( -// licence_id, -// issue, -// increment, -// status, -// start_date, -// end_date, -// external_id, -// date_created, -// date_updated -// ) values ($1, $2, $3, $4, $5, $6, $7, now(), now()) on conflict (external_id) do update set -// licence_id = excluded.licence_id, -// status = excluded.status, -// start_date = excluded.start_date, -// end_date = excluded.end_date, -// date_updated = now() -// returning licence_version_id;` From 06b2e2b87e0eba1f8255ab251219e2c50dc93aea Mon Sep 17 00:00:00 2001 From: jonathangoulding Date: Mon, 22 Jul 2024 10:39:00 +0100 Subject: [PATCH 03/75] feat: get purpose from db and map to rough format --- .../fetch-licence-versions.service.js | 72 ++++++++++++------- .../legacy-import/licence-versions.mapper.js | 38 +++++++++- .../persist-licence-versions.service.js | 2 + 3 files changed, 82 insertions(+), 30 deletions(-) diff --git a/app/services/import/legacy-import/fetch-licence-versions.service.js b/app/services/import/legacy-import/fetch-licence-versions.service.js index c2466841f5..e816d4497d 100644 --- a/app/services/import/legacy-import/fetch-licence-versions.service.js +++ b/app/services/import/legacy-import/fetch-licence-versions.service.js @@ -6,6 +6,14 @@ */ const { db } = require('../../../../db/db.js') +/** + * Gets the licence versions + * + * Returns the licence version purposes + * + * @param {LegacyLicenceType} licenceData - the licence + * @returns {LegacyLicenceVersionsArray} + */ async function go (licenceData) { const { ID: licenceId, FGAC_REGION_CODE: regionCode } = licenceData @@ -14,36 +22,46 @@ async function go (licenceData) { async function _getLicenceVersions (licenceId, regionCode) { const query = ` - SELECT * - FROM import."NALD_ABS_LIC_VERSIONS" v - WHERE v."FGAC_REGION_CODE" = '${regionCode}' - AND v."AABL_ID" = '${licenceId}' - AND v."STATUS" <> 'DRAFT';` + SELECT versions."EFF_END_DATE", + versions."EFF_ST_DATE", + versions."INCR_NO", + versions."ISSUE_NO", + versions."STATUS", + versions."FGAC_REGION_CODE", + versions."AABL_ID", + (SELECT json_agg(json_build_object( + 'PERIOD_END_DAY', purposes."PERIOD_END_DAY", + 'PERIOD_END_MONTH', purposes."PERIOD_END_MONTH", + 'PERIOD_ST_DAY', purposes."PERIOD_ST_DAY", + 'PERIOD_ST_MONTH', purposes."PERIOD_ST_MONTH", + 'ANNUAL_QTY', purposes."ANNUAL_QTY", + 'DAILY_QTY', purposes."DAILY_QTY", + 'FGAC_REGION_CODE', purposes."FGAC_REGION_CODE", + 'ID', purposes."ID", + 'HOURLY_QTY', purposes."HOURLY_QTY", + 'INST_QTY', purposes."INST_QTY", + 'NOTES', purposes."NOTES", + 'APUR_APPR_CODE', purposes."APUR_APPR_CODE", + 'APUR_APSE_CODE', purposes."APUR_APSE_CODE", + 'APUR_APUS_CODE', purposes."APUR_APUS_CODE", + 'TIMELTD_END_DATE', purposes."TIMELTD_END_DATE", + 'TIMELTD_ST_DATE', purposes."TIMELTD_ST_DATE" + ) + ) + FROM import."NALD_ABS_LIC_PURPOSES" purposes + WHERE purposes."AABV_AABL_ID" = versions."AABL_ID" + AND purposes."AABV_ISSUE_NO" = versions."ISSUE_NO" + AND purposes."AABV_INCR_NO" = versions."INCR_NO" + AND purposes."FGAC_REGION_CODE" = versions."FGAC_REGION_CODE") AS purposes + FROM import."NALD_ABS_LIC_VERSIONS" versions + WHERE versions."FGAC_REGION_CODE" = '${regionCode}' + AND versions."AABL_ID" = '${licenceId}' + AND versions."STATUS" <> 'DRAFT'; + ` const { rows } = await db.raw(query) - return select(rows) -} - -/** - * Maps licence versions to the required format / data - * - * @param {{}} rows - the licence version columns - * @returns {LegacyLicenceVersionsArray} - */ -function select (rows) { - return rows.map((row) => { - return { - EFF_END_DATE: row.EFF_END_DATE, - EFF_ST_DATE: row.EFF_ST_DATE, - INCR_NO: row.INCR_NO, - ISSUE_NO: row.ISSUE_NO, - STATUS: row.STATUS, - // can use region code from licence ? - FGAC_REGION_CODE: row.FGAC_REGION_CODE, - AABL_ID: row.AABL_ID - } - }) + return rows } module.exports = { diff --git a/app/services/import/legacy-import/licence-versions.mapper.js b/app/services/import/legacy-import/licence-versions.mapper.js index 1c38edd663..226d072433 100644 --- a/app/services/import/legacy-import/licence-versions.mapper.js +++ b/app/services/import/legacy-import/licence-versions.mapper.js @@ -6,6 +6,7 @@ */ const { formatStandardDateToISO } = require('../../../lib/dates.lib.js') +const { purpose } = require('../../../controllers/return-requirements.controller') const statuses = { CURR: 'current', @@ -25,13 +26,13 @@ const createExternalId = (licenceVersion) => { * @param {LegacyLicenceVersionsArray} licenceVersions * @returns {} */ -function go (licenceVersions, licenceId) { +function go (licenceVersions) { return _mapLicenceVersions(licenceVersions) } function _mapLicenceVersions (licenceVersions) { return licenceVersions.map((licenceVersion) => { - const issue = licenceVersion.ISSUE_NO + const issue = licenceVersion.ISSUE_NO // mapped to the legacy purpose id - const increment = licenceVersion.INCR_NO return { @@ -42,11 +43,42 @@ function _mapLicenceVersions (licenceVersions) { issue: Number(issue), startDate: formatStandardDateToISO(licenceVersion.EFF_ST_DATE), status: statuses[licenceVersion.STATUS], - updatedAt: new Date().toISOString() + updatedAt: new Date().toISOString(), + purposes: _mapPurposes(licenceVersion) } }) } +function _mapPurposes (licenceVersion) { + return licenceVersion.purposes.map((purpose) => { + return mapLicencePurpose(purpose) + }) +} + module.exports = { go } + +const mapLicencePurpose = (purpose) => { + // double check no longer needed because of update sql + // issue: purpose.AABV_ISSUE_NO, + // increment: purpose.AABV_INCR_NO, + + return { + abstractionPeriodEndDay: purpose.PERIOD_END_DAY, + abstractionPeriodEndMonth: purpose.PERIOD_END_MONTH, + abstractionPeriodStartDay: purpose.PERIOD_ST_DAY, + abstractionPeriodStartMonth: purpose.PERIOD_ST_MONTH, + annualQuantity: purpose.ANNUAL_QTY === 'null' ? null : purpose.ANNUAL_QTY, + dailyQuantity: purpose.DAILY_QTY === 'null' ? null : purpose.DAILY_QTY, + externalId: `${purpose.FGAC_REGION_CODE}:${purpose.ID}`, + hourlyQuantity: purpose.HOURLY_QTY === 'null' ? null : purpose.HOURLY_QTY, + instantQuantity: purpose.INST_QTY === 'null' ? null : purpose.INST_QTY, + notes: purpose.NOTES === 'null' ? null : purpose.NOTES, + purposePrimary: purpose.APUR_APPR_CODE, // need to map to the legacy id + purposeSecondary: purpose.APUR_APSE_CODE, // need to map to the legacy id + purposeUse: purpose.APUR_APUS_CODE, // need to map ? + timeLimitedEndDate: formatStandardDateToISO(purpose.TIMELTD_END_DATE), + timeLimitedStartDate: formatStandardDateToISO(purpose.TIMELTD_ST_DATE) + } +} diff --git a/app/services/import/persist-licence-versions.service.js b/app/services/import/persist-licence-versions.service.js index 502bf54749..df77c8f349 100644 --- a/app/services/import/persist-licence-versions.service.js +++ b/app/services/import/persist-licence-versions.service.js @@ -36,3 +36,5 @@ async function go (licenceVersions, licenceId) { module.exports = { go } + +// primairy, secondary, purpose use(purpose id) From a714ad79a0955e8ba103c8537625dbe94e7957e5 Mon Sep 17 00:00:00 2001 From: jonathangoulding Date: Mon, 22 Jul 2024 15:11:43 +0100 Subject: [PATCH 04/75] feat: add licence version purposes --- .../legacy-import/fetch-licence.service.js | 1 + .../legacy-import/licence-versions.mapper.js | 7 +- .../persist-licence-versions.service.js | 88 +++++++++++++++---- 3 files changed, 73 insertions(+), 23 deletions(-) diff --git a/app/services/import/legacy-import/fetch-licence.service.js b/app/services/import/legacy-import/fetch-licence.service.js index a60eddcab1..b5ee709ec1 100644 --- a/app/services/import/legacy-import/fetch-licence.service.js +++ b/app/services/import/legacy-import/fetch-licence.service.js @@ -35,6 +35,7 @@ async function _getLicenceByRef (licenceRef) { * @param {any} licence * @returns {LegacyLicenceType} */ +// TODO: remove this for the select function select (licence) { return { AREP_AREA_CODE: licence.AREP_AREA_CODE, diff --git a/app/services/import/legacy-import/licence-versions.mapper.js b/app/services/import/legacy-import/licence-versions.mapper.js index 226d072433..aabfcdc60a 100644 --- a/app/services/import/legacy-import/licence-versions.mapper.js +++ b/app/services/import/legacy-import/licence-versions.mapper.js @@ -6,7 +6,6 @@ */ const { formatStandardDateToISO } = require('../../../lib/dates.lib.js') -const { purpose } = require('../../../controllers/return-requirements.controller') const statuses = { CURR: 'current', @@ -75,9 +74,9 @@ const mapLicencePurpose = (purpose) => { hourlyQuantity: purpose.HOURLY_QTY === 'null' ? null : purpose.HOURLY_QTY, instantQuantity: purpose.INST_QTY === 'null' ? null : purpose.INST_QTY, notes: purpose.NOTES === 'null' ? null : purpose.NOTES, - purposePrimary: purpose.APUR_APPR_CODE, // need to map to the legacy id - purposeSecondary: purpose.APUR_APSE_CODE, // need to map to the legacy id - purposeUse: purpose.APUR_APUS_CODE, // need to map ? + primaryPurposeId: purpose.APUR_APPR_CODE, + secondaryPurposeId: purpose.APUR_APSE_CODE, + purposeId: purpose.APUR_APUS_CODE, timeLimitedEndDate: formatStandardDateToISO(purpose.TIMELTD_END_DATE), timeLimitedStartDate: formatStandardDateToISO(purpose.TIMELTD_ST_DATE) } diff --git a/app/services/import/persist-licence-versions.service.js b/app/services/import/persist-licence-versions.service.js index df77c8f349..9b421aedd7 100644 --- a/app/services/import/persist-licence-versions.service.js +++ b/app/services/import/persist-licence-versions.service.js @@ -6,6 +6,10 @@ */ const LicenceVersionModel = require('../../models/licence-version.model.js') +const LicenceVersionPurposeModel = require('../../models/licence-version-purpose.model.js') +const PrimaryPurposeModel = require('../../models/primary-purpose.model.js') +const SecondaryPurposeModel = require('../../models/secondary-purpose.model.js') +const PurposeModel = require('../../models/purpose.model.js') /** * Saves the licence versions @@ -14,27 +18,73 @@ const LicenceVersionModel = require('../../models/licence-version.model.js') * @param {string} licenceId */ async function go (licenceVersions, licenceId) { - const data = licenceVersions.map((version) => { - return { - ...version, - licenceId - } - }) - - return LicenceVersionModel.query() - .insert(data) - .onConflict('externalId') - .merge([ - 'licenceId', - 'status', - 'startDate', - 'endDate', - 'updatedAt' - ]) + return Promise.all(licenceVersions.map(async (version) => { + const versionResult = await LicenceVersionModel.query() + .insert({ + ...version, + licenceId + }) + .onConflict('externalId') + .merge([ + 'licenceId', + 'status', + 'startDate', + 'endDate', + 'updatedAt' + ]) + + return Promise.all(version.purposes.map(async (purpose) => { + const primaryPurpose = await PrimaryPurposeModel.query() + .select('id') + .where('legacyId', purpose.primaryPurposeId) + .first() + .limit(1) + + const secondaryPurpose = await SecondaryPurposeModel.query() + .select('id') + .where('legacyId', purpose.secondaryPurposeId) + .first() + .limit(1) + + const purposeUse = await PurposeModel.query() + .select('id') + .where('legacyId', purpose.purposeId) + .first() + .limit(1) + + return LicenceVersionPurposeModel.query() + .insert({ + licence_version_id: versionResult.id, + ...purpose, + primaryPurposeId: primaryPurpose.id, + secondaryPurposeId: secondaryPurpose.id, + purposeId: purposeUse.id, + createdAt: new Date().toISOString(), + updatedAt: new Date().toISOString() + }) + .onConflict('externalId') + .merge([ + 'abstractionPeriodEndDay', + 'abstractionPeriodEndMonth', + 'abstractionPeriodStartDay', + 'abstractionPeriodStartMonth', + 'annualQuantity', + 'dailyQuantity', + 'externalId', + 'hourlyQuantity', + 'instantQuantity', + 'notes', + 'primaryPurposeId', + 'purposeId', + 'secondaryPurposeId', + 'timeLimitedEndDate', + 'timeLimitedStartDate', + 'updatedAt' + ]) + })) + })) } module.exports = { go } - -// primairy, secondary, purpose use(purpose id) From a22867617fa10fbf34dda65a4f78298f2ffbf061 Mon Sep 17 00:00:00 2001 From: jonathangoulding Date: Mon, 22 Jul 2024 15:39:47 +0100 Subject: [PATCH 05/75] feat: add licence version purposes --- .../legacy-import/licence-versions.mapper.js | 4 - .../persist-licence-versions.service.js | 126 ++++++++++-------- 2 files changed, 67 insertions(+), 63 deletions(-) diff --git a/app/services/import/legacy-import/licence-versions.mapper.js b/app/services/import/legacy-import/licence-versions.mapper.js index aabfcdc60a..accc60fc21 100644 --- a/app/services/import/legacy-import/licence-versions.mapper.js +++ b/app/services/import/legacy-import/licence-versions.mapper.js @@ -59,10 +59,6 @@ module.exports = { } const mapLicencePurpose = (purpose) => { - // double check no longer needed because of update sql - // issue: purpose.AABV_ISSUE_NO, - // increment: purpose.AABV_INCR_NO, - return { abstractionPeriodEndDay: purpose.PERIOD_END_DAY, abstractionPeriodEndMonth: purpose.PERIOD_END_MONTH, diff --git a/app/services/import/persist-licence-versions.service.js b/app/services/import/persist-licence-versions.service.js index 9b421aedd7..e7536da83f 100644 --- a/app/services/import/persist-licence-versions.service.js +++ b/app/services/import/persist-licence-versions.service.js @@ -19,70 +19,78 @@ const PurposeModel = require('../../models/purpose.model.js') */ async function go (licenceVersions, licenceId) { return Promise.all(licenceVersions.map(async (version) => { - const versionResult = await LicenceVersionModel.query() - .insert({ - ...version, - licenceId - }) - .onConflict('externalId') - .merge([ - 'licenceId', - 'status', - 'startDate', - 'endDate', - 'updatedAt' - ]) + const versionResult = await _saveLicenceVersion(version, licenceId) return Promise.all(version.purposes.map(async (purpose) => { - const primaryPurpose = await PrimaryPurposeModel.query() - .select('id') - .where('legacyId', purpose.primaryPurposeId) - .first() - .limit(1) + return _saveLicencePurposes(purpose, versionResult.id) + })) + })) +} - const secondaryPurpose = await SecondaryPurposeModel.query() - .select('id') - .where('legacyId', purpose.secondaryPurposeId) - .first() - .limit(1) +async function _saveLicencePurposes (purpose, licenceVersionId) { + const primaryPurpose = await PrimaryPurposeModel.query() + .select('id') + .where('legacyId', purpose.primaryPurposeId) + .first() + .limit(1) - const purposeUse = await PurposeModel.query() - .select('id') - .where('legacyId', purpose.purposeId) - .first() - .limit(1) + const secondaryPurpose = await SecondaryPurposeModel.query() + .select('id') + .where('legacyId', purpose.secondaryPurposeId) + .first() + .limit(1) - return LicenceVersionPurposeModel.query() - .insert({ - licence_version_id: versionResult.id, - ...purpose, - primaryPurposeId: primaryPurpose.id, - secondaryPurposeId: secondaryPurpose.id, - purposeId: purposeUse.id, - createdAt: new Date().toISOString(), - updatedAt: new Date().toISOString() - }) - .onConflict('externalId') - .merge([ - 'abstractionPeriodEndDay', - 'abstractionPeriodEndMonth', - 'abstractionPeriodStartDay', - 'abstractionPeriodStartMonth', - 'annualQuantity', - 'dailyQuantity', - 'externalId', - 'hourlyQuantity', - 'instantQuantity', - 'notes', - 'primaryPurposeId', - 'purposeId', - 'secondaryPurposeId', - 'timeLimitedEndDate', - 'timeLimitedStartDate', - 'updatedAt' - ]) - })) - })) + const purposeUse = await PurposeModel.query() + .select('id') + .where('legacyId', purpose.purposeId) + .first() + .limit(1) + + return LicenceVersionPurposeModel.query() + .insert({ + licenceVersionId, + ...purpose, + primaryPurposeId: primaryPurpose.id, + secondaryPurposeId: secondaryPurpose.id, + purposeId: purposeUse.id, + createdAt: new Date().toISOString(), + updatedAt: new Date().toISOString() + }) + .onConflict('externalId') + .merge([ + 'abstractionPeriodEndDay', + 'abstractionPeriodEndMonth', + 'abstractionPeriodStartDay', + 'abstractionPeriodStartMonth', + 'annualQuantity', + 'dailyQuantity', + 'externalId', + 'hourlyQuantity', + 'instantQuantity', + 'notes', + 'primaryPurposeId', + 'purposeId', + 'secondaryPurposeId', + 'timeLimitedEndDate', + 'timeLimitedStartDate', + 'updatedAt' + ]) +} + +async function _saveLicenceVersion (version, licenceId) { + return LicenceVersionModel.query() + .insert({ + ...version, + licenceId + }) + .onConflict('externalId') + .merge([ + 'licenceId', + 'status', + 'startDate', + 'endDate', + 'updatedAt' + ]) } module.exports = { From 731b99a4ace1e0e58b18d0e2c55bb472bbaa5f15 Mon Sep 17 00:00:00 2001 From: jonathangoulding Date: Mon, 22 Jul 2024 16:13:43 +0100 Subject: [PATCH 06/75] chore: update js docs --- .../fetch-licence-versions.service.js | 21 ++++++++ .../legacy-import/licence-versions.mapper.js | 48 +++++++++++++------ .../import/legacy-import/licence.mapper.js | 2 +- .../import/licence-validator.service.js | 46 ++++++++++++++++-- .../persist-licence-versions.service.js | 4 +- 5 files changed, 98 insertions(+), 23 deletions(-) diff --git a/app/services/import/legacy-import/fetch-licence-versions.service.js b/app/services/import/legacy-import/fetch-licence-versions.service.js index e816d4497d..bd52db6389 100644 --- a/app/services/import/legacy-import/fetch-licence-versions.service.js +++ b/app/services/import/legacy-import/fetch-licence-versions.service.js @@ -79,9 +79,30 @@ module.exports = { * @property {string} STATUS - enum - 'DRAFT', 'SUPER', 'CURR' (Draft will not be selected) * @property {string} FGAC_REGION_CODE * @property {string} AABL_ID + * @property {LegacyLicenceVersionsPurposesType} purposes */ /** * An array of legacy licence versions. * @typedef {LegacyLicenceVersionsType[]} LegacyLicenceVersionsArray */ + +/** + * @typedef {Object} LegacyLicenceVersionsPurposesType + * @property {string} PERIOD_END_DAY - The end day of the period. + * @property {string} PERIOD_END_MONTH - The end month of the period. + * @property {string} PERIOD_ST_DAY - The start day of the period. + * @property {string} PERIOD_ST_MONTH - The start month of the period. + * @property {string} ANNUAL_QTY - The annual quantity. + * @property {string} DAILY_QTY - The daily quantity. + * @property {string} FGAC_REGION_CODE - The FGAC region code. + * @property {string} ID - The identifier. + * @property {string} HOURLY_QTY - The hourly quantity. + * @property {string} INST_QTY - The instant quantity. + * @property {string} NOTES - Additional notes. + * @property {string} APUR_APPR_CODE - The APUR approval code. + * @property {string} APUR_APSE_CODE - The APUR secondary code. + * @property {string} APUR_APUS_CODE - The APUR usage code. + * @property {string} TIMELTD_END_DATE - The time-limited end date. + * @property {string} TIMELTD_ST_DATE - The time-limited start date. + */ diff --git a/app/services/import/legacy-import/licence-versions.mapper.js b/app/services/import/legacy-import/licence-versions.mapper.js index accc60fc21..6952bdbc12 100644 --- a/app/services/import/legacy-import/licence-versions.mapper.js +++ b/app/services/import/legacy-import/licence-versions.mapper.js @@ -23,12 +23,18 @@ const createExternalId = (licenceVersion) => { * Maps the import licence versions data to the desired format * * @param {LegacyLicenceVersionsArray} licenceVersions - * @returns {} + * @returns {ImportLicenceVersionType[]} */ function go (licenceVersions) { return _mapLicenceVersions(licenceVersions) } +/** + * Iterates the import licence versions + * + * @param {LegacyLicenceVersionsArray} licenceVersions + * @returns {ImportLicenceVersionType[]} + */ function _mapLicenceVersions (licenceVersions) { return licenceVersions.map((licenceVersion) => { const issue = licenceVersion.ISSUE_NO // mapped to the legacy purpose id - @@ -48,27 +54,35 @@ function _mapLicenceVersions (licenceVersions) { }) } +/** + * Iterates the import licence versions purposes + * + * @param {LegacyLicenceVersionsType} licenceVersion + * @returns {ImportLicenceVersionPurposeType} + */ function _mapPurposes (licenceVersion) { return licenceVersion.purposes.map((purpose) => { - return mapLicencePurpose(purpose) + return _mapPurpose(purpose) }) } -module.exports = { - go -} - -const mapLicencePurpose = (purpose) => { +/** + * Maps the import licence versions purposes data to the desired format + * + * @param {LegacyLicenceVersionsPurposesType} purpose + * @returns {ImportLicenceVersionPurposeType} + */ +const _mapPurpose = (purpose) => { return { - abstractionPeriodEndDay: purpose.PERIOD_END_DAY, - abstractionPeriodEndMonth: purpose.PERIOD_END_MONTH, - abstractionPeriodStartDay: purpose.PERIOD_ST_DAY, - abstractionPeriodStartMonth: purpose.PERIOD_ST_MONTH, - annualQuantity: purpose.ANNUAL_QTY === 'null' ? null : purpose.ANNUAL_QTY, - dailyQuantity: purpose.DAILY_QTY === 'null' ? null : purpose.DAILY_QTY, + abstractionPeriodEndDay: Number(purpose.PERIOD_END_DAY), + abstractionPeriodEndMonth: Number(purpose.PERIOD_END_MONTH), + abstractionPeriodStartDay: Number(purpose.PERIOD_ST_DAY), + abstractionPeriodStartMonth: Number(purpose.PERIOD_ST_MONTH), + annualQuantity: purpose.ANNUAL_QTY === 'null' ? null : Number(purpose.ANNUAL_QTY), + dailyQuantity: purpose.DAILY_QTY === 'null' ? null : Number(purpose.DAILY_QTY), externalId: `${purpose.FGAC_REGION_CODE}:${purpose.ID}`, - hourlyQuantity: purpose.HOURLY_QTY === 'null' ? null : purpose.HOURLY_QTY, - instantQuantity: purpose.INST_QTY === 'null' ? null : purpose.INST_QTY, + hourlyQuantity: purpose.HOURLY_QTY === 'null' ? null : Number(purpose.HOURLY_QTY), + instantQuantity: purpose.INST_QTY === 'null' ? null : Number(purpose.INST_QTY), notes: purpose.NOTES === 'null' ? null : purpose.NOTES, primaryPurposeId: purpose.APUR_APPR_CODE, secondaryPurposeId: purpose.APUR_APSE_CODE, @@ -77,3 +91,7 @@ const mapLicencePurpose = (purpose) => { timeLimitedStartDate: formatStandardDateToISO(purpose.TIMELTD_ST_DATE) } } + +module.exports = { + go +} diff --git a/app/services/import/legacy-import/licence.mapper.js b/app/services/import/legacy-import/licence.mapper.js index 9cdfdaff6a..400b75dfdf 100644 --- a/app/services/import/legacy-import/licence.mapper.js +++ b/app/services/import/legacy-import/licence.mapper.js @@ -36,7 +36,7 @@ function _mapLicence (licence, licenceVersions) { * Creates a JSON object of the region data * * @param {Object} licenceData - * @return {RegionsType} + * @return {ImportRegionType} */ const _regions = (licenceData) => { const historicalAreaCode = licenceData.AREP_AREA_CODE diff --git a/app/services/import/licence-validator.service.js b/app/services/import/licence-validator.service.js index ddaba850d5..d8a2b88010 100644 --- a/app/services/import/licence-validator.service.js +++ b/app/services/import/licence-validator.service.js @@ -1,18 +1,18 @@ 'use strict' /** - * Validates a licence object + * Validates a import licence object * @module ImportLicenceValidatorService */ const ImportLicenceValidator = require('../../validators/import/licence.validator.js') /** - * Validates a licence is in the correct shape and format to persist in the database + * Validates a import licence is in the correct shape and format to persist in the database * * If the validation fails throw an error * - * @param {ImportLicenceType} licence - The licence to validator + * @param {ImportLicenceType} licence - The licence to validate */ function go (licence) { ImportLicenceValidator.go(licence) @@ -30,7 +30,7 @@ module.exports = { * @property {string | null} lapsedDate * @property {string} licenceRef * @property {number} naldRegionId - * @property {RegionsType} regions + * @property {ImportRegionType} regions * @property {string | null} revokedDate * @property {string} startDate * @property {boolean} waterUndertaker @@ -38,7 +38,7 @@ module.exports = { /** * A valid licence 'regions' json colum - * @typedef {Object} RegionsType + * @typedef {Object} ImportRegionType * * @property {string} regionalChargeArea * @property {string} localEnvironmentAgencyPlanCode @@ -46,3 +46,39 @@ module.exports = { * @property {string} standardUnitChargeCode * */ + +/** + * @typedef {Object} ImportLicenceVersionPurposeType + * + * @property {number} abstractionPeriodEndDay - The end day of the abstraction period. + * @property {number} abstractionPeriodEndMonth - The end month of the abstraction period. + * @property {number} abstractionPeriodStartDay - The start day of the abstraction period. + * @property {number} abstractionPeriodStartMonth - The start month of the abstraction period. + * @property {number|null} annualQuantity - The annual quantity; null if not applicable. + * @property {number|null} dailyQuantity - The daily quantity; null if not applicable. + * @property {string} externalId - The external identifier for the purpose. + * @property {number|null} hourlyQuantity - The hourly quantity; null if not applicable. + * @property {number|null} instantQuantity - The instant quantity; null if not applicable. + * @property {string|null} notes - Additional notes; null if not applicable. + * @property {string} primaryPurposeId - The primary purpose identifier. + * @property {string} secondaryPurposeId - The secondary purpose identifier. + * @property {string} purposeId - The purpose identifier. + * @property {string|null} timeLimitedEndDate - The end date of the time-limited period in ISO format; + * null if not applicable. + * @property {string|null} timeLimitedStartDate - The start date of the time-limited period in ISO format; + * null if not applicable. + */ + +/** + * @typedef {Object} ImportLicenceVersionType + * + * @property {string} createdAt - The creation timestamp in ISO format. + * @property {string|null} endDate - The end date in ISO format; null if not applicable. + * @property {string} externalId - The external identifier for the licence version. + * @property {number} increment - The increment number. + * @property {number} issue - The issue number. + * @property {string|null} startDate - The start date in ISO format; null if not applicable. + * @property {string} status - The status of the licence version. + * @property {string} updatedAt - The update timestamp in ISO format. + * @property {ImportLicenceVersionPurposeType[]} purposes - The array of purposes associated with the licence version. + */ diff --git a/app/services/import/persist-licence-versions.service.js b/app/services/import/persist-licence-versions.service.js index e7536da83f..698e59e357 100644 --- a/app/services/import/persist-licence-versions.service.js +++ b/app/services/import/persist-licence-versions.service.js @@ -1,7 +1,7 @@ 'use strict' /** - * Persists the licence versions + * Persists the licence versions, purposes and conditions * @module PersistLicenceVersionsService */ @@ -14,7 +14,7 @@ const PurposeModel = require('../../models/purpose.model.js') /** * Saves the licence versions * - * @param {LegacyLicenceVersionsArray} licenceVersions + * @param {ImportLicenceVersionType[]} licenceVersions * @param {string} licenceId */ async function go (licenceVersions, licenceId) { From afe6f11a6f4dc358a057f910c684ad9002d7793c Mon Sep 17 00:00:00 2001 From: jonathangoulding Date: Mon, 22 Jul 2024 16:35:53 +0100 Subject: [PATCH 07/75] feat: add licence version and purpose validator --- .../fetch-licence-versions.service.js | 2 +- app/services/import/legacy-licence.service.js | 6 +- .../import/licence-validator.service.js | 5 +- .../import/licence-versions.validator.js | 59 +++++++++++++++++++ 4 files changed, 67 insertions(+), 5 deletions(-) create mode 100644 app/validators/import/licence-versions.validator.js diff --git a/app/services/import/legacy-import/fetch-licence-versions.service.js b/app/services/import/legacy-import/fetch-licence-versions.service.js index bd52db6389..280e0f175a 100644 --- a/app/services/import/legacy-import/fetch-licence-versions.service.js +++ b/app/services/import/legacy-import/fetch-licence-versions.service.js @@ -12,7 +12,7 @@ const { db } = require('../../../../db/db.js') * Returns the licence version purposes * * @param {LegacyLicenceType} licenceData - the licence - * @returns {LegacyLicenceVersionsArray} + * @returns {Promise} */ async function go (licenceData) { const { ID: licenceId, FGAC_REGION_CODE: regionCode } = licenceData diff --git a/app/services/import/legacy-licence.service.js b/app/services/import/legacy-licence.service.js index e3d8a6e043..ed6e4f02f4 100644 --- a/app/services/import/legacy-licence.service.js +++ b/app/services/import/legacy-licence.service.js @@ -28,15 +28,15 @@ async function go (licenceRef) { console.debug('Imported licence versions data: ', licenceVersionsData) - const mappedLicenceData = await LegacyImportLicenceMapper.go(licenceData, licenceVersionsData) + const mappedLicenceData = LegacyImportLicenceMapper.go(licenceData, licenceVersionsData) - const mappedLicenceVersionsData = await LegacyImportLicenceVersionMapper.go(licenceVersionsData) + const mappedLicenceVersionsData = LegacyImportLicenceVersionMapper.go(licenceVersionsData) console.debug('Mapped imported licence data: ', mappedLicenceData) console.debug('Mapped imported licence versions data: ', mappedLicenceVersionsData) - ImportLicenceValidatorService.go(mappedLicenceData) + ImportLicenceValidatorService.go(mappedLicenceData, mappedLicenceVersionsData) const savedLicence = await PersistLicenceService.go(mappedLicenceData) const savedLicenceVersions = await PersistLicenceVersionsService.go(mappedLicenceVersionsData, savedLicence.id) diff --git a/app/services/import/licence-validator.service.js b/app/services/import/licence-validator.service.js index d8a2b88010..026181a0eb 100644 --- a/app/services/import/licence-validator.service.js +++ b/app/services/import/licence-validator.service.js @@ -6,6 +6,7 @@ */ const ImportLicenceValidator = require('../../validators/import/licence.validator.js') +const ImportLicenceVersionsValidator = require('../../validators/import/licence-versions.validator.js') /** * Validates a import licence is in the correct shape and format to persist in the database @@ -13,9 +14,11 @@ const ImportLicenceValidator = require('../../validators/import/licence.validato * If the validation fails throw an error * * @param {ImportLicenceType} licence - The licence to validate + * @param {ImportLicenceVersionType[]} licenceVersions - The licence versions to validate */ -function go (licence) { +function go (licence, licenceVersions) { ImportLicenceValidator.go(licence) + ImportLicenceVersionsValidator.go(licenceVersions) } module.exports = { diff --git a/app/validators/import/licence-versions.validator.js b/app/validators/import/licence-versions.validator.js new file mode 100644 index 0000000000..dcadbe0028 --- /dev/null +++ b/app/validators/import/licence-versions.validator.js @@ -0,0 +1,59 @@ +'use strict' + +/** + * @module ImportLicenceVersionsValidator + */ + +const Joi = require('joi') + +const CustomDateValidator = require('../custom/date.validators.js') + +/** + * Checks that the data for inserting/updating the water.licence table is valid + * + * @param {ImportLicenceVersionType[]} data The data to be validated + * + * Throws an error if anything fails + * + */ +function go (data) { + const purposeSchema = Joi.object({ + primaryPurposeId: Joi.string().required(), + secondaryPurposeId: Joi.string().required(), + purposeId: Joi.string().required(), + abstractionPeriodStartDay: Joi.number().integer().min(1).max(31).required(), + abstractionPeriodStartMonth: Joi.number().integer().min(1).max(12).required(), + abstractionPeriodEndDay: Joi.number().integer().min(1).max(31).required(), + abstractionPeriodEndMonth: Joi.number().integer().min(1).max(12).required(), + timeLimitedStartDate: Joi.date().iso().allow(null), + timeLimitedEndDate: Joi.date().iso().allow(null), + notes: Joi.string().allow(null), + annualQuantity: Joi.number().allow(null), + externalId: Joi.string().required(), + instantQuantity: Joi.number().allow(null), + hourlyQuantity: Joi.number().allow(null), + dailyQuantity: Joi.number().allow(null) + }) + + const schema = Joi.array().items({ + createdAt: Joi.date().iso().required(), + endDate: Joi.date().iso().required().allow(null), + externalId: Joi.string().required(), + increment: Joi.number().required(), + issue: Joi.number().required(), + startDate: Joi.date().iso().required().allow(null), + status: Joi.string().required(), + updatedAt: Joi.date().iso().required(), + purposes: Joi.array().items(purposeSchema).required() + }) + + const result = schema.validate(data) + + if (Object.hasOwn(result, 'error')) { + throw new Error(result.error.details[0].message) + } +} + +module.exports = { + go +} From 3dc605b8c1698644cc28c51b3a3181e8f1dc5011 Mon Sep 17 00:00:00 2001 From: jonathangoulding Date: Mon, 22 Jul 2024 16:36:51 +0100 Subject: [PATCH 08/75] feat: add licence version and purpose validator --- app/validators/import/licence-versions.validator.js | 5 ++--- app/validators/import/licence.validator.js | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/app/validators/import/licence-versions.validator.js b/app/validators/import/licence-versions.validator.js index dcadbe0028..3091431fe2 100644 --- a/app/validators/import/licence-versions.validator.js +++ b/app/validators/import/licence-versions.validator.js @@ -6,10 +6,9 @@ const Joi = require('joi') -const CustomDateValidator = require('../custom/date.validators.js') - /** - * Checks that the data for inserting/updating the water.licence table is valid + * Checks that the data for inserting/updating the public.licence_versions + * and public.licence_versions_purposes table is valid * * @param {ImportLicenceVersionType[]} data The data to be validated * diff --git a/app/validators/import/licence.validator.js b/app/validators/import/licence.validator.js index bc2537f5eb..ed65b5ada5 100644 --- a/app/validators/import/licence.validator.js +++ b/app/validators/import/licence.validator.js @@ -9,7 +9,7 @@ const Joi = require('joi') const CustomDateValidator = require('../custom/date.validators.js') /** - * Checks that the data for inserting/updating the water.licence table is valid + * Checks that the data for inserting/updating the public.licence table is valid * * @param {ImportLicenceType} data The data to be validated * From d829fbf1fdfb30ad24904f19870ad3d45756b8e0 Mon Sep 17 00:00:00 2001 From: jonathangoulding Date: Tue, 23 Jul 2024 12:15:12 +0100 Subject: [PATCH 09/75] test: licence versions mapper --- .../legacy-import/licence-versions.mapper.js | 7 +- .../persist-licence-versions.service.js | 4 +- .../import/licence-versions.validator.js | 2 - .../licence-version-purposes.fixture.js | 22 ++ test/services/import/_fixtures/versions.js | 17 +- .../licence-versions.mapper.test.js | 313 ++++++++++++++++++ .../legacy-import/licence.mapper.test.js | 4 +- 7 files changed, 355 insertions(+), 14 deletions(-) create mode 100644 test/services/import/_fixtures/licence-version-purposes.fixture.js create mode 100644 test/services/import/legacy-import/licence-versions.mapper.test.js diff --git a/app/services/import/legacy-import/licence-versions.mapper.js b/app/services/import/legacy-import/licence-versions.mapper.js index 6952bdbc12..f672dbf01c 100644 --- a/app/services/import/legacy-import/licence-versions.mapper.js +++ b/app/services/import/legacy-import/licence-versions.mapper.js @@ -10,12 +10,14 @@ const { formatStandardDateToISO } = require('../../../lib/dates.lib.js') const statuses = { CURR: 'current', SUPER: 'superseded', - DRAFT: 'draft' + DRAFT: 'draft' // todo: check this can be removed as it the sql does not get draft status } const createExternalId = (licenceVersion) => { const { FGAC_REGION_CODE, AABL_ID, ISSUE_NO, INCR_NO } = licenceVersion + // todo: should we throw here if we can't build up ? + // todo: ask if this is used else where return `${FGAC_REGION_CODE}:${AABL_ID}:${ISSUE_NO}:${INCR_NO}` } @@ -41,14 +43,13 @@ function _mapLicenceVersions (licenceVersions) { const increment = licenceVersion.INCR_NO return { - createdAt: new Date().toISOString(), endDate: formatStandardDateToISO(licenceVersion.EFF_END_DATE), externalId: createExternalId(licenceVersion), + // todo: do we still need to store these ? increment / issue increment: Number(increment), issue: Number(issue), startDate: formatStandardDateToISO(licenceVersion.EFF_ST_DATE), status: statuses[licenceVersion.STATUS], - updatedAt: new Date().toISOString(), purposes: _mapPurposes(licenceVersion) } }) diff --git a/app/services/import/persist-licence-versions.service.js b/app/services/import/persist-licence-versions.service.js index 698e59e357..7abdb5e901 100644 --- a/app/services/import/persist-licence-versions.service.js +++ b/app/services/import/persist-licence-versions.service.js @@ -81,7 +81,9 @@ async function _saveLicenceVersion (version, licenceId) { return LicenceVersionModel.query() .insert({ ...version, - licenceId + licenceId, + createdAt: new Date().toISOString(), + updatedAt: new Date().toISOString() }) .onConflict('externalId') .merge([ diff --git a/app/validators/import/licence-versions.validator.js b/app/validators/import/licence-versions.validator.js index 3091431fe2..11ff068099 100644 --- a/app/validators/import/licence-versions.validator.js +++ b/app/validators/import/licence-versions.validator.js @@ -35,14 +35,12 @@ function go (data) { }) const schema = Joi.array().items({ - createdAt: Joi.date().iso().required(), endDate: Joi.date().iso().required().allow(null), externalId: Joi.string().required(), increment: Joi.number().required(), issue: Joi.number().required(), startDate: Joi.date().iso().required().allow(null), status: Joi.string().required(), - updatedAt: Joi.date().iso().required(), purposes: Joi.array().items(purposeSchema).required() }) diff --git a/test/services/import/_fixtures/licence-version-purposes.fixture.js b/test/services/import/_fixtures/licence-version-purposes.fixture.js new file mode 100644 index 0000000000..d1d6bbd048 --- /dev/null +++ b/test/services/import/_fixtures/licence-version-purposes.fixture.js @@ -0,0 +1,22 @@ +'use strict' + +const purpose = { + PERIOD_END_DAY: '31', + PERIOD_END_MONTH: '3', + PERIOD_ST_DAY: '1', + PERIOD_ST_MONTH: '4', + ANNUAL_QTY: '545520', + DAILY_QTY: '1500.2', + FGAC_REGION_CODE: '3', + ID: '10000004', + HOURLY_QTY: '140.929', + INST_QTY: 'null', + NOTES: 'null', + APUR_APPR_CODE: 'I', + APUR_APSE_CODE: 'OTI', + APUR_APUS_CODE: '160', + TIMELTD_END_DATE: 'null', + TIMELTD_ST_DATE: 'null' +} + +module.exports = purpose diff --git a/test/services/import/_fixtures/versions.js b/test/services/import/_fixtures/versions.js index eba1a14ddd..6eba310294 100644 --- a/test/services/import/_fixtures/versions.js +++ b/test/services/import/_fixtures/versions.js @@ -1,9 +1,14 @@ 'use strict' -const versions = [ - { - EFF_ST_DATE: '05/06/2005' - } -] +const version = { + EFF_END_DATE: '04/06/2007', + EFF_ST_DATE: '05/06/2005', + INCR_NO: '0', + ISSUE_NO: '100', + STATUS: 'SUPER', + FGAC_REGION_CODE: '3', + AABL_ID: '10000003', + purposes: [] +} -module.exports = versions +module.exports = version diff --git a/test/services/import/legacy-import/licence-versions.mapper.test.js b/test/services/import/legacy-import/licence-versions.mapper.test.js new file mode 100644 index 0000000000..c2f0aabfcb --- /dev/null +++ b/test/services/import/legacy-import/licence-versions.mapper.test.js @@ -0,0 +1,313 @@ +'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 FixtureVersions = require('../_fixtures/versions.js') +const FixtureLicenceVersionPurposes = require('../_fixtures/licence-version-purposes.fixture.js') + +// Thing under test +const LegacyImportLicenceVersionMapper = + require('../../../../app/services/import/legacy-import/licence-versions.mapper.js') + +describe.only('Legacy import licence versions mapper', () => { + let licenceVersions + let purpose + let version + + beforeEach(() => { + purpose = FixtureLicenceVersionPurposes + version = FixtureVersions + + licenceVersions = [{ ...version, purposes: [{ ...purpose }] }] + }) + + it('returns the licence version', () => { + const results = LegacyImportLicenceVersionMapper.go(licenceVersions) + + expect(results).to.equal([{ + endDate: '2007-06-04', + externalId: '3:10000003:100:0', + increment: 0, + issue: 100, + purposes: [ + { + abstractionPeriodEndDay: 31, + abstractionPeriodEndMonth: 3, + abstractionPeriodStartDay: 1, + abstractionPeriodStartMonth: 4, + annualQuantity: 545520, + dailyQuantity: 1500.2, + externalId: '3:10000004', + hourlyQuantity: 140.929, + instantQuantity: null, + notes: null, + primaryPurposeId: 'I', + purposeId: '160', + secondaryPurposeId: 'OTI', + timeLimitedEndDate: null, + timeLimitedStartDate: null + } + ], + startDate: '2005-06-05', + status: 'superseded' + }]) + }) + + describe('licence versions', () => { + describe('the "endDate" property', () => { + describe('when the licence version has EFF_END_DATE', () => { + it('returns EFF_END_DATE as the start date in the correct format', () => { + const [result] = LegacyImportLicenceVersionMapper.go(licenceVersions) + + expect(result.endDate).to.equal('2007-06-04') + }) + }) + }) + + describe('the "externalId" property', () => { + describe('when the licence version has FGAC_REGION_CODE, AABL_ID, ISSUE_NO, INCR_NO', () => { + it('returns externalId in the format {FGAC_REGION_CODE}:{AABL_ID}:{ISSUE_NO}:{INCR_NO}', () => { + const [result] = LegacyImportLicenceVersionMapper.go(licenceVersions) + + expect(result.externalId).to.equal('3:10000003:100:0') + }) + }) + }) + + describe('the "increment" property', () => { + describe('when the licence version has INCR_NO', () => { + it('returns INCR_NO as a number', () => { + const [result] = LegacyImportLicenceVersionMapper.go(licenceVersions) + + expect(result.increment).to.be.number() + expect(result.increment).to.equal(0) + }) + }) + }) + + describe('the "increment" property', () => { + describe('when the licence version has INCR_NO', () => { + it('returns INCR_NO as a number', () => { + const [result] = LegacyImportLicenceVersionMapper.go(licenceVersions) + + expect(result.increment).to.be.number() + expect(result.increment).to.equal(0) + }) + }) + }) + + describe('the "issue" property', () => { + describe('when the licence version has ISSUE_NO', () => { + it('returns ISSUE_NO as a number', () => { + const [result] = LegacyImportLicenceVersionMapper.go(licenceVersions) + + expect(result.issue).to.be.number() + expect(result.issue).to.equal(100) + }) + }) + }) + + describe('the "status" property', () => { + describe('when the licence version has STATUS and is CURR', () => { + beforeEach(() => { + licenceVersions[0].STATUS = 'CURR' + }) + + it('returns the status as "curren"t', () => { + const [result] = LegacyImportLicenceVersionMapper.go(licenceVersions) + + expect(result.status).to.equal('current') + }) + }) + + describe('when the licence version has STATUS and is SUPER', () => { + it('returns the status as "superseded"', () => { + const [result] = LegacyImportLicenceVersionMapper.go(licenceVersions) + + expect(result.status).to.equal('superseded') + }) + }) + }) + + describe('the "startDate" property', () => { + describe('when the licence version has EFF_ST_DATE', () => { + it('returns EFF_ST_DATE as the start date in the correct format', () => { + const [result] = LegacyImportLicenceVersionMapper.go(licenceVersions) + + expect(result.startDate).to.equal('2005-06-05') + }) + }) + }) + + describe('licence versions purposes ', () => { + describe('the "abstractionPeriodEndDay" property', () => { + describe('when purpose has PERIOD_END_DAY', () => { + it('returns PERIOD_END_DAY as a number', () => { + const [{ purposes: [result] }] = LegacyImportLicenceVersionMapper.go(licenceVersions) + + expect(result.abstractionPeriodEndDay).to.be.number() + expect(result.abstractionPeriodEndDay).to.equal(31) + }) + }) + }) + + describe('the "abstractionPeriodEndMonth" property', () => { + describe('when purpose has PERIOD_END_MONTH', () => { + it('returns PERIOD_END_MONTH as a number', () => { + const [{ purposes: [result] }] = LegacyImportLicenceVersionMapper.go(licenceVersions) + + expect(result.abstractionPeriodEndMonth).to.be.number() + expect(result.abstractionPeriodEndMonth).to.equal(3) + }) + }) + }) + + describe('the "abstractionPeriodStartDay" property', () => { + describe('when purpose has PERIOD_ST_DAY', () => { + it('returns PERIOD_ST_DAY as a number', () => { + const [{ purposes: [result] }] = LegacyImportLicenceVersionMapper.go(licenceVersions) + + expect(result.abstractionPeriodStartDay).to.be.number() + expect(result.abstractionPeriodStartDay).to.equal(1) + }) + }) + }) + + describe('the "abstractionPeriodStartMonth" property', () => { + describe('when purpose has PERIOD_ST_MONTH', () => { + it('returns PERIOD_ST_MONTH as a number', () => { + const [{ purposes: [result] }] = LegacyImportLicenceVersionMapper.go(licenceVersions) + + expect(result.abstractionPeriodStartMonth).to.be.number() + expect(result.abstractionPeriodStartMonth).to.equal(4) + }) + }) + }) + + describe('the "abstractionPeriodStartMonth" property', () => { + describe('when purpose has PERIOD_ST_MONTH', () => { + it('returns PERIOD_ST_MONTH as a number', () => { + const [{ purposes: [result] }] = LegacyImportLicenceVersionMapper.go(licenceVersions) + + expect(result.abstractionPeriodStartMonth).to.be.number() + expect(result.abstractionPeriodStartMonth).to.equal(4) + }) + }) + }) + + describe('the "annualQuantity" property', () => { + describe('when purpose has ANNUAL_QTY is "null"', () => { + beforeEach(() => { + licenceVersions[0].purposes = [ + { ...purpose, ANNUAL_QTY: 'null' } + ] + }) + + it('returns null', () => { + const [{ purposes: [result] }] = LegacyImportLicenceVersionMapper.go(licenceVersions) + + expect(result.annualQuantity).to.be.null() + }) + }) + + describe('when purpose has ANNUAL_QTY', () => { + it('returns ANNUAL_QTY as a number', () => { + const [{ purposes: [result] }] = LegacyImportLicenceVersionMapper.go(licenceVersions) + + expect(result.annualQuantity).to.be.number() + expect(result.annualQuantity).to.equal(545520) + }) + }) + }) + + describe('the "dailyQuantity" property', () => { + describe('when purpose has DAILY_QTY is "null"', () => { + beforeEach(() => { + licenceVersions[0].purposes = [ + { ...purpose, DAILY_QTY: 'null' } + ] + }) + + it('returns null', () => { + const [{ purposes: [result] }] = LegacyImportLicenceVersionMapper.go(licenceVersions) + + expect(result.dailyQuantity).to.be.null() + }) + }) + + describe('when purpose has DAILY_QTY', () => { + it('returns DAILY_QTY as a number', () => { + const [{ purposes: [result] }] = LegacyImportLicenceVersionMapper.go(licenceVersions) + + expect(result.dailyQuantity).to.be.number() + expect(result.dailyQuantity).to.equal(1500.2) + }) + }) + }) + + describe('the "hourlyQuantity" property', () => { + describe('when purpose has HOURLY_QTY is "null"', () => { + beforeEach(() => { + licenceVersions[0].purposes = [ + { ...purpose, HOURLY_QTY: 'null' } + ] + }) + + it('returns null', () => { + const [{ purposes: [result] }] = LegacyImportLicenceVersionMapper.go(licenceVersions) + + expect(result.hourlyQuantity).to.be.null() + }) + }) + + describe('when purpose has HOURLY_QTY', () => { + it('returns HOURLY_QTY as a number', () => { + const [{ purposes: [result] }] = LegacyImportLicenceVersionMapper.go(licenceVersions) + + expect(result.hourlyQuantity).to.be.number() + expect(result.hourlyQuantity).to.equal(140.929) + }) + }) + }) + + describe('the "instantQuantity" property', () => { + describe('when purpose has INST_QTY is "null"', () => { + it('returns null', () => { + const [{ purposes: [result] }] = LegacyImportLicenceVersionMapper.go(licenceVersions) + + expect(result.instantQuantity).to.be.null() + }) + }) + + describe('when purpose has INST_QTY', () => { + beforeEach(() => { + licenceVersions[0].purposes = [ + { ...purpose, INST_QTY: '123' } + ] + }) + + it('returns INST_QTY as a number', () => { + const [{ purposes: [result] }] = LegacyImportLicenceVersionMapper.go(licenceVersions) + + expect(result.instantQuantity).to.be.number() + expect(result.instantQuantity).to.equal(123) + }) + }) + }) + + // externalId: '3:10000004', + // notes: null, + // primaryPurposeId: 'I', + // purposeId: '160', + // secondaryPurposeId: 'OTI', + // timeLimitedEndDate: null, + // timeLimitedStartDate: null + }) + }) +}) diff --git a/test/services/import/legacy-import/licence.mapper.test.js b/test/services/import/legacy-import/licence.mapper.test.js index 56e7811dcd..14f6f3760c 100644 --- a/test/services/import/legacy-import/licence.mapper.test.js +++ b/test/services/import/legacy-import/licence.mapper.test.js @@ -9,7 +9,7 @@ const { expect } = Code // Test helpers const FixtureLicence = require('../_fixtures/licence.js') -const FixtureVersions = require('../_fixtures/versions.js') +const FixtureVersion = require('../_fixtures/versions.js') // Thing under test const LegacyImportLicenceMapper = @@ -154,7 +154,7 @@ describe('Legacy import licence mapper', () => { describe('then start date of the earliest non-draft licence version is used', () => { it('returns the start date in the ISO format', () => { // need to add licence versions - const result = LegacyImportLicenceMapper.go(licence, FixtureVersions) + const result = LegacyImportLicenceMapper.go(licence, [{ ...FixtureVersion }]) expect(result.startDate).to.equal('2005-06-05') }) From 1b822a0b96da32d43edc20182934e65478bd3e6c Mon Sep 17 00:00:00 2001 From: jonathangoulding Date: Tue, 23 Jul 2024 13:22:29 +0100 Subject: [PATCH 10/75] test: licence versions mapper --- .../licence-versions.mapper.test.js | 122 ++++++++++++++++-- 1 file changed, 113 insertions(+), 9 deletions(-) diff --git a/test/services/import/legacy-import/licence-versions.mapper.test.js b/test/services/import/legacy-import/licence-versions.mapper.test.js index c2f0aabfcb..8ff94cea0d 100644 --- a/test/services/import/legacy-import/licence-versions.mapper.test.js +++ b/test/services/import/legacy-import/licence-versions.mapper.test.js @@ -15,7 +15,7 @@ const FixtureLicenceVersionPurposes = require('../_fixtures/licence-version-purp const LegacyImportLicenceVersionMapper = require('../../../../app/services/import/legacy-import/licence-versions.mapper.js') -describe.only('Legacy import licence versions mapper', () => { +describe('Legacy import licence versions mapper', () => { let licenceVersions let purpose let version @@ -145,7 +145,7 @@ describe.only('Legacy import licence versions mapper', () => { }) }) - describe('licence versions purposes ', () => { + describe('licence versions "purposes" ', () => { describe('the "abstractionPeriodEndDay" property', () => { describe('when purpose has PERIOD_END_DAY', () => { it('returns PERIOD_END_DAY as a number', () => { @@ -301,13 +301,117 @@ describe.only('Legacy import licence versions mapper', () => { }) }) - // externalId: '3:10000004', - // notes: null, - // primaryPurposeId: 'I', - // purposeId: '160', - // secondaryPurposeId: 'OTI', - // timeLimitedEndDate: null, - // timeLimitedStartDate: null + describe('the "externalId" property', () => { + describe('when the purpose has FGAC_REGION_CODE, ID', () => { + it('returns externalId in the format {FGAC_REGION_CODE}:{ID}', () => { + const [{ purposes: [result] }] = LegacyImportLicenceVersionMapper.go(licenceVersions) + + expect(result.externalId).to.equal('3:10000004') + }) + }) + }) + + describe('the "notes" property', () => { + describe('when purpose has NOTES is "null"', () => { + it('returns null', () => { + const [{ purposes: [result] }] = LegacyImportLicenceVersionMapper.go(licenceVersions) + + expect(result.notes).to.be.null() + }) + }) + + describe('when purpose has NOTES', () => { + beforeEach(() => { + licenceVersions[0].purposes = [ + { ...purpose, NOTES: 'a b c' } + ] + }) + + it('returns notes', () => { + const [{ purposes: [result] }] = LegacyImportLicenceVersionMapper.go(licenceVersions) + + expect(result.notes).to.equal('a b c') + }) + }) + }) + + describe('the "primaryPurposeId" property', () => { + describe('when purpose has APUR_APPR_CODE', () => { + it('returns the legacy primaryPurposeId', () => { + const [{ purposes: [result] }] = LegacyImportLicenceVersionMapper.go(licenceVersions) + + expect(result.primaryPurposeId).to.equal('I') + }) + }) + }) + + describe('the "purposeId" property', () => { + describe('when purpose has APUR_APUS_CODE', () => { + it('returns the legacy purposeId', () => { + const [{ purposes: [result] }] = LegacyImportLicenceVersionMapper.go(licenceVersions) + + expect(result.purposeId).to.equal('160') + }) + }) + }) + + describe('the "secondaryPurposeId" property', () => { + describe('when purpose has APUR_APSE_CODE', () => { + it('returns the legacy secondaryPurposeId', () => { + const [{ purposes: [result] }] = LegacyImportLicenceVersionMapper.go(licenceVersions) + + expect(result.secondaryPurposeId).to.equal('OTI') + }) + }) + }) + + describe('the "timeLimitedEndDate" property', () => { + describe('when purpose has TIMELTD_END_DATE', () => { + beforeEach(() => { + licenceVersions[0].purposes = [ + { ...purpose, TIMELTD_END_DATE: '31/03/2015' } + ] + }) + + it('returns the time Limited End Date in the ISO format', () => { + const [{ purposes: [result] }] = LegacyImportLicenceVersionMapper.go(licenceVersions) + + expect(result.timeLimitedEndDate).to.equal('2015-03-31') + }) + }) + + describe('when purpose has TIMELTD_END_DATE', () => { + it('returns null', () => { + const [{ purposes: [result] }] = LegacyImportLicenceVersionMapper.go(licenceVersions) + + expect(result.timeLimitedEndDate).to.be.null() + }) + }) + }) + + describe('the "timeLimitedStartDate" property', () => { + describe('when purpose has TIMELTD_ST_DATE', () => { + beforeEach(() => { + licenceVersions[0].purposes = [ + { ...purpose, TIMELTD_ST_DATE: '31/03/2015' } + ] + }) + + it('returns the time Limited End Date in the ISO format', () => { + const [{ purposes: [result] }] = LegacyImportLicenceVersionMapper.go(licenceVersions) + + expect(result.timeLimitedStartDate).to.equal('2015-03-31') + }) + }) + + describe('when purpose has TIMELTD_ST_DATE', () => { + it('returns null', () => { + const [{ purposes: [result] }] = LegacyImportLicenceVersionMapper.go(licenceVersions) + + expect(result.timeLimitedStartDate).to.be.null() + }) + }) + }) }) }) }) From 54eafa62ae8c763dbbec4c416210f86f6d3635d1 Mon Sep 17 00:00:00 2001 From: jonathangoulding Date: Tue, 23 Jul 2024 13:34:31 +0100 Subject: [PATCH 11/75] test: legacy service need to go and build the seeders for the purposes, primary purposes and secondary purposes --- .../import/legacy-licence.service.test.js | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/test/services/import/legacy-licence.service.test.js b/test/services/import/legacy-licence.service.test.js index 1b06d24c60..6fb627cea0 100644 --- a/test/services/import/legacy-licence.service.test.js +++ b/test/services/import/legacy-licence.service.test.js @@ -12,26 +12,37 @@ const { expect } = Code const FetchLegacyImportLicenceService = require('../../../app/services/import/legacy-import/fetch-licence.service.js') const FetchLegacyImportLicenceVersionsService = require('../../../app/services/import/legacy-import/fetch-licence-versions.service.js') const FixtureLicence = require('./_fixtures/licence.js') -const FixtureVersions = require('./_fixtures/versions.js') +const FixtureVersion = require('./_fixtures/versions.js') const LicenceModel = require('../../../app/models/licence.model.js') const RegionsSeeder = require('../../support/seeders/regions.seeder.js') // Thing under test const LegacyImportLicenceService = require('../../../app/services/import/legacy-licence.service.js') +const FixtureLicenceVersionPurposes = require('./_fixtures/licence-version-purposes.fixture') +const FixtureVersions = require('./_fixtures/versions') -describe('Legacy import licence service', () => { +describe.only('Legacy import licence service', () => { const licenceRef = FixtureLicence.LIC_NO const region = RegionsSeeder.regions.test_region - beforeEach(async () => { + let licenceVersions + let purpose + let version + + beforeEach(() => { + purpose = FixtureLicenceVersionPurposes + version = FixtureVersions + + licenceVersions = [{ ...version, purposes: [{ ...purpose }] }] + Sinon.stub(FetchLegacyImportLicenceService, 'go').resolves({ ...FixtureLicence, FGAC_REGION_CODE: region.nald_region_id }) - Sinon.stub(FetchLegacyImportLicenceVersionsService, 'go').resolves([...FixtureVersions]) + Sinon.stub(FetchLegacyImportLicenceVersionsService, 'go').resolves(licenceVersions) }) it('returns the matching licence data', async () => { From c9315266f51873c97f50823ab5a8bae7df5c0288 Mon Sep 17 00:00:00 2001 From: jonathangoulding Date: Thu, 25 Jul 2024 15:20:47 +0100 Subject: [PATCH 12/75] test: legacy import service versions and purposes --- app/controllers/import.controller.js | 1 + app/services/import/legacy-licence.service.js | 13 +- .../import/legacy-licence.service.test.js | 176 +++++++++++++++--- 3 files changed, 149 insertions(+), 41 deletions(-) diff --git a/app/controllers/import.controller.js b/app/controllers/import.controller.js index bb950c1d0e..3184a018a0 100644 --- a/app/controllers/import.controller.js +++ b/app/controllers/import.controller.js @@ -15,6 +15,7 @@ async function licence (request, h) { return h.response().code(204) // } catch (error) { + // log licence ref error in logs ? // return Boom.badImplementation(error.message) // } } diff --git a/app/services/import/legacy-licence.service.js b/app/services/import/legacy-licence.service.js index ed6e4f02f4..9cbbc44ea6 100644 --- a/app/services/import/legacy-licence.service.js +++ b/app/services/import/legacy-licence.service.js @@ -23,28 +23,17 @@ async function go (licenceRef) { console.debug('Importing licence ref: ', licenceRef) const licenceData = await FetchLegacyImportLicenceService.go(licenceRef) - console.debug('Imported licence data: ', licenceData) const licenceVersionsData = await FetchLegacyImportLicenceVersionsService.go(licenceData) - console.debug('Imported licence versions data: ', licenceVersionsData) - const mappedLicenceData = LegacyImportLicenceMapper.go(licenceData, licenceVersionsData) const mappedLicenceVersionsData = LegacyImportLicenceVersionMapper.go(licenceVersionsData) - console.debug('Mapped imported licence data: ', mappedLicenceData) - - console.debug('Mapped imported licence versions data: ', mappedLicenceVersionsData) - ImportLicenceValidatorService.go(mappedLicenceData, mappedLicenceVersionsData) const savedLicence = await PersistLicenceService.go(mappedLicenceData) - const savedLicenceVersions = await PersistLicenceVersionsService.go(mappedLicenceVersionsData, savedLicence.id) - - console.debug('Saved Licence: ', savedLicence) - console.debug('Saved Licence versions: ', savedLicenceVersions) - return savedLicence + await PersistLicenceVersionsService.go(mappedLicenceVersionsData, savedLicence.id) } module.exports = { diff --git a/test/services/import/legacy-licence.service.test.js b/test/services/import/legacy-licence.service.test.js index 5a1779a438..c50154384f 100644 --- a/test/services/import/legacy-licence.service.test.js +++ b/test/services/import/legacy-licence.service.test.js @@ -5,22 +5,24 @@ const Lab = require('@hapi/lab') const Code = require('@hapi/code') const Sinon = require('sinon') -const { describe, it, beforeEach } = exports.lab = Lab.script() +const { describe, it, before, beforeEach } = exports.lab = Lab.script() const { expect } = Code // Test helpers const FetchLegacyImportLicenceService = require('../../../app/services/import/legacy-import/fetch-licence.service.js') const FetchLegacyImportLicenceVersionsService = require('../../../app/services/import/legacy-import/fetch-licence-versions.service.js') const FixtureLicence = require('./_fixtures/licence.js') +const FixtureLicenceVersionPurposes = require('./_fixtures/licence-version-purposes.fixture.js') const FixtureVersion = require('./_fixtures/versions.js') const LicenceModel = require('../../../app/models/licence.model.js') +const PrimaryPurposesSeeder = require('../../support/seeders/primary-purpose.seeder.js') +const PurposesSeeder = require('../../support/seeders/purposes.seeder.js') const RegionsSeeder = require('../../support/seeders/regions.seeder.js') +const SecondaryPurposesSeeder = require('../../support/seeders/secondary-purpose.seeder.js') // Thing under test const LegacyImportLicenceService = require('../../../app/services/import/legacy-licence.service.js') -const FixtureLicenceVersionPurposes = require('./_fixtures/licence-version-purposes.fixture') -const FixtureVersions = require('./_fixtures/versions') describe.only('Legacy import licence service', () => { const licenceRef = FixtureLicence.LIC_NO @@ -30,14 +32,14 @@ describe.only('Legacy import licence service', () => { }) let licenceVersions - let purpose + let licenceVersionPurpose let version - beforeEach(() => { - purpose = FixtureLicenceVersionPurposes - version = FixtureVersions + before(() => { + licenceVersionPurpose = FixtureLicenceVersionPurposes + version = FixtureVersion - licenceVersions = [{ ...version, purposes: [{ ...purpose }] }] + licenceVersions = [{ ...version, purposes: [{ ...licenceVersionPurpose }] }] Sinon.stub(FetchLegacyImportLicenceService, 'go').resolves({ ...FixtureLicence, @@ -47,27 +49,143 @@ describe.only('Legacy import licence service', () => { Sinon.stub(FetchLegacyImportLicenceVersionsService, 'go').resolves(licenceVersions) }) - it('returns the matching licence data', async () => { - const results = await LegacyImportLicenceService.go(licenceRef) - - const licence = await LicenceModel.query().findById(results.id) - - expect(results).to.equal({ - expiredDate: '2015-03-31', - id: licence.id, - lapsedDate: null, - licenceRef, - regionId: region.id, - regions: { - historicalAreaCode: 'RIDIN', - localEnvironmentAgencyPlanCode: 'AIREL', - regionalChargeArea: 'Yorkshire', - standardUnitChargeCode: 'YORKI' - }, - revokedDate: null, - startDate: '2005-06-03', - updatedAt: licence.updatedAt.toISOString(), - waterUndertaker: false + describe('the "licence" data is imported and saved to the database', () => { + it('returns the matching licence data', async () => { + await LegacyImportLicenceService.go(licenceRef) + + const licence = await LicenceModel.query().select('*').where('licenceRef', licenceRef).first() + + expect(licence).to.equal({ + createdAt: new Date(licence.createdAt), + expiredDate: new Date('2015-03-31'), + id: licence.id, + includeInPresrocBilling: 'no', + includeInSrocBilling: false, + includeInSrocTptBilling: false, + lapsedDate: null, + licenceRef, + regionId: region.id, + regions: { + historicalAreaCode: 'RIDIN', + localEnvironmentAgencyPlanCode: 'AIREL', + regionalChargeArea: 'Yorkshire', + standardUnitChargeCode: 'YORKI' + }, + revokedDate: null, + startDate: new Date('2005-06-03'), + suspendFromBilling: false, + updatedAt: new Date(licence.updatedAt), + waterUndertaker: false + }) + }) + + it('returns defaulted columns', async () => { + await LegacyImportLicenceService.go(licenceRef) + + const licence = await LicenceModel.query().select('*').where('licenceRef', licenceRef).first() + + expect(licence.includeInPresrocBilling).to.equal('no') + expect(licence.includeInSrocBilling).to.be.false() + expect(licence.includeInSrocTptBilling).to.be.false() + expect(licence.suspendFromBilling).to.be.false() + }) + }) + + describe('the "licence versions" ', () => { + it('returns the matching licence versions data', async () => { + await LegacyImportLicenceService.go(licenceRef) + + const licence = await LicenceModel.query().select(['id']).where('licenceRef', licenceRef).first() + .withGraphFetched('licenceVersions') + + const [licenceVersion] = licence.licenceVersions + + expect(licence.licenceVersions).to.be.array() + + expect(licenceVersion).to.equal( + { + createdAt: new Date(licenceVersion.createdAt), + endDate: new Date('2007-06-04'), + externalId: '3:10000003:100:0', + id: licenceVersion.id, + increment: 0, + issue: 100, + licenceId: licence.id, + startDate: new Date('2005-06-05'), + status: 'superseded', + updatedAt: new Date(licenceVersion.updatedAt) + }) + }) + + describe('the "licence version purposes"', () => { + let primaryPurpose + let purpose + let secondaryPurpose + + beforeEach(() => { + primaryPurpose = PrimaryPurposesSeeder.data.find((primaryPurpose) => { + return primaryPurpose.legacyId === FixtureLicenceVersionPurposes.APUR_APPR_CODE + }) + + purpose = PurposesSeeder.data.find((purpose) => { + return purpose.legacyId === FixtureLicenceVersionPurposes.APUR_APUS_CODE + }) + + secondaryPurpose = SecondaryPurposesSeeder.data.find((secondaryPurpose) => { + return secondaryPurpose.legacyId === FixtureLicenceVersionPurposes.APUR_APSE_CODE + }) + }) + + it('returns the matching licence versions purposes data', async () => { + await LegacyImportLicenceService.go(licenceRef) + + const licence = await LicenceModel.query().select(['id']).where('licenceRef', licenceRef).first() + .withGraphFetched('licenceVersions').withGraphFetched('licenceVersions.licenceVersionPurposes') + + const [licenceVersion] = licence.licenceVersions + const { licenceVersionPurposes } = licenceVersion + const [licenceVersionPurpose] = licenceVersionPurposes + + expect(licence.licenceVersions[0].licenceVersionPurposes).to.be.array() + + expect(licenceVersionPurpose).to.equal( + { + id: licenceVersionPurpose.id, + licenceVersionId: licenceVersion.id, + primaryPurposeId: primaryPurpose.id, + secondaryPurposeId: secondaryPurpose.id, + purposeId: purpose.id, + abstractionPeriodStartDay: 1, + abstractionPeriodStartMonth: 4, + abstractionPeriodEndDay: 31, + abstractionPeriodEndMonth: 3, + timeLimitedStartDate: null, + timeLimitedEndDate: null, + notes: null, + instantQuantity: null, + dailyQuantity: 1500.2, + hourlyQuantity: 140.93, + annualQuantity: 545520, + externalId: '3:10000004', + createdAt: new Date(licenceVersionPurpose.createdAt), + updatedAt: new Date(licenceVersionPurpose.updatedAt) + }) + }) + + it('checks the purposes id, primary purpose id and secondary purpose id match to the legacy id provided', async () => { + await LegacyImportLicenceService.go(licenceRef) + + const licence = await LicenceModel.query().select(['id']).where('licenceRef', licenceRef).first() + .withGraphFetched('licenceVersions').withGraphFetched('licenceVersions.licenceVersionPurposes') + + const [licenceVersion] = licence.licenceVersions + const { licenceVersionPurposes } = licenceVersion + const [licenceVersionPurpose] = licenceVersionPurposes + + expect(licenceVersionPurpose.primaryPurposeId).to.equal(primaryPurpose.id) + expect(licenceVersionPurpose.secondaryPurposeId).to.equal(secondaryPurpose.id) + expect(licenceVersionPurpose.purposeId).to.equal(purpose.id) + }) }) }) }) From af6bd125f13de7befbc4f647d0c2f8c55e2eb9c4 Mon Sep 17 00:00:00 2001 From: jonathangoulding Date: Thu, 25 Jul 2024 15:46:53 +0100 Subject: [PATCH 13/75] test: legacy import service versions and purposes --- test/services/import/legacy-licence.service.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/services/import/legacy-licence.service.test.js b/test/services/import/legacy-licence.service.test.js index c50154384f..aa054c6953 100644 --- a/test/services/import/legacy-licence.service.test.js +++ b/test/services/import/legacy-licence.service.test.js @@ -24,7 +24,7 @@ const SecondaryPurposesSeeder = require('../../support/seeders/secondary-purpose const LegacyImportLicenceService = require('../../../app/services/import/legacy-licence.service.js') -describe.only('Legacy import licence service', () => { +describe('Legacy import licence service', () => { const licenceRef = FixtureLicence.LIC_NO const region = RegionsSeeder.data.find((region) => { From 9eb8d6ee31e0f09ac9254918317b5676febe26eb Mon Sep 17 00:00:00 2001 From: jonathangoulding Date: Fri, 26 Jul 2024 10:25:01 +0100 Subject: [PATCH 14/75] chore: fix sql linting --- .../fetch-licence-versions.service.js | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/app/services/import/legacy-import/fetch-licence-versions.service.js b/app/services/import/legacy-import/fetch-licence-versions.service.js index 280e0f175a..63da35ce0c 100644 --- a/app/services/import/legacy-import/fetch-licence-versions.service.js +++ b/app/services/import/legacy-import/fetch-licence-versions.service.js @@ -30,22 +30,22 @@ async function _getLicenceVersions (licenceId, regionCode) { versions."FGAC_REGION_CODE", versions."AABL_ID", (SELECT json_agg(json_build_object( - 'PERIOD_END_DAY', purposes."PERIOD_END_DAY", - 'PERIOD_END_MONTH', purposes."PERIOD_END_MONTH", - 'PERIOD_ST_DAY', purposes."PERIOD_ST_DAY", - 'PERIOD_ST_MONTH', purposes."PERIOD_ST_MONTH", - 'ANNUAL_QTY', purposes."ANNUAL_QTY", - 'DAILY_QTY', purposes."DAILY_QTY", - 'FGAC_REGION_CODE', purposes."FGAC_REGION_CODE", - 'ID', purposes."ID", - 'HOURLY_QTY', purposes."HOURLY_QTY", - 'INST_QTY', purposes."INST_QTY", - 'NOTES', purposes."NOTES", - 'APUR_APPR_CODE', purposes."APUR_APPR_CODE", - 'APUR_APSE_CODE', purposes."APUR_APSE_CODE", - 'APUR_APUS_CODE', purposes."APUR_APUS_CODE", - 'TIMELTD_END_DATE', purposes."TIMELTD_END_DATE", - 'TIMELTD_ST_DATE', purposes."TIMELTD_ST_DATE" + 'PERIOD_END_DAY', purposes."PERIOD_END_DAY", + 'PERIOD_END_MONTH', purposes."PERIOD_END_MONTH", + 'PERIOD_ST_DAY', purposes."PERIOD_ST_DAY", + 'PERIOD_ST_MONTH', purposes."PERIOD_ST_MONTH", + 'ANNUAL_QTY', purposes."ANNUAL_QTY", + 'DAILY_QTY', purposes."DAILY_QTY", + 'FGAC_REGION_CODE', purposes."FGAC_REGION_CODE", + 'ID', purposes."ID", + 'HOURLY_QTY', purposes."HOURLY_QTY", + 'INST_QTY', purposes."INST_QTY", + 'NOTES', purposes."NOTES", + 'APUR_APPR_CODE', purposes."APUR_APPR_CODE", + 'APUR_APSE_CODE', purposes."APUR_APSE_CODE", + 'APUR_APUS_CODE', purposes."APUR_APUS_CODE", + 'TIMELTD_END_DATE', purposes."TIMELTD_END_DATE", + 'TIMELTD_ST_DATE', purposes."TIMELTD_ST_DATE" ) ) FROM import."NALD_ABS_LIC_PURPOSES" purposes From 1e8fffa28c42641ed2b94150d99abdaede20c5f9 Mon Sep 17 00:00:00 2001 From: jonathangoulding Date: Fri, 26 Jul 2024 10:35:11 +0100 Subject: [PATCH 15/75] chore: fix sql linting --- .../fetch-licence-versions.service.js | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/app/services/import/legacy-import/fetch-licence-versions.service.js b/app/services/import/legacy-import/fetch-licence-versions.service.js index 63da35ce0c..280e0f175a 100644 --- a/app/services/import/legacy-import/fetch-licence-versions.service.js +++ b/app/services/import/legacy-import/fetch-licence-versions.service.js @@ -30,22 +30,22 @@ async function _getLicenceVersions (licenceId, regionCode) { versions."FGAC_REGION_CODE", versions."AABL_ID", (SELECT json_agg(json_build_object( - 'PERIOD_END_DAY', purposes."PERIOD_END_DAY", - 'PERIOD_END_MONTH', purposes."PERIOD_END_MONTH", - 'PERIOD_ST_DAY', purposes."PERIOD_ST_DAY", - 'PERIOD_ST_MONTH', purposes."PERIOD_ST_MONTH", - 'ANNUAL_QTY', purposes."ANNUAL_QTY", - 'DAILY_QTY', purposes."DAILY_QTY", - 'FGAC_REGION_CODE', purposes."FGAC_REGION_CODE", - 'ID', purposes."ID", - 'HOURLY_QTY', purposes."HOURLY_QTY", - 'INST_QTY', purposes."INST_QTY", - 'NOTES', purposes."NOTES", - 'APUR_APPR_CODE', purposes."APUR_APPR_CODE", - 'APUR_APSE_CODE', purposes."APUR_APSE_CODE", - 'APUR_APUS_CODE', purposes."APUR_APUS_CODE", - 'TIMELTD_END_DATE', purposes."TIMELTD_END_DATE", - 'TIMELTD_ST_DATE', purposes."TIMELTD_ST_DATE" + 'PERIOD_END_DAY', purposes."PERIOD_END_DAY", + 'PERIOD_END_MONTH', purposes."PERIOD_END_MONTH", + 'PERIOD_ST_DAY', purposes."PERIOD_ST_DAY", + 'PERIOD_ST_MONTH', purposes."PERIOD_ST_MONTH", + 'ANNUAL_QTY', purposes."ANNUAL_QTY", + 'DAILY_QTY', purposes."DAILY_QTY", + 'FGAC_REGION_CODE', purposes."FGAC_REGION_CODE", + 'ID', purposes."ID", + 'HOURLY_QTY', purposes."HOURLY_QTY", + 'INST_QTY', purposes."INST_QTY", + 'NOTES', purposes."NOTES", + 'APUR_APPR_CODE', purposes."APUR_APPR_CODE", + 'APUR_APSE_CODE', purposes."APUR_APSE_CODE", + 'APUR_APUS_CODE', purposes."APUR_APUS_CODE", + 'TIMELTD_END_DATE', purposes."TIMELTD_END_DATE", + 'TIMELTD_ST_DATE', purposes."TIMELTD_ST_DATE" ) ) FROM import."NALD_ABS_LIC_PURPOSES" purposes From df13ff76e62f12d832d0683624d37e1f9339cd89 Mon Sep 17 00:00:00 2001 From: jonathangoulding Date: Fri, 26 Jul 2024 10:37:58 +0100 Subject: [PATCH 16/75] chore: fix sql linting --- .../fetch-licence-versions.service.js | 51 ++++++++++--------- 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/app/services/import/legacy-import/fetch-licence-versions.service.js b/app/services/import/legacy-import/fetch-licence-versions.service.js index 280e0f175a..da37d61586 100644 --- a/app/services/import/legacy-import/fetch-licence-versions.service.js +++ b/app/services/import/legacy-import/fetch-licence-versions.service.js @@ -22,31 +22,32 @@ async function go (licenceData) { async function _getLicenceVersions (licenceId, regionCode) { const query = ` - SELECT versions."EFF_END_DATE", - versions."EFF_ST_DATE", - versions."INCR_NO", - versions."ISSUE_NO", - versions."STATUS", - versions."FGAC_REGION_CODE", - versions."AABL_ID", - (SELECT json_agg(json_build_object( - 'PERIOD_END_DAY', purposes."PERIOD_END_DAY", - 'PERIOD_END_MONTH', purposes."PERIOD_END_MONTH", - 'PERIOD_ST_DAY', purposes."PERIOD_ST_DAY", - 'PERIOD_ST_MONTH', purposes."PERIOD_ST_MONTH", - 'ANNUAL_QTY', purposes."ANNUAL_QTY", - 'DAILY_QTY', purposes."DAILY_QTY", - 'FGAC_REGION_CODE', purposes."FGAC_REGION_CODE", - 'ID', purposes."ID", - 'HOURLY_QTY', purposes."HOURLY_QTY", - 'INST_QTY', purposes."INST_QTY", - 'NOTES', purposes."NOTES", - 'APUR_APPR_CODE', purposes."APUR_APPR_CODE", - 'APUR_APSE_CODE', purposes."APUR_APSE_CODE", - 'APUR_APUS_CODE', purposes."APUR_APUS_CODE", - 'TIMELTD_END_DATE', purposes."TIMELTD_END_DATE", - 'TIMELTD_ST_DATE', purposes."TIMELTD_ST_DATE" - ) + SELECT + versions."EFF_END_DATE", + versions."EFF_ST_DATE", + versions."INCR_NO", + versions."ISSUE_NO", + versions."STATUS", + versions."FGAC_REGION_CODE", + versions."AABL_ID", + (SELECT json_agg(json_build_object( + 'PERIOD_END_DAY', purposes."PERIOD_END_DAY", + 'PERIOD_END_MONTH', purposes."PERIOD_END_MONTH", + 'PERIOD_ST_DAY', purposes."PERIOD_ST_DAY", + 'PERIOD_ST_MONTH', purposes."PERIOD_ST_MONTH", + 'ANNUAL_QTY', purposes."ANNUAL_QTY", + 'DAILY_QTY', purposes."DAILY_QTY", + 'FGAC_REGION_CODE', purposes."FGAC_REGION_CODE", + 'ID', purposes."ID", + 'HOURLY_QTY', purposes."HOURLY_QTY", + 'INST_QTY', purposes."INST_QTY", + 'NOTES', purposes."NOTES", + 'APUR_APPR_CODE', purposes."APUR_APPR_CODE", + 'APUR_APSE_CODE', purposes."APUR_APSE_CODE", + 'APUR_APUS_CODE', purposes."APUR_APUS_CODE", + 'TIMELTD_END_DATE', purposes."TIMELTD_END_DATE", + 'TIMELTD_ST_DATE', purposes."TIMELTD_ST_DATE" + ) ) FROM import."NALD_ABS_LIC_PURPOSES" purposes WHERE purposes."AABV_AABL_ID" = versions."AABL_ID" From 2970e717fe37312c2e362a94bb57f967cec91bee Mon Sep 17 00:00:00 2001 From: jonathangoulding Date: Fri, 26 Jul 2024 10:40:19 +0100 Subject: [PATCH 17/75] chore: fix sql linting --- .../fetch-licence-versions.service.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/app/services/import/legacy-import/fetch-licence-versions.service.js b/app/services/import/legacy-import/fetch-licence-versions.service.js index da37d61586..f064101cf5 100644 --- a/app/services/import/legacy-import/fetch-licence-versions.service.js +++ b/app/services/import/legacy-import/fetch-licence-versions.service.js @@ -23,14 +23,14 @@ async function go (licenceData) { async function _getLicenceVersions (licenceId, regionCode) { const query = ` SELECT - versions."EFF_END_DATE", - versions."EFF_ST_DATE", - versions."INCR_NO", - versions."ISSUE_NO", - versions."STATUS", - versions."FGAC_REGION_CODE", - versions."AABL_ID", - (SELECT json_agg(json_build_object( + versions."EFF_END_DATE", + versions."EFF_ST_DATE", + versions."INCR_NO", + versions."ISSUE_NO", + versions."STATUS", + versions."FGAC_REGION_CODE", + versions."AABL_ID", + (SELECT json_agg(json_build_object( 'PERIOD_END_DAY', purposes."PERIOD_END_DAY", 'PERIOD_END_MONTH', purposes."PERIOD_END_MONTH", 'PERIOD_ST_DAY', purposes."PERIOD_ST_DAY", From 1c154d3cbffd08fd6c90d0980292ab80e4a6d795 Mon Sep 17 00:00:00 2001 From: jonathangoulding Date: Fri, 26 Jul 2024 10:41:41 +0100 Subject: [PATCH 18/75] chore: fix sql linting --- .../fetch-licence-versions.service.js | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/app/services/import/legacy-import/fetch-licence-versions.service.js b/app/services/import/legacy-import/fetch-licence-versions.service.js index f064101cf5..7af82ea85b 100644 --- a/app/services/import/legacy-import/fetch-licence-versions.service.js +++ b/app/services/import/legacy-import/fetch-licence-versions.service.js @@ -31,24 +31,24 @@ async function _getLicenceVersions (licenceId, regionCode) { versions."FGAC_REGION_CODE", versions."AABL_ID", (SELECT json_agg(json_build_object( - 'PERIOD_END_DAY', purposes."PERIOD_END_DAY", - 'PERIOD_END_MONTH', purposes."PERIOD_END_MONTH", - 'PERIOD_ST_DAY', purposes."PERIOD_ST_DAY", - 'PERIOD_ST_MONTH', purposes."PERIOD_ST_MONTH", - 'ANNUAL_QTY', purposes."ANNUAL_QTY", - 'DAILY_QTY', purposes."DAILY_QTY", - 'FGAC_REGION_CODE', purposes."FGAC_REGION_CODE", - 'ID', purposes."ID", - 'HOURLY_QTY', purposes."HOURLY_QTY", - 'INST_QTY', purposes."INST_QTY", - 'NOTES', purposes."NOTES", - 'APUR_APPR_CODE', purposes."APUR_APPR_CODE", - 'APUR_APSE_CODE', purposes."APUR_APSE_CODE", - 'APUR_APUS_CODE', purposes."APUR_APUS_CODE", - 'TIMELTD_END_DATE', purposes."TIMELTD_END_DATE", - 'TIMELTD_ST_DATE', purposes."TIMELTD_ST_DATE" - ) - ) + 'PERIOD_END_DAY', purposes."PERIOD_END_DAY", + 'PERIOD_END_MONTH', purposes."PERIOD_END_MONTH", + 'PERIOD_ST_DAY', purposes."PERIOD_ST_DAY", + 'PERIOD_ST_MONTH', purposes."PERIOD_ST_MONTH", + 'ANNUAL_QTY', purposes."ANNUAL_QTY", + 'DAILY_QTY', purposes."DAILY_QTY", + 'FGAC_REGION_CODE', purposes."FGAC_REGION_CODE", + 'ID', purposes."ID", + 'HOURLY_QTY', purposes."HOURLY_QTY", + 'INST_QTY', purposes."INST_QTY", + 'NOTES', purposes."NOTES", + 'APUR_APPR_CODE', purposes."APUR_APPR_CODE", + 'APUR_APSE_CODE', purposes."APUR_APSE_CODE", + 'APUR_APUS_CODE', purposes."APUR_APUS_CODE", + 'TIMELTD_END_DATE', purposes."TIMELTD_END_DATE", + 'TIMELTD_ST_DATE', purposes."TIMELTD_ST_DATE" + ) + ) FROM import."NALD_ABS_LIC_PURPOSES" purposes WHERE purposes."AABV_AABL_ID" = versions."AABL_ID" AND purposes."AABV_ISSUE_NO" = versions."ISSUE_NO" From 11f25e1d8d1755bc6e6d2cd188feac34398bb08f Mon Sep 17 00:00:00 2001 From: jonathangoulding Date: Fri, 26 Jul 2024 10:54:34 +0100 Subject: [PATCH 19/75] chore: fix sonar cloud issues --- .../legacy-import/fetch-licence.service.js | 43 +++++++------------ .../legacy-import/licence-versions.mapper.js | 5 +-- .../import/licence-versions.validator.js | 13 ++++-- 3 files changed, 25 insertions(+), 36 deletions(-) diff --git a/app/services/import/legacy-import/fetch-licence.service.js b/app/services/import/legacy-import/fetch-licence.service.js index b5ee709ec1..b2775b2747 100644 --- a/app/services/import/legacy-import/fetch-licence.service.js +++ b/app/services/import/legacy-import/fetch-licence.service.js @@ -17,39 +17,26 @@ async function go (licenceRef) { } async function _getLicenceByRef (licenceRef) { - // TODO: granular select ? map data to simplify if needs be const query = ` - SELECT * - FROM import."NALD_ABS_LICENCES" l - WHERE l."LIC_NO" = '${licenceRef}'; + SELECT + licence.AREP_AREA_CODE, + licence.AREP_EIUC_CODE, + licence.AREP_LEAP_CODE, + licence.AREP_SUC_CODE, + licence.EXPIRY_DATE, + licence.FGAC_REGION_CODE, + licence.ID, + licence.LAPSED_DATE, + licence.LIC_NO, + licence.ORIG_EFF_DATE, + licence.REV_DATE + FROM import."NALD_ABS_LICENCES" licence + WHERE licence."LIC_NO" = '${licenceRef}'; ` const { rows: [row] } = await db.raw(query) - return select(row) -} - -/** - * Fetches the licence data for the licence ref from the import.NALD_ABS_LICENCES table - * - * @param {any} licence - * @returns {LegacyLicenceType} - */ -// TODO: remove this for the select -function select (licence) { - return { - AREP_AREA_CODE: licence.AREP_AREA_CODE, - AREP_EIUC_CODE: licence.AREP_EIUC_CODE, - AREP_LEAP_CODE: licence.AREP_LEAP_CODE, - AREP_SUC_CODE: licence.AREP_SUC_CODE, - EXPIRY_DATE: licence.EXPIRY_DATE, - FGAC_REGION_CODE: licence.FGAC_REGION_CODE, - ID: licence.ID, - LAPSED_DATE: licence.LAPSED_DATE, - LIC_NO: licence.LIC_NO, - ORIG_EFF_DATE: licence.ORIG_EFF_DATE, - REV_DATE: licence.REV_DATE - } + return row } module.exports = { diff --git a/app/services/import/legacy-import/licence-versions.mapper.js b/app/services/import/legacy-import/licence-versions.mapper.js index f672dbf01c..0030d516c7 100644 --- a/app/services/import/legacy-import/licence-versions.mapper.js +++ b/app/services/import/legacy-import/licence-versions.mapper.js @@ -16,13 +16,11 @@ const statuses = { const createExternalId = (licenceVersion) => { const { FGAC_REGION_CODE, AABL_ID, ISSUE_NO, INCR_NO } = licenceVersion - // todo: should we throw here if we can't build up ? - // todo: ask if this is used else where return `${FGAC_REGION_CODE}:${AABL_ID}:${ISSUE_NO}:${INCR_NO}` } /** - * Maps the import licence versions data to the desired format + * Maps the import licence versions data * * @param {LegacyLicenceVersionsArray} licenceVersions * @returns {ImportLicenceVersionType[]} @@ -45,7 +43,6 @@ function _mapLicenceVersions (licenceVersions) { return { endDate: formatStandardDateToISO(licenceVersion.EFF_END_DATE), externalId: createExternalId(licenceVersion), - // todo: do we still need to store these ? increment / issue increment: Number(increment), issue: Number(issue), startDate: formatStandardDateToISO(licenceVersion.EFF_ST_DATE), diff --git a/app/validators/import/licence-versions.validator.js b/app/validators/import/licence-versions.validator.js index 11ff068099..023d3d4b3e 100644 --- a/app/validators/import/licence-versions.validator.js +++ b/app/validators/import/licence-versions.validator.js @@ -6,6 +6,11 @@ const Joi = require('joi') +const calender = { + totalDaysInMonth: 31, + totalMonthsInYear: 12 +} + /** * Checks that the data for inserting/updating the public.licence_versions * and public.licence_versions_purposes table is valid @@ -20,10 +25,10 @@ function go (data) { primaryPurposeId: Joi.string().required(), secondaryPurposeId: Joi.string().required(), purposeId: Joi.string().required(), - abstractionPeriodStartDay: Joi.number().integer().min(1).max(31).required(), - abstractionPeriodStartMonth: Joi.number().integer().min(1).max(12).required(), - abstractionPeriodEndDay: Joi.number().integer().min(1).max(31).required(), - abstractionPeriodEndMonth: Joi.number().integer().min(1).max(12).required(), + abstractionPeriodStartDay: Joi.number().integer().min(1).max(calender.totalDaysInMonth).required(), + abstractionPeriodStartMonth: Joi.number().integer().min(1).max(calender.totalMonthsInYear).required(), + abstractionPeriodEndDay: Joi.number().integer().min(1).max(calender.totalDaysInMonth).required(), + abstractionPeriodEndMonth: Joi.number().integer().min(1).max(calender.totalMonthsInYear).required(), timeLimitedStartDate: Joi.date().iso().allow(null), timeLimitedEndDate: Joi.date().iso().allow(null), notes: Joi.string().allow(null), From 32667da5b004bf31f4314dd39de79d5709b32a3f Mon Sep 17 00:00:00 2001 From: jonathangoulding Date: Fri, 26 Jul 2024 11:50:18 +0100 Subject: [PATCH 20/75] test: licence versions validator --- .../legacy-import/fetch-licence.service.js | 22 +- .../import/licence-versions.validator.js | 67 ++-- app/validators/import/licence.validator.js | 34 +- .../valid-licence-versions.fixture.js | 40 +++ .../import/licence-versions.validator.test.js | 299 ++++++++++++++++++ 5 files changed, 405 insertions(+), 57 deletions(-) create mode 100644 test/validators/import/_fixtures/valid-licence-versions.fixture.js create mode 100644 test/validators/import/licence-versions.validator.test.js diff --git a/app/services/import/legacy-import/fetch-licence.service.js b/app/services/import/legacy-import/fetch-licence.service.js index b2775b2747..9ace276dec 100644 --- a/app/services/import/legacy-import/fetch-licence.service.js +++ b/app/services/import/legacy-import/fetch-licence.service.js @@ -19,17 +19,17 @@ async function go (licenceRef) { async function _getLicenceByRef (licenceRef) { const query = ` SELECT - licence.AREP_AREA_CODE, - licence.AREP_EIUC_CODE, - licence.AREP_LEAP_CODE, - licence.AREP_SUC_CODE, - licence.EXPIRY_DATE, - licence.FGAC_REGION_CODE, - licence.ID, - licence.LAPSED_DATE, - licence.LIC_NO, - licence.ORIG_EFF_DATE, - licence.REV_DATE + licence."AREP_AREA_CODE", + licence."AREP_EIUC_CODE", + licence."AREP_LEAP_CODE", + licence."AREP_SUC_CODE", + licence."EXPIRY_DATE", + licence."FGAC_REGION_CODE", + licence."ID", + licence."LAPSED_DATE", + licence."LIC_NO", + licence."ORIG_EFF_DATE", + licence."REV_DATE" FROM import."NALD_ABS_LICENCES" licence WHERE licence."LIC_NO" = '${licenceRef}'; ` diff --git a/app/validators/import/licence-versions.validator.js b/app/validators/import/licence-versions.validator.js index 023d3d4b3e..9a33ab64cc 100644 --- a/app/validators/import/licence-versions.validator.js +++ b/app/validators/import/licence-versions.validator.js @@ -10,6 +10,7 @@ const calender = { totalDaysInMonth: 31, totalMonthsInYear: 12 } +const validStatues = ['current', 'superseded'] /** * Checks that the data for inserting/updating the public.licence_versions @@ -21,41 +22,49 @@ const calender = { * */ function go (data) { - const purposeSchema = Joi.object({ - primaryPurposeId: Joi.string().required(), - secondaryPurposeId: Joi.string().required(), - purposeId: Joi.string().required(), - abstractionPeriodStartDay: Joi.number().integer().min(1).max(calender.totalDaysInMonth).required(), - abstractionPeriodStartMonth: Joi.number().integer().min(1).max(calender.totalMonthsInYear).required(), - abstractionPeriodEndDay: Joi.number().integer().min(1).max(calender.totalDaysInMonth).required(), - abstractionPeriodEndMonth: Joi.number().integer().min(1).max(calender.totalMonthsInYear).required(), - timeLimitedStartDate: Joi.date().iso().allow(null), - timeLimitedEndDate: Joi.date().iso().allow(null), - notes: Joi.string().allow(null), - annualQuantity: Joi.number().allow(null), - externalId: Joi.string().required(), - instantQuantity: Joi.number().allow(null), - hourlyQuantity: Joi.number().allow(null), - dailyQuantity: Joi.number().allow(null) - }) - - const schema = Joi.array().items({ - endDate: Joi.date().iso().required().allow(null), - externalId: Joi.string().required(), - increment: Joi.number().required(), - issue: Joi.number().required(), - startDate: Joi.date().iso().required().allow(null), - status: Joi.string().required(), - purposes: Joi.array().items(purposeSchema).required() - }) - - const result = schema.validate(data) + const result = _schema.validate(data) if (Object.hasOwn(result, 'error')) { throw new Error(result.error.details[0].message) } } +const _isValidStatus = (value) => { + if (validStatues.includes(value)) { + return value + } + + throw new Error(`status must be one of ${validStatues.toString()}`) +} + +const _purposeSchema = Joi.object({ + primaryPurposeId: Joi.string().required(), + secondaryPurposeId: Joi.string().required(), + purposeId: Joi.string().required(), + abstractionPeriodStartDay: Joi.number().integer().min(1).max(calender.totalDaysInMonth).required(), + abstractionPeriodStartMonth: Joi.number().integer().min(1).max(calender.totalMonthsInYear).required(), + abstractionPeriodEndDay: Joi.number().integer().min(1).max(calender.totalDaysInMonth).required(), + abstractionPeriodEndMonth: Joi.number().integer().min(1).max(calender.totalMonthsInYear).required(), + timeLimitedStartDate: Joi.date().iso().allow(null), + timeLimitedEndDate: Joi.date().iso().allow(null), + notes: Joi.string().allow(null), + annualQuantity: Joi.number().allow(null), + externalId: Joi.string().required(), + instantQuantity: Joi.number().allow(null), + hourlyQuantity: Joi.number().allow(null), + dailyQuantity: Joi.number().allow(null) +}) + +const _schema = Joi.array().items({ + endDate: Joi.date().iso().required().allow(null), + externalId: Joi.string().required(), + increment: Joi.number().required(), + issue: Joi.number().required(), + startDate: Joi.date().iso().required(), + status: Joi.string().required().custom(_isValidStatus), + purposes: Joi.array().items(_purposeSchema).required() +}) + module.exports = { go } diff --git a/app/validators/import/licence.validator.js b/app/validators/import/licence.validator.js index ed65b5ada5..60413148ca 100644 --- a/app/validators/import/licence.validator.js +++ b/app/validators/import/licence.validator.js @@ -17,29 +17,29 @@ const CustomDateValidator = require('../custom/date.validators.js') * */ function go (data) { - const schema = Joi.object({ - expiredDate: Joi.string().allow(null).custom(CustomDateValidator.isValidISODate), - lapsedDate: Joi.string().allow(null).custom(CustomDateValidator.isValidISODate), - licenceRef: Joi.string().required(), - naldRegionId: Joi.number().required(), - regions: Joi.object({ - regionalChargeArea: Joi.string(), - localEnvironmentAgencyPlanCode: Joi.string(), - historicalAreaCode: Joi.string(), - standardUnitChargeCode: Joi.string() - }), - revokedDate: Joi.string().allow(null).custom(CustomDateValidator.isValidISODate), - startDate: Joi.string().required().custom(CustomDateValidator.isValidISODate), - waterUndertaker: Joi.boolean().required() - }) - - const result = schema.validate(data) + const result = _schema.validate(data) if (Object.hasOwn(result, 'error')) { throw new Error(result.error.details[0].message) } } +const _schema = Joi.object({ + expiredDate: Joi.string().allow(null).custom(CustomDateValidator.isValidISODate), + lapsedDate: Joi.string().allow(null).custom(CustomDateValidator.isValidISODate), + licenceRef: Joi.string().required(), + naldRegionId: Joi.number().required(), + regions: Joi.object({ + regionalChargeArea: Joi.string(), + localEnvironmentAgencyPlanCode: Joi.string(), + historicalAreaCode: Joi.string(), + standardUnitChargeCode: Joi.string() + }), + revokedDate: Joi.string().allow(null).custom(CustomDateValidator.isValidISODate), + startDate: Joi.string().required().custom(CustomDateValidator.isValidISODate), + waterUndertaker: Joi.boolean().required() +}) + module.exports = { go } diff --git a/test/validators/import/_fixtures/valid-licence-versions.fixture.js b/test/validators/import/_fixtures/valid-licence-versions.fixture.js new file mode 100644 index 0000000000..3c2c4682a2 --- /dev/null +++ b/test/validators/import/_fixtures/valid-licence-versions.fixture.js @@ -0,0 +1,40 @@ +'use strict' + +const validLicencePurposes = [ + { + abstractionPeriodEndDay: 31, + abstractionPeriodEndMonth: 3, + abstractionPeriodStartDay: 1, + abstractionPeriodStartMonth: 4, + annualQuantity: 545520, + dailyQuantity: 1500.2, + externalId: '3:10000004', + hourlyQuantity: 140.929, + instantQuantity: 120, + notes: ' a note on purposes', + primaryPurposeId: 'I', + secondaryPurposeId: 'OTI', + purposeId: '160', + timeLimitedEndDate: '2001-01-02', + timeLimitedStartDate: '2001-01-03' + } +] + +const validLicenceVersion = { + endDate: '2002-01-01', + externalId: '3:10000003:100:0', + increment: 0, + issue: 100, + startDate: '2001-01-01', + status: 'superseded' +} + +const validLicenceVersionsAndPurposes = [ + { ...validLicenceVersion, purposes: [...validLicencePurposes] } +] + +module.exports = { + validLicencePurposes, + validLicenceVersion, + validLicenceVersionsAndPurposes +} diff --git a/test/validators/import/licence-versions.validator.test.js b/test/validators/import/licence-versions.validator.test.js new file mode 100644 index 0000000000..9266ea4142 --- /dev/null +++ b/test/validators/import/licence-versions.validator.test.js @@ -0,0 +1,299 @@ +'use strict' + +// Test framework dependencies +const Lab = require('@hapi/lab') +const Code = require('@hapi/code') + +const { describe, it, before } = exports.lab = Lab.script() +const { expect } = Code + +// Test helpers +const FixtureValidLicenceVersions = require('./_fixtures/valid-licence-versions.fixture.js') + +// Thing under test +const ImportLicenceVersionsValidator = require('../../../app/validators/import/licence-versions.validator.js') + +describe('Import licence versions validator', () => { + let licenceVersion + let licenceVersionPurpose + let licenceVersionPurposes + let licenceVersionsAndPurposes + + before(async () => { + licenceVersion = FixtureValidLicenceVersions.validLicenceVersion + licenceVersionPurpose = FixtureValidLicenceVersions.validLicencePurposes[0] + licenceVersionPurposes = FixtureValidLicenceVersions.validLicencePurposes + licenceVersionsAndPurposes = [...FixtureValidLicenceVersions.validLicenceVersionsAndPurposes] + }) + + it('should not throw if all the required fields validations are met', () => { + expect(() => { + return ImportLicenceVersionsValidator.go(licenceVersionsAndPurposes) + }).to.not.throw() + }) + + describe('the "version"', () => { + describe('"endDate" property', () => { + it('should throw an error if "endDate" is not a valid date or null', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: licenceVersionPurposes, + endDate: 1 + } + ]) + }).to.throw('"[0].endDate" must be a valid date') + }) + + it('should throw an error if "endDate" does not meet ISO 8601', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: licenceVersionPurposes, + endDate: '01/01/2001' + } + ]) + }).to.throw('"[0].endDate" must be in ISO 8601 date format') + }) + + it('should not throw an error if "endDate" is null', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: licenceVersionPurposes, + endDate: null + } + ]) + }).to.not.throw() + }) + + it('should not throw an error if "endDate" is valid date', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: licenceVersionPurposes, + endDate: '2001-01-01' + } + ]) + }).to.not.throw() + }) + }) + + describe('"externalId" property', () => { + it('should throw an error - externalId - must be a string', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: licenceVersionPurposes, + externalId: null + } + ]) + }).to.throw('"[0].externalId" must be a string') + }) + + it('should throw an error - externalId - is required', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + endDate: null + } + ]) + }).to.throw('"[0].externalId" is required') + }) + + it('should not throw an error if "externalId" is a string', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: licenceVersionPurposes + } + ]) + }).to.not.throw() + }) + }) + + describe('"increment" property', () => { + it('should throw an error - increment - must be a number', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: licenceVersionPurposes, + increment: '1a' + } + ]) + }).to.throw('"[0].increment" must be a number') + }) + + it('should throw an error - increment - is required', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + endDate: null, + externalId: '1:2:3' + } + ]) + }).to.throw('"[0].increment" is required') + }) + + it('should not throw an error if "increment" is a number', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: licenceVersionPurposes + } + ]) + }).to.not.throw() + }) + }) + + describe('"issue" property', () => { + it('should throw an error - issue - must be a number', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: licenceVersionPurposes, + issue: '1a' + } + ]) + }).to.throw('"[0].issue" must be a number') + }) + + it('should throw an error - issue - is required', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + endDate: null, + externalId: '1:2:3', + increment: 1 + } + ]) + }).to.throw('"[0].issue" is required') + }) + + it('should not throw an error if "issue" is a number', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: licenceVersionPurposes + } + ]) + }).to.not.throw() + }) + }) + + describe('"status" property', () => { + it('should throw an error - status - must be a string', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: licenceVersionPurposes, + status: 1 + } + ]) + }).to.throw('"[0].status" must be a string') + }) + + it('should throw an error - status - is required', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + endDate: null, + externalId: '1:2:3', + increment: 1, + issue: 1, + startDate: '2001-01-01' + } + ]) + }).to.throw('"[0].status" is required') + }) + + it('should throw an error - status - is not a valid status', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: licenceVersionPurposes, + status: 'draft' + } + ]) + }).to.throw('"[0].status" failed custom validation because status must be one of current,superseded') + }) + + it('should not throw an error if "status" is a valid status', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: licenceVersionPurposes + } + ]) + }).to.not.throw() + }) + }) + + describe('"startDate" property', () => { + it('should throw an error if "startDate" is not a valid date', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: licenceVersionPurposes, + startDate: 1 + } + ]) + }).to.throw('"[0].startDate" must be a valid date') + }) + + it('should throw an error if "startDate" does not meet ISO 8601', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: licenceVersionPurposes, + startDate: '01/01/2001' + } + ]) + }).to.throw('"[0].startDate" must be in ISO 8601 date format') + }) + + it('should throw an error if "startDate" is null', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: licenceVersionPurposes, + startDate: null + } + ]) + }).to.throw('"[0].startDate" must be a valid date') + }) + + it('should not throw an error if "startDate" is valid date string', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: licenceVersionPurposes, + startDate: '2001-01-01' + } + ]) + }).to.not.throw() + }) + }) + + // describe('"purposes" property', () => { + // + // }) + }) +}) From 23974f002b0981e92875b63ea8c6f02b79621636 Mon Sep 17 00:00:00 2001 From: jonathangoulding Date: Fri, 26 Jul 2024 14:39:33 +0100 Subject: [PATCH 21/75] test: licence versions validator --- .../import/licence-versions.validator.test.js | 639 +++++++++++++++++- 1 file changed, 636 insertions(+), 3 deletions(-) diff --git a/test/validators/import/licence-versions.validator.test.js b/test/validators/import/licence-versions.validator.test.js index 9266ea4142..dfa3b603d6 100644 --- a/test/validators/import/licence-versions.validator.test.js +++ b/test/validators/import/licence-versions.validator.test.js @@ -292,8 +292,641 @@ describe('Import licence versions validator', () => { }) }) - // describe('"purposes" property', () => { - // - // }) + describe('"purposes" property', () => { + describe('"abstractionPeriodEndDay" property', () => { + it('should throw an error if "abstractionPeriodEndDay" is not a number', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: [{ ...licenceVersionPurpose, abstractionPeriodEndDay: '1a' }] + } + ]) + }).to.throw('"[0].purposes[0].abstractionPeriodEndDay" must be a number') + }) + + it('should throw an error if "abstractionPeriodEndDay" is null', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: [{ ...licenceVersionPurpose, abstractionPeriodEndDay: null }] + } + ]) + }).to.throw('"[0].purposes[0].abstractionPeriodEndDay" must be a number') + }) + + it('should throw an error if "abstractionPeriodEndDay" is less than 1 (days allowed 1 - 31)', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: [{ ...licenceVersionPurpose, abstractionPeriodEndDay: -1 }] + } + ]) + }).to.throw('"[0].purposes[0].abstractionPeriodEndDay" must be greater than or equal to 1') + }) + + it('should throw an error if "abstractionPeriodEndDay" is more than 31 (days allowed 1 -31)', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: [{ ...licenceVersionPurpose, abstractionPeriodEndDay: 34 }] + } + ]) + }).to.throw('"[0].purposes[0].abstractionPeriodEndDay" must be less than or equal to 31') + }) + + it('should not throw an error if "abstractionPeriodEndDay" is a number within 1 - 31', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: [{ ...licenceVersionPurpose, abstractionPeriodEndDay: 1 }] + } + ]) + }).to.not.throw() + }) + }) + + describe('"abstractionPeriodEndMonth" property', () => { + it('should throw an error if "abstractionPeriodEndMonth" is not a number', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: [{ ...licenceVersionPurpose, abstractionPeriodEndMonth: '1a' }] + } + ]) + }).to.throw('"[0].purposes[0].abstractionPeriodEndMonth" must be a number') + }) + + it('should throw an error if "abstractionPeriodEndMonth" is null', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: [{ ...licenceVersionPurpose, abstractionPeriodEndMonth: null }] + } + ]) + }).to.throw('"[0].purposes[0].abstractionPeriodEndMonth" must be a number') + }) + + it('should throw an error if "abstractionPeriodEndMonth" is less than 1 (months are 1 - 12)', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: [{ ...licenceVersionPurpose, abstractionPeriodEndMonth: -1 }] + } + ]) + }).to.throw('"[0].purposes[0].abstractionPeriodEndMonth" must be greater than or equal to 1') + }) + + it('should throw an error if "abstractionPeriodEndMonth" is more than 12 (months are 1 - 12)', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: [{ ...licenceVersionPurpose, abstractionPeriodEndMonth: 14 }] + } + ]) + }).to.throw('"[0].purposes[0].abstractionPeriodEndMonth" must be less than or equal to 12') + }) + + it('should not throw an error if "abstractionPeriodEndMonth" is a number within 1 - 12', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: [{ ...licenceVersionPurpose, abstractionPeriodEndMonth: 1 }] + } + ]) + }).to.not.throw() + }) + }) + + describe('"abstractionPeriodStartDay" property', () => { + it('should throw an error if "abstractionPeriodStartDay" is not a number', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: [{ ...licenceVersionPurpose, abstractionPeriodStartDay: '1a' }] + } + ]) + }).to.throw('"[0].purposes[0].abstractionPeriodStartDay" must be a number') + }) + + it('should throw an error if "abstractionPeriodStartDay" is null', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: [{ ...licenceVersionPurpose, abstractionPeriodStartDay: null }] + } + ]) + }).to.throw('"[0].purposes[0].abstractionPeriodStartDay" must be a number') + }) + + it('should throw an error if "abstractionPeriodStartDay" is less than 1 (days allowed 1 - 31)', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: [{ ...licenceVersionPurpose, abstractionPeriodStartDay: -1 }] + } + ]) + }).to.throw('"[0].purposes[0].abstractionPeriodStartDay" must be greater than or equal to 1') + }) + + it('should throw an error if "abstractionPeriodStartDay" is more than 31 (days allowed 1 -31)', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: [{ ...licenceVersionPurpose, abstractionPeriodStartDay: 34 }] + } + ]) + }).to.throw('"[0].purposes[0].abstractionPeriodStartDay" must be less than or equal to 31') + }) + + it('should not throw an error if "abstractionPeriodStartDay" is a number within 1 - 31', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: [{ ...licenceVersionPurpose, abstractionPeriodStartDay: 1 }] + } + ]) + }).to.not.throw() + }) + }) + + describe('"abstractionPeriodStartMonth" property', () => { + it('should throw an error if "abstractionPeriodStartMonth" is not a number', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: [{ ...licenceVersionPurpose, abstractionPeriodStartMonth: '1a' }] + } + ]) + }).to.throw('"[0].purposes[0].abstractionPeriodStartMonth" must be a number') + }) + + it('should throw an error if "abstractionPeriodStartMonth" is null', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: [{ ...licenceVersionPurpose, abstractionPeriodStartMonth: null }] + } + ]) + }).to.throw('"[0].purposes[0].abstractionPeriodStartMonth" must be a number') + }) + + it('should throw an error if "abstractionPeriodStartMonth" is less than 1 (months are 1 - 12)', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: [{ ...licenceVersionPurpose, abstractionPeriodStartMonth: -1 }] + } + ]) + }).to.throw('"[0].purposes[0].abstractionPeriodStartMonth" must be greater than or equal to 1') + }) + + it('should throw an error if "abstractionPeriodStartMonth" is more than 12 (months are 1 - 12)', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: [{ ...licenceVersionPurpose, abstractionPeriodStartMonth: 14 }] + } + ]) + }).to.throw('"[0].purposes[0].abstractionPeriodStartMonth" must be less than or equal to 12') + }) + + it('should not throw an error if "abstractionPeriodStartMonth" is a number within 1 - 12', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: [{ ...licenceVersionPurpose, abstractionPeriodStartMonth: 1 }] + } + ]) + }).to.not.throw() + }) + }) + + describe('"annualQuantity" property', () => { + it('should throw an error if "annualQuantity" is not a number or null', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: [{ ...licenceVersionPurpose, annualQuantity: '1a' }] + } + ]) + }).to.throw('"[0].purposes[0].annualQuantity" must be a number') + }) + + it('should not throw an error if "annualQuantity" is null', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: [{ ...licenceVersionPurpose, annualQuantity: null }] + } + ]) + }).to.not.throw() + }) + + it('should not throw an error if "annualQuantity" is a number', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: [{ ...licenceVersionPurpose, annualQuantity: 52311 }] + } + ]) + }).to.not.throw() + }) + }) + + describe('"dailyQuantity" property', () => { + it('should throw an error if "dailyQuantity" is not a number or null', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: [{ ...licenceVersionPurpose, dailyQuantity: '1a' }] + } + ]) + }).to.throw('"[0].purposes[0].dailyQuantity" must be a number') + }) + + it('should not throw an error if "dailyQuantity" is null', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: [{ ...licenceVersionPurpose, dailyQuantity: null }] + } + ]) + }).to.not.throw() + }) + + it('should not throw an error if "dailyQuantity" is a number', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: [{ ...licenceVersionPurpose, dailyQuantity: 503.45 }] + } + ]) + }).to.not.throw() + }) + }) + + describe('"hourlyQuantity" property', () => { + it('should throw an error if "hourlyQuantity" is not a number or null', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: [{ ...licenceVersionPurpose, hourlyQuantity: '1a' }] + } + ]) + }).to.throw('"[0].purposes[0].hourlyQuantity" must be a number') + }) + + it('should not throw an error if "hourlyQuantity" is null', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: [{ ...licenceVersionPurpose, hourlyQuantity: null }] + } + ]) + }).to.not.throw() + }) + + it('should not throw an error if "hourlyQuantity" is a number', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: [{ ...licenceVersionPurpose, hourlyQuantity: 109.25 }] + } + ]) + }).to.not.throw() + }) + }) + + describe('"instantQuantity" property', () => { + it('should throw an error if "instantQuantity" is not a number or null', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: [{ ...licenceVersionPurpose, instantQuantity: '1a' }] + } + ]) + }).to.throw('"[0].purposes[0].instantQuantity" must be a number') + }) + + it('should not throw an error if "instantQuantity" is null', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: [{ ...licenceVersionPurpose, instantQuantity: null }] + } + ]) + }).to.not.throw() + }) + + it('should not throw an error if "instantQuantity" is a number', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: [{ ...licenceVersionPurpose, instantQuantity: 109 }] + } + ]) + }).to.not.throw() + }) + }) + + describe('"primaryPurposeId" property', () => { + it('should throw an error if "primaryPurposeId" is not a string or null', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: [{ ...licenceVersionPurpose, primaryPurposeId: 1 }] + } + ]) + }).to.throw('"[0].purposes[0].primaryPurposeId" must be a string') + }) + + it('should throw an error if "primaryPurposeId" is null', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: [{ ...licenceVersionPurpose, primaryPurposeId: null }] + } + ]) + }).to.throw('"[0].purposes[0].primaryPurposeId" must be a string') + }) + + it('should not throw an error if "primaryPurposeId" is a string', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: [{ ...licenceVersionPurpose, primaryPurposeId: 'I' }] + } + ]) + }).to.not.throw() + }) + }) + + describe('"secondaryPurposeId" property', () => { + it('should throw an error if "secondaryPurposeId" is not a string or null', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: [{ ...licenceVersionPurpose, secondaryPurposeId: 1 }] + } + ]) + }).to.throw('"[0].purposes[0].secondaryPurposeId" must be a string') + }) + + it('should throw an error if "secondaryPurposeId" is null', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: [{ ...licenceVersionPurpose, secondaryPurposeId: null }] + } + ]) + }).to.throw('"[0].purposes[0].secondaryPurposeId" must be a string') + }) + + it('should not throw an error if "secondaryPurposeId" is a string', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: [{ ...licenceVersionPurpose, secondaryPurposeId: 'OTI' }] + } + ]) + }).to.not.throw() + }) + }) + + describe('"purposeId" property', () => { + it('should throw an error if "purposeId" is not a string or null', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: [{ ...licenceVersionPurpose, purposeId: 1 }] + } + ]) + }).to.throw('"[0].purposes[0].purposeId" must be a string') + }) + + it('should throw an error if "purposeId" is null', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: [{ ...licenceVersionPurpose, purposeId: null }] + } + ]) + }).to.throw('"[0].purposes[0].purposeId" must be a string') + }) + + it('should not throw an error if "purposeId" is a string', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: [{ ...licenceVersionPurpose, purposeId: '160' }] + } + ]) + }).to.not.throw() + }) + }) + + describe('"notes" property', () => { + it('should throw an error if "notes" is string or null', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: [{ ...licenceVersionPurpose, notes: 1 }] + } + ]) + }).to.throw('"[0].purposes[0].notes" must be a string') + }) + + it('should not throw an error if "notes" is null', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: [{ ...licenceVersionPurpose, notes: null }] + } + ]) + }).to.not.throw() + }) + + it('should not throw an error if "notes" is a string', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: [{ ...licenceVersionPurpose, notes: 'a fancy note' }] + } + ]) + }).to.not.throw() + }) + }) + + describe('"externalId" property', () => { + it('should throw an error if "externalId" is not a string or null', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: [{ ...licenceVersionPurpose, externalId: 1 }] + } + ]) + }).to.throw('"[0].purposes[0].externalId" must be a string') + }) + + it('should throw an error if "externalId" is null', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: [{ ...licenceVersionPurpose, externalId: null }] + } + ]) + }).to.throw('"[0].purposes[0].externalId" must be a string') + }) + + it('should not throw an error if "externalId" is a string', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: [{ ...licenceVersionPurpose, externalId: '1:900' }] + } + ]) + }).to.not.throw() + }) + }) + + describe('"timeLimitedEndDate" property', () => { + it('should throw an error if "timeLimitedEndDate" is not a valid date', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: [{ ...licenceVersionPurpose, timeLimitedEndDate: 1 }] + } + ]) + }).to.throw('"[0].purposes[0].timeLimitedEndDate" must be a valid date') + }) + + it('should throw an error if "timeLimitedEndDate" does not meet ISO 8601', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: [{ ...licenceVersionPurpose, timeLimitedEndDate: '01/01/2001' }] + } + ]) + }).to.throw('"[0].purposes[0].timeLimitedEndDate" must be in ISO 8601 date format') + }) + + it('should not throw an error if "timeLimitedEndDate" is null', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: [{ ...licenceVersionPurpose, timeLimitedEndDate: null }] + } + ]) + }).to.not.throw() + }) + + it('should not throw an error if "timeLimitedEndDate" is valid date string', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: [{ ...licenceVersionPurpose, timeLimitedEndDate: '2001-01-01' }] + } + ]) + }).to.not.throw() + }) + }) + + describe('"timeLimitedStartDate" property', () => { + it('should throw an error if "timeLimitedStartDate" is not a valid date', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: [{ ...licenceVersionPurpose, timeLimitedStartDate: 1 }] + } + ]) + }).to.throw('"[0].purposes[0].timeLimitedStartDate" must be a valid date') + }) + + it('should throw an error if "timeLimitedStartDate" does not meet ISO 8601', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: [{ ...licenceVersionPurpose, timeLimitedStartDate: '01/01/2001' }] + } + ]) + }).to.throw('"[0].purposes[0].timeLimitedStartDate" must be in ISO 8601 date format') + }) + + it('should not throw an error if "timeLimitedStartDate" is null', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: [{ ...licenceVersionPurpose, timeLimitedStartDate: null }] + } + ]) + }).to.not.throw() + }) + + it('should not throw an error if "timeLimitedStartDate" is valid date string', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: [{ ...licenceVersionPurpose, timeLimitedStartDate: '2001-01-01' }] + } + ]) + }).to.not.throw() + }) + }) + }) }) }) From 8bb382410f0ecd26ca53a78c3ec8e3bf7a726565 Mon Sep 17 00:00:00 2001 From: jonathangoulding Date: Fri, 26 Jul 2024 14:51:11 +0100 Subject: [PATCH 22/75] feat: add licence ref to error log --- app/controllers/import.controller.js | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/app/controllers/import.controller.js b/app/controllers/import.controller.js index 3184a018a0..ec79fba24f 100644 --- a/app/controllers/import.controller.js +++ b/app/controllers/import.controller.js @@ -8,16 +8,15 @@ const Boom = require('@hapi/boom') * @module ImportController */ async function licence (request, h) { - // try { const { licenceRef } = request.payload - await LegacyImportLicenceService.go(licenceRef) + try { + await LegacyImportLicenceService.go(licenceRef) - return h.response().code(204) - // } catch (error) { - // log licence ref error in logs ? - // return Boom.badImplementation(error.message) - // } + return h.response().code(204) + } catch (error) { + return Boom.badImplementation(`Licence ref: ${licenceRef} failed with error - ${error.message}`) + } } module.exports = { From e869e72bdbbaf7db8a76ff55ed65170d53c12429 Mon Sep 17 00:00:00 2001 From: Jonathan Goulding <58443816+jonathangoulding@users.noreply.github.com> Date: Fri, 26 Jul 2024 15:08:25 +0100 Subject: [PATCH 23/75] Update app/services/import/legacy-import/fetch-licence-versions.service.js --- .../import/legacy-import/fetch-licence-versions.service.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/services/import/legacy-import/fetch-licence-versions.service.js b/app/services/import/legacy-import/fetch-licence-versions.service.js index 7af82ea85b..29bc4ccf2f 100644 --- a/app/services/import/legacy-import/fetch-licence-versions.service.js +++ b/app/services/import/legacy-import/fetch-licence-versions.service.js @@ -7,7 +7,7 @@ const { db } = require('../../../../db/db.js') /** - * Gets the licence versions + * Gets the legacy licence versions * * Returns the licence version purposes * From 7f8c3979da7e96fc96c3b9cc5565eb6cf9a2f033 Mon Sep 17 00:00:00 2001 From: Jonathan Goulding <58443816+jonathangoulding@users.noreply.github.com> Date: Fri, 26 Jul 2024 15:08:31 +0100 Subject: [PATCH 24/75] Update app/services/import/legacy-import/fetch-licence-versions.service.js --- .../import/legacy-import/fetch-licence-versions.service.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/services/import/legacy-import/fetch-licence-versions.service.js b/app/services/import/legacy-import/fetch-licence-versions.service.js index 29bc4ccf2f..5a84ea7cd6 100644 --- a/app/services/import/legacy-import/fetch-licence-versions.service.js +++ b/app/services/import/legacy-import/fetch-licence-versions.service.js @@ -9,7 +9,7 @@ const { db } = require('../../../../db/db.js') /** * Gets the legacy licence versions * - * Returns the licence version purposes + * Returns the legacy licence version purposes * * @param {LegacyLicenceType} licenceData - the licence * @returns {Promise} From a9cfc9f8cdcdeecbf9adbc63b4badfc05b15ae4f Mon Sep 17 00:00:00 2001 From: Jonathan Goulding <58443816+jonathangoulding@users.noreply.github.com> Date: Fri, 26 Jul 2024 15:09:34 +0100 Subject: [PATCH 25/75] Update app/services/import/legacy-import/fetch-licence-versions.service.js --- .../import/legacy-import/fetch-licence-versions.service.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/services/import/legacy-import/fetch-licence-versions.service.js b/app/services/import/legacy-import/fetch-licence-versions.service.js index 5a84ea7cd6..e99c0f2abe 100644 --- a/app/services/import/legacy-import/fetch-licence-versions.service.js +++ b/app/services/import/legacy-import/fetch-licence-versions.service.js @@ -11,7 +11,7 @@ const { db } = require('../../../../db/db.js') * * Returns the legacy licence version purposes * - * @param {LegacyLicenceType} licenceData - the licence + * @param {LegacyLicenceType} licenceData * @returns {Promise} */ async function go (licenceData) { From 7f50242aa69993300bc5757e078cdfd22b85545a Mon Sep 17 00:00:00 2001 From: Jonathan Goulding <58443816+jonathangoulding@users.noreply.github.com> Date: Fri, 26 Jul 2024 15:09:40 +0100 Subject: [PATCH 26/75] Update app/services/import/legacy-import/fetch-licence-versions.service.js --- .../import/legacy-import/fetch-licence-versions.service.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/services/import/legacy-import/fetch-licence-versions.service.js b/app/services/import/legacy-import/fetch-licence-versions.service.js index e99c0f2abe..912ec71837 100644 --- a/app/services/import/legacy-import/fetch-licence-versions.service.js +++ b/app/services/import/legacy-import/fetch-licence-versions.service.js @@ -76,7 +76,7 @@ module.exports = { * @property {string} EFF_END_DATE - date in UK format - can be 'null' * @property {string} EFF_ST_DATE - date in UK format * @property {string} INCR_NO - a number between 1 - 5 - * @property {string} ISSUE_NO - a number - linked to the purpose id ? + * @property {string} ISSUE_NO - a number * @property {string} STATUS - enum - 'DRAFT', 'SUPER', 'CURR' (Draft will not be selected) * @property {string} FGAC_REGION_CODE * @property {string} AABL_ID From 4bc5899a1335dcf26772d111339a09b84818db30 Mon Sep 17 00:00:00 2001 From: Jonathan Goulding <58443816+jonathangoulding@users.noreply.github.com> Date: Fri, 26 Jul 2024 15:10:45 +0100 Subject: [PATCH 27/75] Update app/services/import/legacy-import/fetch-licence-versions.service.js --- .../import/legacy-import/fetch-licence-versions.service.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/services/import/legacy-import/fetch-licence-versions.service.js b/app/services/import/legacy-import/fetch-licence-versions.service.js index 912ec71837..6f410075b0 100644 --- a/app/services/import/legacy-import/fetch-licence-versions.service.js +++ b/app/services/import/legacy-import/fetch-licence-versions.service.js @@ -97,7 +97,7 @@ module.exports = { * @property {string} ANNUAL_QTY - The annual quantity. * @property {string} DAILY_QTY - The daily quantity. * @property {string} FGAC_REGION_CODE - The FGAC region code. - * @property {string} ID - The identifier. + * @property {string} ID * @property {string} HOURLY_QTY - The hourly quantity. * @property {string} INST_QTY - The instant quantity. * @property {string} NOTES - Additional notes. From b51422d5bf42702beb4fbc145564c0594945ad0f Mon Sep 17 00:00:00 2001 From: Jonathan Goulding <58443816+jonathangoulding@users.noreply.github.com> Date: Fri, 26 Jul 2024 15:10:50 +0100 Subject: [PATCH 28/75] Update app/validators/import/licence-versions.validator.js --- app/validators/import/licence-versions.validator.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/validators/import/licence-versions.validator.js b/app/validators/import/licence-versions.validator.js index 9a33ab64cc..bedbc1d579 100644 --- a/app/validators/import/licence-versions.validator.js +++ b/app/validators/import/licence-versions.validator.js @@ -34,7 +34,7 @@ const _isValidStatus = (value) => { return value } - throw new Error(`status must be one of ${validStatues.toString()}`) + throw new Error(`Status must be one of ${validStatues.toString()}`) } const _purposeSchema = Joi.object({ From 03530c2705bbb2a0ac142b07efe401243853b2fc Mon Sep 17 00:00:00 2001 From: Jonathan Goulding <58443816+jonathangoulding@users.noreply.github.com> Date: Fri, 26 Jul 2024 15:10:58 +0100 Subject: [PATCH 29/75] Update test/services/import/legacy-licence.service.test.js --- test/services/import/legacy-licence.service.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/services/import/legacy-licence.service.test.js b/test/services/import/legacy-licence.service.test.js index aa054c6953..8d349923df 100644 --- a/test/services/import/legacy-licence.service.test.js +++ b/test/services/import/legacy-licence.service.test.js @@ -172,7 +172,7 @@ describe('Legacy import licence service', () => { }) }) - it('checks the purposes id, primary purpose id and secondary purpose id match to the legacy id provided', async () => { + it('checks the purposes id, primary purpose id and secondary purpose id match the legacy id provided', async () => { await LegacyImportLicenceService.go(licenceRef) const licence = await LicenceModel.query().select(['id']).where('licenceRef', licenceRef).first() From a6159733b9986590e54b0839a8234597b331b245 Mon Sep 17 00:00:00 2001 From: Jonathan Goulding <58443816+jonathangoulding@users.noreply.github.com> Date: Fri, 26 Jul 2024 15:11:12 +0100 Subject: [PATCH 30/75] Update app/services/import/legacy-import/licence-versions.mapper.js --- app/services/import/legacy-import/licence-versions.mapper.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/services/import/legacy-import/licence-versions.mapper.js b/app/services/import/legacy-import/licence-versions.mapper.js index 0030d516c7..811b3b62e5 100644 --- a/app/services/import/legacy-import/licence-versions.mapper.js +++ b/app/services/import/legacy-import/licence-versions.mapper.js @@ -1,7 +1,7 @@ 'use strict' /** - * Maps the import licence versions data to the desired format + * Maps the import licence versions and licence versions purposes data * @module LegacyImportLicenceVersionMapper */ From f201df851b5b16e954e2846d7d5eb86d0ac13b6d Mon Sep 17 00:00:00 2001 From: Jonathan Goulding <58443816+jonathangoulding@users.noreply.github.com> Date: Fri, 26 Jul 2024 15:11:24 +0100 Subject: [PATCH 31/75] Update app/services/import/legacy-import/licence-versions.mapper.js --- app/services/import/legacy-import/licence-versions.mapper.js | 1 - 1 file changed, 1 deletion(-) diff --git a/app/services/import/legacy-import/licence-versions.mapper.js b/app/services/import/legacy-import/licence-versions.mapper.js index 811b3b62e5..60bdcafb3d 100644 --- a/app/services/import/legacy-import/licence-versions.mapper.js +++ b/app/services/import/legacy-import/licence-versions.mapper.js @@ -10,7 +10,6 @@ const { formatStandardDateToISO } = require('../../../lib/dates.lib.js') const statuses = { CURR: 'current', SUPER: 'superseded', - DRAFT: 'draft' // todo: check this can be removed as it the sql does not get draft status } const createExternalId = (licenceVersion) => { From 83857e742d85b33ba9dc315c6c4281caaea383b4 Mon Sep 17 00:00:00 2001 From: Jonathan Goulding <58443816+jonathangoulding@users.noreply.github.com> Date: Fri, 26 Jul 2024 15:13:04 +0100 Subject: [PATCH 32/75] Update app/services/import/legacy-import/licence-versions.mapper.js --- app/services/import/legacy-import/licence-versions.mapper.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/services/import/legacy-import/licence-versions.mapper.js b/app/services/import/legacy-import/licence-versions.mapper.js index 60bdcafb3d..bd1b89a734 100644 --- a/app/services/import/legacy-import/licence-versions.mapper.js +++ b/app/services/import/legacy-import/licence-versions.mapper.js @@ -9,7 +9,7 @@ const { formatStandardDateToISO } = require('../../../lib/dates.lib.js') const statuses = { CURR: 'current', - SUPER: 'superseded', + SUPER: 'superseded' } const createExternalId = (licenceVersion) => { From 619ceacd1af5823f8815d3448ea072999820f5e3 Mon Sep 17 00:00:00 2001 From: Jonathan Goulding <58443816+jonathangoulding@users.noreply.github.com> Date: Fri, 26 Jul 2024 15:13:12 +0100 Subject: [PATCH 33/75] Update app/services/import/legacy-import/licence-versions.mapper.js --- app/services/import/legacy-import/licence-versions.mapper.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/services/import/legacy-import/licence-versions.mapper.js b/app/services/import/legacy-import/licence-versions.mapper.js index bd1b89a734..ed6d0a08df 100644 --- a/app/services/import/legacy-import/licence-versions.mapper.js +++ b/app/services/import/legacy-import/licence-versions.mapper.js @@ -36,7 +36,7 @@ function go (licenceVersions) { */ function _mapLicenceVersions (licenceVersions) { return licenceVersions.map((licenceVersion) => { - const issue = licenceVersion.ISSUE_NO // mapped to the legacy purpose id - + const issue = licenceVersion.ISSUE_NO const increment = licenceVersion.INCR_NO return { From cb49d30aff6cc3c9104e8e7ddb3ae51a1e5cb741 Mon Sep 17 00:00:00 2001 From: Jonathan Goulding <58443816+jonathangoulding@users.noreply.github.com> Date: Fri, 26 Jul 2024 15:13:20 +0100 Subject: [PATCH 34/75] Update app/services/import/legacy-import/licence-versions.mapper.js --- app/services/import/legacy-import/licence-versions.mapper.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/services/import/legacy-import/licence-versions.mapper.js b/app/services/import/legacy-import/licence-versions.mapper.js index ed6d0a08df..544323507a 100644 --- a/app/services/import/legacy-import/licence-versions.mapper.js +++ b/app/services/import/legacy-import/licence-versions.mapper.js @@ -64,7 +64,7 @@ function _mapPurposes (licenceVersion) { } /** - * Maps the import licence versions purposes data to the desired format + * Maps the import licence versions purposes data * * @param {LegacyLicenceVersionsPurposesType} purpose * @returns {ImportLicenceVersionPurposeType} From e04100f22819278cabb752eddb9bccf7b9b8a288 Mon Sep 17 00:00:00 2001 From: Jonathan Goulding <58443816+jonathangoulding@users.noreply.github.com> Date: Fri, 26 Jul 2024 15:13:28 +0100 Subject: [PATCH 35/75] Update app/services/import/persist-licence-versions.service.js --- app/services/import/persist-licence-versions.service.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/services/import/persist-licence-versions.service.js b/app/services/import/persist-licence-versions.service.js index 7abdb5e901..7bd34bd48d 100644 --- a/app/services/import/persist-licence-versions.service.js +++ b/app/services/import/persist-licence-versions.service.js @@ -12,7 +12,7 @@ const SecondaryPurposeModel = require('../../models/secondary-purpose.model.js') const PurposeModel = require('../../models/purpose.model.js') /** - * Saves the licence versions + * Saves the licence versions, purposes and conditions * * @param {ImportLicenceVersionType[]} licenceVersions * @param {string} licenceId From 275095c18c9ae9bc8570e8b96cc13d3bbfe02f8e Mon Sep 17 00:00:00 2001 From: jonathangoulding Date: Fri, 26 Jul 2024 15:21:03 +0100 Subject: [PATCH 36/75] fix: licence date validation --- app/validators/custom/date.validators.js | 33 ------------------- app/validators/import/licence.validator.js | 10 +++--- .../import/licence.validator.test.js | 28 ++++++++-------- 3 files changed, 18 insertions(+), 53 deletions(-) delete mode 100644 app/validators/custom/date.validators.js diff --git a/app/validators/custom/date.validators.js b/app/validators/custom/date.validators.js deleted file mode 100644 index 90ad92b344..0000000000 --- a/app/validators/custom/date.validators.js +++ /dev/null @@ -1,33 +0,0 @@ -'use strict' - -/** - * @module CustomDateValidator - */ - -/** - * Validates a string is in the format yyyy-mm-dd - * - */ -const isValidISODate = (value) => { - const regex = /^\d{4}-\d{2}-\d{2}$/ - - if (!regex.test(value)) { - throw new Error('date must be in the format YYYY-MM-DD') - } - - const [, month, day] = value.split('-') - - const maxMonths = 12 - const maxDays = 31 - - // Basic check for valid month and day values (can be extended for more robust validation) - if (month < 1 || month > maxMonths || day < 1 || day > maxDays) { - throw new Error('date must be a valid date') - } - - return value -} - -module.exports = { - isValidISODate -} diff --git a/app/validators/import/licence.validator.js b/app/validators/import/licence.validator.js index 60413148ca..6178958b48 100644 --- a/app/validators/import/licence.validator.js +++ b/app/validators/import/licence.validator.js @@ -6,8 +6,6 @@ const Joi = require('joi') -const CustomDateValidator = require('../custom/date.validators.js') - /** * Checks that the data for inserting/updating the public.licence table is valid * @@ -25,8 +23,8 @@ function go (data) { } const _schema = Joi.object({ - expiredDate: Joi.string().allow(null).custom(CustomDateValidator.isValidISODate), - lapsedDate: Joi.string().allow(null).custom(CustomDateValidator.isValidISODate), + expiredDate: Joi.date().iso().allow(null), + lapsedDate: Joi.date().iso().allow(null), licenceRef: Joi.string().required(), naldRegionId: Joi.number().required(), regions: Joi.object({ @@ -35,8 +33,8 @@ const _schema = Joi.object({ historicalAreaCode: Joi.string(), standardUnitChargeCode: Joi.string() }), - revokedDate: Joi.string().allow(null).custom(CustomDateValidator.isValidISODate), - startDate: Joi.string().required().custom(CustomDateValidator.isValidISODate), + revokedDate: Joi.date().iso().allow(null), + startDate: Joi.date().iso().required(), waterUndertaker: Joi.boolean().required() }) diff --git a/test/validators/import/licence.validator.test.js b/test/validators/import/licence.validator.test.js index 177c938609..ab78723085 100644 --- a/test/validators/import/licence.validator.test.js +++ b/test/validators/import/licence.validator.test.js @@ -13,7 +13,7 @@ const { validLicenceRequiredOnly } = require('./_fixtures/valid-licence.fixture. // Thing under test const ImportLicenceValidator = require('../../../app/validators/import/licence.validator.js') -describe('Import licence validator', () => { +describe.only('Import licence validator', () => { let licence before(async () => { @@ -37,16 +37,16 @@ describe('Import licence validator', () => { ...licence, expiredDate: 1 }) - }).to.throw('"expiredDate" must be a string') + }).to.throw('"expiredDate" must be a valid date') }) - it('should throw an error if "expiredDate" is not in the correct format YYYY-MM-DD', async () => { + it('should throw an error if "expiredDate" does not meet ISO 8601', async () => { expect(() => { return ImportLicenceValidator.go({ ...licence, expiredDate: '01/01/2001' }) - }).to.throw('"expiredDate" failed custom validation because date must be in the format YYYY-MM-DD') + }).to.throw('"expiredDate" must be in ISO 8601 date format') }) it('should not throw an error if "expiredDate" is null', async () => { @@ -75,16 +75,16 @@ describe('Import licence validator', () => { ...licence, lapsedDate: 1 }) - }).to.throw('"lapsedDate" must be a string') + }).to.throw('"lapsedDate" must be a valid date') }) - it('should throw an error if "lapsedDate" is not in the correct format YYYY-MM-DD', async () => { + it('should throw an error if "lapsedDate" does not meet ISO 8601', async () => { expect(() => { return ImportLicenceValidator.go({ ...licence, lapsedDate: '01/01/2001' }) - }).to.throw('"lapsedDate" failed custom validation because date must be in the format YYYY-MM-DD') + }).to.throw('"lapsedDate" must be in ISO 8601 date format') }) it('should not throw an error if "lapsedDate" is null', async () => { @@ -228,16 +228,16 @@ describe('Import licence validator', () => { ...licence, revokedDate: 1 }) - }).to.throw('"revokedDate" must be a string') + }).to.throw('"revokedDate" must be a valid date') }) - it('should throw an error if "revokedDate" is not in the correct format YYYY-MM-DD', async () => { + it('should throw an error if "revokedDate" does not meet ISO 8601', async () => { expect(() => { return ImportLicenceValidator.go({ ...licence, revokedDate: '01/01/2001' }) - }).to.throw('"revokedDate" failed custom validation because date must be in the format YYYY-MM-DD') + }).to.throw('"revokedDate" must be in ISO 8601 date format') }) it('should not throw an error if "revokedDate" is null', async () => { @@ -266,16 +266,16 @@ describe('Import licence validator', () => { ...licence, startDate: 1 }) - }).to.throw('"startDate" must be a string') + }).to.throw('"startDate" must be a valid date') }) - it('should throw an error if "startDate" is not in the correct format YYYY-MM-DD', async () => { + it('should throw an error if "startDate" does not meet ISO 8601', async () => { expect(() => { return ImportLicenceValidator.go({ ...licence, startDate: '01/01/2001' }) - }).to.throw('"startDate" failed custom validation because date must be in the format YYYY-MM-DD') + }).to.throw('"startDate" must be in ISO 8601 date format') }) it('should throw an error if "startDate" is null', async () => { @@ -284,7 +284,7 @@ describe('Import licence validator', () => { ...licence, startDate: null }) - }).to.throw('"startDate" must be a string') + }).to.throw('"startDate" must be a valid date') }) it('should not throw an error if "startDate" is valid date string', async () => { From 5ba138725a460bcf34b2dedf5e5279f0efa0fb2d Mon Sep 17 00:00:00 2001 From: jonathangoulding Date: Fri, 26 Jul 2024 15:22:41 +0100 Subject: [PATCH 37/75] fix: licence date validation --- .../import/_fixtures/{versions.js => licence-version.js} | 0 .../import/legacy-import/licence-versions.mapper.test.js | 2 +- test/services/import/legacy-import/licence.mapper.test.js | 2 +- test/services/import/legacy-licence.service.test.js | 2 +- test/validators/import/licence.validator.test.js | 2 +- 5 files changed, 4 insertions(+), 4 deletions(-) rename test/services/import/_fixtures/{versions.js => licence-version.js} (100%) diff --git a/test/services/import/_fixtures/versions.js b/test/services/import/_fixtures/licence-version.js similarity index 100% rename from test/services/import/_fixtures/versions.js rename to test/services/import/_fixtures/licence-version.js diff --git a/test/services/import/legacy-import/licence-versions.mapper.test.js b/test/services/import/legacy-import/licence-versions.mapper.test.js index 8ff94cea0d..6c28e3e5ce 100644 --- a/test/services/import/legacy-import/licence-versions.mapper.test.js +++ b/test/services/import/legacy-import/licence-versions.mapper.test.js @@ -8,7 +8,7 @@ const { describe, it, beforeEach } = exports.lab = Lab.script() const { expect } = Code // Test helpers -const FixtureVersions = require('../_fixtures/versions.js') +const FixtureVersions = require('../_fixtures/licence-version.js') const FixtureLicenceVersionPurposes = require('../_fixtures/licence-version-purposes.fixture.js') // Thing under test diff --git a/test/services/import/legacy-import/licence.mapper.test.js b/test/services/import/legacy-import/licence.mapper.test.js index 14f6f3760c..8f6d0ad28f 100644 --- a/test/services/import/legacy-import/licence.mapper.test.js +++ b/test/services/import/legacy-import/licence.mapper.test.js @@ -9,7 +9,7 @@ const { expect } = Code // Test helpers const FixtureLicence = require('../_fixtures/licence.js') -const FixtureVersion = require('../_fixtures/versions.js') +const FixtureVersion = require('../_fixtures/licence-version.js') // Thing under test const LegacyImportLicenceMapper = diff --git a/test/services/import/legacy-licence.service.test.js b/test/services/import/legacy-licence.service.test.js index 8d349923df..cc54fd906d 100644 --- a/test/services/import/legacy-licence.service.test.js +++ b/test/services/import/legacy-licence.service.test.js @@ -13,7 +13,7 @@ const FetchLegacyImportLicenceService = require('../../../app/services/import/le const FetchLegacyImportLicenceVersionsService = require('../../../app/services/import/legacy-import/fetch-licence-versions.service.js') const FixtureLicence = require('./_fixtures/licence.js') const FixtureLicenceVersionPurposes = require('./_fixtures/licence-version-purposes.fixture.js') -const FixtureVersion = require('./_fixtures/versions.js') +const FixtureVersion = require('./_fixtures/licence-version.js') const LicenceModel = require('../../../app/models/licence.model.js') const PrimaryPurposesSeeder = require('../../support/seeders/primary-purpose.seeder.js') const PurposesSeeder = require('../../support/seeders/purposes.seeder.js') diff --git a/test/validators/import/licence.validator.test.js b/test/validators/import/licence.validator.test.js index ab78723085..962f5eae79 100644 --- a/test/validators/import/licence.validator.test.js +++ b/test/validators/import/licence.validator.test.js @@ -13,7 +13,7 @@ const { validLicenceRequiredOnly } = require('./_fixtures/valid-licence.fixture. // Thing under test const ImportLicenceValidator = require('../../../app/validators/import/licence.validator.js') -describe.only('Import licence validator', () => { +describe('Import licence validator', () => { let licence before(async () => { From 73da354caac35b1c72c025c84b6c77f0626e5d40 Mon Sep 17 00:00:00 2001 From: jonathangoulding Date: Fri, 26 Jul 2024 15:29:56 +0100 Subject: [PATCH 38/75] fix: licence date validation --- test/validators/import/licence-versions.validator.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/validators/import/licence-versions.validator.test.js b/test/validators/import/licence-versions.validator.test.js index dfa3b603d6..09cae0a85d 100644 --- a/test/validators/import/licence-versions.validator.test.js +++ b/test/validators/import/licence-versions.validator.test.js @@ -227,7 +227,7 @@ describe('Import licence versions validator', () => { status: 'draft' } ]) - }).to.throw('"[0].status" failed custom validation because status must be one of current,superseded') + }).to.throw('"[0].status" failed custom validation because Status must be one of current,superseded') }) it('should not throw an error if "status" is a valid status', async () => { From 01d97a69461ab6defa95ecd5005be5307f0dab8a Mon Sep 17 00:00:00 2001 From: jonathangoulding Date: Mon, 29 Jul 2024 12:33:44 +0100 Subject: [PATCH 39/75] test: add licence versions persist tests unify fixtures names and layouts --- .../legacy-import/licence-versions.mapper.js | 18 ++-- .../persist-licence-versions.service.js | 9 +- .../import/persist-licence.service.js | 6 +- .../import-licence-versions.fixture.js} | 18 ++-- .../_fixtures/import-licence.fixture.js | 36 +++++++ ...egacy-licence-version-purposes.fixture.js} | 0 ...n.js => legacy-licence-version.fixture.js} | 4 +- .../{licence.js => legacy-licence.fixture.js} | 4 +- .../licence-versions.mapper.test.js | 8 +- .../legacy-import/licence.mapper.test.js | 8 +- .../import/legacy-licence.service.test.js | 20 ++-- .../import/licence-validator.service.test.js | 4 +- .../persist-licence-versions.service.test.js | 98 +++++++++++++++++++ .../import/persist-licence.service.test.js | 46 ++------- .../import/_fixtures/valid-licence.fixture.js | 14 --- .../import/licence-versions.validator.test.js | 10 +- .../import/licence.validator.test.js | 4 +- 17 files changed, 200 insertions(+), 107 deletions(-) rename test/{validators/import/_fixtures/valid-licence-versions.fixture.js => services/import/_fixtures/import-licence-versions.fixture.js} (61%) create mode 100644 test/services/import/_fixtures/import-licence.fixture.js rename test/services/import/_fixtures/{licence-version-purposes.fixture.js => legacy-licence-version-purposes.fixture.js} (100%) rename test/services/import/_fixtures/{licence-version.js => legacy-licence-version.fixture.js} (69%) rename test/services/import/_fixtures/{licence.js => legacy-licence.fixture.js} (84%) create mode 100644 test/services/import/persist-licence-versions.service.test.js delete mode 100644 test/validators/import/_fixtures/valid-licence.fixture.js diff --git a/app/services/import/legacy-import/licence-versions.mapper.js b/app/services/import/legacy-import/licence-versions.mapper.js index 544323507a..1286da26ff 100644 --- a/app/services/import/legacy-import/licence-versions.mapper.js +++ b/app/services/import/legacy-import/licence-versions.mapper.js @@ -12,12 +12,6 @@ const statuses = { SUPER: 'superseded' } -const createExternalId = (licenceVersion) => { - const { FGAC_REGION_CODE, AABL_ID, ISSUE_NO, INCR_NO } = licenceVersion - - return `${FGAC_REGION_CODE}:${AABL_ID}:${ISSUE_NO}:${INCR_NO}` -} - /** * Maps the import licence versions data * @@ -28,8 +22,14 @@ function go (licenceVersions) { return _mapLicenceVersions(licenceVersions) } +const _createExternalId = (licenceVersion) => { + const { FGAC_REGION_CODE, AABL_ID, ISSUE_NO, INCR_NO } = licenceVersion + + return `${FGAC_REGION_CODE}:${AABL_ID}:${ISSUE_NO}:${INCR_NO}` +} + /** - * Iterates the import licence versions + * Iterates the import licence versions and formats the licence version * * @param {LegacyLicenceVersionsArray} licenceVersions * @returns {ImportLicenceVersionType[]} @@ -41,7 +41,7 @@ function _mapLicenceVersions (licenceVersions) { return { endDate: formatStandardDateToISO(licenceVersion.EFF_END_DATE), - externalId: createExternalId(licenceVersion), + externalId: _createExternalId(licenceVersion), increment: Number(increment), issue: Number(issue), startDate: formatStandardDateToISO(licenceVersion.EFF_ST_DATE), @@ -52,7 +52,7 @@ function _mapLicenceVersions (licenceVersions) { } /** - * Iterates the import licence versions purposes + * Iterates the import licence version purposes * * @param {LegacyLicenceVersionsType} licenceVersion * @returns {ImportLicenceVersionPurposeType} diff --git a/app/services/import/persist-licence-versions.service.js b/app/services/import/persist-licence-versions.service.js index 7bd34bd48d..22577af10a 100644 --- a/app/services/import/persist-licence-versions.service.js +++ b/app/services/import/persist-licence-versions.service.js @@ -21,13 +21,15 @@ async function go (licenceVersions, licenceId) { return Promise.all(licenceVersions.map(async (version) => { const versionResult = await _saveLicenceVersion(version, licenceId) - return Promise.all(version.purposes.map(async (purpose) => { - return _saveLicencePurposes(purpose, versionResult.id) + Promise.all(version.purposes.map(async (purpose) => { + return _saveLicenceVersionPurposes(purpose, versionResult.id) })) + + return { ...versionResult } })) } -async function _saveLicencePurposes (purpose, licenceVersionId) { +async function _saveLicenceVersionPurposes (purpose, licenceVersionId) { const primaryPurpose = await PrimaryPurposeModel.query() .select('id') .where('legacyId', purpose.primaryPurposeId) @@ -64,7 +66,6 @@ async function _saveLicencePurposes (purpose, licenceVersionId) { 'abstractionPeriodStartMonth', 'annualQuantity', 'dailyQuantity', - 'externalId', 'hourlyQuantity', 'instantQuantity', 'notes', diff --git a/app/services/import/persist-licence.service.js b/app/services/import/persist-licence.service.js index a8f7c76314..c63e6762c7 100644 --- a/app/services/import/persist-licence.service.js +++ b/app/services/import/persist-licence.service.js @@ -41,14 +41,12 @@ async function go (licence) { .onConflict('licenceRef') .merge([ 'expiredDate', - 'waterUndertaker', 'lapsedDate', - 'licenceRef', - 'regionId', 'regions', 'revokedDate', 'startDate', - 'updatedAt' + 'updatedAt', + 'waterUndertaker' ]) } diff --git a/test/validators/import/_fixtures/valid-licence-versions.fixture.js b/test/services/import/_fixtures/import-licence-versions.fixture.js similarity index 61% rename from test/validators/import/_fixtures/valid-licence-versions.fixture.js rename to test/services/import/_fixtures/import-licence-versions.fixture.js index 3c2c4682a2..43259e1783 100644 --- a/test/validators/import/_fixtures/valid-licence-versions.fixture.js +++ b/test/services/import/_fixtures/import-licence-versions.fixture.js @@ -1,6 +1,8 @@ 'use strict' -const validLicencePurposes = [ +const { randomInteger } = require('../../../support/general.js') + +const importLicenceVersionPurposes = [ { abstractionPeriodEndDay: 31, abstractionPeriodEndMonth: 3, @@ -20,21 +22,21 @@ const validLicencePurposes = [ } ] -const validLicenceVersion = { +const importLicenceVersion = { endDate: '2002-01-01', - externalId: '3:10000003:100:0', + externalId: `9:${randomInteger(10000, 99999)}:1:0`, increment: 0, issue: 100, startDate: '2001-01-01', status: 'superseded' } -const validLicenceVersionsAndPurposes = [ - { ...validLicenceVersion, purposes: [...validLicencePurposes] } +const importLicenceVersionsAndPurposes = [ + { ...importLicenceVersion, purposes: [...importLicenceVersionPurposes] } ] module.exports = { - validLicencePurposes, - validLicenceVersion, - validLicenceVersionsAndPurposes + importLicenceVersionPurposes, + importLicenceVersion, + importLicenceVersionsAndPurposes } diff --git a/test/services/import/_fixtures/import-licence.fixture.js b/test/services/import/_fixtures/import-licence.fixture.js new file mode 100644 index 0000000000..1b57223eec --- /dev/null +++ b/test/services/import/_fixtures/import-licence.fixture.js @@ -0,0 +1,36 @@ +'use strict' + +const { generateLicenceRef } = require('../../../support/helpers/licence.helper.js') +const RegionsSeeder = require('../../../support/seeders/regions.seeder.js') + +const region = RegionsSeeder.data.find((region) => { + return region.displayName === 'Test Region' +}) + +const importLicence = { + expiredDate: '2015-03-31', + lapsedDate: null, + licenceRef: generateLicenceRef(), + naldRegionId: region.naldRegionId, + regions: { + historicalAreaCode: 'RIDIN', + regionalChargeArea: 'Yorkshire', + standardUnitChargeCode: 'YORKI', + localEnvironmentAgencyPlanCode: 'AIREL' + }, + revokedDate: null, + startDate: '2005-06-03', + waterUndertaker: false +} + +const importLicenceRequiredOnly = { + licenceRef: generateLicenceRef(), + naldRegionId: region.naldRegionId, + startDate: '2001-01-01', + waterUndertaker: true +} + +module.exports = { + importLicence, + importLicenceRequiredOnly +} diff --git a/test/services/import/_fixtures/licence-version-purposes.fixture.js b/test/services/import/_fixtures/legacy-licence-version-purposes.fixture.js similarity index 100% rename from test/services/import/_fixtures/licence-version-purposes.fixture.js rename to test/services/import/_fixtures/legacy-licence-version-purposes.fixture.js diff --git a/test/services/import/_fixtures/licence-version.js b/test/services/import/_fixtures/legacy-licence-version.fixture.js similarity index 69% rename from test/services/import/_fixtures/licence-version.js rename to test/services/import/_fixtures/legacy-licence-version.fixture.js index 6eba310294..ef06a0efb3 100644 --- a/test/services/import/_fixtures/licence-version.js +++ b/test/services/import/_fixtures/legacy-licence-version.fixture.js @@ -1,6 +1,6 @@ 'use strict' -const version = { +const legacyLicenceVersionFixture = { EFF_END_DATE: '04/06/2007', EFF_ST_DATE: '05/06/2005', INCR_NO: '0', @@ -11,4 +11,4 @@ const version = { purposes: [] } -module.exports = version +module.exports = legacyLicenceVersionFixture diff --git a/test/services/import/_fixtures/licence.js b/test/services/import/_fixtures/legacy-licence.fixture.js similarity index 84% rename from test/services/import/_fixtures/licence.js rename to test/services/import/_fixtures/legacy-licence.fixture.js index 12c7a17489..a5546df39d 100644 --- a/test/services/import/_fixtures/licence.js +++ b/test/services/import/_fixtures/legacy-licence.fixture.js @@ -2,7 +2,7 @@ const { generateLicenceRef } = require('../../../support/helpers/licence.helper.js') -const licence = { +const legacyLicenceFixture = { AREP_AREA_CODE: 'RIDIN', AREP_EIUC_CODE: 'YOOTH', AREP_LEAP_CODE: 'AIREL', @@ -16,4 +16,4 @@ const licence = { REV_DATE: 'null' } -module.exports = licence +module.exports = legacyLicenceFixture diff --git a/test/services/import/legacy-import/licence-versions.mapper.test.js b/test/services/import/legacy-import/licence-versions.mapper.test.js index 6c28e3e5ce..fc334331f5 100644 --- a/test/services/import/legacy-import/licence-versions.mapper.test.js +++ b/test/services/import/legacy-import/licence-versions.mapper.test.js @@ -8,8 +8,8 @@ const { describe, it, beforeEach } = exports.lab = Lab.script() const { expect } = Code // Test helpers -const FixtureVersions = require('../_fixtures/licence-version.js') -const FixtureLicenceVersionPurposes = require('../_fixtures/licence-version-purposes.fixture.js') +const FixtureLegacyLicenceVersion = require('../_fixtures/legacy-licence-version.fixture.js') +const FixtureLegacyLicenceVersionPurposes = require('../_fixtures/legacy-licence-version-purposes.fixture.js') // Thing under test const LegacyImportLicenceVersionMapper = @@ -21,8 +21,8 @@ describe('Legacy import licence versions mapper', () => { let version beforeEach(() => { - purpose = FixtureLicenceVersionPurposes - version = FixtureVersions + purpose = FixtureLegacyLicenceVersionPurposes + version = FixtureLegacyLicenceVersion licenceVersions = [{ ...version, purposes: [{ ...purpose }] }] }) diff --git a/test/services/import/legacy-import/licence.mapper.test.js b/test/services/import/legacy-import/licence.mapper.test.js index 8f6d0ad28f..39788f55b8 100644 --- a/test/services/import/legacy-import/licence.mapper.test.js +++ b/test/services/import/legacy-import/licence.mapper.test.js @@ -8,8 +8,8 @@ const { describe, it, beforeEach } = exports.lab = Lab.script() const { expect } = Code // Test helpers -const FixtureLicence = require('../_fixtures/licence.js') -const FixtureVersion = require('../_fixtures/licence-version.js') +const FixtureLegacyLicence = require('../_fixtures/legacy-licence.fixture.js') +const FixtureLegacyLicenceVersion = require('../_fixtures/legacy-licence-version.fixture.js') // Thing under test const LegacyImportLicenceMapper = @@ -19,7 +19,7 @@ describe('Legacy import licence mapper', () => { let licence beforeEach(() => { - licence = { ...FixtureLicence } + licence = { ...FixtureLegacyLicence } }) it('returns the matching agreements data', () => { @@ -154,7 +154,7 @@ describe('Legacy import licence mapper', () => { describe('then start date of the earliest non-draft licence version is used', () => { it('returns the start date in the ISO format', () => { // need to add licence versions - const result = LegacyImportLicenceMapper.go(licence, [{ ...FixtureVersion }]) + const result = LegacyImportLicenceMapper.go(licence, [{ ...FixtureLegacyLicenceVersion }]) expect(result.startDate).to.equal('2005-06-05') }) diff --git a/test/services/import/legacy-licence.service.test.js b/test/services/import/legacy-licence.service.test.js index cc54fd906d..89ba1ae2b8 100644 --- a/test/services/import/legacy-licence.service.test.js +++ b/test/services/import/legacy-licence.service.test.js @@ -11,9 +11,9 @@ const { expect } = Code // Test helpers const FetchLegacyImportLicenceService = require('../../../app/services/import/legacy-import/fetch-licence.service.js') const FetchLegacyImportLicenceVersionsService = require('../../../app/services/import/legacy-import/fetch-licence-versions.service.js') -const FixtureLicence = require('./_fixtures/licence.js') -const FixtureLicenceVersionPurposes = require('./_fixtures/licence-version-purposes.fixture.js') -const FixtureVersion = require('./_fixtures/licence-version.js') +const FixtureLegacyLicence = require('./_fixtures/legacy-licence.fixture.js') +const FixtureLegacyLicenceVersionPurposes = require('./_fixtures/legacy-licence-version-purposes.fixture.js') +const FixtureLegacyLicenceVersion = require('./_fixtures/legacy-licence-version.fixture.js') const LicenceModel = require('../../../app/models/licence.model.js') const PrimaryPurposesSeeder = require('../../support/seeders/primary-purpose.seeder.js') const PurposesSeeder = require('../../support/seeders/purposes.seeder.js') @@ -25,7 +25,7 @@ const LegacyImportLicenceService = require('../../../app/services/import/legacy-licence.service.js') describe('Legacy import licence service', () => { - const licenceRef = FixtureLicence.LIC_NO + const licenceRef = FixtureLegacyLicence.LIC_NO const region = RegionsSeeder.data.find((region) => { return region.displayName === 'Test Region' @@ -36,13 +36,13 @@ describe('Legacy import licence service', () => { let version before(() => { - licenceVersionPurpose = FixtureLicenceVersionPurposes - version = FixtureVersion + licenceVersionPurpose = FixtureLegacyLicenceVersionPurposes + version = FixtureLegacyLicenceVersion licenceVersions = [{ ...version, purposes: [{ ...licenceVersionPurpose }] }] Sinon.stub(FetchLegacyImportLicenceService, 'go').resolves({ - ...FixtureLicence, + ...FixtureLegacyLicence, FGAC_REGION_CODE: region.naldRegionId }) @@ -124,15 +124,15 @@ describe('Legacy import licence service', () => { beforeEach(() => { primaryPurpose = PrimaryPurposesSeeder.data.find((primaryPurpose) => { - return primaryPurpose.legacyId === FixtureLicenceVersionPurposes.APUR_APPR_CODE + return primaryPurpose.legacyId === FixtureLegacyLicenceVersionPurposes.APUR_APPR_CODE }) purpose = PurposesSeeder.data.find((purpose) => { - return purpose.legacyId === FixtureLicenceVersionPurposes.APUR_APUS_CODE + return purpose.legacyId === FixtureLegacyLicenceVersionPurposes.APUR_APUS_CODE }) secondaryPurpose = SecondaryPurposesSeeder.data.find((secondaryPurpose) => { - return secondaryPurpose.legacyId === FixtureLicenceVersionPurposes.APUR_APSE_CODE + return secondaryPurpose.legacyId === FixtureLegacyLicenceVersionPurposes.APUR_APSE_CODE }) }) diff --git a/test/services/import/licence-validator.service.test.js b/test/services/import/licence-validator.service.test.js index 41dec89c8d..e91b5ceff5 100644 --- a/test/services/import/licence-validator.service.test.js +++ b/test/services/import/licence-validator.service.test.js @@ -8,7 +8,7 @@ const { describe, it, beforeEach } = exports.lab = Lab.script() const { expect } = Code // Test helpers -const FixtureValidImportLicence = require('../../validators/import/_fixtures/valid-licence.fixture.js') +const FixtureValidImportLicence = require('./_fixtures/import-licence.fixture.js') // Thing under test const ImportLicenceValidatorService = @@ -19,7 +19,7 @@ describe('Import licence validator service', () => { beforeEach(async () => { licence = { - ...FixtureValidImportLicence.validLicenceRequiredOnly + ...FixtureValidImportLicence.importLicenceRequiredOnly } }) diff --git a/test/services/import/persist-licence-versions.service.test.js b/test/services/import/persist-licence-versions.service.test.js new file mode 100644 index 0000000000..47ddb98a79 --- /dev/null +++ b/test/services/import/persist-licence-versions.service.test.js @@ -0,0 +1,98 @@ +'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 LicenceVersionModel = require('../../../app/models/licence-version.model.js') +const FixtureValidLicenceVersions = require('./_fixtures/import-licence-versions.fixture.js') +const LicenceHelper = require('../../support/helpers/licence.helper.js') + +// Thing under test +const PersistLicenceVersionsService = + require('../../../app/services/import/persist-licence-versions.service.js') + +describe('Persist licence versions and licence versions purposes service', () => { + let licenceVersionsAndPurposes + let licence + + beforeEach(async () => { + licence = await LicenceHelper.add() + + licenceVersionsAndPurposes = [ + { + ...FixtureValidLicenceVersions.importLicenceVersion, + purposes: [] + } + ] + }) + + describe('when the licence version does not exist', () => { + it('returns the updated licence version', async () => { + const [result] = await PersistLicenceVersionsService.go(licenceVersionsAndPurposes, licence.id) + + const savedLicenceVersion = await LicenceVersionModel.query() + .select('*') + .where('externalId', FixtureValidLicenceVersions.importLicenceVersion.externalId).first() + + expect(result).to.equal({ + createdAt: savedLicenceVersion.createdAt.toISOString(), + endDate: '2002-01-01', + externalId: FixtureValidLicenceVersions.importLicenceVersion.externalId, + id: result.id, + increment: 0, + issue: 100, + licenceId: licence.id, + purposes: [], + startDate: '2001-01-01', + status: 'superseded', + updatedAt: savedLicenceVersion.updatedAt.toISOString() + }) + }) + }) + + describe('when the licence version already exists', () => { + beforeEach(async () => { + licenceVersionsAndPurposes = [ + { + ...FixtureValidLicenceVersions.importLicenceVersion, + purposes: [], + increment: 1 + } + ] + + await PersistLicenceVersionsService.go(licenceVersionsAndPurposes, licence.id) + }) + + it('returns the created licence version with updated values', async () => { + const [result] = await PersistLicenceVersionsService.go(licenceVersionsAndPurposes, licence.id) + + const savedLicenceVersion = await LicenceVersionModel.query() + .select('*') + .where('externalId', FixtureValidLicenceVersions.importLicenceVersion.externalId).first() + + expect(result).to.equal({ + endDate: '2002-01-01', + externalId: FixtureValidLicenceVersions.importLicenceVersion.externalId, + id: result.id, + increment: 1, + issue: 100, + licenceId: licence.id, + purposes: [], + startDate: '2001-01-01', + status: 'superseded', + updatedAt: savedLicenceVersion.updatedAt.toISOString() + }, { skip: ['createdAt'] }) + + expect(result.increment).to.equal(1) + }) + }) + + // todo: add these tests + // licence exists - purpose newly created and purpose updated ? + // licence does not exists - purpose newly created +}) diff --git a/test/services/import/persist-licence.service.test.js b/test/services/import/persist-licence.service.test.js index 2fe7a85c12..1d11775311 100644 --- a/test/services/import/persist-licence.service.test.js +++ b/test/services/import/persist-licence.service.test.js @@ -8,9 +8,9 @@ const { describe, it, beforeEach } = exports.lab = Lab.script() const { expect } = Code // Test helpers +const FixtureImportLicence = require('./_fixtures/import-licence.fixture.js') const LicenceModel = require('../../../app/models/licence.model.js') const RegionsSeeder = require('../../support/seeders/regions.seeder.js') -const { generateLicenceRef } = require('../../support/helpers/licence.helper.js') // Thing under test const PersistLicenceService = @@ -21,34 +21,20 @@ describe('Persist licence service', () => { let licence beforeEach(async () => { + licence = { ...FixtureImportLicence.importLicence } + region = RegionsSeeder.data.find((region) => { return region.displayName === 'Test Region' }) }) describe('when the licence ref does not exist', () => { - beforeEach(() => { - licence = { - expiredDate: '2015-03-31', - lapsedDate: null, - licenceRef: generateLicenceRef(), - naldRegionId: region.naldRegionId, - regions: { - historicalAreaCode: 'RIDIN', - regionalChargeArea: 'Yorkshire', - standardUnitChargeCode: 'YORKI', - localEnvironmentAgencyPlanCode: 'AIREL' - }, - revokedDate: null, - startDate: '2005-06-03', - waterUndertaker: false - } - }) - it('returns the created licence', async () => { const results = await PersistLicenceService.go(licence) - const savedLicence = await LicenceModel.query().findById(results.id) + const savedLicence = await LicenceModel.query() + .select('*') + .where('licenceRef', licence.licenceRef).first() expect(results).to.equal({ expiredDate: '2015-03-31', @@ -73,22 +59,6 @@ describe('Persist licence service', () => { describe('when the licence ref already exist', () => { beforeEach(async () => { - licence = { - expiredDate: '2015-03-31', - lapsedDate: null, - licenceRef: generateLicenceRef(), - naldRegionId: region.naldRegionId, - regions: { - historicalAreaCode: 'RIDIN', - regionalChargeArea: 'Yorkshire', - standardUnitChargeCode: 'YORKI', - localEnvironmentAgencyPlanCode: 'AIREL' - }, - revokedDate: null, - startDate: '2005-06-03', - waterUndertaker: false - } - // create a licence that exists already (DB rule to only allow on occurrence of licence ref) await PersistLicenceService.go(licence) }) @@ -103,7 +73,9 @@ describe('Persist licence service', () => { startDate: '2005-06-03' }) - const savedLicence = await LicenceModel.query().findById(results.id) + const savedLicence = await LicenceModel.query() + .select('*') + .where('licenceRef', licence.licenceRef).first() expect(results).to.equal({ expiredDate: undefined, diff --git a/test/validators/import/_fixtures/valid-licence.fixture.js b/test/validators/import/_fixtures/valid-licence.fixture.js deleted file mode 100644 index 34de22ba08..0000000000 --- a/test/validators/import/_fixtures/valid-licence.fixture.js +++ /dev/null @@ -1,14 +0,0 @@ -'use strict' - -const { generateLicenceRef } = require('../../../support/helpers/licence.helper.js') - -const validLicenceRequiredOnly = { - licenceRef: generateLicenceRef(), - naldRegionId: 1, - startDate: '2001-01-01', - waterUndertaker: true -} - -module.exports = { - validLicenceRequiredOnly -} diff --git a/test/validators/import/licence-versions.validator.test.js b/test/validators/import/licence-versions.validator.test.js index 09cae0a85d..7a8738adc0 100644 --- a/test/validators/import/licence-versions.validator.test.js +++ b/test/validators/import/licence-versions.validator.test.js @@ -8,7 +8,7 @@ const { describe, it, before } = exports.lab = Lab.script() const { expect } = Code // Test helpers -const FixtureValidLicenceVersions = require('./_fixtures/valid-licence-versions.fixture.js') +const FixtureValidLicenceVersions = require('../../services/import/_fixtures/import-licence-versions.fixture.js') // Thing under test const ImportLicenceVersionsValidator = require('../../../app/validators/import/licence-versions.validator.js') @@ -20,10 +20,10 @@ describe('Import licence versions validator', () => { let licenceVersionsAndPurposes before(async () => { - licenceVersion = FixtureValidLicenceVersions.validLicenceVersion - licenceVersionPurpose = FixtureValidLicenceVersions.validLicencePurposes[0] - licenceVersionPurposes = FixtureValidLicenceVersions.validLicencePurposes - licenceVersionsAndPurposes = [...FixtureValidLicenceVersions.validLicenceVersionsAndPurposes] + licenceVersion = FixtureValidLicenceVersions.importLicenceVersion + licenceVersionPurpose = FixtureValidLicenceVersions.importLicenceVersionPurposes[0] + licenceVersionPurposes = FixtureValidLicenceVersions.importLicenceVersionPurposes + licenceVersionsAndPurposes = [...FixtureValidLicenceVersions.importLicenceVersionsAndPurposes] }) it('should not throw if all the required fields validations are met', () => { diff --git a/test/validators/import/licence.validator.test.js b/test/validators/import/licence.validator.test.js index 962f5eae79..8f374f6853 100644 --- a/test/validators/import/licence.validator.test.js +++ b/test/validators/import/licence.validator.test.js @@ -8,7 +8,7 @@ const { describe, it, before } = exports.lab = Lab.script() const { expect } = Code // Test helpers -const { validLicenceRequiredOnly } = require('./_fixtures/valid-licence.fixture.js') +const { importLicenceRequiredOnly } = require('../../services/import/_fixtures/import-licence.fixture.js') // Thing under test const ImportLicenceValidator = require('../../../app/validators/import/licence.validator.js') @@ -18,7 +18,7 @@ describe('Import licence validator', () => { before(async () => { licence = { - ...validLicenceRequiredOnly + ...importLicenceRequiredOnly } }) From a310bf883e5909804492917865d42feaf9d6ba56 Mon Sep 17 00:00:00 2001 From: jonathangoulding Date: Mon, 29 Jul 2024 13:51:29 +0100 Subject: [PATCH 40/75] test: licence versions purposes --- .../persist-licence-versions.service.js | 8 +- .../import-licence-versions.fixture.js | 7 +- .../persist-licence-versions.service.test.js | 77 +++++++++++++++++-- .../import/licence-versions.validator.test.js | 4 +- 4 files changed, 82 insertions(+), 14 deletions(-) diff --git a/app/services/import/persist-licence-versions.service.js b/app/services/import/persist-licence-versions.service.js index 22577af10a..0c11e9edf6 100644 --- a/app/services/import/persist-licence-versions.service.js +++ b/app/services/import/persist-licence-versions.service.js @@ -19,13 +19,17 @@ const PurposeModel = require('../../models/purpose.model.js') */ async function go (licenceVersions, licenceId) { return Promise.all(licenceVersions.map(async (version) => { + const purposes = version.purposes + + delete version.purposes + const versionResult = await _saveLicenceVersion(version, licenceId) - Promise.all(version.purposes.map(async (purpose) => { + const licenceVersionPurposes = await Promise.all(purposes.map(async (purpose) => { return _saveLicenceVersionPurposes(purpose, versionResult.id) })) - return { ...versionResult } + return { ...versionResult, purposes: licenceVersionPurposes } })) } diff --git a/test/services/import/_fixtures/import-licence-versions.fixture.js b/test/services/import/_fixtures/import-licence-versions.fixture.js index 43259e1783..4cb9eb16f3 100644 --- a/test/services/import/_fixtures/import-licence-versions.fixture.js +++ b/test/services/import/_fixtures/import-licence-versions.fixture.js @@ -2,7 +2,7 @@ const { randomInteger } = require('../../../support/general.js') -const importLicenceVersionPurposes = [ +const importLicenceVersionPurpose = { abstractionPeriodEndDay: 31, abstractionPeriodEndMonth: 3, @@ -20,7 +20,6 @@ const importLicenceVersionPurposes = [ timeLimitedEndDate: '2001-01-02', timeLimitedStartDate: '2001-01-03' } -] const importLicenceVersion = { endDate: '2002-01-01', @@ -32,11 +31,11 @@ const importLicenceVersion = { } const importLicenceVersionsAndPurposes = [ - { ...importLicenceVersion, purposes: [...importLicenceVersionPurposes] } + { ...importLicenceVersion, purposes: [{ ...importLicenceVersionPurpose }] } ] module.exports = { - importLicenceVersionPurposes, + importLicenceVersionPurpose, importLicenceVersion, importLicenceVersionsAndPurposes } diff --git a/test/services/import/persist-licence-versions.service.test.js b/test/services/import/persist-licence-versions.service.test.js index 47ddb98a79..4e3997b3f1 100644 --- a/test/services/import/persist-licence-versions.service.test.js +++ b/test/services/import/persist-licence-versions.service.test.js @@ -8,9 +8,13 @@ const { describe, it, beforeEach } = exports.lab = Lab.script() const { expect } = Code // Test helpers -const LicenceVersionModel = require('../../../app/models/licence-version.model.js') +const FixtureLegacyLicenceVersionPurposes = require('./_fixtures/legacy-licence-version-purposes.fixture.js') const FixtureValidLicenceVersions = require('./_fixtures/import-licence-versions.fixture.js') const LicenceHelper = require('../../support/helpers/licence.helper.js') +const LicenceVersionModel = require('../../../app/models/licence-version.model.js') +const PrimaryPurposesSeeder = require('../../support/seeders/primary-purpose.seeder.js') +const PurposesSeeder = require('../../support/seeders/purposes.seeder.js') +const SecondaryPurposesSeeder = require('../../support/seeders/secondary-purpose.seeder.js') // Thing under test const PersistLicenceVersionsService = @@ -20,6 +24,10 @@ describe('Persist licence versions and licence versions purposes service', () => let licenceVersionsAndPurposes let licence + let primaryPurpose + let purpose + let secondaryPurpose + beforeEach(async () => { licence = await LicenceHelper.add() @@ -29,6 +37,18 @@ describe('Persist licence versions and licence versions purposes service', () => purposes: [] } ] + + primaryPurpose = PrimaryPurposesSeeder.data.find((primaryPurpose) => { + return primaryPurpose.legacyId === FixtureLegacyLicenceVersionPurposes.APUR_APPR_CODE + }) + + purpose = PurposesSeeder.data.find((purpose) => { + return purpose.legacyId === FixtureLegacyLicenceVersionPurposes.APUR_APUS_CODE + }) + + secondaryPurpose = SecondaryPurposesSeeder.data.find((secondaryPurpose) => { + return secondaryPurpose.legacyId === FixtureLegacyLicenceVersionPurposes.APUR_APSE_CODE + }) }) describe('when the licence version does not exist', () => { @@ -53,23 +73,69 @@ describe('Persist licence versions and licence versions purposes service', () => updatedAt: savedLicenceVersion.updatedAt.toISOString() }) }) + + describe('and has purposes', () => { + beforeEach(() => { + licenceVersionsAndPurposes = [ + { + ...FixtureValidLicenceVersions.importLicenceVersion, + purposes: [{ ...FixtureValidLicenceVersions.importLicenceVersionPurpose }] + } + ] + }) + + it('returns the updated licence version', async () => { + const [result] = await PersistLicenceVersionsService.go(licenceVersionsAndPurposes, licence.id) + + const savedLicenceVersionPurposes = await LicenceVersionModel.query() + .select('*') + .where('externalId', FixtureValidLicenceVersions.importLicenceVersion.externalId).first() + .withGraphFetched('licenceVersionPurposes') + + const [savedLicenceVersionPurpose] = savedLicenceVersionPurposes.licenceVersionPurposes + + expect(result.purposes[0]).to.equal({ + id: savedLicenceVersionPurpose.id, + licenceVersionId: savedLicenceVersionPurpose.licenceVersionId, + primaryPurposeId: primaryPurpose.id, + secondaryPurposeId: secondaryPurpose.id, + purposeId: purpose.id, + abstractionPeriodStartDay: 1, + abstractionPeriodStartMonth: 4, + abstractionPeriodEndDay: 31, + abstractionPeriodEndMonth: 3, + timeLimitedStartDate: '2001-01-03', + timeLimitedEndDate: '2001-01-02', + notes: ' a note on purposes', + instantQuantity: 120, + dailyQuantity: 1500.2, + hourlyQuantity: 140.93, + annualQuantity: 545520, + externalId: '3:10000004', + createdAt: savedLicenceVersionPurpose.createdAt.toISOString(), + updatedAt: savedLicenceVersionPurpose.updatedAt.toISOString() + }) + }) + }) }) describe('when the licence version already exists', () => { + let licenceVersionsAndPurposesUpdated + beforeEach(async () => { - licenceVersionsAndPurposes = [ + await PersistLicenceVersionsService.go(licenceVersionsAndPurposes, licence.id) + + licenceVersionsAndPurposesUpdated = [ { ...FixtureValidLicenceVersions.importLicenceVersion, purposes: [], increment: 1 } ] - - await PersistLicenceVersionsService.go(licenceVersionsAndPurposes, licence.id) }) it('returns the created licence version with updated values', async () => { - const [result] = await PersistLicenceVersionsService.go(licenceVersionsAndPurposes, licence.id) + const [result] = await PersistLicenceVersionsService.go(licenceVersionsAndPurposesUpdated, licence.id) const savedLicenceVersion = await LicenceVersionModel.query() .select('*') @@ -94,5 +160,4 @@ describe('Persist licence versions and licence versions purposes service', () => // todo: add these tests // licence exists - purpose newly created and purpose updated ? - // licence does not exists - purpose newly created }) diff --git a/test/validators/import/licence-versions.validator.test.js b/test/validators/import/licence-versions.validator.test.js index 7a8738adc0..86e176a182 100644 --- a/test/validators/import/licence-versions.validator.test.js +++ b/test/validators/import/licence-versions.validator.test.js @@ -21,8 +21,8 @@ describe('Import licence versions validator', () => { before(async () => { licenceVersion = FixtureValidLicenceVersions.importLicenceVersion - licenceVersionPurpose = FixtureValidLicenceVersions.importLicenceVersionPurposes[0] - licenceVersionPurposes = FixtureValidLicenceVersions.importLicenceVersionPurposes + licenceVersionPurpose = FixtureValidLicenceVersions.importLicenceVersionPurpose + licenceVersionPurposes = [{ ...FixtureValidLicenceVersions.importLicenceVersionPurpose }] licenceVersionsAndPurposes = [...FixtureValidLicenceVersions.importLicenceVersionsAndPurposes] }) From d71e2a47e9d6e96a517a63e31bade5e7c91e7e09 Mon Sep 17 00:00:00 2001 From: jonathangoulding Date: Mon, 29 Jul 2024 14:57:36 +0100 Subject: [PATCH 41/75] test: licence versions purposes --- .../import-licence-versions.fixture.js | 31 ++++---- .../persist-licence-versions.service.test.js | 75 ++++++++++--------- .../import/licence-versions.validator.test.js | 8 +- 3 files changed, 63 insertions(+), 51 deletions(-) diff --git a/test/services/import/_fixtures/import-licence-versions.fixture.js b/test/services/import/_fixtures/import-licence-versions.fixture.js index 4cb9eb16f3..42bc170e64 100644 --- a/test/services/import/_fixtures/import-licence-versions.fixture.js +++ b/test/services/import/_fixtures/import-licence-versions.fixture.js @@ -2,15 +2,15 @@ const { randomInteger } = require('../../../support/general.js') -const importLicenceVersionPurpose = - { +function importLicenceVersionPurpose () { + return { abstractionPeriodEndDay: 31, abstractionPeriodEndMonth: 3, abstractionPeriodStartDay: 1, abstractionPeriodStartMonth: 4, annualQuantity: 545520, dailyQuantity: 1500.2, - externalId: '3:10000004', + externalId: `${randomInteger(1, 9)}:${randomInteger(10000004, 99999999)}`, hourlyQuantity: 140.929, instantQuantity: 120, notes: ' a note on purposes', @@ -20,19 +20,24 @@ const importLicenceVersionPurpose = timeLimitedEndDate: '2001-01-02', timeLimitedStartDate: '2001-01-03' } +} -const importLicenceVersion = { - endDate: '2002-01-01', - externalId: `9:${randomInteger(10000, 99999)}:1:0`, - increment: 0, - issue: 100, - startDate: '2001-01-01', - status: 'superseded' +function importLicenceVersion () { + return { + endDate: '2002-01-01', + externalId: `9:${randomInteger(10000, 99999)}:1:0`, + increment: 0, + issue: 100, + startDate: '2001-01-01', + status: 'superseded' + } } -const importLicenceVersionsAndPurposes = [ - { ...importLicenceVersion, purposes: [{ ...importLicenceVersionPurpose }] } -] +function importLicenceVersionsAndPurposes () { + return [ + { ...importLicenceVersion(), purposes: [{ ...importLicenceVersionPurpose() }] } + ] +} module.exports = { importLicenceVersionPurpose, diff --git a/test/services/import/persist-licence-versions.service.test.js b/test/services/import/persist-licence-versions.service.test.js index 4e3997b3f1..bb6480f3df 100644 --- a/test/services/import/persist-licence-versions.service.test.js +++ b/test/services/import/persist-licence-versions.service.test.js @@ -9,7 +9,7 @@ const { expect } = Code // Test helpers const FixtureLegacyLicenceVersionPurposes = require('./_fixtures/legacy-licence-version-purposes.fixture.js') -const FixtureValidLicenceVersions = require('./_fixtures/import-licence-versions.fixture.js') +const FixtureImportLicenceVersions = require('./_fixtures/import-licence-versions.fixture.js') const LicenceHelper = require('../../support/helpers/licence.helper.js') const LicenceVersionModel = require('../../../app/models/licence-version.model.js') const PrimaryPurposesSeeder = require('../../support/seeders/primary-purpose.seeder.js') @@ -21,9 +21,10 @@ const PersistLicenceVersionsService = require('../../../app/services/import/persist-licence-versions.service.js') describe('Persist licence versions and licence versions purposes service', () => { - let licenceVersionsAndPurposes let licence - + let licenceVersion + let licenceVersionsPurpose + let licenceVersionsAndPurposes let primaryPurpose let purpose let secondaryPurpose @@ -31,9 +32,12 @@ describe('Persist licence versions and licence versions purposes service', () => beforeEach(async () => { licence = await LicenceHelper.add() + licenceVersion = { ...FixtureImportLicenceVersions.importLicenceVersion() } + licenceVersionsPurpose = { ...FixtureImportLicenceVersions.importLicenceVersionPurpose() } + licenceVersionsAndPurposes = [ { - ...FixtureValidLicenceVersions.importLicenceVersion, + ...licenceVersion, purposes: [] } ] @@ -57,12 +61,12 @@ describe('Persist licence versions and licence versions purposes service', () => const savedLicenceVersion = await LicenceVersionModel.query() .select('*') - .where('externalId', FixtureValidLicenceVersions.importLicenceVersion.externalId).first() + .where('externalId', licenceVersion.externalId).first() expect(result).to.equal({ createdAt: savedLicenceVersion.createdAt.toISOString(), endDate: '2002-01-01', - externalId: FixtureValidLicenceVersions.importLicenceVersion.externalId, + externalId: licenceVersion.externalId, id: result.id, increment: 0, issue: 100, @@ -78,43 +82,46 @@ describe('Persist licence versions and licence versions purposes service', () => beforeEach(() => { licenceVersionsAndPurposes = [ { - ...FixtureValidLicenceVersions.importLicenceVersion, - purposes: [{ ...FixtureValidLicenceVersions.importLicenceVersionPurpose }] + ...licenceVersion, + purposes: [{ ...licenceVersionsPurpose }] } ] }) - it('returns the updated licence version', async () => { + it('returns the created purposes', async () => { const [result] = await PersistLicenceVersionsService.go(licenceVersionsAndPurposes, licence.id) const savedLicenceVersionPurposes = await LicenceVersionModel.query() .select('*') - .where('externalId', FixtureValidLicenceVersions.importLicenceVersion.externalId).first() + .where('externalId', licenceVersion.externalId).first() .withGraphFetched('licenceVersionPurposes') const [savedLicenceVersionPurpose] = savedLicenceVersionPurposes.licenceVersionPurposes - expect(result.purposes[0]).to.equal({ - id: savedLicenceVersionPurpose.id, - licenceVersionId: savedLicenceVersionPurpose.licenceVersionId, - primaryPurposeId: primaryPurpose.id, - secondaryPurposeId: secondaryPurpose.id, - purposeId: purpose.id, - abstractionPeriodStartDay: 1, - abstractionPeriodStartMonth: 4, - abstractionPeriodEndDay: 31, - abstractionPeriodEndMonth: 3, - timeLimitedStartDate: '2001-01-03', - timeLimitedEndDate: '2001-01-02', - notes: ' a note on purposes', - instantQuantity: 120, - dailyQuantity: 1500.2, - hourlyQuantity: 140.93, - annualQuantity: 545520, - externalId: '3:10000004', - createdAt: savedLicenceVersionPurpose.createdAt.toISOString(), - updatedAt: savedLicenceVersionPurpose.updatedAt.toISOString() - }) + expect(result.purposes).to.equal([ + { + id: savedLicenceVersionPurpose.id, + licenceVersionId: savedLicenceVersionPurpose.licenceVersionId, + primaryPurposeId: primaryPurpose.id, + secondaryPurposeId: secondaryPurpose.id, + purposeId: purpose.id, + abstractionPeriodStartDay: 1, + abstractionPeriodStartMonth: 4, + abstractionPeriodEndDay: 31, + abstractionPeriodEndMonth: 3, + timeLimitedStartDate: '2001-01-03', + timeLimitedEndDate: '2001-01-02', + notes: ' a note on purposes', + instantQuantity: 120, + dailyQuantity: 1500.2, + hourlyQuantity: 140.93, + annualQuantity: 545520, + // should this be unique ? db says so ? + externalId: licenceVersionsPurpose.externalId, + createdAt: savedLicenceVersionPurpose.createdAt.toISOString(), + updatedAt: savedLicenceVersionPurpose.updatedAt.toISOString() + } + ]) }) }) }) @@ -127,7 +134,7 @@ describe('Persist licence versions and licence versions purposes service', () => licenceVersionsAndPurposesUpdated = [ { - ...FixtureValidLicenceVersions.importLicenceVersion, + ...licenceVersion, purposes: [], increment: 1 } @@ -139,11 +146,11 @@ describe('Persist licence versions and licence versions purposes service', () => const savedLicenceVersion = await LicenceVersionModel.query() .select('*') - .where('externalId', FixtureValidLicenceVersions.importLicenceVersion.externalId).first() + .where('externalId', licenceVersion.externalId).first() expect(result).to.equal({ endDate: '2002-01-01', - externalId: FixtureValidLicenceVersions.importLicenceVersion.externalId, + externalId: licenceVersion.externalId, id: result.id, increment: 1, issue: 100, diff --git a/test/validators/import/licence-versions.validator.test.js b/test/validators/import/licence-versions.validator.test.js index 86e176a182..ea92a704cd 100644 --- a/test/validators/import/licence-versions.validator.test.js +++ b/test/validators/import/licence-versions.validator.test.js @@ -20,10 +20,10 @@ describe('Import licence versions validator', () => { let licenceVersionsAndPurposes before(async () => { - licenceVersion = FixtureValidLicenceVersions.importLicenceVersion - licenceVersionPurpose = FixtureValidLicenceVersions.importLicenceVersionPurpose - licenceVersionPurposes = [{ ...FixtureValidLicenceVersions.importLicenceVersionPurpose }] - licenceVersionsAndPurposes = [...FixtureValidLicenceVersions.importLicenceVersionsAndPurposes] + licenceVersion = FixtureValidLicenceVersions.importLicenceVersion() + licenceVersionPurpose = FixtureValidLicenceVersions.importLicenceVersionPurpose() + licenceVersionPurposes = [{ ...FixtureValidLicenceVersions.importLicenceVersionPurpose() }] + licenceVersionsAndPurposes = [...FixtureValidLicenceVersions.importLicenceVersionsAndPurposes()] }) it('should not throw if all the required fields validations are met', () => { From fdfedc8f94127460f8c74ca8c4722117f2c98292 Mon Sep 17 00:00:00 2001 From: jonathangoulding Date: Mon, 29 Jul 2024 16:14:25 +0100 Subject: [PATCH 42/75] test: licence versions purposes --- .../import-licence-versions.fixture.js | 19 +- .../persist-licence-versions.service.test.js | 173 +++++++++++++++--- .../import/licence-versions.validator.test.js | 11 +- 3 files changed, 167 insertions(+), 36 deletions(-) diff --git a/test/services/import/_fixtures/import-licence-versions.fixture.js b/test/services/import/_fixtures/import-licence-versions.fixture.js index 42bc170e64..502ac8985a 100644 --- a/test/services/import/_fixtures/import-licence-versions.fixture.js +++ b/test/services/import/_fixtures/import-licence-versions.fixture.js @@ -2,7 +2,7 @@ const { randomInteger } = require('../../../support/general.js') -function importLicenceVersionPurpose () { +function _createLicenceVersionPurpose () { return { abstractionPeriodEndDay: 31, abstractionPeriodEndMonth: 3, @@ -22,7 +22,7 @@ function importLicenceVersionPurpose () { } } -function importLicenceVersion () { +function _createtLicenceVersion () { return { endDate: '2002-01-01', externalId: `9:${randomInteger(10000, 99999)}:1:0`, @@ -33,14 +33,17 @@ function importLicenceVersion () { } } -function importLicenceVersionsAndPurposes () { - return [ - { ...importLicenceVersion(), purposes: [{ ...importLicenceVersionPurpose() }] } +function create (data) { + const defaults = [ + { + ..._createtLicenceVersion(), + purposes: [{ ..._createLicenceVersionPurpose() }] + } ] + + return [...defaults] } module.exports = { - importLicenceVersionPurpose, - importLicenceVersion, - importLicenceVersionsAndPurposes + create } diff --git a/test/services/import/persist-licence-versions.service.test.js b/test/services/import/persist-licence-versions.service.test.js index bb6480f3df..799833e692 100644 --- a/test/services/import/persist-licence-versions.service.test.js +++ b/test/services/import/persist-licence-versions.service.test.js @@ -8,7 +8,6 @@ const { describe, it, beforeEach } = exports.lab = Lab.script() const { expect } = Code // Test helpers -const FixtureLegacyLicenceVersionPurposes = require('./_fixtures/legacy-licence-version-purposes.fixture.js') const FixtureImportLicenceVersions = require('./_fixtures/import-licence-versions.fixture.js') const LicenceHelper = require('../../support/helpers/licence.helper.js') const LicenceVersionModel = require('../../../app/models/licence-version.model.js') @@ -32,26 +31,21 @@ describe('Persist licence versions and licence versions purposes service', () => beforeEach(async () => { licence = await LicenceHelper.add() - licenceVersion = { ...FixtureImportLicenceVersions.importLicenceVersion() } - licenceVersionsPurpose = { ...FixtureImportLicenceVersions.importLicenceVersionPurpose() } + licenceVersionsAndPurposes = FixtureImportLicenceVersions.create() - licenceVersionsAndPurposes = [ - { - ...licenceVersion, - purposes: [] - } - ] + licenceVersion = { ...licenceVersionsAndPurposes[0] } + licenceVersionsPurpose = { ...licenceVersion.purposes[0] } primaryPurpose = PrimaryPurposesSeeder.data.find((primaryPurpose) => { - return primaryPurpose.legacyId === FixtureLegacyLicenceVersionPurposes.APUR_APPR_CODE + return primaryPurpose.legacyId === licenceVersionsPurpose.primaryPurposeId }) purpose = PurposesSeeder.data.find((purpose) => { - return purpose.legacyId === FixtureLegacyLicenceVersionPurposes.APUR_APUS_CODE + return purpose.legacyId === licenceVersionsPurpose.purposeId }) secondaryPurpose = SecondaryPurposesSeeder.data.find((secondaryPurpose) => { - return secondaryPurpose.legacyId === FixtureLegacyLicenceVersionPurposes.APUR_APSE_CODE + return secondaryPurpose.legacyId === licenceVersionsPurpose.secondaryPurposeId }) }) @@ -62,6 +56,9 @@ describe('Persist licence versions and licence versions purposes service', () => const savedLicenceVersion = await LicenceVersionModel.query() .select('*') .where('externalId', licenceVersion.externalId).first() + .withGraphFetched('licenceVersionPurposes') + + const [savedLicenceVersionPurpose] = savedLicenceVersion.licenceVersionPurposes expect(result).to.equal({ createdAt: savedLicenceVersion.createdAt.toISOString(), @@ -71,23 +68,59 @@ describe('Persist licence versions and licence versions purposes service', () => increment: 0, issue: 100, licenceId: licence.id, - purposes: [], + purposes: [ + { + id: savedLicenceVersionPurpose.id, + licenceVersionId: savedLicenceVersionPurpose.licenceVersionId, + primaryPurposeId: primaryPurpose.id, + secondaryPurposeId: secondaryPurpose.id, + purposeId: purpose.id, + abstractionPeriodStartDay: 1, + abstractionPeriodStartMonth: 4, + abstractionPeriodEndDay: 31, + abstractionPeriodEndMonth: 3, + timeLimitedStartDate: '2001-01-03', + timeLimitedEndDate: '2001-01-02', + notes: ' a note on purposes', + instantQuantity: 120, + dailyQuantity: 1500.2, + hourlyQuantity: 140.929, + annualQuantity: 545520, + externalId: licenceVersionsPurpose.externalId, + createdAt: savedLicenceVersionPurpose.createdAt.toISOString(), + updatedAt: savedLicenceVersionPurpose.updatedAt.toISOString() + } + ], startDate: '2001-01-01', status: 'superseded', updatedAt: savedLicenceVersion.updatedAt.toISOString() }) }) - describe('and has purposes', () => { + describe('and does not have "purposes"', () => { beforeEach(() => { licenceVersionsAndPurposes = [ { ...licenceVersion, - purposes: [{ ...licenceVersionsPurpose }] + purposes: [] } ] }) + it('does not return purposes', async () => { + const [result] = await PersistLicenceVersionsService.go(licenceVersionsAndPurposes, licence.id) + + const savedLicenceVersionPurposes = await LicenceVersionModel.query() + .select('*') + .where('externalId', licenceVersion.externalId).first() + .withGraphFetched('licenceVersionPurposes') + + expect(result.purposes).to.equal([]) + expect(savedLicenceVersionPurposes.licenceVersionPurposes).to.equal([]) + }) + }) + + describe('and has "purposes"', () => { it('returns the created purposes', async () => { const [result] = await PersistLicenceVersionsService.go(licenceVersionsAndPurposes, licence.id) @@ -114,9 +147,8 @@ describe('Persist licence versions and licence versions purposes service', () => notes: ' a note on purposes', instantQuantity: 120, dailyQuantity: 1500.2, - hourlyQuantity: 140.93, + hourlyQuantity: 140.929, annualQuantity: 545520, - // should this be unique ? db says so ? externalId: licenceVersionsPurpose.externalId, createdAt: savedLicenceVersionPurpose.createdAt.toISOString(), updatedAt: savedLicenceVersionPurpose.updatedAt.toISOString() @@ -135,18 +167,21 @@ describe('Persist licence versions and licence versions purposes service', () => licenceVersionsAndPurposesUpdated = [ { ...licenceVersion, - purposes: [], + purposes: [{ ...licenceVersionsPurpose }], increment: 1 } ] }) - it('returns the created licence version with updated values', async () => { + it('returns the updated licence version and purposes', async () => { const [result] = await PersistLicenceVersionsService.go(licenceVersionsAndPurposesUpdated, licence.id) const savedLicenceVersion = await LicenceVersionModel.query() .select('*') .where('externalId', licenceVersion.externalId).first() + .withGraphFetched('licenceVersionPurposes') + + const [savedLicenceVersionPurpose] = savedLicenceVersion.licenceVersionPurposes expect(result).to.equal({ endDate: '2002-01-01', @@ -155,16 +190,108 @@ describe('Persist licence versions and licence versions purposes service', () => increment: 1, issue: 100, licenceId: licence.id, - purposes: [], + purposes: [ + { + id: savedLicenceVersionPurpose.id, + licenceVersionId: savedLicenceVersionPurpose.licenceVersionId, + primaryPurposeId: primaryPurpose.id, + secondaryPurposeId: secondaryPurpose.id, + purposeId: purpose.id, + abstractionPeriodStartDay: 1, + abstractionPeriodStartMonth: 4, + abstractionPeriodEndDay: 31, + abstractionPeriodEndMonth: 3, + timeLimitedStartDate: '2001-01-03', + timeLimitedEndDate: '2001-01-02', + notes: ' a note on purposes', + instantQuantity: 120, + dailyQuantity: 1500.2, + hourlyQuantity: 140.929, + annualQuantity: 545520, + externalId: licenceVersionsPurpose.externalId, + createdAt: savedLicenceVersionPurpose.createdAt.toISOString(), + updatedAt: savedLicenceVersionPurpose.updatedAt.toISOString() + } + ], startDate: '2001-01-01', status: 'superseded', updatedAt: savedLicenceVersion.updatedAt.toISOString() }, { skip: ['createdAt'] }) + }) + + it('returns the updated licence version increment', async () => { + const [result] = await PersistLicenceVersionsService.go(licenceVersionsAndPurposesUpdated, licence.id) expect(result.increment).to.equal(1) }) - }) - // todo: add these tests - // licence exists - purpose newly created and purpose updated ? + describe('and does not have purposes', () => { + beforeEach(async () => { + await PersistLicenceVersionsService.go(licenceVersionsAndPurposesUpdated, licence.id) + + licenceVersionsAndPurposesUpdated[0].purposes = [] + }) + + it('returns the updated licence version and no purposes', async () => { + const [result] = await PersistLicenceVersionsService.go(licenceVersionsAndPurposesUpdated, licence.id) + + const savedLicenceVersion = await LicenceVersionModel.query() + .select('*') + .where('externalId', licenceVersion.externalId).first() + + expect(result).to.equal({ + endDate: '2002-01-01', + externalId: licenceVersion.externalId, + id: result.id, + increment: 1, + issue: 100, + licenceId: licence.id, + purposes: [], + startDate: '2001-01-01', + status: 'superseded', + updatedAt: savedLicenceVersion.updatedAt.toISOString() + }, { skip: ['createdAt'] }) + + expect(result.increment).to.equal(1) + }) + }) + + describe('and has purposes', () => { + it('returns the updated licence version purposes', async () => { + const [result] = await PersistLicenceVersionsService.go(licenceVersionsAndPurposesUpdated, licence.id) + + const savedLicenceVersion = await LicenceVersionModel.query() + .select('*') + .where('externalId', licenceVersion.externalId).first() + .withGraphFetched('licenceVersionPurposes') + + const [savedLicenceVersionPurpose] = savedLicenceVersion.licenceVersionPurposes + + expect(result.purposes).to.equal([ + { + id: savedLicenceVersionPurpose.id, + licenceVersionId: savedLicenceVersionPurpose.licenceVersionId, + primaryPurposeId: primaryPurpose.id, + secondaryPurposeId: secondaryPurpose.id, + purposeId: purpose.id, + abstractionPeriodStartDay: 1, + abstractionPeriodStartMonth: 4, + abstractionPeriodEndDay: 31, + abstractionPeriodEndMonth: 3, + timeLimitedStartDate: '2001-01-03', + timeLimitedEndDate: '2001-01-02', + notes: ' a note on purposes', + instantQuantity: 120, + dailyQuantity: 1500.2, + hourlyQuantity: 140.929, + annualQuantity: 545520, + externalId: licenceVersionsPurpose.externalId, + updatedAt: savedLicenceVersionPurpose.updatedAt.toISOString() + } + ], { skip: ['createdAt'] }) + + expect(result.increment).to.equal(1) + }) + }) + }) }) diff --git a/test/validators/import/licence-versions.validator.test.js b/test/validators/import/licence-versions.validator.test.js index ea92a704cd..19b70d5ea5 100644 --- a/test/validators/import/licence-versions.validator.test.js +++ b/test/validators/import/licence-versions.validator.test.js @@ -8,7 +8,7 @@ const { describe, it, before } = exports.lab = Lab.script() const { expect } = Code // Test helpers -const FixtureValidLicenceVersions = require('../../services/import/_fixtures/import-licence-versions.fixture.js') +const FixtureImportLicenceVersions = require('../../services/import/_fixtures/import-licence-versions.fixture.js') // Thing under test const ImportLicenceVersionsValidator = require('../../../app/validators/import/licence-versions.validator.js') @@ -20,10 +20,11 @@ describe('Import licence versions validator', () => { let licenceVersionsAndPurposes before(async () => { - licenceVersion = FixtureValidLicenceVersions.importLicenceVersion() - licenceVersionPurpose = FixtureValidLicenceVersions.importLicenceVersionPurpose() - licenceVersionPurposes = [{ ...FixtureValidLicenceVersions.importLicenceVersionPurpose() }] - licenceVersionsAndPurposes = [...FixtureValidLicenceVersions.importLicenceVersionsAndPurposes()] + licenceVersionsAndPurposes = FixtureImportLicenceVersions.create() + + licenceVersion = licenceVersionsAndPurposes[0] + licenceVersionPurpose = licenceVersion.purposes[0] + licenceVersionPurposes = licenceVersion.purposes }) it('should not throw if all the required fields validations are met', () => { From 86f8a63fb807dcfc5ff8df792ce62e2f71584a32 Mon Sep 17 00:00:00 2001 From: jonathangoulding Date: Tue, 30 Jul 2024 09:18:21 +0100 Subject: [PATCH 43/75] chore: pre pr checks --- .../legacy-import/fetch-licence.service.js | 8 ++++---- .../import/legacy-licence.service.test.js | 17 +---------------- .../persist-licence-versions.service.test.js | 15 +++++++++++++++ 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/app/services/import/legacy-import/fetch-licence.service.js b/app/services/import/legacy-import/fetch-licence.service.js index 9ace276dec..f25dde623d 100644 --- a/app/services/import/legacy-import/fetch-licence.service.js +++ b/app/services/import/legacy-import/fetch-licence.service.js @@ -48,10 +48,10 @@ module.exports = { * * @typedef {Object} LegacyLicenceType * - * @property {string} AREP_AREA_CODE - * @property {string} AREP_EIUC_CODE - * @property {string} AREP_LEAP_CODE - * @property {string} AREP_SUC_CODE + * @property {string} AREP_AREA_CODE - historicalAreaCode + * @property {string} AREP_EIUC_CODE - regionPrefix / regionalChargeArea + * @property {string} AREP_LEAP_CODE - localEnvironmentAgencyPlanCode + * @property {string} AREP_SUC_CODE - standardUnitChargeCode * @property {string} EXPIRY_DATE * @property {string} ID * @property {string} LAPSED_DATE diff --git a/test/services/import/legacy-licence.service.test.js b/test/services/import/legacy-licence.service.test.js index 89ba1ae2b8..44fd245b01 100644 --- a/test/services/import/legacy-licence.service.test.js +++ b/test/services/import/legacy-licence.service.test.js @@ -24,7 +24,7 @@ const SecondaryPurposesSeeder = require('../../support/seeders/secondary-purpose const LegacyImportLicenceService = require('../../../app/services/import/legacy-licence.service.js') -describe('Legacy import licence service', () => { +describe.only('Legacy import licence service', () => { const licenceRef = FixtureLegacyLicence.LIC_NO const region = RegionsSeeder.data.find((region) => { @@ -171,21 +171,6 @@ describe('Legacy import licence service', () => { updatedAt: new Date(licenceVersionPurpose.updatedAt) }) }) - - it('checks the purposes id, primary purpose id and secondary purpose id match the legacy id provided', async () => { - await LegacyImportLicenceService.go(licenceRef) - - const licence = await LicenceModel.query().select(['id']).where('licenceRef', licenceRef).first() - .withGraphFetched('licenceVersions').withGraphFetched('licenceVersions.licenceVersionPurposes') - - const [licenceVersion] = licence.licenceVersions - const { licenceVersionPurposes } = licenceVersion - const [licenceVersionPurpose] = licenceVersionPurposes - - expect(licenceVersionPurpose.primaryPurposeId).to.equal(primaryPurpose.id) - expect(licenceVersionPurpose.secondaryPurposeId).to.equal(secondaryPurpose.id) - expect(licenceVersionPurpose.purposeId).to.equal(purpose.id) - }) }) }) }) diff --git a/test/services/import/persist-licence-versions.service.test.js b/test/services/import/persist-licence-versions.service.test.js index 799833e692..84eeb79723 100644 --- a/test/services/import/persist-licence-versions.service.test.js +++ b/test/services/import/persist-licence-versions.service.test.js @@ -292,6 +292,21 @@ describe('Persist licence versions and licence versions purposes service', () => expect(result.increment).to.equal(1) }) + + it('checks the purposes id, primary purpose id and secondary purpose id match the legacy id provided', async () => { + await PersistLicenceVersionsService.go(licenceVersionsAndPurposesUpdated, licence.id) + + const savedLicenceVersion = await LicenceVersionModel.query() + .select('*') + .where('externalId', licenceVersion.externalId).first() + .withGraphFetched('licenceVersionPurposes') + + const [savedLicenceVersionPurpose] = savedLicenceVersion.licenceVersionPurposes + + expect(savedLicenceVersionPurpose.primaryPurposeId).to.equal(primaryPurpose.id) + expect(savedLicenceVersionPurpose.secondaryPurposeId).to.equal(secondaryPurpose.id) + expect(savedLicenceVersionPurpose.purposeId).to.equal(purpose.id) + }) }) }) }) From d75f1dd6344353a039a45198657df32d8686ce8d Mon Sep 17 00:00:00 2001 From: jonathangoulding Date: Tue, 30 Jul 2024 11:09:42 +0100 Subject: [PATCH 44/75] feat: regions are required --- app/validators/import/licence.validator.js | 8 ++++---- .../import/_fixtures/import-licence.fixture.js | 8 +++++++- .../import/legacy-licence.service.test.js | 2 +- test/validators/import/licence.validator.test.js | 16 ++++++++-------- 4 files changed, 20 insertions(+), 14 deletions(-) diff --git a/app/validators/import/licence.validator.js b/app/validators/import/licence.validator.js index 6178958b48..8548b0c156 100644 --- a/app/validators/import/licence.validator.js +++ b/app/validators/import/licence.validator.js @@ -28,10 +28,10 @@ const _schema = Joi.object({ licenceRef: Joi.string().required(), naldRegionId: Joi.number().required(), regions: Joi.object({ - regionalChargeArea: Joi.string(), - localEnvironmentAgencyPlanCode: Joi.string(), - historicalAreaCode: Joi.string(), - standardUnitChargeCode: Joi.string() + regionalChargeArea: Joi.string().required(), + localEnvironmentAgencyPlanCode: Joi.string().required(), + historicalAreaCode: Joi.string().required(), + standardUnitChargeCode: Joi.string().required() }), revokedDate: Joi.date().iso().allow(null), startDate: Joi.date().iso().required(), diff --git a/test/services/import/_fixtures/import-licence.fixture.js b/test/services/import/_fixtures/import-licence.fixture.js index 1b57223eec..4a453e35ae 100644 --- a/test/services/import/_fixtures/import-licence.fixture.js +++ b/test/services/import/_fixtures/import-licence.fixture.js @@ -27,7 +27,13 @@ const importLicenceRequiredOnly = { licenceRef: generateLicenceRef(), naldRegionId: region.naldRegionId, startDate: '2001-01-01', - waterUndertaker: true + waterUndertaker: true, + regions: { + historicalAreaCode: 'RIDIN', + regionalChargeArea: 'Yorkshire', + standardUnitChargeCode: 'YORKI', + localEnvironmentAgencyPlanCode: 'AIREL' + } } module.exports = { diff --git a/test/services/import/legacy-licence.service.test.js b/test/services/import/legacy-licence.service.test.js index 44fd245b01..0f010b0ac3 100644 --- a/test/services/import/legacy-licence.service.test.js +++ b/test/services/import/legacy-licence.service.test.js @@ -24,7 +24,7 @@ const SecondaryPurposesSeeder = require('../../support/seeders/secondary-purpose const LegacyImportLicenceService = require('../../../app/services/import/legacy-licence.service.js') -describe.only('Legacy import licence service', () => { +describe('Legacy import licence service', () => { const licenceRef = FixtureLegacyLicence.LIC_NO const region = RegionsSeeder.data.find((region) => { diff --git a/test/validators/import/licence.validator.test.js b/test/validators/import/licence.validator.test.js index 8f374f6853..c3b828da21 100644 --- a/test/validators/import/licence.validator.test.js +++ b/test/validators/import/licence.validator.test.js @@ -145,7 +145,7 @@ describe('Import licence validator', () => { expect(() => { return ImportLicenceValidator.go({ ...licence, - regions: { regionalChargeArea: 1 } + regions: { ...licence.regions, regionalChargeArea: 1 } }) }).to.throw('"regions.regionalChargeArea" must be a string') }) @@ -154,7 +154,7 @@ describe('Import licence validator', () => { expect(() => { return ImportLicenceValidator.go({ ...licence, - regions: { regionalChargeArea: 'a string' } + regions: { ...licence.regions, regionalChargeArea: 'a string' } }) }).to.not.throw() }) @@ -165,7 +165,7 @@ describe('Import licence validator', () => { expect(() => { return ImportLicenceValidator.go({ ...licence, - regions: { localEnvironmentAgencyPlanCode: 1 } + regions: { ...licence.regions, localEnvironmentAgencyPlanCode: 1 } }) }).to.throw('"regions.localEnvironmentAgencyPlanCode" must be a string') }) @@ -174,7 +174,7 @@ describe('Import licence validator', () => { expect(() => { return ImportLicenceValidator.go({ ...licence, - regions: { localEnvironmentAgencyPlanCode: 'a string' } + regions: { ...licence.regions, localEnvironmentAgencyPlanCode: 'a string' } }) }).to.not.throw() }) @@ -185,7 +185,7 @@ describe('Import licence validator', () => { expect(() => { return ImportLicenceValidator.go({ ...licence, - regions: { historicalAreaCode: 1 } + regions: { ...licence.regions, historicalAreaCode: 1 } }) }).to.throw('"regions.historicalAreaCode" must be a string') }) @@ -194,7 +194,7 @@ describe('Import licence validator', () => { expect(() => { return ImportLicenceValidator.go({ ...licence, - regions: { historicalAreaCode: 'a string' } + regions: { ...licence.regions, historicalAreaCode: 'a string' } }) }).to.not.throw() }) @@ -205,7 +205,7 @@ describe('Import licence validator', () => { expect(() => { return ImportLicenceValidator.go({ ...licence, - regions: { standardUnitChargeCode: 1 } + regions: { ...licence.regions, standardUnitChargeCode: 1 } }) }).to.throw('"regions.standardUnitChargeCode" must be a string') }) @@ -214,7 +214,7 @@ describe('Import licence validator', () => { expect(() => { return ImportLicenceValidator.go({ ...licence, - regions: { standardUnitChargeCode: 'a string' } + regions: { ...licence.regions, standardUnitChargeCode: 'a string' } }) }).to.not.throw() }) From dca16ca3cc35248a9515b24eb7e51ee0ec742d32 Mon Sep 17 00:00:00 2001 From: jonathangoulding Date: Tue, 30 Jul 2024 11:39:58 +0100 Subject: [PATCH 45/75] feat: licence version and purposes are required fields --- .../import/licence-versions.validator.js | 23 ++++++++++-------- .../import/licence-versions.validator.test.js | 24 ++++++++++++++++++- 2 files changed, 36 insertions(+), 11 deletions(-) diff --git a/app/validators/import/licence-versions.validator.js b/app/validators/import/licence-versions.validator.js index bedbc1d579..0ac6990a22 100644 --- a/app/validators/import/licence-versions.validator.js +++ b/app/validators/import/licence-versions.validator.js @@ -53,17 +53,20 @@ const _purposeSchema = Joi.object({ instantQuantity: Joi.number().allow(null), hourlyQuantity: Joi.number().allow(null), dailyQuantity: Joi.number().allow(null) -}) +}).required().label('Licence versions purpose') -const _schema = Joi.array().items({ - endDate: Joi.date().iso().required().allow(null), - externalId: Joi.string().required(), - increment: Joi.number().required(), - issue: Joi.number().required(), - startDate: Joi.date().iso().required(), - status: Joi.string().required().custom(_isValidStatus), - purposes: Joi.array().items(_purposeSchema).required() -}) +const _schema = Joi.array().items( + Joi.object({ + endDate: Joi.date().iso().required().allow(null), + externalId: Joi.string().required(), + increment: Joi.number().required(), + issue: Joi.number().required(), + startDate: Joi.date().iso().required(), + status: Joi.string().required().custom(_isValidStatus), + purposes: Joi.array().items(_purposeSchema).label('Licence versions purposes') + }).required() + .label('Licence version') +).label('Licence versions') module.exports = { go diff --git a/test/validators/import/licence-versions.validator.test.js b/test/validators/import/licence-versions.validator.test.js index 19b70d5ea5..d72500824e 100644 --- a/test/validators/import/licence-versions.validator.test.js +++ b/test/validators/import/licence-versions.validator.test.js @@ -4,7 +4,7 @@ const Lab = require('@hapi/lab') const Code = require('@hapi/code') -const { describe, it, before } = exports.lab = Lab.script() +const { describe, it, before, beforeEach } = exports.lab = Lab.script() const { expect } = Code // Test helpers @@ -33,6 +33,12 @@ describe('Import licence versions validator', () => { }).to.not.throw() }) + it('should throw if there are no licence versions', () => { + expect(() => { + return ImportLicenceVersionsValidator.go([]) + }).to.throw('"Licence versions" does not contain [Licence version]') + }) + describe('the "version"', () => { describe('"endDate" property', () => { it('should throw an error if "endDate" is not a valid date or null', async () => { @@ -294,6 +300,22 @@ describe('Import licence versions validator', () => { }) describe('"purposes" property', () => { + describe('when no purposes a', () => { + let licenceVersionNoPurposes + + beforeEach(() => { + licenceVersionNoPurposes = FixtureImportLicenceVersions.create() + + licenceVersionNoPurposes[0].purposes = [] + }) + + it('should throw if there are no licence versions', () => { + expect(() => { + return ImportLicenceVersionsValidator.go(licenceVersionNoPurposes) + }).to.throw('"Licence versions purposes" does not contain [Licence versions purpose]') + }) + }) + describe('"abstractionPeriodEndDay" property', () => { it('should throw an error if "abstractionPeriodEndDay" is not a number', async () => { expect(() => { From e7157a8bb4a4971d136cd29dd75056cb624263f9 Mon Sep 17 00:00:00 2001 From: jonathangoulding Date: Tue, 30 Jul 2024 12:10:08 +0100 Subject: [PATCH 46/75] feat: licence version and purposes are required fields add custom min error messages --- .../import/licence-versions.validator.js | 51 +++++++++++-------- .../import/licence-versions.validator.test.js | 4 +- 2 files changed, 32 insertions(+), 23 deletions(-) diff --git a/app/validators/import/licence-versions.validator.js b/app/validators/import/licence-versions.validator.js index 0ac6990a22..a4ffb2bfb9 100644 --- a/app/validators/import/licence-versions.validator.js +++ b/app/validators/import/licence-versions.validator.js @@ -37,25 +37,30 @@ const _isValidStatus = (value) => { throw new Error(`Status must be one of ${validStatues.toString()}`) } -const _purposeSchema = Joi.object({ - primaryPurposeId: Joi.string().required(), - secondaryPurposeId: Joi.string().required(), - purposeId: Joi.string().required(), - abstractionPeriodStartDay: Joi.number().integer().min(1).max(calender.totalDaysInMonth).required(), - abstractionPeriodStartMonth: Joi.number().integer().min(1).max(calender.totalMonthsInYear).required(), - abstractionPeriodEndDay: Joi.number().integer().min(1).max(calender.totalDaysInMonth).required(), - abstractionPeriodEndMonth: Joi.number().integer().min(1).max(calender.totalMonthsInYear).required(), - timeLimitedStartDate: Joi.date().iso().allow(null), - timeLimitedEndDate: Joi.date().iso().allow(null), - notes: Joi.string().allow(null), - annualQuantity: Joi.number().allow(null), - externalId: Joi.string().required(), - instantQuantity: Joi.number().allow(null), - hourlyQuantity: Joi.number().allow(null), - dailyQuantity: Joi.number().allow(null) -}).required().label('Licence versions purpose') +const _purposeSchema = + Joi.array().min(1).items( + Joi.object({ + primaryPurposeId: Joi.string().required(), + secondaryPurposeId: Joi.string().required(), + purposeId: Joi.string().required(), + abstractionPeriodStartDay: Joi.number().integer().min(1).max(calender.totalDaysInMonth).required(), + abstractionPeriodStartMonth: Joi.number().integer().min(1).max(calender.totalMonthsInYear).required(), + abstractionPeriodEndDay: Joi.number().integer().min(1).max(calender.totalDaysInMonth).required(), + abstractionPeriodEndMonth: Joi.number().integer().min(1).max(calender.totalMonthsInYear).required(), + timeLimitedStartDate: Joi.date().iso().allow(null), + timeLimitedEndDate: Joi.date().iso().allow(null), + notes: Joi.string().allow(null), + annualQuantity: Joi.number().allow(null), + externalId: Joi.string().required(), + instantQuantity: Joi.number().allow(null), + hourlyQuantity: Joi.number().allow(null), + dailyQuantity: Joi.number().allow(null) + }).label('Licence versions purpose') + ).label('Licence versions purposes').messages({ + 'array.min': 'A licence version must have at least one Licence version purpose' + }) -const _schema = Joi.array().items( +const _schema = Joi.array().min(1).items( Joi.object({ endDate: Joi.date().iso().required().allow(null), externalId: Joi.string().required(), @@ -63,10 +68,14 @@ const _schema = Joi.array().items( issue: Joi.number().required(), startDate: Joi.date().iso().required(), status: Joi.string().required().custom(_isValidStatus), - purposes: Joi.array().items(_purposeSchema).label('Licence versions purposes') - }).required() + purposes: _purposeSchema + }) .label('Licence version') -).label('Licence versions') +) + .label('Licence versions') + .messages({ + 'array.min': 'A licence must have at least one Licence version' + }) module.exports = { go diff --git a/test/validators/import/licence-versions.validator.test.js b/test/validators/import/licence-versions.validator.test.js index d72500824e..be9ca2b538 100644 --- a/test/validators/import/licence-versions.validator.test.js +++ b/test/validators/import/licence-versions.validator.test.js @@ -36,7 +36,7 @@ describe('Import licence versions validator', () => { it('should throw if there are no licence versions', () => { expect(() => { return ImportLicenceVersionsValidator.go([]) - }).to.throw('"Licence versions" does not contain [Licence version]') + }).to.throw('A licence must have at least one Licence version') }) describe('the "version"', () => { @@ -312,7 +312,7 @@ describe('Import licence versions validator', () => { it('should throw if there are no licence versions', () => { expect(() => { return ImportLicenceVersionsValidator.go(licenceVersionNoPurposes) - }).to.throw('"Licence versions purposes" does not contain [Licence versions purpose]') + }).to.throw('A licence version must have at least one Licence version purpose') }) }) From 0849920aef74541e2b8d7c58472241de6eda0c27 Mon Sep 17 00:00:00 2001 From: jonathangoulding Date: Tue, 30 Jul 2024 13:30:11 +0100 Subject: [PATCH 47/75] chore: add regions key to legacy fetch licence --- .../import/legacy-import/fetch-licence.service.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/services/import/legacy-import/fetch-licence.service.js b/app/services/import/legacy-import/fetch-licence.service.js index f25dde623d..9aa17ef955 100644 --- a/app/services/import/legacy-import/fetch-licence.service.js +++ b/app/services/import/legacy-import/fetch-licence.service.js @@ -48,10 +48,10 @@ module.exports = { * * @typedef {Object} LegacyLicenceType * - * @property {string} AREP_AREA_CODE - historicalAreaCode - * @property {string} AREP_EIUC_CODE - regionPrefix / regionalChargeArea - * @property {string} AREP_LEAP_CODE - localEnvironmentAgencyPlanCode - * @property {string} AREP_SUC_CODE - standardUnitChargeCode + * @property {string} AREP_AREA_CODE - regions - historicalAreaCode + * @property {string} AREP_EIUC_CODE - regions -regionPrefix / regionalChargeArea + * @property {string} AREP_LEAP_CODE - regions -localEnvironmentAgencyPlanCode + * @property {string} AREP_SUC_CODE - regions -standardUnitChargeCode * @property {string} EXPIRY_DATE * @property {string} ID * @property {string} LAPSED_DATE From 582cd3ce86242291fbbd96919b2f86b1d2da0659 Mon Sep 17 00:00:00 2001 From: jonathangoulding Date: Tue, 30 Jul 2024 15:40:16 +0100 Subject: [PATCH 48/75] refactor: fixtures to use func to generate random data --- app/controllers/import.controller.js | 8 +--- app/services/import/legacy-licence.service.js | 25 ++++++---- .../_fixtures/import-licence.fixture.js | 46 ++++++++----------- .../legacy-licence-version-purpose.fixture.js | 32 +++++++++++++ ...legacy-licence-version-purposes.fixture.js | 22 --------- .../legacy-licence-version.fixture.js | 30 ++++++++---- .../_fixtures/legacy-licence.fixture.js | 36 +++++++++------ .../licence-versions.mapper.test.js | 6 +-- .../legacy-import/licence.mapper.test.js | 4 +- .../import/legacy-licence.service.test.js | 23 ++++++---- .../import/licence-validator.service.test.js | 12 +++-- .../import/persist-licence.service.test.js | 2 +- .../import/licence.validator.test.js | 4 +- 13 files changed, 143 insertions(+), 107 deletions(-) create mode 100644 test/services/import/_fixtures/legacy-licence-version-purpose.fixture.js delete mode 100644 test/services/import/_fixtures/legacy-licence-version-purposes.fixture.js diff --git a/app/controllers/import.controller.js b/app/controllers/import.controller.js index ec79fba24f..c613cf9068 100644 --- a/app/controllers/import.controller.js +++ b/app/controllers/import.controller.js @@ -10,13 +10,9 @@ const Boom = require('@hapi/boom') async function licence (request, h) { const { licenceRef } = request.payload - try { - await LegacyImportLicenceService.go(licenceRef) + LegacyImportLicenceService.go(licenceRef) - return h.response().code(204) - } catch (error) { - return Boom.badImplementation(`Licence ref: ${licenceRef} failed with error - ${error.message}`) - } + return h.response().code(204) } module.exports = { diff --git a/app/services/import/legacy-licence.service.js b/app/services/import/legacy-licence.service.js index 9cbbc44ea6..45b686514b 100644 --- a/app/services/import/legacy-licence.service.js +++ b/app/services/import/legacy-licence.service.js @@ -5,6 +5,7 @@ * @module LegacyImportLicenceService */ +const Boom = require('@hapi/boom') const FetchLegacyImportLicenceService = require('./legacy-import/fetch-licence.service.js') const FetchLegacyImportLicenceVersionsService = require('./legacy-import/fetch-licence-versions.service.js') const ImportLicenceValidatorService = require('./licence-validator.service.js') @@ -12,6 +13,7 @@ const LegacyImportLicenceMapper = require('./legacy-import/licence.mapper.js') const LegacyImportLicenceVersionMapper = require('./legacy-import/licence-versions.mapper.js') const PersistLicenceService = require('./persist-licence.service.js') const PersistLicenceVersionsService = require('./persist-licence-versions.service.js') +const { currentTimeInNanoseconds, calculateAndLogTimeTaken } = require('../../lib/general.lib.js') /** * Imports a licence from the legacy import tables. Maps and validates the data and then saves to the database. @@ -20,20 +22,27 @@ const PersistLicenceVersionsService = require('./persist-licence-versions.servic * @returns {Promise} an object representing the saved licence in the database */ async function go (licenceRef) { - console.debug('Importing licence ref: ', licenceRef) - const licenceData = await FetchLegacyImportLicenceService.go(licenceRef) + try { + const startTime = currentTimeInNanoseconds() - const licenceVersionsData = await FetchLegacyImportLicenceVersionsService.go(licenceData) + console.debug('Importing licence ref: ', licenceRef) + const licenceData = await FetchLegacyImportLicenceService.go(licenceRef) - const mappedLicenceData = LegacyImportLicenceMapper.go(licenceData, licenceVersionsData) + const licenceVersionsData = await FetchLegacyImportLicenceVersionsService.go(licenceData) - const mappedLicenceVersionsData = LegacyImportLicenceVersionMapper.go(licenceVersionsData) + const mappedLicenceData = LegacyImportLicenceMapper.go(licenceData, licenceVersionsData) - ImportLicenceValidatorService.go(mappedLicenceData, mappedLicenceVersionsData) + const mappedLicenceVersionsData = LegacyImportLicenceVersionMapper.go(licenceVersionsData) - const savedLicence = await PersistLicenceService.go(mappedLicenceData) + ImportLicenceValidatorService.go(mappedLicenceData, mappedLicenceVersionsData) - await PersistLicenceVersionsService.go(mappedLicenceVersionsData, savedLicence.id) + const savedLicence = await PersistLicenceService.go(mappedLicenceData) + + await PersistLicenceVersionsService.go(mappedLicenceVersionsData, savedLicence.id) + calculateAndLogTimeTaken(startTime, 'Process licence', { licenceRef }) + } catch (error) { + return Boom.badImplementation(`Licence ref: ${licenceRef} failed with error - ${error.message}`) + } } module.exports = { diff --git a/test/services/import/_fixtures/import-licence.fixture.js b/test/services/import/_fixtures/import-licence.fixture.js index 4a453e35ae..2ed3462142 100644 --- a/test/services/import/_fixtures/import-licence.fixture.js +++ b/test/services/import/_fixtures/import-licence.fixture.js @@ -7,36 +7,30 @@ const region = RegionsSeeder.data.find((region) => { return region.displayName === 'Test Region' }) -const importLicence = { - expiredDate: '2015-03-31', - lapsedDate: null, - licenceRef: generateLicenceRef(), - naldRegionId: region.naldRegionId, - regions: { - historicalAreaCode: 'RIDIN', - regionalChargeArea: 'Yorkshire', - standardUnitChargeCode: 'YORKI', - localEnvironmentAgencyPlanCode: 'AIREL' - }, - revokedDate: null, - startDate: '2005-06-03', - waterUndertaker: false +function importLicence () { + return { + expiredDate: '2015-03-31', + lapsedDate: null, + licenceRef: generateLicenceRef(), + naldRegionId: region.naldRegionId, + regions: { + historicalAreaCode: 'RIDIN', + regionalChargeArea: 'Yorkshire', + standardUnitChargeCode: 'YORKI', + localEnvironmentAgencyPlanCode: 'AIREL' + }, + revokedDate: null, + startDate: '2005-06-03', + waterUndertaker: false + } } -const importLicenceRequiredOnly = { - licenceRef: generateLicenceRef(), - naldRegionId: region.naldRegionId, - startDate: '2001-01-01', - waterUndertaker: true, - regions: { - historicalAreaCode: 'RIDIN', - regionalChargeArea: 'Yorkshire', - standardUnitChargeCode: 'YORKI', - localEnvironmentAgencyPlanCode: 'AIREL' +function create (data) { + return { + ...importLicence() } } module.exports = { - importLicence, - importLicenceRequiredOnly + create } diff --git a/test/services/import/_fixtures/legacy-licence-version-purpose.fixture.js b/test/services/import/_fixtures/legacy-licence-version-purpose.fixture.js new file mode 100644 index 0000000000..56706bd995 --- /dev/null +++ b/test/services/import/_fixtures/legacy-licence-version-purpose.fixture.js @@ -0,0 +1,32 @@ +'use strict' + +function purpose () { + return { + PERIOD_END_DAY: '31', + PERIOD_END_MONTH: '3', + PERIOD_ST_DAY: '1', + PERIOD_ST_MONTH: '4', + ANNUAL_QTY: '545520', + DAILY_QTY: '1500.2', + FGAC_REGION_CODE: '3', + ID: '10000004', + HOURLY_QTY: '140.929', + INST_QTY: 'null', + NOTES: 'null', + APUR_APPR_CODE: 'I', + APUR_APSE_CODE: 'OTI', + APUR_APUS_CODE: '160', + TIMELTD_END_DATE: 'null', + TIMELTD_ST_DATE: 'null' + } +} + +function create (data) { + return { + ...purpose() + } +} + +module.exports = { + create +} diff --git a/test/services/import/_fixtures/legacy-licence-version-purposes.fixture.js b/test/services/import/_fixtures/legacy-licence-version-purposes.fixture.js deleted file mode 100644 index d1d6bbd048..0000000000 --- a/test/services/import/_fixtures/legacy-licence-version-purposes.fixture.js +++ /dev/null @@ -1,22 +0,0 @@ -'use strict' - -const purpose = { - PERIOD_END_DAY: '31', - PERIOD_END_MONTH: '3', - PERIOD_ST_DAY: '1', - PERIOD_ST_MONTH: '4', - ANNUAL_QTY: '545520', - DAILY_QTY: '1500.2', - FGAC_REGION_CODE: '3', - ID: '10000004', - HOURLY_QTY: '140.929', - INST_QTY: 'null', - NOTES: 'null', - APUR_APPR_CODE: 'I', - APUR_APSE_CODE: 'OTI', - APUR_APUS_CODE: '160', - TIMELTD_END_DATE: 'null', - TIMELTD_ST_DATE: 'null' -} - -module.exports = purpose diff --git a/test/services/import/_fixtures/legacy-licence-version.fixture.js b/test/services/import/_fixtures/legacy-licence-version.fixture.js index ef06a0efb3..454f3d789a 100644 --- a/test/services/import/_fixtures/legacy-licence-version.fixture.js +++ b/test/services/import/_fixtures/legacy-licence-version.fixture.js @@ -1,14 +1,24 @@ 'use strict' -const legacyLicenceVersionFixture = { - EFF_END_DATE: '04/06/2007', - EFF_ST_DATE: '05/06/2005', - INCR_NO: '0', - ISSUE_NO: '100', - STATUS: 'SUPER', - FGAC_REGION_CODE: '3', - AABL_ID: '10000003', - purposes: [] +function legacyLicenceVersionFixture () { + return { + EFF_END_DATE: '04/06/2007', + EFF_ST_DATE: '05/06/2005', + INCR_NO: '0', + ISSUE_NO: '100', + STATUS: 'SUPER', + FGAC_REGION_CODE: '3', + AABL_ID: '10000003', + purposes: [] + } } -module.exports = legacyLicenceVersionFixture +function create (data) { + return { + ...legacyLicenceVersionFixture() + } +} + +module.exports = { + create +} diff --git a/test/services/import/_fixtures/legacy-licence.fixture.js b/test/services/import/_fixtures/legacy-licence.fixture.js index a5546df39d..8fb18440b8 100644 --- a/test/services/import/_fixtures/legacy-licence.fixture.js +++ b/test/services/import/_fixtures/legacy-licence.fixture.js @@ -2,18 +2,28 @@ const { generateLicenceRef } = require('../../../support/helpers/licence.helper.js') -const legacyLicenceFixture = { - AREP_AREA_CODE: 'RIDIN', - AREP_EIUC_CODE: 'YOOTH', - AREP_LEAP_CODE: 'AIREL', - AREP_SUC_CODE: 'YORKI', - EXPIRY_DATE: '31/03/2015', - FGAC_REGION_CODE: '3', - ID: '10013151', - LAPSED_DATE: 'null', - LIC_NO: generateLicenceRef(), - ORIG_EFF_DATE: '03/06/2005', - REV_DATE: 'null' +function legacyLicenceFixture () { + return { + AREP_AREA_CODE: 'RIDIN', + AREP_EIUC_CODE: 'YOOTH', + AREP_LEAP_CODE: 'AIREL', + AREP_SUC_CODE: 'YORKI', + EXPIRY_DATE: '31/03/2015', + FGAC_REGION_CODE: '3', + ID: '10013151', + LAPSED_DATE: 'null', + LIC_NO: generateLicenceRef(), + ORIG_EFF_DATE: '03/06/2005', + REV_DATE: 'null' + } } -module.exports = legacyLicenceFixture +function create (data) { + return { + ...legacyLicenceFixture() + } +} + +module.exports = { + create +} diff --git a/test/services/import/legacy-import/licence-versions.mapper.test.js b/test/services/import/legacy-import/licence-versions.mapper.test.js index fc334331f5..e52ea96907 100644 --- a/test/services/import/legacy-import/licence-versions.mapper.test.js +++ b/test/services/import/legacy-import/licence-versions.mapper.test.js @@ -9,7 +9,7 @@ const { expect } = Code // Test helpers const FixtureLegacyLicenceVersion = require('../_fixtures/legacy-licence-version.fixture.js') -const FixtureLegacyLicenceVersionPurposes = require('../_fixtures/legacy-licence-version-purposes.fixture.js') +const FixtureLegacyLicenceVersionPurpose = require('../_fixtures/legacy-licence-version-purpose.fixture.js') // Thing under test const LegacyImportLicenceVersionMapper = @@ -21,8 +21,8 @@ describe('Legacy import licence versions mapper', () => { let version beforeEach(() => { - purpose = FixtureLegacyLicenceVersionPurposes - version = FixtureLegacyLicenceVersion + purpose = FixtureLegacyLicenceVersionPurpose.create() + version = FixtureLegacyLicenceVersion.create() licenceVersions = [{ ...version, purposes: [{ ...purpose }] }] }) diff --git a/test/services/import/legacy-import/licence.mapper.test.js b/test/services/import/legacy-import/licence.mapper.test.js index 39788f55b8..e2cc43e275 100644 --- a/test/services/import/legacy-import/licence.mapper.test.js +++ b/test/services/import/legacy-import/licence.mapper.test.js @@ -19,7 +19,7 @@ describe('Legacy import licence mapper', () => { let licence beforeEach(() => { - licence = { ...FixtureLegacyLicence } + licence = { ...FixtureLegacyLicence.create() } }) it('returns the matching agreements data', () => { @@ -154,7 +154,7 @@ describe('Legacy import licence mapper', () => { describe('then start date of the earliest non-draft licence version is used', () => { it('returns the start date in the ISO format', () => { // need to add licence versions - const result = LegacyImportLicenceMapper.go(licence, [{ ...FixtureLegacyLicenceVersion }]) + const result = LegacyImportLicenceMapper.go(licence, [{ ...FixtureLegacyLicenceVersion.create() }]) expect(result.startDate).to.equal('2005-06-05') }) diff --git a/test/services/import/legacy-licence.service.test.js b/test/services/import/legacy-licence.service.test.js index 0f010b0ac3..116c71d1bb 100644 --- a/test/services/import/legacy-licence.service.test.js +++ b/test/services/import/legacy-licence.service.test.js @@ -12,7 +12,7 @@ const { expect } = Code const FetchLegacyImportLicenceService = require('../../../app/services/import/legacy-import/fetch-licence.service.js') const FetchLegacyImportLicenceVersionsService = require('../../../app/services/import/legacy-import/fetch-licence-versions.service.js') const FixtureLegacyLicence = require('./_fixtures/legacy-licence.fixture.js') -const FixtureLegacyLicenceVersionPurposes = require('./_fixtures/legacy-licence-version-purposes.fixture.js') +const FixtureLegacyLicenceVersionPurpose = require('./_fixtures/legacy-licence-version-purpose.fixture.js') const FixtureLegacyLicenceVersion = require('./_fixtures/legacy-licence-version.fixture.js') const LicenceModel = require('../../../app/models/licence.model.js') const PrimaryPurposesSeeder = require('../../support/seeders/primary-purpose.seeder.js') @@ -25,24 +25,27 @@ const LegacyImportLicenceService = require('../../../app/services/import/legacy-licence.service.js') describe('Legacy import licence service', () => { - const licenceRef = FixtureLegacyLicence.LIC_NO - const region = RegionsSeeder.data.find((region) => { return region.displayName === 'Test Region' }) - let licenceVersions + let legacyLicence + let licenceRef let licenceVersionPurpose + let licenceVersions let version before(() => { - licenceVersionPurpose = FixtureLegacyLicenceVersionPurposes - version = FixtureLegacyLicenceVersion + legacyLicence = FixtureLegacyLicence.create() + licenceRef = legacyLicence.LIC_NO + + licenceVersionPurpose = FixtureLegacyLicenceVersionPurpose.create() + version = FixtureLegacyLicenceVersion.create() licenceVersions = [{ ...version, purposes: [{ ...licenceVersionPurpose }] }] Sinon.stub(FetchLegacyImportLicenceService, 'go').resolves({ - ...FixtureLegacyLicence, + ...legacyLicence, FGAC_REGION_CODE: region.naldRegionId }) @@ -124,15 +127,15 @@ describe('Legacy import licence service', () => { beforeEach(() => { primaryPurpose = PrimaryPurposesSeeder.data.find((primaryPurpose) => { - return primaryPurpose.legacyId === FixtureLegacyLicenceVersionPurposes.APUR_APPR_CODE + return primaryPurpose.legacyId === licenceVersionPurpose.APUR_APPR_CODE }) purpose = PurposesSeeder.data.find((purpose) => { - return purpose.legacyId === FixtureLegacyLicenceVersionPurposes.APUR_APUS_CODE + return purpose.legacyId === licenceVersionPurpose.APUR_APUS_CODE }) secondaryPurpose = SecondaryPurposesSeeder.data.find((secondaryPurpose) => { - return secondaryPurpose.legacyId === FixtureLegacyLicenceVersionPurposes.APUR_APSE_CODE + return secondaryPurpose.legacyId === licenceVersionPurpose.APUR_APSE_CODE }) }) diff --git a/test/services/import/licence-validator.service.test.js b/test/services/import/licence-validator.service.test.js index e91b5ceff5..d1f8444eba 100644 --- a/test/services/import/licence-validator.service.test.js +++ b/test/services/import/licence-validator.service.test.js @@ -8,7 +8,8 @@ const { describe, it, beforeEach } = exports.lab = Lab.script() const { expect } = Code // Test helpers -const FixtureValidImportLicence = require('./_fixtures/import-licence.fixture.js') +const FixtureImportLicence = require('./_fixtures/import-licence.fixture.js') +const FixtureImportLicenceVersion = require('./_fixtures/import-licence-versions.fixture.js') // Thing under test const ImportLicenceValidatorService = @@ -16,15 +17,18 @@ const ImportLicenceValidatorService = describe('Import licence validator service', () => { let licence + let licenceVersionsAndPurposes beforeEach(async () => { licence = { - ...FixtureValidImportLicence.importLicenceRequiredOnly + ...FixtureImportLicence.create() } + + licenceVersionsAndPurposes = [...FixtureImportLicenceVersion.create()] }) it('should not throw an error - licence is valid', async () => { - expect(() => { return ImportLicenceValidatorService.go(licence) }).to.not.throw() + expect(() => { return ImportLicenceValidatorService.go(licence, licenceVersionsAndPurposes) }).to.not.throw() }) describe('when a licence has badly formatted data', () => { @@ -33,7 +37,7 @@ describe('Import licence validator service', () => { }) it('should not throw an error - licence is valid', async () => { - expect(() => { return ImportLicenceValidatorService.go(licence) }).to.throw('"licenceRef" is required') + expect(() => { return ImportLicenceValidatorService.go(licence, licenceVersionsAndPurposes) }).to.throw('"licenceRef" is required') }) }) }) diff --git a/test/services/import/persist-licence.service.test.js b/test/services/import/persist-licence.service.test.js index 1d11775311..91c901669b 100644 --- a/test/services/import/persist-licence.service.test.js +++ b/test/services/import/persist-licence.service.test.js @@ -21,7 +21,7 @@ describe('Persist licence service', () => { let licence beforeEach(async () => { - licence = { ...FixtureImportLicence.importLicence } + licence = { ...FixtureImportLicence.create() } region = RegionsSeeder.data.find((region) => { return region.displayName === 'Test Region' diff --git a/test/validators/import/licence.validator.test.js b/test/validators/import/licence.validator.test.js index c3b828da21..c09b9b69ad 100644 --- a/test/validators/import/licence.validator.test.js +++ b/test/validators/import/licence.validator.test.js @@ -8,7 +8,7 @@ const { describe, it, before } = exports.lab = Lab.script() const { expect } = Code // Test helpers -const { importLicenceRequiredOnly } = require('../../services/import/_fixtures/import-licence.fixture.js') +const FixtureImportLicence = require('../../services/import/_fixtures/import-licence.fixture.js') // Thing under test const ImportLicenceValidator = require('../../../app/validators/import/licence.validator.js') @@ -18,7 +18,7 @@ describe('Import licence validator', () => { before(async () => { licence = { - ...importLicenceRequiredOnly + ...FixtureImportLicence.create() } }) From 285a830d2150214b14a589dc2652d0f625a1569a Mon Sep 17 00:00:00 2001 From: jonathangoulding Date: Tue, 30 Jul 2024 15:47:34 +0100 Subject: [PATCH 49/75] refactor: add nald regions to static lib --- app/lib/static-lookups.lib.js | 17 +++++++++++++++ .../import/legacy-import/constants.js | 21 ------------------- .../import/legacy-import/licence.mapper.js | 4 ++-- 3 files changed, 19 insertions(+), 23 deletions(-) delete mode 100644 app/services/import/legacy-import/constants.js diff --git a/app/lib/static-lookups.lib.js b/app/lib/static-lookups.lib.js index a65b27f53a..57f0cb825e 100644 --- a/app/lib/static-lookups.lib.js +++ b/app/lib/static-lookups.lib.js @@ -51,6 +51,22 @@ const returnRequirementReasons = { 'transfer-licence': 'Transfer licence' } +/** + * NALD region prefix from import.NALD_ABS_LICENCES.AREP_EIUC_CODE will be mapped to one of the below regions + * + */ +const naldRegions = { + AN: 'Anglian', + MD: 'Midlands', + NO: 'Northumbria', + NW: 'North West', + SO: 'Southern', + SW: 'South West (incl Wessex)', + TH: 'Thames', + WL: 'Wales', + YO: 'Yorkshire' +} + const sources = [ 'nald', 'wrls' @@ -78,6 +94,7 @@ module.exports = { organisationTypes, returnRequirementFrequencies, returnRequirementReasons, + naldRegions, sources, twoPartTariffReviewIssues } diff --git a/app/services/import/legacy-import/constants.js b/app/services/import/legacy-import/constants.js deleted file mode 100644 index 65947b2886..0000000000 --- a/app/services/import/legacy-import/constants.js +++ /dev/null @@ -1,21 +0,0 @@ -'use strict' - -/** - * NALD region prefix from import.NALD_ABS_LICENCES.AREP_EIUC_CODE will be mapped to one of the below regions - * - */ -const regions = { - AN: 'Anglian', - MD: 'Midlands', - NO: 'Northumbria', - NW: 'North West', - SO: 'Southern', - SW: 'South West (incl Wessex)', - TH: 'Thames', - WL: 'Wales', - YO: 'Yorkshire' -} - -module.exports = { - regions -} diff --git a/app/services/import/legacy-import/licence.mapper.js b/app/services/import/legacy-import/licence.mapper.js index 400b75dfdf..edebd08c7f 100644 --- a/app/services/import/legacy-import/licence.mapper.js +++ b/app/services/import/legacy-import/licence.mapper.js @@ -6,7 +6,7 @@ */ const { formatStandardDateToISO } = require('../../../lib/dates.lib.js') -const { regions } = require('./constants.js') +const { naldRegions } = require('../../../lib/static-lookups.lib.js') /** * Maps the import data to the desired format @@ -41,7 +41,7 @@ function _mapLicence (licence, licenceVersions) { const _regions = (licenceData) => { const historicalAreaCode = licenceData.AREP_AREA_CODE const regionPrefix = licenceData.AREP_EIUC_CODE.substr(0, 2) - const regionalChargeArea = regions[regionPrefix] + const regionalChargeArea = naldRegions[regionPrefix] const standardUnitChargeCode = licenceData.AREP_SUC_CODE const localEnvironmentAgencyPlanCode = licenceData.AREP_LEAP_CODE From a950db4841704135fff78d531f2569c952136497 Mon Sep 17 00:00:00 2001 From: jonathangoulding Date: Tue, 30 Jul 2024 16:55:39 +0100 Subject: [PATCH 50/75] refactor: date lib to throw an error --- app/lib/dates.lib.js | 2 +- test/controllers/import.controller.test.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/lib/dates.lib.js b/app/lib/dates.lib.js index 1e1e0e680e..8629ed25f5 100644 --- a/app/lib/dates.lib.js +++ b/app/lib/dates.lib.js @@ -31,7 +31,7 @@ function formatStandardDateToISO (date) { if (isValidDate(isoDateString)) { return isoDateString } else { - return null + throw new Error(`${isoDateString} is not a valid date`) } } diff --git a/test/controllers/import.controller.test.js b/test/controllers/import.controller.test.js index 198554a4be..756c89889a 100644 --- a/test/controllers/import.controller.test.js +++ b/test/controllers/import.controller.test.js @@ -65,7 +65,7 @@ describe('Import controller', () => { Sinon.stub(LegacyImportLicenceService, 'go').rejects() }) - it('redirects to select return start date page', async () => { + it('returns the error 500', async () => { const response = await server.inject(options) expect(response.statusCode).to.equal(500) From dbfe0d7c9124d721a90808322aca25f9d22533a5 Mon Sep 17 00:00:00 2001 From: jonathangoulding Date: Wed, 31 Jul 2024 09:28:05 +0100 Subject: [PATCH 51/75] refactor: import controller test --- test/controllers/import.controller.test.js | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/test/controllers/import.controller.test.js b/test/controllers/import.controller.test.js index 756c89889a..b97643fa58 100644 --- a/test/controllers/import.controller.test.js +++ b/test/controllers/import.controller.test.js @@ -57,20 +57,6 @@ describe('Import controller', () => { expect(response.statusCode).to.equal(204) }) }) - - describe('when a request does include the licence ref', () => { - beforeEach(() => { - options.payload = {} - - Sinon.stub(LegacyImportLicenceService, 'go').rejects() - }) - - it('returns the error 500', async () => { - const response = await server.inject(options) - - expect(response.statusCode).to.equal(500) - }) - }) }) }) }) From e5f9033af308e0c1369f23171e9cfbdd4d578ebc Mon Sep 17 00:00:00 2001 From: jonathangoulding Date: Thu, 8 Aug 2024 14:59:31 +0100 Subject: [PATCH 52/75] chore: merge main pr and fix --- .../import/_fixtures/import-licence.fixture.js | 4 ++-- .../import/persist-licence-versions.service.test.js | 12 ++++++------ test/services/import/persist-licence.service.test.js | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/test/services/import/_fixtures/import-licence.fixture.js b/test/services/import/_fixtures/import-licence.fixture.js index 2ed3462142..68f0bee1a7 100644 --- a/test/services/import/_fixtures/import-licence.fixture.js +++ b/test/services/import/_fixtures/import-licence.fixture.js @@ -1,9 +1,9 @@ 'use strict' const { generateLicenceRef } = require('../../../support/helpers/licence.helper.js') -const RegionsSeeder = require('../../../support/seeders/regions.seeder.js') +const RegionHelper = require('../../../support/helpers/region.helper.js') -const region = RegionsSeeder.data.find((region) => { +const region = RegionHelper.data.find((region) => { return region.displayName === 'Test Region' }) diff --git a/test/services/import/persist-licence-versions.service.test.js b/test/services/import/persist-licence-versions.service.test.js index 84eeb79723..72b6283bf3 100644 --- a/test/services/import/persist-licence-versions.service.test.js +++ b/test/services/import/persist-licence-versions.service.test.js @@ -11,9 +11,9 @@ const { expect } = Code const FixtureImportLicenceVersions = require('./_fixtures/import-licence-versions.fixture.js') const LicenceHelper = require('../../support/helpers/licence.helper.js') const LicenceVersionModel = require('../../../app/models/licence-version.model.js') -const PrimaryPurposesSeeder = require('../../support/seeders/primary-purpose.seeder.js') -const PurposesSeeder = require('../../support/seeders/purposes.seeder.js') -const SecondaryPurposesSeeder = require('../../support/seeders/secondary-purpose.seeder.js') +const PurposeHelper = require('../../support/helpers/purpose.helper.js') +const PrimaryPurposeHelper = require('../../support/helpers/primary-purpose.helper.js') +const SecondaryPurposeHelper = require('../../support/helpers/secondary-purpose.helper.js') // Thing under test const PersistLicenceVersionsService = @@ -36,15 +36,15 @@ describe('Persist licence versions and licence versions purposes service', () => licenceVersion = { ...licenceVersionsAndPurposes[0] } licenceVersionsPurpose = { ...licenceVersion.purposes[0] } - primaryPurpose = PrimaryPurposesSeeder.data.find((primaryPurpose) => { + primaryPurpose = PrimaryPurposeHelper.data.find((primaryPurpose) => { return primaryPurpose.legacyId === licenceVersionsPurpose.primaryPurposeId }) - purpose = PurposesSeeder.data.find((purpose) => { + purpose = PurposeHelper.data.find((purpose) => { return purpose.legacyId === licenceVersionsPurpose.purposeId }) - secondaryPurpose = SecondaryPurposesSeeder.data.find((secondaryPurpose) => { + secondaryPurpose = SecondaryPurposeHelper.data.find((secondaryPurpose) => { return secondaryPurpose.legacyId === licenceVersionsPurpose.secondaryPurposeId }) }) diff --git a/test/services/import/persist-licence.service.test.js b/test/services/import/persist-licence.service.test.js index 91c901669b..4f804bb0a3 100644 --- a/test/services/import/persist-licence.service.test.js +++ b/test/services/import/persist-licence.service.test.js @@ -10,7 +10,7 @@ const { expect } = Code // Test helpers const FixtureImportLicence = require('./_fixtures/import-licence.fixture.js') const LicenceModel = require('../../../app/models/licence.model.js') -const RegionsSeeder = require('../../support/seeders/regions.seeder.js') +const RegionHelper = require('../../support/helpers/region.helper.js') // Thing under test const PersistLicenceService = @@ -23,7 +23,7 @@ describe('Persist licence service', () => { beforeEach(async () => { licence = { ...FixtureImportLicence.create() } - region = RegionsSeeder.data.find((region) => { + region = RegionHelper.data.find((region) => { return region.displayName === 'Test Region' }) }) From 08cdc0068328c3515a75f38758bb8b4c31a45826 Mon Sep 17 00:00:00 2001 From: jonathangoulding Date: Thu, 8 Aug 2024 15:29:41 +0100 Subject: [PATCH 53/75] fix: remove expectation of includeInSrocTptBilling in licence default return due to recent migration. --- .../import/legacy-licence.service.test.js | 22 ++++++++----------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/test/services/import/legacy-licence.service.test.js b/test/services/import/legacy-licence.service.test.js index 116c71d1bb..9441de1b73 100644 --- a/test/services/import/legacy-licence.service.test.js +++ b/test/services/import/legacy-licence.service.test.js @@ -12,22 +12,20 @@ const { expect } = Code const FetchLegacyImportLicenceService = require('../../../app/services/import/legacy-import/fetch-licence.service.js') const FetchLegacyImportLicenceVersionsService = require('../../../app/services/import/legacy-import/fetch-licence-versions.service.js') const FixtureLegacyLicence = require('./_fixtures/legacy-licence.fixture.js') -const FixtureLegacyLicenceVersionPurpose = require('./_fixtures/legacy-licence-version-purpose.fixture.js') const FixtureLegacyLicenceVersion = require('./_fixtures/legacy-licence-version.fixture.js') +const FixtureLegacyLicenceVersionPurpose = require('./_fixtures/legacy-licence-version-purpose.fixture.js') const LicenceModel = require('../../../app/models/licence.model.js') -const PrimaryPurposesSeeder = require('../../support/seeders/primary-purpose.seeder.js') -const PurposesSeeder = require('../../support/seeders/purposes.seeder.js') -const RegionsSeeder = require('../../support/seeders/regions.seeder.js') -const SecondaryPurposesSeeder = require('../../support/seeders/secondary-purpose.seeder.js') +const PrimaryPurposeHelper = require('../../support/helpers/primary-purpose.helper.js') +const PurposeHelper = require('../../support/helpers/purpose.helper.js') +const RegionHelper = require('../../support/helpers/region.helper.js') +const SecondaryPurposeHelper = require('../../support/helpers/secondary-purpose.helper.js') // Thing under test const LegacyImportLicenceService = require('../../../app/services/import/legacy-licence.service.js') describe('Legacy import licence service', () => { - const region = RegionsSeeder.data.find((region) => { - return region.displayName === 'Test Region' - }) + const region = RegionHelper.select() let legacyLicence let licenceRef @@ -64,7 +62,6 @@ describe('Legacy import licence service', () => { id: licence.id, includeInPresrocBilling: 'no', includeInSrocBilling: false, - includeInSrocTptBilling: false, lapsedDate: null, licenceRef, regionId: region.id, @@ -89,7 +86,6 @@ describe('Legacy import licence service', () => { expect(licence.includeInPresrocBilling).to.equal('no') expect(licence.includeInSrocBilling).to.be.false() - expect(licence.includeInSrocTptBilling).to.be.false() expect(licence.suspendFromBilling).to.be.false() }) }) @@ -126,15 +122,15 @@ describe('Legacy import licence service', () => { let secondaryPurpose beforeEach(() => { - primaryPurpose = PrimaryPurposesSeeder.data.find((primaryPurpose) => { + primaryPurpose = PrimaryPurposeHelper.data.find((primaryPurpose) => { return primaryPurpose.legacyId === licenceVersionPurpose.APUR_APPR_CODE }) - purpose = PurposesSeeder.data.find((purpose) => { + purpose = PurposeHelper.data.find((purpose) => { return purpose.legacyId === licenceVersionPurpose.APUR_APUS_CODE }) - secondaryPurpose = SecondaryPurposesSeeder.data.find((secondaryPurpose) => { + secondaryPurpose = SecondaryPurposeHelper.data.find((secondaryPurpose) => { return secondaryPurpose.legacyId === licenceVersionPurpose.APUR_APSE_CODE }) }) From a17ea4d274cceb206717e3f445cff36df7937d42 Mon Sep 17 00:00:00 2001 From: jonathangoulding Date: Thu, 8 Aug 2024 15:37:02 +0100 Subject: [PATCH 54/75] fix: sonar consistent return --- app/services/import/legacy-licence.service.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/services/import/legacy-licence.service.js b/app/services/import/legacy-licence.service.js index 45b686514b..9d3092e3c2 100644 --- a/app/services/import/legacy-licence.service.js +++ b/app/services/import/legacy-licence.service.js @@ -41,7 +41,7 @@ async function go (licenceRef) { await PersistLicenceVersionsService.go(mappedLicenceVersionsData, savedLicence.id) calculateAndLogTimeTaken(startTime, 'Process licence', { licenceRef }) } catch (error) { - return Boom.badImplementation(`Licence ref: ${licenceRef} failed with error - ${error.message}`) + Boom.badImplementation(`Licence ref: ${licenceRef} failed with error - ${error.message}`) } } From 17d419d9dbbeab6605fee8d3fdab6e7a49306eef Mon Sep 17 00:00:00 2001 From: jonathangoulding Date: Fri, 9 Aug 2024 10:51:14 +0100 Subject: [PATCH 55/75] fix: data binding remove console debugs --- .../import/legacy-import/fetch-licence-versions.service.js | 6 +++--- app/services/import/legacy-import/fetch-licence.service.js | 4 ++-- app/services/import/legacy-licence.service.js | 4 +--- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/app/services/import/legacy-import/fetch-licence-versions.service.js b/app/services/import/legacy-import/fetch-licence-versions.service.js index 6f410075b0..0e9b64d554 100644 --- a/app/services/import/legacy-import/fetch-licence-versions.service.js +++ b/app/services/import/legacy-import/fetch-licence-versions.service.js @@ -55,12 +55,12 @@ async function _getLicenceVersions (licenceId, regionCode) { AND purposes."AABV_INCR_NO" = versions."INCR_NO" AND purposes."FGAC_REGION_CODE" = versions."FGAC_REGION_CODE") AS purposes FROM import."NALD_ABS_LIC_VERSIONS" versions - WHERE versions."FGAC_REGION_CODE" = '${regionCode}' - AND versions."AABL_ID" = '${licenceId}' + WHERE versions."FGAC_REGION_CODE" = ? + AND versions."AABL_ID" = ? AND versions."STATUS" <> 'DRAFT'; ` - const { rows } = await db.raw(query) + const { rows } = await db.raw(query, [regionCode, licenceId]) return rows } diff --git a/app/services/import/legacy-import/fetch-licence.service.js b/app/services/import/legacy-import/fetch-licence.service.js index 9aa17ef955..446721365a 100644 --- a/app/services/import/legacy-import/fetch-licence.service.js +++ b/app/services/import/legacy-import/fetch-licence.service.js @@ -31,10 +31,10 @@ async function _getLicenceByRef (licenceRef) { licence."ORIG_EFF_DATE", licence."REV_DATE" FROM import."NALD_ABS_LICENCES" licence - WHERE licence."LIC_NO" = '${licenceRef}'; + WHERE licence."LIC_NO" = ?; ` - const { rows: [row] } = await db.raw(query) + const { rows: [row] } = await db.raw(query, [licenceRef]) return row } diff --git a/app/services/import/legacy-licence.service.js b/app/services/import/legacy-licence.service.js index 9d3092e3c2..3ec932ca61 100644 --- a/app/services/import/legacy-licence.service.js +++ b/app/services/import/legacy-licence.service.js @@ -5,7 +5,6 @@ * @module LegacyImportLicenceService */ -const Boom = require('@hapi/boom') const FetchLegacyImportLicenceService = require('./legacy-import/fetch-licence.service.js') const FetchLegacyImportLicenceVersionsService = require('./legacy-import/fetch-licence-versions.service.js') const ImportLicenceValidatorService = require('./licence-validator.service.js') @@ -25,7 +24,6 @@ async function go (licenceRef) { try { const startTime = currentTimeInNanoseconds() - console.debug('Importing licence ref: ', licenceRef) const licenceData = await FetchLegacyImportLicenceService.go(licenceRef) const licenceVersionsData = await FetchLegacyImportLicenceVersionsService.go(licenceData) @@ -41,7 +39,7 @@ async function go (licenceRef) { await PersistLicenceVersionsService.go(mappedLicenceVersionsData, savedLicence.id) calculateAndLogTimeTaken(startTime, 'Process licence', { licenceRef }) } catch (error) { - Boom.badImplementation(`Licence ref: ${licenceRef} failed with error - ${error.message}`) + global.GlobalNotifier.omfg('Licence import failed', { licenceRef }, error) } } From 5dd0e74309f7b5d142e77b551fccb1030cb2522a Mon Sep 17 00:00:00 2001 From: jonathangoulding Date: Fri, 9 Aug 2024 10:52:45 +0100 Subject: [PATCH 56/75] fix: controller logic - follow convention --- app/controllers/import.controller.js | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/app/controllers/import.controller.js b/app/controllers/import.controller.js index 7838f57355..d1fc329dbb 100644 --- a/app/controllers/import.controller.js +++ b/app/controllers/import.controller.js @@ -1,7 +1,5 @@ 'use strict' -const Boom = require('@hapi/boom') - const FeatureFlags = require('../../config/feature-flags.config.js') const LegacyImportLicenceService = require('../services/import/legacy-licence.service.js') @@ -10,17 +8,13 @@ const LegacyImportLicenceService = require('../services/import/legacy-licence.se * @module ImportController */ async function licence (request, h) { - try { - const { licenceRef } = request.payload - - if (FeatureFlags.enableSystemImportLegacyLicence) { - await LegacyImportLicenceService.go(licenceRef) - } + const { licenceRef } = request.payload - return h.response().code(204) - } catch (error) { - return Boom.badImplementation(error.message) + if (FeatureFlags.enableSystemImportLegacyLicence) { + LegacyImportLicenceService.go(licenceRef) } + + return h.response().code(204) } module.exports = { From e93fc736f025d5bf53165e72dba93c1658362999 Mon Sep 17 00:00:00 2001 From: jonathangoulding Date: Fri, 9 Aug 2024 12:16:01 +0100 Subject: [PATCH 57/75] fix: error handling for import controller test --- test/controllers/import.controller.test.js | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/test/controllers/import.controller.test.js b/test/controllers/import.controller.test.js index 8d1ebf0dbf..e83dc5b202 100644 --- a/test/controllers/import.controller.test.js +++ b/test/controllers/import.controller.test.js @@ -63,25 +63,11 @@ describe('Import controller', () => { expect(response.statusCode).to.equal(204) }) }) - - describe('when a request does include the licence ref', () => { - beforeEach(() => { - options.payload = {} - - Sinon.stub(LegacyImportLicenceService, 'go').rejects() - }) - - it('redirects to select return start date page', async () => { - const response = await server.inject(options) - - expect(response.statusCode).to.equal(500) - }) - }) }) describe('when the feature flag "enableSystemLicenceView" is false', () => { beforeEach(() => { - Sinon.stub(LegacyImportLicenceService, 'go') + Sinon.stub(LegacyImportLicenceService, 'go').resolves() Sinon.stub(FeatureFlagsConfig, 'enableSystemImportLegacyLicence').value(false) }) From c9d8f44d8e1dee174b8a12d94cc6afabcaf02f64 Mon Sep 17 00:00:00 2001 From: jonathangoulding Date: Fri, 9 Aug 2024 12:30:10 +0100 Subject: [PATCH 58/75] chore: update js docs remove typedefs --- .../fetch-licence-versions.service.js | 122 ++++++++---------- .../legacy-import/fetch-licence.service.js | 30 ++--- .../legacy-import/licence-versions.mapper.js | 22 +--- .../import/legacy-import/licence.mapper.js | 14 +- .../import/licence-validator.service.js | 67 +--------- .../import/licence-versions.validator.js | 34 ++++- app/validators/import/licence.validator.js | 22 +++- 7 files changed, 124 insertions(+), 187 deletions(-) diff --git a/app/services/import/legacy-import/fetch-licence-versions.service.js b/app/services/import/legacy-import/fetch-licence-versions.service.js index 0e9b64d554..896c4f3b1d 100644 --- a/app/services/import/legacy-import/fetch-licence-versions.service.js +++ b/app/services/import/legacy-import/fetch-licence-versions.service.js @@ -9,10 +9,36 @@ const { db } = require('../../../../db/db.js') /** * Gets the legacy licence versions * - * Returns the legacy licence version purposes + * Returns the legacy licence version purposes. * - * @param {LegacyLicenceType} licenceData - * @returns {Promise} + * @param { object } licenceData - The data related to the licence. + * @returns {Promise>} */ async function go (licenceData) { const { ID: licenceId, FGAC_REGION_CODE: regionCode } = licenceData @@ -22,33 +48,32 @@ async function go (licenceData) { async function _getLicenceVersions (licenceId, regionCode) { const query = ` - SELECT - versions."EFF_END_DATE", - versions."EFF_ST_DATE", - versions."INCR_NO", - versions."ISSUE_NO", - versions."STATUS", - versions."FGAC_REGION_CODE", - versions."AABL_ID", - (SELECT json_agg(json_build_object( - 'PERIOD_END_DAY', purposes."PERIOD_END_DAY", - 'PERIOD_END_MONTH', purposes."PERIOD_END_MONTH", - 'PERIOD_ST_DAY', purposes."PERIOD_ST_DAY", - 'PERIOD_ST_MONTH', purposes."PERIOD_ST_MONTH", - 'ANNUAL_QTY', purposes."ANNUAL_QTY", - 'DAILY_QTY', purposes."DAILY_QTY", - 'FGAC_REGION_CODE', purposes."FGAC_REGION_CODE", - 'ID', purposes."ID", - 'HOURLY_QTY', purposes."HOURLY_QTY", - 'INST_QTY', purposes."INST_QTY", - 'NOTES', purposes."NOTES", - 'APUR_APPR_CODE', purposes."APUR_APPR_CODE", - 'APUR_APSE_CODE', purposes."APUR_APSE_CODE", - 'APUR_APUS_CODE', purposes."APUR_APUS_CODE", - 'TIMELTD_END_DATE', purposes."TIMELTD_END_DATE", - 'TIMELTD_ST_DATE', purposes."TIMELTD_ST_DATE" + SELECT versions."EFF_END_DATE", + versions."EFF_ST_DATE", + versions."INCR_NO", + versions."ISSUE_NO", + versions."STATUS", + versions."FGAC_REGION_CODE", + versions."AABL_ID", + (SELECT json_agg(json_build_object( + 'PERIOD_END_DAY', purposes."PERIOD_END_DAY", + 'PERIOD_END_MONTH', purposes."PERIOD_END_MONTH", + 'PERIOD_ST_DAY', purposes."PERIOD_ST_DAY", + 'PERIOD_ST_MONTH', purposes."PERIOD_ST_MONTH", + 'ANNUAL_QTY', purposes."ANNUAL_QTY", + 'DAILY_QTY', purposes."DAILY_QTY", + 'FGAC_REGION_CODE', purposes."FGAC_REGION_CODE", + 'ID', purposes."ID", + 'HOURLY_QTY', purposes."HOURLY_QTY", + 'INST_QTY', purposes."INST_QTY", + 'NOTES', purposes."NOTES", + 'APUR_APPR_CODE', purposes."APUR_APPR_CODE", + 'APUR_APSE_CODE', purposes."APUR_APSE_CODE", + 'APUR_APUS_CODE', purposes."APUR_APUS_CODE", + 'TIMELTD_END_DATE', purposes."TIMELTD_END_DATE", + 'TIMELTD_ST_DATE', purposes."TIMELTD_ST_DATE" ) - ) + ) FROM import."NALD_ABS_LIC_PURPOSES" purposes WHERE purposes."AABV_AABL_ID" = versions."AABL_ID" AND purposes."AABV_ISSUE_NO" = versions."ISSUE_NO" @@ -68,42 +93,3 @@ async function _getLicenceVersions (licenceId, regionCode) { module.exports = { go } - -/** - * A legacy licence version - * @typedef {Object} LegacyLicenceVersionsType - * - * @property {string} EFF_END_DATE - date in UK format - can be 'null' - * @property {string} EFF_ST_DATE - date in UK format - * @property {string} INCR_NO - a number between 1 - 5 - * @property {string} ISSUE_NO - a number - * @property {string} STATUS - enum - 'DRAFT', 'SUPER', 'CURR' (Draft will not be selected) - * @property {string} FGAC_REGION_CODE - * @property {string} AABL_ID - * @property {LegacyLicenceVersionsPurposesType} purposes - */ - -/** - * An array of legacy licence versions. - * @typedef {LegacyLicenceVersionsType[]} LegacyLicenceVersionsArray - */ - -/** - * @typedef {Object} LegacyLicenceVersionsPurposesType - * @property {string} PERIOD_END_DAY - The end day of the period. - * @property {string} PERIOD_END_MONTH - The end month of the period. - * @property {string} PERIOD_ST_DAY - The start day of the period. - * @property {string} PERIOD_ST_MONTH - The start month of the period. - * @property {string} ANNUAL_QTY - The annual quantity. - * @property {string} DAILY_QTY - The daily quantity. - * @property {string} FGAC_REGION_CODE - The FGAC region code. - * @property {string} ID - * @property {string} HOURLY_QTY - The hourly quantity. - * @property {string} INST_QTY - The instant quantity. - * @property {string} NOTES - Additional notes. - * @property {string} APUR_APPR_CODE - The APUR approval code. - * @property {string} APUR_APSE_CODE - The APUR secondary code. - * @property {string} APUR_APUS_CODE - The APUR usage code. - * @property {string} TIMELTD_END_DATE - The time-limited end date. - * @property {string} TIMELTD_ST_DATE - The time-limited start date. - */ diff --git a/app/services/import/legacy-import/fetch-licence.service.js b/app/services/import/legacy-import/fetch-licence.service.js index 446721365a..3beaa9af4e 100644 --- a/app/services/import/legacy-import/fetch-licence.service.js +++ b/app/services/import/legacy-import/fetch-licence.service.js @@ -10,7 +10,17 @@ const { db } = require('../../../../db/db.js') * Fetches the licence data for the licence ref from the import.NALD_ABS_LICENCES table * * @param {string} licenceRef - the licence ref - * @returns {Promise} + * @returns {Promise} - A promise that resolves to an object with the following properties: + * - {string} AREP_AREA_CODE - regions - historicalAreaCode + * - {string} AREP_EIUC_CODE - regions - regionPrefix / regionalChargeArea + * - {string} AREP_LEAP_CODE - regions - localEnvironmentAgencyPlanCode + * - {string} AREP_SUC_CODE - regions - standardUnitChargeCode + * - {string} EXPIRY_DATE + * - {string} ID + * - {string} LAPSED_DATE + * - {string} LIC_NO + * - {string} ORIG_EFF_DATE + * - {string} REV_DATE */ async function go (licenceRef) { return _getLicenceByRef(licenceRef) @@ -42,21 +52,3 @@ async function _getLicenceByRef (licenceRef) { module.exports = { go } - -/** - * A legacy licence - * - * @typedef {Object} LegacyLicenceType - * - * @property {string} AREP_AREA_CODE - regions - historicalAreaCode - * @property {string} AREP_EIUC_CODE - regions -regionPrefix / regionalChargeArea - * @property {string} AREP_LEAP_CODE - regions -localEnvironmentAgencyPlanCode - * @property {string} AREP_SUC_CODE - regions -standardUnitChargeCode - * @property {string} EXPIRY_DATE - * @property {string} ID - * @property {string} LAPSED_DATE - * @property {string} LIC_NO - * @property {string} ORIG_EFF_DATE - * @property {string} REV_DATE - * - */ diff --git a/app/services/import/legacy-import/licence-versions.mapper.js b/app/services/import/legacy-import/licence-versions.mapper.js index 1286da26ff..fa75909b10 100644 --- a/app/services/import/legacy-import/licence-versions.mapper.js +++ b/app/services/import/legacy-import/licence-versions.mapper.js @@ -15,8 +15,8 @@ const statuses = { /** * Maps the import licence versions data * - * @param {LegacyLicenceVersionsArray} licenceVersions - * @returns {ImportLicenceVersionType[]} + * @param { array } licenceVersions - the legacy licence versions and purposes + * @returns { array } - mapped licence versions */ function go (licenceVersions) { return _mapLicenceVersions(licenceVersions) @@ -28,12 +28,6 @@ const _createExternalId = (licenceVersion) => { return `${FGAC_REGION_CODE}:${AABL_ID}:${ISSUE_NO}:${INCR_NO}` } -/** - * Iterates the import licence versions and formats the licence version - * - * @param {LegacyLicenceVersionsArray} licenceVersions - * @returns {ImportLicenceVersionType[]} - */ function _mapLicenceVersions (licenceVersions) { return licenceVersions.map((licenceVersion) => { const issue = licenceVersion.ISSUE_NO @@ -51,24 +45,12 @@ function _mapLicenceVersions (licenceVersions) { }) } -/** - * Iterates the import licence version purposes - * - * @param {LegacyLicenceVersionsType} licenceVersion - * @returns {ImportLicenceVersionPurposeType} - */ function _mapPurposes (licenceVersion) { return licenceVersion.purposes.map((purpose) => { return _mapPurpose(purpose) }) } -/** - * Maps the import licence versions purposes data - * - * @param {LegacyLicenceVersionsPurposesType} purpose - * @returns {ImportLicenceVersionPurposeType} - */ const _mapPurpose = (purpose) => { return { abstractionPeriodEndDay: Number(purpose.PERIOD_END_DAY), diff --git a/app/services/import/legacy-import/licence.mapper.js b/app/services/import/legacy-import/licence.mapper.js index edebd08c7f..ff6501b857 100644 --- a/app/services/import/legacy-import/licence.mapper.js +++ b/app/services/import/legacy-import/licence.mapper.js @@ -11,9 +11,9 @@ const { naldRegions } = require('../../../lib/static-lookups.lib.js') /** * Maps the import data to the desired format * - * @param {LegacyLicenceType} licence - * @param {LegacyLicenceVersionsArray} licenceVersions - * @returns {ImportLicenceType} + * @param { object} licence - the legacy licence + * @param { array } licenceVersions - the legacy licence versions and purposes + * @returns { object } */ function go (licence, licenceVersions = []) { return _mapLicence(licence, licenceVersions) @@ -34,9 +34,7 @@ function _mapLicence (licence, licenceVersions) { /** * Creates a JSON object of the region data - * - * @param {Object} licenceData - * @return {ImportRegionType} + * This is stored as a JSON object in the licence.regions column. */ const _regions = (licenceData) => { const historicalAreaCode = licenceData.AREP_AREA_CODE @@ -56,8 +54,8 @@ const _regions = (licenceData) => { * * It is assumed one of these will always exist * - * @param {LegacyLicenceType} licence - * @param {LegacyLicenceVersionsArray} licenceVersions + * @param { object } licence + * @param { array } licenceVersions * @return {String} YYYY-MM-DD */ const _startDate = (licence, licenceVersions) => { diff --git a/app/services/import/licence-validator.service.js b/app/services/import/licence-validator.service.js index 026181a0eb..da7e8cc98a 100644 --- a/app/services/import/licence-validator.service.js +++ b/app/services/import/licence-validator.service.js @@ -9,12 +9,12 @@ const ImportLicenceValidator = require('../../validators/import/licence.validato const ImportLicenceVersionsValidator = require('../../validators/import/licence-versions.validator.js') /** - * Validates a import licence is in the correct shape and format to persist in the database + * Validates an import licence is in the correct shape and format to persist in the database * * If the validation fails throw an error * - * @param {ImportLicenceType} licence - The licence to validate - * @param {ImportLicenceVersionType[]} licenceVersions - The licence versions to validate + * @param { object } licence - The licence to validate + * @param { array } licenceVersions - The licence versions to validate */ function go (licence, licenceVersions) { ImportLicenceValidator.go(licence) @@ -24,64 +24,3 @@ function go (licence, licenceVersions) { module.exports = { go } - -/** - * A valid licence that is in the correct shape / format to save in the database - * @typedef {Object} ImportLicenceType - * - * @property {string | null} expiredDate - * @property {string | null} lapsedDate - * @property {string} licenceRef - * @property {number} naldRegionId - * @property {ImportRegionType} regions - * @property {string | null} revokedDate - * @property {string} startDate - * @property {boolean} waterUndertaker - */ - -/** - * A valid licence 'regions' json colum - * @typedef {Object} ImportRegionType - * - * @property {string} regionalChargeArea - * @property {string} localEnvironmentAgencyPlanCode - * @property {string} historicalAreaCode - * @property {string} standardUnitChargeCode - * - */ - -/** - * @typedef {Object} ImportLicenceVersionPurposeType - * - * @property {number} abstractionPeriodEndDay - The end day of the abstraction period. - * @property {number} abstractionPeriodEndMonth - The end month of the abstraction period. - * @property {number} abstractionPeriodStartDay - The start day of the abstraction period. - * @property {number} abstractionPeriodStartMonth - The start month of the abstraction period. - * @property {number|null} annualQuantity - The annual quantity; null if not applicable. - * @property {number|null} dailyQuantity - The daily quantity; null if not applicable. - * @property {string} externalId - The external identifier for the purpose. - * @property {number|null} hourlyQuantity - The hourly quantity; null if not applicable. - * @property {number|null} instantQuantity - The instant quantity; null if not applicable. - * @property {string|null} notes - Additional notes; null if not applicable. - * @property {string} primaryPurposeId - The primary purpose identifier. - * @property {string} secondaryPurposeId - The secondary purpose identifier. - * @property {string} purposeId - The purpose identifier. - * @property {string|null} timeLimitedEndDate - The end date of the time-limited period in ISO format; - * null if not applicable. - * @property {string|null} timeLimitedStartDate - The start date of the time-limited period in ISO format; - * null if not applicable. - */ - -/** - * @typedef {Object} ImportLicenceVersionType - * - * @property {string} createdAt - The creation timestamp in ISO format. - * @property {string|null} endDate - The end date in ISO format; null if not applicable. - * @property {string} externalId - The external identifier for the licence version. - * @property {number} increment - The increment number. - * @property {number} issue - The issue number. - * @property {string|null} startDate - The start date in ISO format; null if not applicable. - * @property {string} status - The status of the licence version. - * @property {string} updatedAt - The update timestamp in ISO format. - * @property {ImportLicenceVersionPurposeType[]} purposes - The array of purposes associated with the licence version. - */ diff --git a/app/validators/import/licence-versions.validator.js b/app/validators/import/licence-versions.validator.js index a4ffb2bfb9..3cea5751de 100644 --- a/app/validators/import/licence-versions.validator.js +++ b/app/validators/import/licence-versions.validator.js @@ -14,12 +14,38 @@ const validStatues = ['current', 'superseded'] /** * Checks that the data for inserting/updating the public.licence_versions - * and public.licence_versions_purposes table is valid + * and public.licence_versions_purposes table is valid. * - * @param {ImportLicenceVersionType[]} data The data to be validated - * - * Throws an error if anything fails + * @param {Array<{ + * createdAt: string, + * endDate: string | null, + * externalId: string, + * increment: number, + * issue: number, + * startDate: string | null, + * status: string, + * updatedAt: string, + * purposes: Array<{ + * abstractionPeriodEndDay: number, + * abstractionPeriodEndMonth: number, + * abstractionPeriodStartDay: number, + * abstractionPeriodStartMonth: number, + * annualQuantity: number | null, + * dailyQuantity: number | null, + * externalId: string, + * hourlyQuantity: number | null, + * instantQuantity: number | null, + * notes: string | null, + * primaryPurposeId: string, + * secondaryPurposeId: string, + * purposeId: string, + * timeLimitedEndDate: string | null, + * timeLimitedStartDate: string | null + * }> + * }>} data - The data to be validated. * + * @returns {void} + * @throws {Error} If validation fails. */ function go (data) { const result = _schema.validate(data) diff --git a/app/validators/import/licence.validator.js b/app/validators/import/licence.validator.js index 8548b0c156..feb81710db 100644 --- a/app/validators/import/licence.validator.js +++ b/app/validators/import/licence.validator.js @@ -9,11 +9,25 @@ const Joi = require('joi') /** * Checks that the data for inserting/updating the public.licence table is valid * - * @param {ImportLicenceType} data The data to be validated - * - * Throws an error if anything fails - * + * @param {{ + * expiredDate: string | null, + * lapsedDate: string | null, + * licenceRef: string, + * naldRegionId: number, + * regions: { + * regionalChargeArea: string, + * localEnvironmentAgencyPlanCode: string, + * historicalAreaCode: string, + * standardUnitChargeCode: string + * }, + * revokedDate: string | null, + * startDate: string, + * waterUndertaker: boolean + * }} data - The mapped licence data + * @returns { void } + * @throws {Error} - throw an error if any of the validations fail */ + function go (data) { const result = _schema.validate(data) From 209a01f3f65c824ae2de769dec9ec7cef4582f01 Mon Sep 17 00:00:00 2001 From: jonathangoulding Date: Fri, 9 Aug 2024 15:59:30 +0100 Subject: [PATCH 59/75] fix: persist licence version does not need to return anything adjust the tests accordingly. --- .../persist-licence-versions.service.js | 12 +- .../import/persist-licence.service.js | 2 +- ...08_water-licence-version-purposes-table.js | 8 +- .../persist-licence-versions.service.test.js | 237 ++++++++++++------ .../import/persist-licence.service.test.js | 34 ++- 5 files changed, 197 insertions(+), 96 deletions(-) diff --git a/app/services/import/persist-licence-versions.service.js b/app/services/import/persist-licence-versions.service.js index 0c11e9edf6..37a02a3c0a 100644 --- a/app/services/import/persist-licence-versions.service.js +++ b/app/services/import/persist-licence-versions.service.js @@ -14,22 +14,20 @@ const PurposeModel = require('../../models/purpose.model.js') /** * Saves the licence versions, purposes and conditions * - * @param {ImportLicenceVersionType[]} licenceVersions - * @param {string} licenceId + * @param { array } licenceVersions + * @param { string } licenceId */ async function go (licenceVersions, licenceId) { - return Promise.all(licenceVersions.map(async (version) => { + await Promise.all(licenceVersions.map(async (version) => { const purposes = version.purposes delete version.purposes const versionResult = await _saveLicenceVersion(version, licenceId) - const licenceVersionPurposes = await Promise.all(purposes.map(async (purpose) => { + await Promise.all(purposes.map(async (purpose) => { return _saveLicenceVersionPurposes(purpose, versionResult.id) })) - - return { ...versionResult, purposes: licenceVersionPurposes } })) } @@ -52,7 +50,7 @@ async function _saveLicenceVersionPurposes (purpose, licenceVersionId) { .first() .limit(1) - return LicenceVersionPurposeModel.query() + await LicenceVersionPurposeModel.query() .insert({ licenceVersionId, ...purpose, diff --git a/app/services/import/persist-licence.service.js b/app/services/import/persist-licence.service.js index c63e6762c7..33317a506e 100644 --- a/app/services/import/persist-licence.service.js +++ b/app/services/import/persist-licence.service.js @@ -26,7 +26,7 @@ async function go (licence) { .limit(1) .first() - return LicenceModel.query() + await LicenceModel.query() .insert({ expiredDate, waterUndertaker, diff --git a/db/migrations/legacy/20221108007008_water-licence-version-purposes-table.js b/db/migrations/legacy/20221108007008_water-licence-version-purposes-table.js index 09e14ee522..453badc500 100644 --- a/db/migrations/legacy/20221108007008_water-licence-version-purposes-table.js +++ b/db/migrations/legacy/20221108007008_water-licence-version-purposes-table.js @@ -22,10 +22,10 @@ exports.up = function (knex) { table.date('time_limited_start_date') table.date('time_limited_end_date') table.text('notes') - table.decimal('instant_quantity') - table.decimal('daily_quantity') - table.decimal('hourly_quantity') - table.decimal('annual_quantity') + table.decimal('instant_quantity', null, null) + table.decimal('daily_quantity', null, null) + table.decimal('hourly_quantity', null, null) + table.decimal('annual_quantity', null, null) table.string('external_id').notNullable() table.boolean('is_test').notNullable().default(false) diff --git a/test/services/import/persist-licence-versions.service.test.js b/test/services/import/persist-licence-versions.service.test.js index 72b6283bf3..44e1f687c6 100644 --- a/test/services/import/persist-licence-versions.service.test.js +++ b/test/services/import/persist-licence-versions.service.test.js @@ -19,7 +19,7 @@ const SecondaryPurposeHelper = require('../../support/helpers/secondary-purpose. const PersistLicenceVersionsService = require('../../../app/services/import/persist-licence-versions.service.js') -describe('Persist licence versions and licence versions purposes service', () => { +describe.only('Persist licence versions and licence versions purposes service', () => { let licence let licenceVersion let licenceVersionsPurpose @@ -51,7 +51,7 @@ describe('Persist licence versions and licence versions purposes service', () => describe('when the licence version does not exist', () => { it('returns the updated licence version', async () => { - const [result] = await PersistLicenceVersionsService.go(licenceVersionsAndPurposes, licence.id) + await PersistLicenceVersionsService.go(licenceVersionsAndPurposes, licence.id) const savedLicenceVersion = await LicenceVersionModel.query() .select('*') @@ -60,11 +60,11 @@ describe('Persist licence versions and licence versions purposes service', () => const [savedLicenceVersionPurpose] = savedLicenceVersion.licenceVersionPurposes - expect(result).to.equal({ - createdAt: savedLicenceVersion.createdAt.toISOString(), - endDate: '2002-01-01', + expect(savedLicenceVersion).to.equal({ + createdAt: savedLicenceVersion.createdAt, + endDate: new Date('2002-01-01'), externalId: licenceVersion.externalId, - id: result.id, + id: savedLicenceVersion.id, increment: 0, issue: 100, licenceId: licence.id, @@ -79,21 +79,21 @@ describe('Persist licence versions and licence versions purposes service', () => abstractionPeriodStartMonth: 4, abstractionPeriodEndDay: 31, abstractionPeriodEndMonth: 3, - timeLimitedStartDate: '2001-01-03', - timeLimitedEndDate: '2001-01-02', + timeLimitedStartDate: new Date('2001-01-03'), + timeLimitedEndDate: new Date('2001-01-02'), notes: ' a note on purposes', instantQuantity: 120, dailyQuantity: 1500.2, hourlyQuantity: 140.929, annualQuantity: 545520, externalId: licenceVersionsPurpose.externalId, - createdAt: savedLicenceVersionPurpose.createdAt.toISOString(), - updatedAt: savedLicenceVersionPurpose.updatedAt.toISOString() + createdAt: savedLicenceVersionPurpose.createdAt, + updatedAt: savedLicenceVersionPurpose.updatedAt } ], - startDate: '2001-01-01', + startDate: new Date('2001-01-01'), status: 'superseded', - updatedAt: savedLicenceVersion.updatedAt.toISOString() + updatedAt: savedLicenceVersion.updatedAt }) }) @@ -108,21 +108,20 @@ describe('Persist licence versions and licence versions purposes service', () => }) it('does not return purposes', async () => { - const [result] = await PersistLicenceVersionsService.go(licenceVersionsAndPurposes, licence.id) + await PersistLicenceVersionsService.go(licenceVersionsAndPurposes, licence.id) const savedLicenceVersionPurposes = await LicenceVersionModel.query() .select('*') .where('externalId', licenceVersion.externalId).first() .withGraphFetched('licenceVersionPurposes') - expect(result.purposes).to.equal([]) expect(savedLicenceVersionPurposes.licenceVersionPurposes).to.equal([]) }) }) describe('and has "purposes"', () => { it('returns the created purposes', async () => { - const [result] = await PersistLicenceVersionsService.go(licenceVersionsAndPurposes, licence.id) + await PersistLicenceVersionsService.go(licenceVersionsAndPurposes, licence.id) const savedLicenceVersionPurposes = await LicenceVersionModel.query() .select('*') @@ -131,7 +130,7 @@ describe('Persist licence versions and licence versions purposes service', () => const [savedLicenceVersionPurpose] = savedLicenceVersionPurposes.licenceVersionPurposes - expect(result.purposes).to.equal([ + expect(savedLicenceVersionPurposes.licenceVersionPurposes).to.equal([ { id: savedLicenceVersionPurpose.id, licenceVersionId: savedLicenceVersionPurpose.licenceVersionId, @@ -142,22 +141,110 @@ describe('Persist licence versions and licence versions purposes service', () => abstractionPeriodStartMonth: 4, abstractionPeriodEndDay: 31, abstractionPeriodEndMonth: 3, - timeLimitedStartDate: '2001-01-03', - timeLimitedEndDate: '2001-01-02', + timeLimitedStartDate: new Date('2001-01-03'), + timeLimitedEndDate: new Date('2001-01-02'), notes: ' a note on purposes', instantQuantity: 120, dailyQuantity: 1500.2, hourlyQuantity: 140.929, annualQuantity: 545520, externalId: licenceVersionsPurpose.externalId, - createdAt: savedLicenceVersionPurpose.createdAt.toISOString(), - updatedAt: savedLicenceVersionPurpose.updatedAt.toISOString() + createdAt: savedLicenceVersionPurpose.createdAt, + updatedAt: savedLicenceVersionPurpose.updatedAt } ]) }) }) }) + describe('when the licence version has multiple increments', () => { + let licenceVersionsAndPurposesUpdated + // There is a convention where the increment is updated in the third number of an external id. + // This as far as we can tell is the only element in the id that changes + // This test has been added to highlight this 'functionality' from the nald data. + let updatedExternalId + + beforeEach(async () => { + await PersistLicenceVersionsService.go(licenceVersionsAndPurposes, licence.id) + + const parts = licenceVersion.externalId.split(':') + + parts[2] = '2' + updatedExternalId = parts.join(':') + + licenceVersionsAndPurposesUpdated = [ + { + ...licenceVersion, + purposes: [{ ...licenceVersionsPurpose }], + externalId: updatedExternalId, + increment: 2 + } + ] + }) + + it('returns the licence versions with multiple increments', async () => { + await PersistLicenceVersionsService.go(licenceVersionsAndPurposesUpdated, licence.id) + + const savedLicenceVersions = await LicenceVersionModel.query() + .select('*') + .where('licenceId', licence.id).orderBy('increment', 'asc') + .withGraphFetched('licenceVersionPurposes') + + const [savedLicenceVersionOne, savedLicenceVersionTwo] = savedLicenceVersions + + expect(savedLicenceVersions).to.equal([ + { + createdAt: savedLicenceVersionOne.createdAt, + endDate: new Date('2002-01-01'), + externalId: licenceVersion.externalId, + id: savedLicenceVersionOne.id, + increment: 0, + issue: 100, + licenceId: licence.id, + licenceVersionPurposes: [ + { + abstractionPeriodEndDay: 31, + abstractionPeriodEndMonth: 3, + abstractionPeriodStartDay: 1, + abstractionPeriodStartMonth: 4, + annualQuantity: 545520, + createdAt: savedLicenceVersionOne.licenceVersionPurposes[0].createdAt, + dailyQuantity: 1500.2, + externalId: licenceVersionsPurpose.externalId, + hourlyQuantity: 140.929, + id: savedLicenceVersionOne.licenceVersionPurposes[0].id, + instantQuantity: 120, + licenceVersionId: savedLicenceVersionOne.id, + notes: ' a note on purposes', + primaryPurposeId: primaryPurpose.id, + purposeId: purpose.id, + secondaryPurposeId: secondaryPurpose.id, + timeLimitedEndDate: new Date('2001-01-02'), + timeLimitedStartDate: new Date(' 2001-01-03'), + updatedAt: savedLicenceVersionOne.licenceVersionPurposes[0].updatedAt + } + ], + startDate: new Date('2001-01-01'), + status: 'superseded', + updatedAt: savedLicenceVersionOne.updatedAt + }, + { + createdAt: savedLicenceVersionTwo.createdAt, + endDate: new Date('2002-01-01'), + externalId: updatedExternalId, + id: savedLicenceVersionTwo.id, + increment: 2, + issue: 100, + licenceId: licence.id, + licenceVersionPurposes: [], + startDate: new Date('2001-01-01'), + status: 'superseded', + updatedAt: savedLicenceVersionTwo.updatedAt + } + ]) + }) + }) + describe('when the licence version already exists', () => { let licenceVersionsAndPurposesUpdated @@ -168,29 +255,32 @@ describe('Persist licence versions and licence versions purposes service', () => { ...licenceVersion, purposes: [{ ...licenceVersionsPurpose }], - increment: 1 + status: 'current' } ] }) it('returns the updated licence version and purposes', async () => { - const [result] = await PersistLicenceVersionsService.go(licenceVersionsAndPurposesUpdated, licence.id) + await PersistLicenceVersionsService.go(licenceVersionsAndPurposesUpdated, licence.id) - const savedLicenceVersion = await LicenceVersionModel.query() + const savedLicenceVersions = await LicenceVersionModel.query() .select('*') - .where('externalId', licenceVersion.externalId).first() + .where('externalId', licenceVersion.externalId) .withGraphFetched('licenceVersionPurposes') + const savedLicenceVersion = savedLicenceVersions[0] + const [savedLicenceVersionPurpose] = savedLicenceVersion.licenceVersionPurposes - expect(result).to.equal({ - endDate: '2002-01-01', + expect(savedLicenceVersion).to.equal({ + createdAt: savedLicenceVersion.createdAt, + endDate: new Date('2002-01-01'), externalId: licenceVersion.externalId, - id: result.id, - increment: 1, + id: savedLicenceVersion.id, + increment: 0, issue: 100, licenceId: licence.id, - purposes: [ + licenceVersionPurposes: [ { id: savedLicenceVersionPurpose.id, licenceVersionId: savedLicenceVersionPurpose.licenceVersionId, @@ -201,28 +291,35 @@ describe('Persist licence versions and licence versions purposes service', () => abstractionPeriodStartMonth: 4, abstractionPeriodEndDay: 31, abstractionPeriodEndMonth: 3, - timeLimitedStartDate: '2001-01-03', - timeLimitedEndDate: '2001-01-02', + timeLimitedStartDate: new Date('2001-01-03'), + timeLimitedEndDate: new Date('2001-01-02'), notes: ' a note on purposes', instantQuantity: 120, dailyQuantity: 1500.2, hourlyQuantity: 140.929, annualQuantity: 545520, externalId: licenceVersionsPurpose.externalId, - createdAt: savedLicenceVersionPurpose.createdAt.toISOString(), - updatedAt: savedLicenceVersionPurpose.updatedAt.toISOString() + createdAt: savedLicenceVersionPurpose.createdAt, + updatedAt: savedLicenceVersionPurpose.updatedAt } ], - startDate: '2001-01-01', - status: 'superseded', - updatedAt: savedLicenceVersion.updatedAt.toISOString() - }, { skip: ['createdAt'] }) + startDate: new Date('2001-01-01'), + status: 'current', + updatedAt: savedLicenceVersion.updatedAt + }) }) - it('returns the updated licence version increment', async () => { - const [result] = await PersistLicenceVersionsService.go(licenceVersionsAndPurposesUpdated, licence.id) + it('returns the updated licence version status', async () => { + await PersistLicenceVersionsService.go(licenceVersionsAndPurposesUpdated, licence.id) + + const savedLicenceVersions = await LicenceVersionModel.query() + .select('*') + .where('externalId', licenceVersion.externalId) + .withGraphFetched('licenceVersionPurposes') - expect(result.increment).to.equal(1) + const savedLicenceVersion = savedLicenceVersions[0] + + expect(savedLicenceVersion.status).to.equal('current') }) describe('and does not have purposes', () => { @@ -233,32 +330,30 @@ describe('Persist licence versions and licence versions purposes service', () => }) it('returns the updated licence version and no purposes', async () => { - const [result] = await PersistLicenceVersionsService.go(licenceVersionsAndPurposesUpdated, licence.id) + await PersistLicenceVersionsService.go(licenceVersionsAndPurposesUpdated, licence.id) const savedLicenceVersion = await LicenceVersionModel.query() .select('*') .where('externalId', licenceVersion.externalId).first() - expect(result).to.equal({ - endDate: '2002-01-01', + expect(savedLicenceVersion).to.equal({ + createdAt: savedLicenceVersion.createdAt, + endDate: new Date('2002-01-01'), externalId: licenceVersion.externalId, - id: result.id, - increment: 1, + id: savedLicenceVersion.id, + increment: 0, issue: 100, licenceId: licence.id, - purposes: [], - startDate: '2001-01-01', - status: 'superseded', - updatedAt: savedLicenceVersion.updatedAt.toISOString() - }, { skip: ['createdAt'] }) - - expect(result.increment).to.equal(1) + startDate: new Date('2001-01-01'), + status: 'current', + updatedAt: savedLicenceVersion.updatedAt + }) }) }) describe('and has purposes', () => { it('returns the updated licence version purposes', async () => { - const [result] = await PersistLicenceVersionsService.go(licenceVersionsAndPurposesUpdated, licence.id) + await PersistLicenceVersionsService.go(licenceVersionsAndPurposesUpdated, licence.id) const savedLicenceVersion = await LicenceVersionModel.query() .select('*') @@ -267,8 +362,9 @@ describe('Persist licence versions and licence versions purposes service', () => const [savedLicenceVersionPurpose] = savedLicenceVersion.licenceVersionPurposes - expect(result.purposes).to.equal([ + expect(savedLicenceVersion.licenceVersionPurposes).to.equal([ { + createdAt: savedLicenceVersionPurpose.createdAt, id: savedLicenceVersionPurpose.id, licenceVersionId: savedLicenceVersionPurpose.licenceVersionId, primaryPurposeId: primaryPurpose.id, @@ -278,34 +374,33 @@ describe('Persist licence versions and licence versions purposes service', () => abstractionPeriodStartMonth: 4, abstractionPeriodEndDay: 31, abstractionPeriodEndMonth: 3, - timeLimitedStartDate: '2001-01-03', - timeLimitedEndDate: '2001-01-02', + timeLimitedStartDate: new Date('2001-01-03'), + timeLimitedEndDate: new Date('2001-01-02'), notes: ' a note on purposes', instantQuantity: 120, dailyQuantity: 1500.2, hourlyQuantity: 140.929, annualQuantity: 545520, externalId: licenceVersionsPurpose.externalId, - updatedAt: savedLicenceVersionPurpose.updatedAt.toISOString() + updatedAt: savedLicenceVersionPurpose.updatedAt } - ], { skip: ['createdAt'] }) - - expect(result.increment).to.equal(1) - }) + ] + ) - it('checks the purposes id, primary purpose id and secondary purpose id match the legacy id provided', async () => { - await PersistLicenceVersionsService.go(licenceVersionsAndPurposesUpdated, licence.id) + it('checks the purposes id, primary purpose id and secondary purpose id match the legacy id provided', async () => { + await PersistLicenceVersionsService.go(licenceVersionsAndPurposesUpdated, licence.id) - const savedLicenceVersion = await LicenceVersionModel.query() - .select('*') - .where('externalId', licenceVersion.externalId).first() - .withGraphFetched('licenceVersionPurposes') + const savedLicenceVersion = await LicenceVersionModel.query() + .select('*') + .where('externalId', licenceVersion.externalId).first() + .withGraphFetched('licenceVersionPurposes') - const [savedLicenceVersionPurpose] = savedLicenceVersion.licenceVersionPurposes + const [savedLicenceVersionPurpose] = savedLicenceVersion.licenceVersionPurposes - expect(savedLicenceVersionPurpose.primaryPurposeId).to.equal(primaryPurpose.id) - expect(savedLicenceVersionPurpose.secondaryPurposeId).to.equal(secondaryPurpose.id) - expect(savedLicenceVersionPurpose.purposeId).to.equal(purpose.id) + expect(savedLicenceVersionPurpose.primaryPurposeId).to.equal(primaryPurpose.id) + expect(savedLicenceVersionPurpose.secondaryPurposeId).to.equal(secondaryPurpose.id) + expect(savedLicenceVersionPurpose.purposeId).to.equal(purpose.id) + }) }) }) }) diff --git a/test/services/import/persist-licence.service.test.js b/test/services/import/persist-licence.service.test.js index 4f804bb0a3..c4fdee9446 100644 --- a/test/services/import/persist-licence.service.test.js +++ b/test/services/import/persist-licence.service.test.js @@ -30,15 +30,18 @@ describe('Persist licence service', () => { describe('when the licence ref does not exist', () => { it('returns the created licence', async () => { - const results = await PersistLicenceService.go(licence) + await PersistLicenceService.go(licence) const savedLicence = await LicenceModel.query() .select('*') .where('licenceRef', licence.licenceRef).first() - expect(results).to.equal({ - expiredDate: '2015-03-31', + expect(savedLicence).to.equal({ + createdAt: savedLicence.createdAt, + expiredDate: new Date('2015-03-31'), id: savedLicence.id, + includeInPresrocBilling: 'no', + includeInSrocBilling: false, lapsedDate: null, licenceRef: licence.licenceRef, regionId: region.id, @@ -49,8 +52,9 @@ describe('Persist licence service', () => { standardUnitChargeCode: 'YORKI' }, revokedDate: null, - startDate: '2005-06-03', - updatedAt: savedLicence.updatedAt.toISOString(), + startDate: new Date('2005-06-03'), + suspendFromBilling: false, + updatedAt: savedLicence.updatedAt, waterUndertaker: false } ) @@ -64,7 +68,7 @@ describe('Persist licence service', () => { }) it('returns newly updated licence', async () => { - const results = await PersistLicenceService.go({ + await PersistLicenceService.go({ licenceRef: licence.licenceRef, naldRegionId: region.naldRegionId, // not null constraints @@ -77,10 +81,13 @@ describe('Persist licence service', () => { .select('*') .where('licenceRef', licence.licenceRef).first() - expect(results).to.equal({ - expiredDate: undefined, + expect(savedLicence).to.equal({ + createdAt: savedLicence.createdAt, + expiredDate: null, id: savedLicence.id, - lapsedDate: undefined, + includeInPresrocBilling: 'no', + includeInSrocBilling: false, + lapsedDate: null, licenceRef: licence.licenceRef, regionId: region.id, regions: { @@ -89,13 +96,14 @@ describe('Persist licence service', () => { regionalChargeArea: 'Yorkshire', standardUnitChargeCode: 'YORKI' }, - revokedDate: undefined, - startDate: '2005-06-03', - updatedAt: savedLicence.updatedAt.toISOString(), + revokedDate: null, + startDate: new Date('2005-06-03'), + suspendFromBilling: false, + updatedAt: savedLicence.updatedAt, waterUndertaker: true }) - expect(results.waterUndertaker).to.be.true() + expect(savedLicence.waterUndertaker).to.be.true() }) }) }) From 29d1d851d0c10d1213173cae6bb6666e8c94f84b Mon Sep 17 00:00:00 2001 From: jonathangoulding Date: Fri, 9 Aug 2024 16:00:30 +0100 Subject: [PATCH 60/75] fix: persist licence version does not need to return anything adjust the tests accordingly. --- test/services/import/persist-licence-versions.service.test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/services/import/persist-licence-versions.service.test.js b/test/services/import/persist-licence-versions.service.test.js index 44e1f687c6..de150fdb53 100644 --- a/test/services/import/persist-licence-versions.service.test.js +++ b/test/services/import/persist-licence-versions.service.test.js @@ -19,7 +19,7 @@ const SecondaryPurposeHelper = require('../../support/helpers/secondary-purpose. const PersistLicenceVersionsService = require('../../../app/services/import/persist-licence-versions.service.js') -describe.only('Persist licence versions and licence versions purposes service', () => { +describe('Persist licence versions and licence versions purposes service', () => { let licence let licenceVersion let licenceVersionsPurpose @@ -68,7 +68,7 @@ describe.only('Persist licence versions and licence versions purposes service', increment: 0, issue: 100, licenceId: licence.id, - purposes: [ + licenceVersionPurposes: [ { id: savedLicenceVersionPurpose.id, licenceVersionId: savedLicenceVersionPurpose.licenceVersionId, From 60930dcde654cdf179f10ae9298b25a35c10e0a0 Mon Sep 17 00:00:00 2001 From: jonathangoulding Date: Fri, 9 Aug 2024 16:05:23 +0100 Subject: [PATCH 61/75] chore: fix lint --- .../fetch-licence-versions.service.js | 53 ++++++++++--------- 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/app/services/import/legacy-import/fetch-licence-versions.service.js b/app/services/import/legacy-import/fetch-licence-versions.service.js index 896c4f3b1d..83230d8c05 100644 --- a/app/services/import/legacy-import/fetch-licence-versions.service.js +++ b/app/services/import/legacy-import/fetch-licence-versions.service.js @@ -48,32 +48,33 @@ async function go (licenceData) { async function _getLicenceVersions (licenceId, regionCode) { const query = ` - SELECT versions."EFF_END_DATE", - versions."EFF_ST_DATE", - versions."INCR_NO", - versions."ISSUE_NO", - versions."STATUS", - versions."FGAC_REGION_CODE", - versions."AABL_ID", - (SELECT json_agg(json_build_object( - 'PERIOD_END_DAY', purposes."PERIOD_END_DAY", - 'PERIOD_END_MONTH', purposes."PERIOD_END_MONTH", - 'PERIOD_ST_DAY', purposes."PERIOD_ST_DAY", - 'PERIOD_ST_MONTH', purposes."PERIOD_ST_MONTH", - 'ANNUAL_QTY', purposes."ANNUAL_QTY", - 'DAILY_QTY', purposes."DAILY_QTY", - 'FGAC_REGION_CODE', purposes."FGAC_REGION_CODE", - 'ID', purposes."ID", - 'HOURLY_QTY', purposes."HOURLY_QTY", - 'INST_QTY', purposes."INST_QTY", - 'NOTES', purposes."NOTES", - 'APUR_APPR_CODE', purposes."APUR_APPR_CODE", - 'APUR_APSE_CODE', purposes."APUR_APSE_CODE", - 'APUR_APUS_CODE', purposes."APUR_APUS_CODE", - 'TIMELTD_END_DATE', purposes."TIMELTD_END_DATE", - 'TIMELTD_ST_DATE', purposes."TIMELTD_ST_DATE" - ) - ) + SELECT + versions."EFF_END_DATE", + versions."EFF_ST_DATE", + versions."INCR_NO", + versions."ISSUE_NO", + versions."STATUS", + versions."FGAC_REGION_CODE", + versions."AABL_ID", + (SELECT json_agg(json_build_object( + 'PERIOD_END_DAY', purposes."PERIOD_END_DAY", + 'PERIOD_END_MONTH', purposes."PERIOD_END_MONTH", + 'PERIOD_ST_DAY', purposes."PERIOD_ST_DAY", + 'PERIOD_ST_MONTH', purposes."PERIOD_ST_MONTH", + 'ANNUAL_QTY', purposes."ANNUAL_QTY", + 'DAILY_QTY', purposes."DAILY_QTY", + 'FGAC_REGION_CODE', purposes."FGAC_REGION_CODE", + 'ID', purposes."ID", + 'HOURLY_QTY', purposes."HOURLY_QTY", + 'INST_QTY', purposes."INST_QTY", + 'NOTES', purposes."NOTES", + 'APUR_APPR_CODE', purposes."APUR_APPR_CODE", + 'APUR_APSE_CODE', purposes."APUR_APSE_CODE", + 'APUR_APUS_CODE', purposes."APUR_APUS_CODE", + 'TIMELTD_END_DATE', purposes."TIMELTD_END_DATE", + 'TIMELTD_ST_DATE', purposes."TIMELTD_ST_DATE" + ) + ) FROM import."NALD_ABS_LIC_PURPOSES" purposes WHERE purposes."AABV_AABL_ID" = versions."AABL_ID" AND purposes."AABV_ISSUE_NO" = versions."ISSUE_NO" From 77f8e76f19a138dd9c3f55049edd351cfd3ec192 Mon Sep 17 00:00:00 2001 From: jonathangoulding Date: Fri, 9 Aug 2024 16:51:37 +0100 Subject: [PATCH 62/75] fix: persist licence test - persist should return the licence --- .../import/persist-licence.service.js | 2 +- .../import/legacy-licence.service.test.js | 8 +++-- .../import/persist-licence.service.test.js | 30 +++++++++++++++++-- 3 files changed, 34 insertions(+), 6 deletions(-) diff --git a/app/services/import/persist-licence.service.js b/app/services/import/persist-licence.service.js index 33317a506e..c63e6762c7 100644 --- a/app/services/import/persist-licence.service.js +++ b/app/services/import/persist-licence.service.js @@ -26,7 +26,7 @@ async function go (licence) { .limit(1) .first() - await LicenceModel.query() + return LicenceModel.query() .insert({ expiredDate, waterUndertaker, diff --git a/test/services/import/legacy-licence.service.test.js b/test/services/import/legacy-licence.service.test.js index 9441de1b73..efc83e87b3 100644 --- a/test/services/import/legacy-licence.service.test.js +++ b/test/services/import/legacy-licence.service.test.js @@ -48,6 +48,8 @@ describe('Legacy import licence service', () => { }) Sinon.stub(FetchLegacyImportLicenceVersionsService, 'go').resolves(licenceVersions) + + global.GlobalNotifier = { omfg: Sinon.stub() } }) describe('the "licence" data is imported and saved to the database', () => { @@ -103,7 +105,7 @@ describe('Legacy import licence service', () => { expect(licenceVersion).to.equal( { - createdAt: new Date(licenceVersion.createdAt), + createdAt: licenceVersion.createdAt, endDate: new Date('2007-06-04'), externalId: '3:10000003:100:0', id: licenceVersion.id, @@ -112,7 +114,7 @@ describe('Legacy import licence service', () => { licenceId: licence.id, startDate: new Date('2005-06-05'), status: 'superseded', - updatedAt: new Date(licenceVersion.updatedAt) + updatedAt: licenceVersion.updatedAt }) }) @@ -163,7 +165,7 @@ describe('Legacy import licence service', () => { notes: null, instantQuantity: null, dailyQuantity: 1500.2, - hourlyQuantity: 140.93, + hourlyQuantity: 140.929, annualQuantity: 545520, externalId: '3:10000004', createdAt: new Date(licenceVersionPurpose.createdAt), diff --git a/test/services/import/persist-licence.service.test.js b/test/services/import/persist-licence.service.test.js index c4fdee9446..6dd5f1ef15 100644 --- a/test/services/import/persist-licence.service.test.js +++ b/test/services/import/persist-licence.service.test.js @@ -28,8 +28,34 @@ describe('Persist licence service', () => { }) }) + it('returns the licence', async () => { + const result = await PersistLicenceService.go(licence) + + const savedLicence = await LicenceModel.query() + .select('*') + .where('licenceRef', licence.licenceRef).first() + + expect(result).to.equal({ + expiredDate: '2015-03-31', + id: savedLicence.id, + lapsedDate: null, + licenceRef: licence.licenceRef, + regionId: region.id, + regions: { + historicalAreaCode: 'RIDIN', + localEnvironmentAgencyPlanCode: 'AIREL', + regionalChargeArea: 'Yorkshire', + standardUnitChargeCode: 'YORKI' + }, + revokedDate: null, + startDate: '2005-06-03', + updatedAt: savedLicence.updatedAt.toISOString(), + waterUndertaker: false + }) + }) + describe('when the licence ref does not exist', () => { - it('returns the created licence', async () => { + it('creates the licence', async () => { await PersistLicenceService.go(licence) const savedLicence = await LicenceModel.query() @@ -67,7 +93,7 @@ describe('Persist licence service', () => { await PersistLicenceService.go(licence) }) - it('returns newly updated licence', async () => { + it('updates the licence', async () => { await PersistLicenceService.go({ licenceRef: licence.licenceRef, naldRegionId: region.naldRegionId, From 67a9ab963bfec7ec58cbbe44e3ac52fcae95da66 Mon Sep 17 00:00:00 2001 From: jonathangoulding Date: Fri, 9 Aug 2024 17:01:17 +0100 Subject: [PATCH 63/75] chore: lint / fix js docs --- .../legacy-import/fetch-licence-versions.service.js | 2 +- .../import/legacy-import/licence-versions.mapper.js | 4 ++-- app/services/import/legacy-import/licence.mapper.js | 10 +++++----- app/services/import/licence-validator.service.js | 4 ++-- .../import/persist-licence-versions.service.js | 4 ++-- app/services/import/persist-licence.service.js | 6 ++++++ app/validators/import/licence.validator.js | 2 +- 7 files changed, 19 insertions(+), 13 deletions(-) diff --git a/app/services/import/legacy-import/fetch-licence-versions.service.js b/app/services/import/legacy-import/fetch-licence-versions.service.js index 83230d8c05..04e3333e65 100644 --- a/app/services/import/legacy-import/fetch-licence-versions.service.js +++ b/app/services/import/legacy-import/fetch-licence-versions.service.js @@ -11,7 +11,7 @@ const { db } = require('../../../../db/db.js') * * Returns the legacy licence version purposes. * - * @param { object } licenceData - The data related to the licence. + * @param {object} licenceData - The data related to the licence. * @returns {Promise } licenceVersions - the legacy licence versions and purposes - * @returns { array } - mapped licence versions + * @param {object[]} licenceVersions - the legacy licence versions and purposes + * @returns {object[]} - mapped licence versions */ function go (licenceVersions) { return _mapLicenceVersions(licenceVersions) diff --git a/app/services/import/legacy-import/licence.mapper.js b/app/services/import/legacy-import/licence.mapper.js index ff6501b857..0a7a10e6d3 100644 --- a/app/services/import/legacy-import/licence.mapper.js +++ b/app/services/import/legacy-import/licence.mapper.js @@ -11,9 +11,9 @@ const { naldRegions } = require('../../../lib/static-lookups.lib.js') /** * Maps the import data to the desired format * - * @param { object} licence - the legacy licence - * @param { array } licenceVersions - the legacy licence versions and purposes - * @returns { object } + * @param {object} licence - the legacy licence + * @param {object[]} licenceVersions - the legacy licence versions and purposes + * @returns {object} */ function go (licence, licenceVersions = []) { return _mapLicence(licence, licenceVersions) @@ -54,8 +54,8 @@ const _regions = (licenceData) => { * * It is assumed one of these will always exist * - * @param { object } licence - * @param { array } licenceVersions + * @param {object} licence - the legacy licence data + * @param {object[]} licenceVersions - the legacy licence versions * @return {String} YYYY-MM-DD */ const _startDate = (licence, licenceVersions) => { diff --git a/app/services/import/licence-validator.service.js b/app/services/import/licence-validator.service.js index da7e8cc98a..ce05a50d8a 100644 --- a/app/services/import/licence-validator.service.js +++ b/app/services/import/licence-validator.service.js @@ -13,8 +13,8 @@ const ImportLicenceVersionsValidator = require('../../validators/import/licence- * * If the validation fails throw an error * - * @param { object } licence - The licence to validate - * @param { array } licenceVersions - The licence versions to validate + * @param {object} licence - The licence to validate + * @param {object[]} licenceVersions - The licence versions to validate */ function go (licence, licenceVersions) { ImportLicenceValidator.go(licence) diff --git a/app/services/import/persist-licence-versions.service.js b/app/services/import/persist-licence-versions.service.js index 37a02a3c0a..c90ca45f07 100644 --- a/app/services/import/persist-licence-versions.service.js +++ b/app/services/import/persist-licence-versions.service.js @@ -14,8 +14,8 @@ const PurposeModel = require('../../models/purpose.model.js') /** * Saves the licence versions, purposes and conditions * - * @param { array } licenceVersions - * @param { string } licenceId + * @param {object[]} licenceVersions + * @param {string} licenceId */ async function go (licenceVersions, licenceId) { await Promise.all(licenceVersions.map(async (version) => { diff --git a/app/services/import/persist-licence.service.js b/app/services/import/persist-licence.service.js index c63e6762c7..e84b32d4e5 100644 --- a/app/services/import/persist-licence.service.js +++ b/app/services/import/persist-licence.service.js @@ -8,6 +8,12 @@ const LicenceModel = require('../../models/licence.model.js') const RegionModel = require('../../models/region.model.js') +/** + * Saves the licence versions, purposes and conditions + * + * @param {object} licence - the mapped and validated licence to persist + * @returns {Promise} + */ async function go (licence) { const { expiredDate, diff --git a/app/validators/import/licence.validator.js b/app/validators/import/licence.validator.js index feb81710db..36f5d7fa2c 100644 --- a/app/validators/import/licence.validator.js +++ b/app/validators/import/licence.validator.js @@ -24,7 +24,7 @@ const Joi = require('joi') * startDate: string, * waterUndertaker: boolean * }} data - The mapped licence data - * @returns { void } + * @returns {void} * @throws {Error} - throw an error if any of the validations fail */ From d0e6276f71aaf94f0d907e98eadc5f09f4dfc2b6 Mon Sep 17 00:00:00 2001 From: jonathangoulding Date: Mon, 12 Aug 2024 08:54:34 +0100 Subject: [PATCH 64/75] refactor: add specific date sort for licence mapper start date --- app/services/import/legacy-import/licence.mapper.js | 4 +++- .../import/legacy-import/licence.mapper.test.js | 13 ++++++++++--- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/app/services/import/legacy-import/licence.mapper.js b/app/services/import/legacy-import/licence.mapper.js index 0a7a10e6d3..2f634a6203 100644 --- a/app/services/import/legacy-import/licence.mapper.js +++ b/app/services/import/legacy-import/licence.mapper.js @@ -68,7 +68,9 @@ const _startDate = (licence, licenceVersions) => { .map((version) => { return formatStandardDateToISO(version.EFF_ST_DATE) }) - .sort() + .sort((a, b) => { + return new Date(a) - new Date(b) + }) .shift() } diff --git a/test/services/import/legacy-import/licence.mapper.test.js b/test/services/import/legacy-import/licence.mapper.test.js index e2cc43e275..ff4a1f40c8 100644 --- a/test/services/import/legacy-import/licence.mapper.test.js +++ b/test/services/import/legacy-import/licence.mapper.test.js @@ -147,16 +147,23 @@ describe('Legacy import licence mapper', () => { }) }) describe('when the licence ORIG_EFF_DATE is null', () => { + let licenceVersions + beforeEach(() => { licence.ORIG_EFF_DATE = 'null' + + licenceVersions = [ + { ...FixtureLegacyLicenceVersion.create(), EFF_ST_DATE: '07/07/2001' }, + // This licence version should be used by the sort as it is the earliest + { ...FixtureLegacyLicenceVersion.create(), EFF_ST_DATE: '01/01/2001' } + ] }) describe('then start date of the earliest non-draft licence version is used', () => { it('returns the start date in the ISO format', () => { - // need to add licence versions - const result = LegacyImportLicenceMapper.go(licence, [{ ...FixtureLegacyLicenceVersion.create() }]) + const result = LegacyImportLicenceMapper.go(licence, licenceVersions) - expect(result.startDate).to.equal('2005-06-05') + expect(result.startDate).to.equal('2001-01-01') }) }) }) From ba900bee4ecbcfdf919796047acba76da4f7a2a8 Mon Sep 17 00:00:00 2001 From: jonathangoulding Date: Tue, 13 Aug 2024 16:20:19 +0100 Subject: [PATCH 65/75] refactor: pair programming refactor re structure code rename modules update tests with new paths / descriptions --- app/controllers/import.controller.js | 4 +- .../legacy/licence-versions.presenter.js} | 4 +- .../import/legacy/licence.presenter.js} | 6 +- app/services/import/legacy-licence.service.js | 48 ------------ .../fetch-licence-versions.service.js | 71 ++++++++++-------- .../fetch-licence.service.js | 35 ++++++--- .../import/legacy/process-licence.service.js | 48 ++++++++++++ .../persist-licence-versions.service.js | 1 + ...service.js => validate-licence.service.js} | 2 +- test/controllers/import.controller.test.js | 2 +- .../licence-versions.presenter.test.js} | 74 +++++++++---------- .../import/legacy/licence.presenter.test.js} | 38 +++++----- .../process-licence.service.test.js} | 38 +++++----- ...st.js => validate-licence.service.test.js} | 8 +- 14 files changed, 201 insertions(+), 178 deletions(-) rename app/{services/import/legacy-import/licence-versions.mapper.js => presenters/import/legacy/licence-versions.presenter.js} (94%) rename app/{services/import/legacy-import/licence.mapper.js => presenters/import/legacy/licence.presenter.js} (92%) delete mode 100644 app/services/import/legacy-licence.service.js rename app/services/import/{legacy-import => legacy}/fetch-licence-versions.service.js (56%) rename app/services/import/{legacy-import => legacy}/fetch-licence.service.js (52%) create mode 100644 app/services/import/legacy/process-licence.service.js rename app/services/import/{licence-validator.service.js => validate-licence.service.js} (94%) rename test/{services/import/legacy-import/licence-versions.mapper.test.js => presenters/import/legacy/licence-versions.presenter.test.js} (76%) rename test/{services/import/legacy-import/licence.mapper.test.js => presenters/import/legacy/licence.presenter.test.js} (79%) rename test/services/import/{legacy-licence.service.test.js => legacy/process-licence.service.test.js} (77%) rename test/services/import/{licence-validator.service.test.js => validate-licence.service.test.js} (72%) diff --git a/app/controllers/import.controller.js b/app/controllers/import.controller.js index d1fc329dbb..9d3c6394ad 100644 --- a/app/controllers/import.controller.js +++ b/app/controllers/import.controller.js @@ -1,7 +1,7 @@ 'use strict' const FeatureFlags = require('../../config/feature-flags.config.js') -const LegacyImportLicenceService = require('../services/import/legacy-licence.service.js') +const ImportLegacyProcessLicenceService = require('../services/import/legacy/process-licence.service.js') /** * Controller for /import @@ -11,7 +11,7 @@ async function licence (request, h) { const { licenceRef } = request.payload if (FeatureFlags.enableSystemImportLegacyLicence) { - LegacyImportLicenceService.go(licenceRef) + ImportLegacyProcessLicenceService.go(licenceRef) } return h.response().code(204) diff --git a/app/services/import/legacy-import/licence-versions.mapper.js b/app/presenters/import/legacy/licence-versions.presenter.js similarity index 94% rename from app/services/import/legacy-import/licence-versions.mapper.js rename to app/presenters/import/legacy/licence-versions.presenter.js index 49226cbf94..6c4a7873e1 100644 --- a/app/services/import/legacy-import/licence-versions.mapper.js +++ b/app/presenters/import/legacy/licence-versions.presenter.js @@ -2,7 +2,7 @@ /** * Maps the import licence versions and licence versions purposes data - * @module LegacyImportLicenceVersionMapper + * @module LicenceVersionsPresenter */ const { formatStandardDateToISO } = require('../../../lib/dates.lib.js') @@ -15,7 +15,7 @@ const statuses = { /** * Maps the import licence versions data * - * @param {object[]} licenceVersions - the legacy licence versions and purposes + * @param {ImportLegacyLicenceVersionsType[]} licenceVersions - the legacy licence versions and purposes * @returns {object[]} - mapped licence versions */ function go (licenceVersions) { diff --git a/app/services/import/legacy-import/licence.mapper.js b/app/presenters/import/legacy/licence.presenter.js similarity index 92% rename from app/services/import/legacy-import/licence.mapper.js rename to app/presenters/import/legacy/licence.presenter.js index 2f634a6203..1c201cacbd 100644 --- a/app/services/import/legacy-import/licence.mapper.js +++ b/app/presenters/import/legacy/licence.presenter.js @@ -2,7 +2,7 @@ /** * Maps the import data to the desired format - * @module LegacyImportLicenceMapper + * @module LicencePresenter */ const { formatStandardDateToISO } = require('../../../lib/dates.lib.js') @@ -11,8 +11,8 @@ const { naldRegions } = require('../../../lib/static-lookups.lib.js') /** * Maps the import data to the desired format * - * @param {object} licence - the legacy licence - * @param {object[]} licenceVersions - the legacy licence versions and purposes + * @param {ImportLegacyLicenceType} licence - the legacy licence + * @param {ImportLegacyLicenceVersionsType[]} licenceVersions - the legacy licence versions and purposes * @returns {object} */ function go (licence, licenceVersions = []) { diff --git a/app/services/import/legacy-licence.service.js b/app/services/import/legacy-licence.service.js deleted file mode 100644 index 3ec932ca61..0000000000 --- a/app/services/import/legacy-licence.service.js +++ /dev/null @@ -1,48 +0,0 @@ -'use strict' - -/** - * Imports a licence from the imports tables into the views - * @module LegacyImportLicenceService - */ - -const FetchLegacyImportLicenceService = require('./legacy-import/fetch-licence.service.js') -const FetchLegacyImportLicenceVersionsService = require('./legacy-import/fetch-licence-versions.service.js') -const ImportLicenceValidatorService = require('./licence-validator.service.js') -const LegacyImportLicenceMapper = require('./legacy-import/licence.mapper.js') -const LegacyImportLicenceVersionMapper = require('./legacy-import/licence-versions.mapper.js') -const PersistLicenceService = require('./persist-licence.service.js') -const PersistLicenceVersionsService = require('./persist-licence-versions.service.js') -const { currentTimeInNanoseconds, calculateAndLogTimeTaken } = require('../../lib/general.lib.js') - -/** - * Imports a licence from the legacy import tables. Maps and validates the data and then saves to the database. - * - * @param {string} licenceRef - The licence reference of the licence - * @returns {Promise} an object representing the saved licence in the database - */ -async function go (licenceRef) { - try { - const startTime = currentTimeInNanoseconds() - - const licenceData = await FetchLegacyImportLicenceService.go(licenceRef) - - const licenceVersionsData = await FetchLegacyImportLicenceVersionsService.go(licenceData) - - const mappedLicenceData = LegacyImportLicenceMapper.go(licenceData, licenceVersionsData) - - const mappedLicenceVersionsData = LegacyImportLicenceVersionMapper.go(licenceVersionsData) - - ImportLicenceValidatorService.go(mappedLicenceData, mappedLicenceVersionsData) - - const savedLicence = await PersistLicenceService.go(mappedLicenceData) - - await PersistLicenceVersionsService.go(mappedLicenceVersionsData, savedLicence.id) - calculateAndLogTimeTaken(startTime, 'Process licence', { licenceRef }) - } catch (error) { - global.GlobalNotifier.omfg('Licence import failed', { licenceRef }, error) - } -} - -module.exports = { - go -} diff --git a/app/services/import/legacy-import/fetch-licence-versions.service.js b/app/services/import/legacy/fetch-licence-versions.service.js similarity index 56% rename from app/services/import/legacy-import/fetch-licence-versions.service.js rename to app/services/import/legacy/fetch-licence-versions.service.js index 04e3333e65..daccae8687 100644 --- a/app/services/import/legacy-import/fetch-licence-versions.service.js +++ b/app/services/import/legacy/fetch-licence-versions.service.js @@ -2,43 +2,19 @@ /** * Service for /import/licence - * @module FetchLegacyImportLicenceVersionsService + * @module FetchLicenceVersionsService */ + const { db } = require('../../../../db/db.js') /** * Gets the legacy licence versions * - * Returns the legacy licence version purposes. + * Returns the legacy licence version and purposes. + * + * @param {ImportLegacyLicenceType} licenceData - The data related to the licence. * - * @param {object} licenceData - The data related to the licence. - * @returns {Promise>} + * @returns {Promise} */ async function go (licenceData) { const { ID: licenceId, FGAC_REGION_CODE: regionCode } = licenceData @@ -94,3 +70,38 @@ async function _getLicenceVersions (licenceId, regionCode) { module.exports = { go } + +/** + * A legacy licence version + * @typedef {Object} ImportLegacyLicenceVersionsType + * + * @property {string} EFF_END_DATE - date in UK format - can be 'null' + * @property {string} EFF_ST_DATE - date in UK format + * @property {string} INCR_NO - a number between 1 - 5 + * @property {string} ISSUE_NO - a number + * @property {string} STATUS - enum - 'DRAFT', 'SUPER', 'CURR' (Draft will not be selected) + * @property {string} FGAC_REGION_CODE + * @property {string} AABL_ID + * @property {ImportLegacyLicenceVersionsPurposesType} purposes + */ + +/** + * @typedef {Object} ImportLegacyLicenceVersionsPurposesType + * + * @property {string} PERIOD_END_DAY - The end day of the period. + * @property {string} PERIOD_END_MONTH - The end month of the period. + * @property {string} PERIOD_ST_DAY - The start day of the period. + * @property {string} PERIOD_ST_MONTH - The start month of the period. + * @property {string} ANNUAL_QTY - The annual quantity. + * @property {string} DAILY_QTY - The daily quantity. + * @property {string} FGAC_REGION_CODE - The FGAC region code. + * @property {string} ID + * @property {string} HOURLY_QTY - The hourly quantity. + * @property {string} INST_QTY - The instant quantity. + * @property {string} NOTES - Additional notes. + * @property {string} APUR_APPR_CODE - The APUR approval code. + * @property {string} APUR_APSE_CODE - The APUR secondary code. + * @property {string} APUR_APUS_CODE - The APUR usage code. + * @property {string} TIMELTD_END_DATE - The time-limited end date. + * @property {string} TIMELTD_ST_DATE - The time-limited start date. + */ diff --git a/app/services/import/legacy-import/fetch-licence.service.js b/app/services/import/legacy/fetch-licence.service.js similarity index 52% rename from app/services/import/legacy-import/fetch-licence.service.js rename to app/services/import/legacy/fetch-licence.service.js index 3beaa9af4e..6947b717cf 100644 --- a/app/services/import/legacy-import/fetch-licence.service.js +++ b/app/services/import/legacy/fetch-licence.service.js @@ -2,25 +2,17 @@ /** * Service for /import/licence - * @module FetchLegacyImportLicenceService + * @module FetchLicenceService */ + const { db } = require('../../../../db/db.js') /** * Fetches the licence data for the licence ref from the import.NALD_ABS_LICENCES table * * @param {string} licenceRef - the licence ref - * @returns {Promise} - A promise that resolves to an object with the following properties: - * - {string} AREP_AREA_CODE - regions - historicalAreaCode - * - {string} AREP_EIUC_CODE - regions - regionPrefix / regionalChargeArea - * - {string} AREP_LEAP_CODE - regions - localEnvironmentAgencyPlanCode - * - {string} AREP_SUC_CODE - regions - standardUnitChargeCode - * - {string} EXPIRY_DATE - * - {string} ID - * - {string} LAPSED_DATE - * - {string} LIC_NO - * - {string} ORIG_EFF_DATE - * - {string} REV_DATE + * + * @returns {Promise} */ async function go (licenceRef) { return _getLicenceByRef(licenceRef) @@ -52,3 +44,22 @@ async function _getLicenceByRef (licenceRef) { module.exports = { go } + +/** + * An Import legacy licence + * + * @typedef {Object} ImportLegacyLicenceType + * + * @property {string} AREP_AREA_CODE - historicalAreaCode + * @property {string} AREP_EIUC_CODE - regionPrefix / regionalChargeArea + * @property {string} AREP_LEAP_CODE - localEnvironmentAgencyPlanCode + * @property {string} AREP_SUC_CODE - standardUnitChargeCode + * @property {string} AREP_AREA_CODE - regions - historicalAreaCode + * @property {string} AREP_EIUC_CODE - regions - regionPrefix / regionalChargeArea + * @property {string} AREP_LEAP_CODE - regions - localEnvironmentAgencyPlanCode + * @property {string} AREP_SUC_CODE - regions - standardUnitChargeCode + * @property {string} EXPIRY_DATE + * @property {string} ID + * @property {string} LAPSED_DATE + * @property {string} LIC_NO - Licence Ref + */ diff --git a/app/services/import/legacy/process-licence.service.js b/app/services/import/legacy/process-licence.service.js new file mode 100644 index 0000000000..ec5eaba27b --- /dev/null +++ b/app/services/import/legacy/process-licence.service.js @@ -0,0 +1,48 @@ +'use strict' + +/** + * Imports a licence from the imports tables into the views + * @module ImportLegacyProcessLicenceService + */ + +const FetchLicenceService = require('./fetch-licence.service.js') +const FetchLicenceVersionsService = require('./fetch-licence-versions.service.js') +const ValidateLicenceService = require('../validate-licence.service.js') +const LicencePresenter = require('../../../presenters/import/legacy/licence.presenter.js') +const LicenceVersionsPresenter = require('../../../presenters/import/legacy/licence-versions.presenter.js') +const PersistLicenceService = require('../persist-licence.service.js') +const PersistLicenceVersionsService = require('../persist-licence-versions.service.js') +const { currentTimeInNanoseconds, calculateAndLogTimeTaken } = require('../../../lib/general.lib.js') + +/** + * Imports a licence from the legacy import tables. Maps and validates the data and then saves to the database. + * + * @param {string} licenceRef - The licence reference of the licence + * @returns {Promise} an object representing the saved licence in the database + */ +async function go (licenceRef) { + try { + const startTime = currentTimeInNanoseconds() + + const licenceData = await FetchLicenceService.go(licenceRef) + + const licenceVersionsData = await FetchLicenceVersionsService.go(licenceData) + + const mappedLicenceData = LicencePresenter.go(licenceData, licenceVersionsData) + + const mappedLicenceVersionsData = LicenceVersionsPresenter.go(licenceVersionsData) + + ValidateLicenceService.go(mappedLicenceData, mappedLicenceVersionsData) + + const savedLicence = await PersistLicenceService.go(mappedLicenceData) + + await PersistLicenceVersionsService.go(mappedLicenceVersionsData, savedLicence.id) + calculateAndLogTimeTaken(startTime, 'Process licence', { licenceRef }) + } catch (error) { + global.GlobalNotifier.omfg('Licence import failed', { licenceRef }, error) + } +} + +module.exports = { + go +} diff --git a/app/services/import/persist-licence-versions.service.js b/app/services/import/persist-licence-versions.service.js index c90ca45f07..f33a4b0cf8 100644 --- a/app/services/import/persist-licence-versions.service.js +++ b/app/services/import/persist-licence-versions.service.js @@ -85,6 +85,7 @@ async function _saveLicenceVersion (version, licenceId) { .insert({ ...version, licenceId, + // TODO: lift out to presenters createdAt: new Date().toISOString(), updatedAt: new Date().toISOString() }) diff --git a/app/services/import/licence-validator.service.js b/app/services/import/validate-licence.service.js similarity index 94% rename from app/services/import/licence-validator.service.js rename to app/services/import/validate-licence.service.js index ce05a50d8a..6a9212b4a0 100644 --- a/app/services/import/licence-validator.service.js +++ b/app/services/import/validate-licence.service.js @@ -2,7 +2,7 @@ /** * Validates a import licence object - * @module ImportLicenceValidatorService + * @module ValidateLicenceService */ const ImportLicenceValidator = require('../../validators/import/licence.validator.js') diff --git a/test/controllers/import.controller.test.js b/test/controllers/import.controller.test.js index e83dc5b202..fbb927036b 100644 --- a/test/controllers/import.controller.test.js +++ b/test/controllers/import.controller.test.js @@ -10,7 +10,7 @@ const { expect } = Code // Things we need to stub const FeatureFlagsConfig = require('../../config/feature-flags.config.js') -const LegacyImportLicenceService = require('../../app/services/import/legacy-licence.service.js') +const LegacyImportLicenceService = require('../../app/services/import/legacy/process-licence.service.js') // For running our service const { init } = require('../../app/server.js') diff --git a/test/services/import/legacy-import/licence-versions.mapper.test.js b/test/presenters/import/legacy/licence-versions.presenter.test.js similarity index 76% rename from test/services/import/legacy-import/licence-versions.mapper.test.js rename to test/presenters/import/legacy/licence-versions.presenter.test.js index e52ea96907..806e6c2c24 100644 --- a/test/services/import/legacy-import/licence-versions.mapper.test.js +++ b/test/presenters/import/legacy/licence-versions.presenter.test.js @@ -8,14 +8,14 @@ const { describe, it, beforeEach } = exports.lab = Lab.script() const { expect } = Code // Test helpers -const FixtureLegacyLicenceVersion = require('../_fixtures/legacy-licence-version.fixture.js') -const FixtureLegacyLicenceVersionPurpose = require('../_fixtures/legacy-licence-version-purpose.fixture.js') +const FixtureLegacyLicenceVersion = require('../../../services/import/_fixtures/legacy-licence-version.fixture.js') +const FixtureLegacyLicenceVersionPurpose = require('../../../services/import/_fixtures/legacy-licence-version-purpose.fixture.js') // Thing under test -const LegacyImportLicenceVersionMapper = - require('../../../../app/services/import/legacy-import/licence-versions.mapper.js') +const LicenceVersionsPresenter = + require('../../../../app/presenters/import/legacy/licence-versions.presenter.js') -describe('Legacy import licence versions mapper', () => { +describe('Import legacy licence versions presenter', () => { let licenceVersions let purpose let version @@ -28,7 +28,7 @@ describe('Legacy import licence versions mapper', () => { }) it('returns the licence version', () => { - const results = LegacyImportLicenceVersionMapper.go(licenceVersions) + const results = LicenceVersionsPresenter.go(licenceVersions) expect(results).to.equal([{ endDate: '2007-06-04', @@ -63,7 +63,7 @@ describe('Legacy import licence versions mapper', () => { describe('the "endDate" property', () => { describe('when the licence version has EFF_END_DATE', () => { it('returns EFF_END_DATE as the start date in the correct format', () => { - const [result] = LegacyImportLicenceVersionMapper.go(licenceVersions) + const [result] = LicenceVersionsPresenter.go(licenceVersions) expect(result.endDate).to.equal('2007-06-04') }) @@ -73,7 +73,7 @@ describe('Legacy import licence versions mapper', () => { describe('the "externalId" property', () => { describe('when the licence version has FGAC_REGION_CODE, AABL_ID, ISSUE_NO, INCR_NO', () => { it('returns externalId in the format {FGAC_REGION_CODE}:{AABL_ID}:{ISSUE_NO}:{INCR_NO}', () => { - const [result] = LegacyImportLicenceVersionMapper.go(licenceVersions) + const [result] = LicenceVersionsPresenter.go(licenceVersions) expect(result.externalId).to.equal('3:10000003:100:0') }) @@ -83,7 +83,7 @@ describe('Legacy import licence versions mapper', () => { describe('the "increment" property', () => { describe('when the licence version has INCR_NO', () => { it('returns INCR_NO as a number', () => { - const [result] = LegacyImportLicenceVersionMapper.go(licenceVersions) + const [result] = LicenceVersionsPresenter.go(licenceVersions) expect(result.increment).to.be.number() expect(result.increment).to.equal(0) @@ -94,7 +94,7 @@ describe('Legacy import licence versions mapper', () => { describe('the "increment" property', () => { describe('when the licence version has INCR_NO', () => { it('returns INCR_NO as a number', () => { - const [result] = LegacyImportLicenceVersionMapper.go(licenceVersions) + const [result] = LicenceVersionsPresenter.go(licenceVersions) expect(result.increment).to.be.number() expect(result.increment).to.equal(0) @@ -105,7 +105,7 @@ describe('Legacy import licence versions mapper', () => { describe('the "issue" property', () => { describe('when the licence version has ISSUE_NO', () => { it('returns ISSUE_NO as a number', () => { - const [result] = LegacyImportLicenceVersionMapper.go(licenceVersions) + const [result] = LicenceVersionsPresenter.go(licenceVersions) expect(result.issue).to.be.number() expect(result.issue).to.equal(100) @@ -120,7 +120,7 @@ describe('Legacy import licence versions mapper', () => { }) it('returns the status as "curren"t', () => { - const [result] = LegacyImportLicenceVersionMapper.go(licenceVersions) + const [result] = LicenceVersionsPresenter.go(licenceVersions) expect(result.status).to.equal('current') }) @@ -128,7 +128,7 @@ describe('Legacy import licence versions mapper', () => { describe('when the licence version has STATUS and is SUPER', () => { it('returns the status as "superseded"', () => { - const [result] = LegacyImportLicenceVersionMapper.go(licenceVersions) + const [result] = LicenceVersionsPresenter.go(licenceVersions) expect(result.status).to.equal('superseded') }) @@ -138,7 +138,7 @@ describe('Legacy import licence versions mapper', () => { describe('the "startDate" property', () => { describe('when the licence version has EFF_ST_DATE', () => { it('returns EFF_ST_DATE as the start date in the correct format', () => { - const [result] = LegacyImportLicenceVersionMapper.go(licenceVersions) + const [result] = LicenceVersionsPresenter.go(licenceVersions) expect(result.startDate).to.equal('2005-06-05') }) @@ -149,7 +149,7 @@ describe('Legacy import licence versions mapper', () => { describe('the "abstractionPeriodEndDay" property', () => { describe('when purpose has PERIOD_END_DAY', () => { it('returns PERIOD_END_DAY as a number', () => { - const [{ purposes: [result] }] = LegacyImportLicenceVersionMapper.go(licenceVersions) + const [{ purposes: [result] }] = LicenceVersionsPresenter.go(licenceVersions) expect(result.abstractionPeriodEndDay).to.be.number() expect(result.abstractionPeriodEndDay).to.equal(31) @@ -160,7 +160,7 @@ describe('Legacy import licence versions mapper', () => { describe('the "abstractionPeriodEndMonth" property', () => { describe('when purpose has PERIOD_END_MONTH', () => { it('returns PERIOD_END_MONTH as a number', () => { - const [{ purposes: [result] }] = LegacyImportLicenceVersionMapper.go(licenceVersions) + const [{ purposes: [result] }] = LicenceVersionsPresenter.go(licenceVersions) expect(result.abstractionPeriodEndMonth).to.be.number() expect(result.abstractionPeriodEndMonth).to.equal(3) @@ -171,7 +171,7 @@ describe('Legacy import licence versions mapper', () => { describe('the "abstractionPeriodStartDay" property', () => { describe('when purpose has PERIOD_ST_DAY', () => { it('returns PERIOD_ST_DAY as a number', () => { - const [{ purposes: [result] }] = LegacyImportLicenceVersionMapper.go(licenceVersions) + const [{ purposes: [result] }] = LicenceVersionsPresenter.go(licenceVersions) expect(result.abstractionPeriodStartDay).to.be.number() expect(result.abstractionPeriodStartDay).to.equal(1) @@ -182,7 +182,7 @@ describe('Legacy import licence versions mapper', () => { describe('the "abstractionPeriodStartMonth" property', () => { describe('when purpose has PERIOD_ST_MONTH', () => { it('returns PERIOD_ST_MONTH as a number', () => { - const [{ purposes: [result] }] = LegacyImportLicenceVersionMapper.go(licenceVersions) + const [{ purposes: [result] }] = LicenceVersionsPresenter.go(licenceVersions) expect(result.abstractionPeriodStartMonth).to.be.number() expect(result.abstractionPeriodStartMonth).to.equal(4) @@ -193,7 +193,7 @@ describe('Legacy import licence versions mapper', () => { describe('the "abstractionPeriodStartMonth" property', () => { describe('when purpose has PERIOD_ST_MONTH', () => { it('returns PERIOD_ST_MONTH as a number', () => { - const [{ purposes: [result] }] = LegacyImportLicenceVersionMapper.go(licenceVersions) + const [{ purposes: [result] }] = LicenceVersionsPresenter.go(licenceVersions) expect(result.abstractionPeriodStartMonth).to.be.number() expect(result.abstractionPeriodStartMonth).to.equal(4) @@ -210,7 +210,7 @@ describe('Legacy import licence versions mapper', () => { }) it('returns null', () => { - const [{ purposes: [result] }] = LegacyImportLicenceVersionMapper.go(licenceVersions) + const [{ purposes: [result] }] = LicenceVersionsPresenter.go(licenceVersions) expect(result.annualQuantity).to.be.null() }) @@ -218,7 +218,7 @@ describe('Legacy import licence versions mapper', () => { describe('when purpose has ANNUAL_QTY', () => { it('returns ANNUAL_QTY as a number', () => { - const [{ purposes: [result] }] = LegacyImportLicenceVersionMapper.go(licenceVersions) + const [{ purposes: [result] }] = LicenceVersionsPresenter.go(licenceVersions) expect(result.annualQuantity).to.be.number() expect(result.annualQuantity).to.equal(545520) @@ -235,7 +235,7 @@ describe('Legacy import licence versions mapper', () => { }) it('returns null', () => { - const [{ purposes: [result] }] = LegacyImportLicenceVersionMapper.go(licenceVersions) + const [{ purposes: [result] }] = LicenceVersionsPresenter.go(licenceVersions) expect(result.dailyQuantity).to.be.null() }) @@ -243,7 +243,7 @@ describe('Legacy import licence versions mapper', () => { describe('when purpose has DAILY_QTY', () => { it('returns DAILY_QTY as a number', () => { - const [{ purposes: [result] }] = LegacyImportLicenceVersionMapper.go(licenceVersions) + const [{ purposes: [result] }] = LicenceVersionsPresenter.go(licenceVersions) expect(result.dailyQuantity).to.be.number() expect(result.dailyQuantity).to.equal(1500.2) @@ -260,7 +260,7 @@ describe('Legacy import licence versions mapper', () => { }) it('returns null', () => { - const [{ purposes: [result] }] = LegacyImportLicenceVersionMapper.go(licenceVersions) + const [{ purposes: [result] }] = LicenceVersionsPresenter.go(licenceVersions) expect(result.hourlyQuantity).to.be.null() }) @@ -268,7 +268,7 @@ describe('Legacy import licence versions mapper', () => { describe('when purpose has HOURLY_QTY', () => { it('returns HOURLY_QTY as a number', () => { - const [{ purposes: [result] }] = LegacyImportLicenceVersionMapper.go(licenceVersions) + const [{ purposes: [result] }] = LicenceVersionsPresenter.go(licenceVersions) expect(result.hourlyQuantity).to.be.number() expect(result.hourlyQuantity).to.equal(140.929) @@ -279,7 +279,7 @@ describe('Legacy import licence versions mapper', () => { describe('the "instantQuantity" property', () => { describe('when purpose has INST_QTY is "null"', () => { it('returns null', () => { - const [{ purposes: [result] }] = LegacyImportLicenceVersionMapper.go(licenceVersions) + const [{ purposes: [result] }] = LicenceVersionsPresenter.go(licenceVersions) expect(result.instantQuantity).to.be.null() }) @@ -293,7 +293,7 @@ describe('Legacy import licence versions mapper', () => { }) it('returns INST_QTY as a number', () => { - const [{ purposes: [result] }] = LegacyImportLicenceVersionMapper.go(licenceVersions) + const [{ purposes: [result] }] = LicenceVersionsPresenter.go(licenceVersions) expect(result.instantQuantity).to.be.number() expect(result.instantQuantity).to.equal(123) @@ -304,7 +304,7 @@ describe('Legacy import licence versions mapper', () => { describe('the "externalId" property', () => { describe('when the purpose has FGAC_REGION_CODE, ID', () => { it('returns externalId in the format {FGAC_REGION_CODE}:{ID}', () => { - const [{ purposes: [result] }] = LegacyImportLicenceVersionMapper.go(licenceVersions) + const [{ purposes: [result] }] = LicenceVersionsPresenter.go(licenceVersions) expect(result.externalId).to.equal('3:10000004') }) @@ -314,7 +314,7 @@ describe('Legacy import licence versions mapper', () => { describe('the "notes" property', () => { describe('when purpose has NOTES is "null"', () => { it('returns null', () => { - const [{ purposes: [result] }] = LegacyImportLicenceVersionMapper.go(licenceVersions) + const [{ purposes: [result] }] = LicenceVersionsPresenter.go(licenceVersions) expect(result.notes).to.be.null() }) @@ -328,7 +328,7 @@ describe('Legacy import licence versions mapper', () => { }) it('returns notes', () => { - const [{ purposes: [result] }] = LegacyImportLicenceVersionMapper.go(licenceVersions) + const [{ purposes: [result] }] = LicenceVersionsPresenter.go(licenceVersions) expect(result.notes).to.equal('a b c') }) @@ -338,7 +338,7 @@ describe('Legacy import licence versions mapper', () => { describe('the "primaryPurposeId" property', () => { describe('when purpose has APUR_APPR_CODE', () => { it('returns the legacy primaryPurposeId', () => { - const [{ purposes: [result] }] = LegacyImportLicenceVersionMapper.go(licenceVersions) + const [{ purposes: [result] }] = LicenceVersionsPresenter.go(licenceVersions) expect(result.primaryPurposeId).to.equal('I') }) @@ -348,7 +348,7 @@ describe('Legacy import licence versions mapper', () => { describe('the "purposeId" property', () => { describe('when purpose has APUR_APUS_CODE', () => { it('returns the legacy purposeId', () => { - const [{ purposes: [result] }] = LegacyImportLicenceVersionMapper.go(licenceVersions) + const [{ purposes: [result] }] = LicenceVersionsPresenter.go(licenceVersions) expect(result.purposeId).to.equal('160') }) @@ -358,7 +358,7 @@ describe('Legacy import licence versions mapper', () => { describe('the "secondaryPurposeId" property', () => { describe('when purpose has APUR_APSE_CODE', () => { it('returns the legacy secondaryPurposeId', () => { - const [{ purposes: [result] }] = LegacyImportLicenceVersionMapper.go(licenceVersions) + const [{ purposes: [result] }] = LicenceVersionsPresenter.go(licenceVersions) expect(result.secondaryPurposeId).to.equal('OTI') }) @@ -374,7 +374,7 @@ describe('Legacy import licence versions mapper', () => { }) it('returns the time Limited End Date in the ISO format', () => { - const [{ purposes: [result] }] = LegacyImportLicenceVersionMapper.go(licenceVersions) + const [{ purposes: [result] }] = LicenceVersionsPresenter.go(licenceVersions) expect(result.timeLimitedEndDate).to.equal('2015-03-31') }) @@ -382,7 +382,7 @@ describe('Legacy import licence versions mapper', () => { describe('when purpose has TIMELTD_END_DATE', () => { it('returns null', () => { - const [{ purposes: [result] }] = LegacyImportLicenceVersionMapper.go(licenceVersions) + const [{ purposes: [result] }] = LicenceVersionsPresenter.go(licenceVersions) expect(result.timeLimitedEndDate).to.be.null() }) @@ -398,7 +398,7 @@ describe('Legacy import licence versions mapper', () => { }) it('returns the time Limited End Date in the ISO format', () => { - const [{ purposes: [result] }] = LegacyImportLicenceVersionMapper.go(licenceVersions) + const [{ purposes: [result] }] = LicenceVersionsPresenter.go(licenceVersions) expect(result.timeLimitedStartDate).to.equal('2015-03-31') }) @@ -406,7 +406,7 @@ describe('Legacy import licence versions mapper', () => { describe('when purpose has TIMELTD_ST_DATE', () => { it('returns null', () => { - const [{ purposes: [result] }] = LegacyImportLicenceVersionMapper.go(licenceVersions) + const [{ purposes: [result] }] = LicenceVersionsPresenter.go(licenceVersions) expect(result.timeLimitedStartDate).to.be.null() }) diff --git a/test/services/import/legacy-import/licence.mapper.test.js b/test/presenters/import/legacy/licence.presenter.test.js similarity index 79% rename from test/services/import/legacy-import/licence.mapper.test.js rename to test/presenters/import/legacy/licence.presenter.test.js index ff4a1f40c8..911d3b61f7 100644 --- a/test/services/import/legacy-import/licence.mapper.test.js +++ b/test/presenters/import/legacy/licence.presenter.test.js @@ -8,14 +8,14 @@ const { describe, it, beforeEach } = exports.lab = Lab.script() const { expect } = Code // Test helpers -const FixtureLegacyLicence = require('../_fixtures/legacy-licence.fixture.js') -const FixtureLegacyLicenceVersion = require('../_fixtures/legacy-licence-version.fixture.js') +const FixtureLegacyLicence = require('../../../services/import/_fixtures/legacy-licence.fixture.js') +const FixtureLegacyLicenceVersion = require('../../../services/import/_fixtures/legacy-licence-version.fixture.js') // Thing under test -const LegacyImportLicenceMapper = - require('../../../../app/services/import/legacy-import/licence.mapper.js') +const LicencePresenter = + require('../../../../app/presenters/import/legacy/licence.presenter.js') -describe('Legacy import licence mapper', () => { +describe('Import legacy licence presenter', () => { let licence beforeEach(() => { @@ -23,7 +23,7 @@ describe('Legacy import licence mapper', () => { }) it('returns the matching agreements data', () => { - const results = LegacyImportLicenceMapper.go(licence) + const results = LicencePresenter.go(licence) expect(results).to.equal({ licenceRef: licence.LIC_NO, @@ -47,7 +47,7 @@ describe('Legacy import licence mapper', () => { describe('the "expiredDate" property', () => { describe('when the licence has an expiry date', () => { it('returns the licence expired date in the ISO format', () => { - const result = LegacyImportLicenceMapper.go(licence) + const result = LicencePresenter.go(licence) expect(result.expiredDate).to.equal('2015-03-31') }) @@ -58,7 +58,7 @@ describe('Legacy import licence mapper', () => { licence.EXPIRY_DATE = 'null' }) it('returns null', () => { - const result = LegacyImportLicenceMapper.go(licence) + const result = LicencePresenter.go(licence) expect(result.expiredDate).to.be.null() }) @@ -72,7 +72,7 @@ describe('Legacy import licence mapper', () => { }) it('returns the licence expired date in the ISO format', () => { - const result = LegacyImportLicenceMapper.go(licence) + const result = LicencePresenter.go(licence) expect(result.lapsedDate).to.equal('2006-09-01') }) @@ -80,7 +80,7 @@ describe('Legacy import licence mapper', () => { describe('when the licence does not have an lapsed date', () => { it('returns null', () => { - const result = LegacyImportLicenceMapper.go(licence) + const result = LicencePresenter.go(licence) expect(result.lapsedDate).to.be.null() }) @@ -89,7 +89,7 @@ describe('Legacy import licence mapper', () => { describe('the "licenceRef" property', () => { it('returns licence ref from the licence LIC_NO', () => { - const result = LegacyImportLicenceMapper.go(licence) + const result = LicencePresenter.go(licence) expect(result.licenceRef).to.equal(licence.LIC_NO) }) @@ -97,7 +97,7 @@ describe('Legacy import licence mapper', () => { describe('the "naldRegionId" property', () => { it('returns the FGAC_REGION_CODE as an integer assigned to naldRegionId', () => { - const result = LegacyImportLicenceMapper.go(licence) + const result = LicencePresenter.go(licence) expect(result.naldRegionId).to.equal(3) }) @@ -105,7 +105,7 @@ describe('Legacy import licence mapper', () => { describe('the "regions" property', () => { it('returns region', () => { - const result = LegacyImportLicenceMapper.go(licence) + const result = LicencePresenter.go(licence) expect(result.regions).to.equal({ historicalAreaCode: 'RIDIN', @@ -123,7 +123,7 @@ describe('Legacy import licence mapper', () => { }) it('returns the licence revoked date in the ISO format', () => { - const result = LegacyImportLicenceMapper.go(licence) + const result = LicencePresenter.go(licence) expect(result.revokedDate).to.equal('2006-09-01') }) @@ -131,7 +131,7 @@ describe('Legacy import licence mapper', () => { describe('when the licence does not have an revoked date', () => { it('returns null', () => { - const result = LegacyImportLicenceMapper.go(licence) + const result = LicencePresenter.go(licence) expect(result.revokedDate).to.be.null() }) @@ -141,7 +141,7 @@ describe('Legacy import licence mapper', () => { describe('the "startDate" property', () => { describe('when the licence has ORIG_EFF_DATE', () => { it('returns ORIG_EFF_DATE as the start date in the correct format', () => { - const result = LegacyImportLicenceMapper.go(licence) + const result = LicencePresenter.go(licence) expect(result.startDate).to.equal('2005-06-03') }) @@ -161,7 +161,7 @@ describe('Legacy import licence mapper', () => { describe('then start date of the earliest non-draft licence version is used', () => { it('returns the start date in the ISO format', () => { - const result = LegacyImportLicenceMapper.go(licence, licenceVersions) + const result = LicencePresenter.go(licence, licenceVersions) expect(result.startDate).to.equal('2001-01-01') }) @@ -176,7 +176,7 @@ describe('Legacy import licence mapper', () => { }) it('returns waterUndertaker as true', () => { - const result = LegacyImportLicenceMapper.go(licence) + const result = LicencePresenter.go(licence) expect(result.waterUndertaker).to.be.true() }) @@ -184,7 +184,7 @@ describe('Legacy import licence mapper', () => { describe('when the licence AREP_EIUC_CODE does not end with "SWC" ', () => { it('returns waterUndertaker as false', () => { - const result = LegacyImportLicenceMapper.go(licence) + const result = LicencePresenter.go(licence) expect(result.waterUndertaker).to.be.false() }) diff --git a/test/services/import/legacy-licence.service.test.js b/test/services/import/legacy/process-licence.service.test.js similarity index 77% rename from test/services/import/legacy-licence.service.test.js rename to test/services/import/legacy/process-licence.service.test.js index efc83e87b3..d74df9cbbc 100644 --- a/test/services/import/legacy-licence.service.test.js +++ b/test/services/import/legacy/process-licence.service.test.js @@ -9,22 +9,22 @@ const { describe, it, before, beforeEach } = exports.lab = Lab.script() const { expect } = Code // Test helpers -const FetchLegacyImportLicenceService = require('../../../app/services/import/legacy-import/fetch-licence.service.js') -const FetchLegacyImportLicenceVersionsService = require('../../../app/services/import/legacy-import/fetch-licence-versions.service.js') -const FixtureLegacyLicence = require('./_fixtures/legacy-licence.fixture.js') -const FixtureLegacyLicenceVersion = require('./_fixtures/legacy-licence-version.fixture.js') -const FixtureLegacyLicenceVersionPurpose = require('./_fixtures/legacy-licence-version-purpose.fixture.js') -const LicenceModel = require('../../../app/models/licence.model.js') -const PrimaryPurposeHelper = require('../../support/helpers/primary-purpose.helper.js') -const PurposeHelper = require('../../support/helpers/purpose.helper.js') -const RegionHelper = require('../../support/helpers/region.helper.js') -const SecondaryPurposeHelper = require('../../support/helpers/secondary-purpose.helper.js') +const FetchLicenceService = require('../../../../app/services/import/legacy/fetch-licence.service.js') +const FetchLicenceVersionsService = require('../../../../app/services/import/legacy/fetch-licence-versions.service.js') +const FixtureLegacyLicence = require('../_fixtures/legacy-licence.fixture.js') +const FixtureLegacyLicenceVersion = require('../_fixtures/legacy-licence-version.fixture.js') +const FixtureLegacyLicenceVersionPurpose = require('../_fixtures/legacy-licence-version-purpose.fixture.js') +const LicenceModel = require('../../../../app/models/licence.model.js') +const PrimaryPurposeHelper = require('../../../support/helpers/primary-purpose.helper.js') +const PurposeHelper = require('../../../support/helpers/purpose.helper.js') +const RegionHelper = require('../../../support/helpers/region.helper.js') +const SecondaryPurposeHelper = require('../../../support/helpers/secondary-purpose.helper.js') // Thing under test -const LegacyImportLicenceService = - require('../../../app/services/import/legacy-licence.service.js') +const ImportLegacyProcessLicenceService = + require('../../../../app/services/import/legacy/process-licence.service.js') -describe('Legacy import licence service', () => { +describe('Import legacy process licence service', () => { const region = RegionHelper.select() let legacyLicence @@ -42,19 +42,19 @@ describe('Legacy import licence service', () => { licenceVersions = [{ ...version, purposes: [{ ...licenceVersionPurpose }] }] - Sinon.stub(FetchLegacyImportLicenceService, 'go').resolves({ + Sinon.stub(FetchLicenceService, 'go').resolves({ ...legacyLicence, FGAC_REGION_CODE: region.naldRegionId }) - Sinon.stub(FetchLegacyImportLicenceVersionsService, 'go').resolves(licenceVersions) + Sinon.stub(FetchLicenceVersionsService, 'go').resolves(licenceVersions) global.GlobalNotifier = { omfg: Sinon.stub() } }) describe('the "licence" data is imported and saved to the database', () => { it('returns the matching licence data', async () => { - await LegacyImportLicenceService.go(licenceRef) + await ImportLegacyProcessLicenceService.go(licenceRef) const licence = await LicenceModel.query().select('*').where('licenceRef', licenceRef).first() @@ -82,7 +82,7 @@ describe('Legacy import licence service', () => { }) it('returns defaulted columns', async () => { - await LegacyImportLicenceService.go(licenceRef) + await ImportLegacyProcessLicenceService.go(licenceRef) const licence = await LicenceModel.query().select('*').where('licenceRef', licenceRef).first() @@ -94,7 +94,7 @@ describe('Legacy import licence service', () => { describe('the "licence versions" ', () => { it('returns the matching licence versions data', async () => { - await LegacyImportLicenceService.go(licenceRef) + await ImportLegacyProcessLicenceService.go(licenceRef) const licence = await LicenceModel.query().select(['id']).where('licenceRef', licenceRef).first() .withGraphFetched('licenceVersions') @@ -138,7 +138,7 @@ describe('Legacy import licence service', () => { }) it('returns the matching licence versions purposes data', async () => { - await LegacyImportLicenceService.go(licenceRef) + await ImportLegacyProcessLicenceService.go(licenceRef) const licence = await LicenceModel.query().select(['id']).where('licenceRef', licenceRef).first() .withGraphFetched('licenceVersions').withGraphFetched('licenceVersions.licenceVersionPurposes') diff --git a/test/services/import/licence-validator.service.test.js b/test/services/import/validate-licence.service.test.js similarity index 72% rename from test/services/import/licence-validator.service.test.js rename to test/services/import/validate-licence.service.test.js index d1f8444eba..20c81d4120 100644 --- a/test/services/import/licence-validator.service.test.js +++ b/test/services/import/validate-licence.service.test.js @@ -12,8 +12,8 @@ const FixtureImportLicence = require('./_fixtures/import-licence.fixture.js') const FixtureImportLicenceVersion = require('./_fixtures/import-licence-versions.fixture.js') // Thing under test -const ImportLicenceValidatorService = - require('../../../app/services/import/licence-validator.service.js') +const ValidateLicenceService = + require('../../../app/services/import/validate-licence.service.js') describe('Import licence validator service', () => { let licence @@ -28,7 +28,7 @@ describe('Import licence validator service', () => { }) it('should not throw an error - licence is valid', async () => { - expect(() => { return ImportLicenceValidatorService.go(licence, licenceVersionsAndPurposes) }).to.not.throw() + expect(() => { return ValidateLicenceService.go(licence, licenceVersionsAndPurposes) }).to.not.throw() }) describe('when a licence has badly formatted data', () => { @@ -37,7 +37,7 @@ describe('Import licence validator service', () => { }) it('should not throw an error - licence is valid', async () => { - expect(() => { return ImportLicenceValidatorService.go(licence, licenceVersionsAndPurposes) }).to.throw('"licenceRef" is required') + expect(() => { return ValidateLicenceService.go(licence, licenceVersionsAndPurposes) }).to.throw('"licenceRef" is required') }) }) }) From 752c95054a7c2a5b7bcbed4cff3b97570512c642 Mon Sep 17 00:00:00 2001 From: jonathangoulding Date: Wed, 14 Aug 2024 09:18:57 +0100 Subject: [PATCH 66/75] refactor: use data object in persist licence rename naldRegionId to regionId in the mapper / update validator. --- .../import/legacy/licence.presenter.js | 2 +- .../import/persist-licence.service.js | 28 ++++--------------- app/validators/import/licence.validator.js | 2 +- .../import/legacy/licence.presenter.test.js | 8 +++--- .../_fixtures/import-licence.fixture.js | 2 +- .../import/persist-licence.service.test.js | 3 +- .../import/licence.validator.test.js | 12 ++++---- 7 files changed, 19 insertions(+), 38 deletions(-) diff --git a/app/presenters/import/legacy/licence.presenter.js b/app/presenters/import/legacy/licence.presenter.js index 1c201cacbd..906919c2bb 100644 --- a/app/presenters/import/legacy/licence.presenter.js +++ b/app/presenters/import/legacy/licence.presenter.js @@ -24,7 +24,7 @@ function _mapLicence (licence, licenceVersions) { expiredDate: formatStandardDateToISO(licence.EXPIRY_DATE), lapsedDate: formatStandardDateToISO(licence.LAPSED_DATE), licenceRef: licence.LIC_NO, - naldRegionId: parseInt(licence.FGAC_REGION_CODE, 10), + regionId: parseInt(licence.FGAC_REGION_CODE, 10), regions: _regions(licence), revokedDate: formatStandardDateToISO(licence.REV_DATE), startDate: _startDate(licence, licenceVersions), diff --git a/app/services/import/persist-licence.service.js b/app/services/import/persist-licence.service.js index e84b32d4e5..f37e0d098d 100644 --- a/app/services/import/persist-licence.service.js +++ b/app/services/import/persist-licence.service.js @@ -11,38 +11,20 @@ const RegionModel = require('../../models/region.model.js') /** * Saves the licence versions, purposes and conditions * - * @param {object} licence - the mapped and validated licence to persist + * @param {object} licenceData - the mapped and validated licence to persist * @returns {Promise} */ -async function go (licence) { - const { - expiredDate, - lapsedDate, - licenceRef, - naldRegionId, - regions, - revokedDate, - startDate, - waterUndertaker - } = licence - +async function go (licenceData) { const region = await RegionModel.query() .select(['id']) - .where('naldRegionId', naldRegionId) + .where('naldRegionId', licenceData.regionId) .limit(1) .first() return LicenceModel.query() .insert({ - expiredDate, - waterUndertaker, - lapsedDate, - licenceRef, - regionId: region.id, - regions, - revokedDate, - startDate, - updatedAt: new Date().toISOString() + ...licenceData, + regionId: region.id }) .onConflict('licenceRef') .merge([ diff --git a/app/validators/import/licence.validator.js b/app/validators/import/licence.validator.js index 36f5d7fa2c..2cd685496d 100644 --- a/app/validators/import/licence.validator.js +++ b/app/validators/import/licence.validator.js @@ -40,7 +40,7 @@ const _schema = Joi.object({ expiredDate: Joi.date().iso().allow(null), lapsedDate: Joi.date().iso().allow(null), licenceRef: Joi.string().required(), - naldRegionId: Joi.number().required(), + regionId: Joi.number().required(), regions: Joi.object({ regionalChargeArea: Joi.string().required(), localEnvironmentAgencyPlanCode: Joi.string().required(), diff --git a/test/presenters/import/legacy/licence.presenter.test.js b/test/presenters/import/legacy/licence.presenter.test.js index 911d3b61f7..03e12288c5 100644 --- a/test/presenters/import/legacy/licence.presenter.test.js +++ b/test/presenters/import/legacy/licence.presenter.test.js @@ -35,7 +35,7 @@ describe('Import legacy licence presenter', () => { standardUnitChargeCode: 'YORKI', localEnvironmentAgencyPlanCode: 'AIREL' }, - naldRegionId: 3, + regionId: 3, expiredDate: '2015-03-31', lapsedDate: null, revokedDate: null @@ -95,11 +95,11 @@ describe('Import legacy licence presenter', () => { }) }) - describe('the "naldRegionId" property', () => { - it('returns the FGAC_REGION_CODE as an integer assigned to naldRegionId', () => { + describe('the "regionId" property', () => { + it('returns the FGAC_REGION_CODE as an integer assigned to regionId', () => { const result = LicencePresenter.go(licence) - expect(result.naldRegionId).to.equal(3) + expect(result.regionId).to.equal(3) }) }) diff --git a/test/services/import/_fixtures/import-licence.fixture.js b/test/services/import/_fixtures/import-licence.fixture.js index 68f0bee1a7..4f48a0d62a 100644 --- a/test/services/import/_fixtures/import-licence.fixture.js +++ b/test/services/import/_fixtures/import-licence.fixture.js @@ -12,7 +12,7 @@ function importLicence () { expiredDate: '2015-03-31', lapsedDate: null, licenceRef: generateLicenceRef(), - naldRegionId: region.naldRegionId, + regionId: region.naldRegionId, regions: { historicalAreaCode: 'RIDIN', regionalChargeArea: 'Yorkshire', diff --git a/test/services/import/persist-licence.service.test.js b/test/services/import/persist-licence.service.test.js index 6dd5f1ef15..e619c05b9d 100644 --- a/test/services/import/persist-licence.service.test.js +++ b/test/services/import/persist-licence.service.test.js @@ -49,7 +49,6 @@ describe('Persist licence service', () => { }, revokedDate: null, startDate: '2005-06-03', - updatedAt: savedLicence.updatedAt.toISOString(), waterUndertaker: false }) }) @@ -96,7 +95,7 @@ describe('Persist licence service', () => { it('updates the licence', async () => { await PersistLicenceService.go({ licenceRef: licence.licenceRef, - naldRegionId: region.naldRegionId, + regionId: region.naldRegionId, // not null constraints waterUndertaker: true, regions: licence.regions, diff --git a/test/validators/import/licence.validator.test.js b/test/validators/import/licence.validator.test.js index c09b9b69ad..67ab6dc26e 100644 --- a/test/validators/import/licence.validator.test.js +++ b/test/validators/import/licence.validator.test.js @@ -120,22 +120,22 @@ describe('Import licence validator', () => { }) }) - describe('"naldRegionId" property', () => { - it('should throw an error - naldRegionId - must be a number', async () => { + describe('"regionId" property', () => { + it('should throw an error - regionId - must be a number', async () => { expect(() => { return ImportLicenceValidator.go({ licenceRef: 'l', - naldRegionId: 'one' + regionId: 'one' }) - }).to.throw('"naldRegionId" must be a number') + }).to.throw('"regionId" must be a number') }) - it('should throw an error - naldRegionId - is required', async () => { + it('should throw an error - regionId - is required', async () => { expect(() => { return ImportLicenceValidator.go({ licenceRef: 'l' }) - }).to.throw('"naldRegionId" is required') + }).to.throw('"regionId" is required') }) }) From 6b836cc9c942cf2dfed89aa80040ea6a8c42aefd Mon Sep 17 00:00:00 2001 From: jonathangoulding Date: Wed, 14 Aug 2024 09:59:32 +0100 Subject: [PATCH 67/75] refactor: move licence versions created and update at into presenter --- .../legacy/licence-versions.presenter.js | 4 +- .../persist-licence-versions.service.js | 5 +- .../import/licence-versions.validator.js | 4 +- .../legacy/licence-versions.presenter.test.js | 17 ++++- .../import-licence-versions.fixture.js | 4 +- .../persist-licence-versions.service.test.js | 4 +- .../import/licence-versions.validator.test.js | 74 +++++++++++++++++++ 7 files changed, 101 insertions(+), 11 deletions(-) diff --git a/app/presenters/import/legacy/licence-versions.presenter.js b/app/presenters/import/legacy/licence-versions.presenter.js index 6c4a7873e1..d86eaf81f2 100644 --- a/app/presenters/import/legacy/licence-versions.presenter.js +++ b/app/presenters/import/legacy/licence-versions.presenter.js @@ -40,7 +40,9 @@ function _mapLicenceVersions (licenceVersions) { issue: Number(issue), startDate: formatStandardDateToISO(licenceVersion.EFF_ST_DATE), status: statuses[licenceVersion.STATUS], - purposes: _mapPurposes(licenceVersion) + purposes: _mapPurposes(licenceVersion), + updatedAt: new Date(), + createdAt: new Date() } }) } diff --git a/app/services/import/persist-licence-versions.service.js b/app/services/import/persist-licence-versions.service.js index f33a4b0cf8..7d674638f2 100644 --- a/app/services/import/persist-licence-versions.service.js +++ b/app/services/import/persist-licence-versions.service.js @@ -84,10 +84,7 @@ async function _saveLicenceVersion (version, licenceId) { return LicenceVersionModel.query() .insert({ ...version, - licenceId, - // TODO: lift out to presenters - createdAt: new Date().toISOString(), - updatedAt: new Date().toISOString() + licenceId }) .onConflict('externalId') .merge([ diff --git a/app/validators/import/licence-versions.validator.js b/app/validators/import/licence-versions.validator.js index 3cea5751de..c1e66271e2 100644 --- a/app/validators/import/licence-versions.validator.js +++ b/app/validators/import/licence-versions.validator.js @@ -94,7 +94,9 @@ const _schema = Joi.array().min(1).items( issue: Joi.number().required(), startDate: Joi.date().iso().required(), status: Joi.string().required().custom(_isValidStatus), - purposes: _purposeSchema + purposes: _purposeSchema, + createdAt: Joi.date().required(), + updatedAt: Joi.date().required() }) .label('Licence version') ) diff --git a/test/presenters/import/legacy/licence-versions.presenter.test.js b/test/presenters/import/legacy/licence-versions.presenter.test.js index 806e6c2c24..7d37f77042 100644 --- a/test/presenters/import/legacy/licence-versions.presenter.test.js +++ b/test/presenters/import/legacy/licence-versions.presenter.test.js @@ -3,8 +3,9 @@ // 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 { describe, it, afterEach, beforeEach } = exports.lab = Lab.script() const { expect } = Code // Test helpers @@ -16,6 +17,9 @@ const LicenceVersionsPresenter = require('../../../../app/presenters/import/legacy/licence-versions.presenter.js') describe('Import legacy licence versions presenter', () => { + const testDate = new Date('2023-08-21') + + let clock let licenceVersions let purpose let version @@ -25,6 +29,13 @@ describe('Import legacy licence versions presenter', () => { version = FixtureLegacyLicenceVersion.create() licenceVersions = [{ ...version, purposes: [{ ...purpose }] }] + + clock = Sinon.useFakeTimers(testDate) + }) + + afterEach(() => { + clock.restore() + Sinon.restore() }) it('returns the licence version', () => { @@ -55,7 +66,9 @@ describe('Import legacy licence versions presenter', () => { } ], startDate: '2005-06-05', - status: 'superseded' + status: 'superseded', + createdAt: testDate, + updatedAt: testDate }]) }) diff --git a/test/services/import/_fixtures/import-licence-versions.fixture.js b/test/services/import/_fixtures/import-licence-versions.fixture.js index 502ac8985a..09a53d587d 100644 --- a/test/services/import/_fixtures/import-licence-versions.fixture.js +++ b/test/services/import/_fixtures/import-licence-versions.fixture.js @@ -29,7 +29,9 @@ function _createtLicenceVersion () { increment: 0, issue: 100, startDate: '2001-01-01', - status: 'superseded' + status: 'superseded', + createdAt: new Date(), + updatedAt: new Date() } } diff --git a/test/services/import/persist-licence-versions.service.test.js b/test/services/import/persist-licence-versions.service.test.js index de150fdb53..70a7134baa 100644 --- a/test/services/import/persist-licence-versions.service.test.js +++ b/test/services/import/persist-licence-versions.service.test.js @@ -61,7 +61,7 @@ describe('Persist licence versions and licence versions purposes service', () => const [savedLicenceVersionPurpose] = savedLicenceVersion.licenceVersionPurposes expect(savedLicenceVersion).to.equal({ - createdAt: savedLicenceVersion.createdAt, + createdAt: licenceVersion.createdAt, endDate: new Date('2002-01-01'), externalId: licenceVersion.externalId, id: savedLicenceVersion.id, @@ -93,7 +93,7 @@ describe('Persist licence versions and licence versions purposes service', () => ], startDate: new Date('2001-01-01'), status: 'superseded', - updatedAt: savedLicenceVersion.updatedAt + updatedAt: licenceVersion.updatedAt }) }) diff --git a/test/validators/import/licence-versions.validator.test.js b/test/validators/import/licence-versions.validator.test.js index be9ca2b538..131c8049d3 100644 --- a/test/validators/import/licence-versions.validator.test.js +++ b/test/validators/import/licence-versions.validator.test.js @@ -299,6 +299,80 @@ describe('Import licence versions validator', () => { }) }) + describe('"createdAt" property', () => { + it('should throw an error if "createdAt" is not a valid date', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: licenceVersionPurposes, + createdAt: '' + } + ]) + }).to.throw('"[0].createdAt" must be a valid date') + }) + + it('should throw an error if "createdAt" is null', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: licenceVersionPurposes, + createdAt: null + } + ]) + }).to.throw() + }) + + it('should not throw an error if "createdAt" is valid date', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: licenceVersionPurposes + } + ]) + }).to.not.throw() + }) + }) + + describe('"updatedAt" property', () => { + it('should throw an error if "updatedAt" is not a valid date', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: licenceVersionPurposes, + updatedAt: '' + } + ]) + }).to.throw('"[0].updatedAt" must be a valid date') + }) + + it('should throw an error if "updatedAt" is null', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: licenceVersionPurposes, + updatedAt: null + } + ]) + }).to.throw() + }) + + it('should not throw an error if "updatedAt" is valid date', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: licenceVersionPurposes + } + ]) + }).to.not.throw() + }) + }) + describe('"purposes" property', () => { describe('when no purposes a', () => { let licenceVersionNoPurposes From 6b76ade0c94b7b013147f11ce12b6807d777eb9b Mon Sep 17 00:00:00 2001 From: jonathangoulding Date: Wed, 14 Aug 2024 10:19:54 +0100 Subject: [PATCH 68/75] refactor: move licence versions purposes created and update at into presenter --- .../legacy/licence-versions.presenter.js | 4 +- .../persist-licence-versions.service.js | 4 +- .../import/licence-versions.validator.js | 4 +- .../legacy/licence-versions.presenter.test.js | 22 +++++- .../import-licence-versions.fixture.js | 4 +- .../import/licence-versions.validator.test.js | 72 ++++++++++++++++++- 6 files changed, 102 insertions(+), 8 deletions(-) diff --git a/app/presenters/import/legacy/licence-versions.presenter.js b/app/presenters/import/legacy/licence-versions.presenter.js index d86eaf81f2..3acb1bd9f8 100644 --- a/app/presenters/import/legacy/licence-versions.presenter.js +++ b/app/presenters/import/legacy/licence-versions.presenter.js @@ -69,7 +69,9 @@ const _mapPurpose = (purpose) => { secondaryPurposeId: purpose.APUR_APSE_CODE, purposeId: purpose.APUR_APUS_CODE, timeLimitedEndDate: formatStandardDateToISO(purpose.TIMELTD_END_DATE), - timeLimitedStartDate: formatStandardDateToISO(purpose.TIMELTD_ST_DATE) + timeLimitedStartDate: formatStandardDateToISO(purpose.TIMELTD_ST_DATE), + updatedAt: new Date(), + createdAt: new Date() } } diff --git a/app/services/import/persist-licence-versions.service.js b/app/services/import/persist-licence-versions.service.js index 7d674638f2..0beca81788 100644 --- a/app/services/import/persist-licence-versions.service.js +++ b/app/services/import/persist-licence-versions.service.js @@ -56,9 +56,7 @@ async function _saveLicenceVersionPurposes (purpose, licenceVersionId) { ...purpose, primaryPurposeId: primaryPurpose.id, secondaryPurposeId: secondaryPurpose.id, - purposeId: purposeUse.id, - createdAt: new Date().toISOString(), - updatedAt: new Date().toISOString() + purposeId: purposeUse.id }) .onConflict('externalId') .merge([ diff --git a/app/validators/import/licence-versions.validator.js b/app/validators/import/licence-versions.validator.js index c1e66271e2..4ac8d6f3b6 100644 --- a/app/validators/import/licence-versions.validator.js +++ b/app/validators/import/licence-versions.validator.js @@ -80,7 +80,9 @@ const _purposeSchema = externalId: Joi.string().required(), instantQuantity: Joi.number().allow(null), hourlyQuantity: Joi.number().allow(null), - dailyQuantity: Joi.number().allow(null) + dailyQuantity: Joi.number().allow(null), + createdAt: Joi.date().required(), + updatedAt: Joi.date().required() }).label('Licence versions purpose') ).label('Licence versions purposes').messages({ 'array.min': 'A licence version must have at least one Licence version purpose' diff --git a/test/presenters/import/legacy/licence-versions.presenter.test.js b/test/presenters/import/legacy/licence-versions.presenter.test.js index 7d37f77042..a32fdbc05a 100644 --- a/test/presenters/import/legacy/licence-versions.presenter.test.js +++ b/test/presenters/import/legacy/licence-versions.presenter.test.js @@ -62,7 +62,9 @@ describe('Import legacy licence versions presenter', () => { purposeId: '160', secondaryPurposeId: 'OTI', timeLimitedEndDate: null, - timeLimitedStartDate: null + timeLimitedStartDate: null, + createdAt: testDate, + updatedAt: testDate } ], startDate: '2005-06-05', @@ -425,6 +427,24 @@ describe('Import legacy licence versions presenter', () => { }) }) }) + + describe('the "createdAt" property', () => { + it('returns the current date', () => { + const [{ purposes: [result] }] = LicenceVersionsPresenter.go(licenceVersions) + + expect(result.createdAt).to.be.date() + expect(result.createdAt).to.be.equal(testDate) + }) + }) + + describe('the "updatedAt" property', () => { + it('returns the current date', () => { + const [{ purposes: [result] }] = LicenceVersionsPresenter.go(licenceVersions) + + expect(result.updatedAt).to.be.date() + expect(result.updatedAt).to.be.equal(testDate) + }) + }) }) }) }) diff --git a/test/services/import/_fixtures/import-licence-versions.fixture.js b/test/services/import/_fixtures/import-licence-versions.fixture.js index 09a53d587d..d7d1dcf879 100644 --- a/test/services/import/_fixtures/import-licence-versions.fixture.js +++ b/test/services/import/_fixtures/import-licence-versions.fixture.js @@ -18,7 +18,9 @@ function _createLicenceVersionPurpose () { secondaryPurposeId: 'OTI', purposeId: '160', timeLimitedEndDate: '2001-01-02', - timeLimitedStartDate: '2001-01-03' + timeLimitedStartDate: '2001-01-03', + createdAt: new Date(), + updatedAt: new Date() } } diff --git a/test/validators/import/licence-versions.validator.test.js b/test/validators/import/licence-versions.validator.test.js index 131c8049d3..086f93bb38 100644 --- a/test/validators/import/licence-versions.validator.test.js +++ b/test/validators/import/licence-versions.validator.test.js @@ -374,7 +374,7 @@ describe('Import licence versions validator', () => { }) describe('"purposes" property', () => { - describe('when no purposes a', () => { + describe('when no purposes', () => { let licenceVersionNoPurposes beforeEach(() => { @@ -1024,6 +1024,76 @@ describe('Import licence versions validator', () => { }).to.not.throw() }) }) + + describe('"createdAt" property', () => { + it('should throw an error if "createdAt" is not a valid date', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: [{ ...licenceVersionPurpose, createdAt: '' }] + } + ]) + }).to.throw('"[0].purposes[0].createdAt" must be a valid date') + }) + + it('should throw an error if "createdAt" is null', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: [{ ...licenceVersionPurpose, createdAt: null }] + } + ]) + }).to.throw('"[0].purposes[0].createdAt" must be a valid date') + }) + + it('should not throw an error if "createdAt" is valid date', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: licenceVersionPurposes + } + ]) + }).to.not.throw() + }) + }) + + describe('"updatedAt" property', () => { + it('should throw an error if "updatedAt" is not a valid date', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: [{ ...licenceVersionPurpose, updatedAt: '' }] + } + ]) + }).to.throw('"[0].purposes[0].updatedAt" must be a valid date') + }) + + it('should throw an error if "updatedAt" is null', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: [{ ...licenceVersionPurpose, updatedAt: null }] + } + ]) + }).to.throw('"[0].purposes[0].updatedAt" must be a valid date') + }) + + it('should not throw an error if "updatedAt" is valid date', async () => { + expect(() => { + return ImportLicenceVersionsValidator.go([ + { + ...licenceVersion, + purposes: licenceVersionPurposes + } + ]) + }).to.not.throw() + }) + }) }) }) }) From a404c840485d0cfa9a20ac1a9bc0ff566a751987 Mon Sep 17 00:00:00 2001 From: jonathangoulding Date: Wed, 14 Aug 2024 10:28:12 +0100 Subject: [PATCH 69/75] fix: sonar assert thrown error --- test/validators/import/licence-versions.validator.test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/validators/import/licence-versions.validator.test.js b/test/validators/import/licence-versions.validator.test.js index 086f93bb38..1f811e9152 100644 --- a/test/validators/import/licence-versions.validator.test.js +++ b/test/validators/import/licence-versions.validator.test.js @@ -321,7 +321,7 @@ describe('Import licence versions validator', () => { createdAt: null } ]) - }).to.throw() + }).to.throw('"[0].createdAt" must be a valid date') }) it('should not throw an error if "createdAt" is valid date', async () => { @@ -358,7 +358,7 @@ describe('Import licence versions validator', () => { updatedAt: null } ]) - }).to.throw() + }).to.throw('"[0].updatedAt" must be a valid date') }) it('should not throw an error if "updatedAt" is valid date', async () => { From dffb80f017dea7d3a0d190809254e492d2c1e64c Mon Sep 17 00:00:00 2001 From: jonathangoulding Date: Wed, 14 Aug 2024 10:39:17 +0100 Subject: [PATCH 70/75] Revert "fix: sonar assert thrown error" This reverts commit a404c840485d0cfa9a20ac1a9bc0ff566a751987. --- test/validators/import/licence-versions.validator.test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/validators/import/licence-versions.validator.test.js b/test/validators/import/licence-versions.validator.test.js index 1f811e9152..086f93bb38 100644 --- a/test/validators/import/licence-versions.validator.test.js +++ b/test/validators/import/licence-versions.validator.test.js @@ -321,7 +321,7 @@ describe('Import licence versions validator', () => { createdAt: null } ]) - }).to.throw('"[0].createdAt" must be a valid date') + }).to.throw() }) it('should not throw an error if "createdAt" is valid date', async () => { @@ -358,7 +358,7 @@ describe('Import licence versions validator', () => { updatedAt: null } ]) - }).to.throw('"[0].updatedAt" must be a valid date') + }).to.throw() }) it('should not throw an error if "updatedAt" is valid date', async () => { From 3f895617ca8c809bb400dc8267f22f522cb2642c Mon Sep 17 00:00:00 2001 From: jonathangoulding Date: Wed, 14 Aug 2024 10:39:18 +0100 Subject: [PATCH 71/75] Revert "refactor: move licence versions purposes created and update at into presenter" This reverts commit 6b76ade0c94b7b013147f11ce12b6807d777eb9b. --- .../legacy/licence-versions.presenter.js | 4 +- .../persist-licence-versions.service.js | 4 +- .../import/licence-versions.validator.js | 4 +- .../legacy/licence-versions.presenter.test.js | 22 +----- .../import-licence-versions.fixture.js | 4 +- .../import/licence-versions.validator.test.js | 72 +------------------ 6 files changed, 8 insertions(+), 102 deletions(-) diff --git a/app/presenters/import/legacy/licence-versions.presenter.js b/app/presenters/import/legacy/licence-versions.presenter.js index 3acb1bd9f8..d86eaf81f2 100644 --- a/app/presenters/import/legacy/licence-versions.presenter.js +++ b/app/presenters/import/legacy/licence-versions.presenter.js @@ -69,9 +69,7 @@ const _mapPurpose = (purpose) => { secondaryPurposeId: purpose.APUR_APSE_CODE, purposeId: purpose.APUR_APUS_CODE, timeLimitedEndDate: formatStandardDateToISO(purpose.TIMELTD_END_DATE), - timeLimitedStartDate: formatStandardDateToISO(purpose.TIMELTD_ST_DATE), - updatedAt: new Date(), - createdAt: new Date() + timeLimitedStartDate: formatStandardDateToISO(purpose.TIMELTD_ST_DATE) } } diff --git a/app/services/import/persist-licence-versions.service.js b/app/services/import/persist-licence-versions.service.js index 0beca81788..7d674638f2 100644 --- a/app/services/import/persist-licence-versions.service.js +++ b/app/services/import/persist-licence-versions.service.js @@ -56,7 +56,9 @@ async function _saveLicenceVersionPurposes (purpose, licenceVersionId) { ...purpose, primaryPurposeId: primaryPurpose.id, secondaryPurposeId: secondaryPurpose.id, - purposeId: purposeUse.id + purposeId: purposeUse.id, + createdAt: new Date().toISOString(), + updatedAt: new Date().toISOString() }) .onConflict('externalId') .merge([ diff --git a/app/validators/import/licence-versions.validator.js b/app/validators/import/licence-versions.validator.js index 4ac8d6f3b6..c1e66271e2 100644 --- a/app/validators/import/licence-versions.validator.js +++ b/app/validators/import/licence-versions.validator.js @@ -80,9 +80,7 @@ const _purposeSchema = externalId: Joi.string().required(), instantQuantity: Joi.number().allow(null), hourlyQuantity: Joi.number().allow(null), - dailyQuantity: Joi.number().allow(null), - createdAt: Joi.date().required(), - updatedAt: Joi.date().required() + dailyQuantity: Joi.number().allow(null) }).label('Licence versions purpose') ).label('Licence versions purposes').messages({ 'array.min': 'A licence version must have at least one Licence version purpose' diff --git a/test/presenters/import/legacy/licence-versions.presenter.test.js b/test/presenters/import/legacy/licence-versions.presenter.test.js index a32fdbc05a..7d37f77042 100644 --- a/test/presenters/import/legacy/licence-versions.presenter.test.js +++ b/test/presenters/import/legacy/licence-versions.presenter.test.js @@ -62,9 +62,7 @@ describe('Import legacy licence versions presenter', () => { purposeId: '160', secondaryPurposeId: 'OTI', timeLimitedEndDate: null, - timeLimitedStartDate: null, - createdAt: testDate, - updatedAt: testDate + timeLimitedStartDate: null } ], startDate: '2005-06-05', @@ -427,24 +425,6 @@ describe('Import legacy licence versions presenter', () => { }) }) }) - - describe('the "createdAt" property', () => { - it('returns the current date', () => { - const [{ purposes: [result] }] = LicenceVersionsPresenter.go(licenceVersions) - - expect(result.createdAt).to.be.date() - expect(result.createdAt).to.be.equal(testDate) - }) - }) - - describe('the "updatedAt" property', () => { - it('returns the current date', () => { - const [{ purposes: [result] }] = LicenceVersionsPresenter.go(licenceVersions) - - expect(result.updatedAt).to.be.date() - expect(result.updatedAt).to.be.equal(testDate) - }) - }) }) }) }) diff --git a/test/services/import/_fixtures/import-licence-versions.fixture.js b/test/services/import/_fixtures/import-licence-versions.fixture.js index d7d1dcf879..09a53d587d 100644 --- a/test/services/import/_fixtures/import-licence-versions.fixture.js +++ b/test/services/import/_fixtures/import-licence-versions.fixture.js @@ -18,9 +18,7 @@ function _createLicenceVersionPurpose () { secondaryPurposeId: 'OTI', purposeId: '160', timeLimitedEndDate: '2001-01-02', - timeLimitedStartDate: '2001-01-03', - createdAt: new Date(), - updatedAt: new Date() + timeLimitedStartDate: '2001-01-03' } } diff --git a/test/validators/import/licence-versions.validator.test.js b/test/validators/import/licence-versions.validator.test.js index 086f93bb38..131c8049d3 100644 --- a/test/validators/import/licence-versions.validator.test.js +++ b/test/validators/import/licence-versions.validator.test.js @@ -374,7 +374,7 @@ describe('Import licence versions validator', () => { }) describe('"purposes" property', () => { - describe('when no purposes', () => { + describe('when no purposes a', () => { let licenceVersionNoPurposes beforeEach(() => { @@ -1024,76 +1024,6 @@ describe('Import licence versions validator', () => { }).to.not.throw() }) }) - - describe('"createdAt" property', () => { - it('should throw an error if "createdAt" is not a valid date', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: [{ ...licenceVersionPurpose, createdAt: '' }] - } - ]) - }).to.throw('"[0].purposes[0].createdAt" must be a valid date') - }) - - it('should throw an error if "createdAt" is null', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: [{ ...licenceVersionPurpose, createdAt: null }] - } - ]) - }).to.throw('"[0].purposes[0].createdAt" must be a valid date') - }) - - it('should not throw an error if "createdAt" is valid date', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: licenceVersionPurposes - } - ]) - }).to.not.throw() - }) - }) - - describe('"updatedAt" property', () => { - it('should throw an error if "updatedAt" is not a valid date', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: [{ ...licenceVersionPurpose, updatedAt: '' }] - } - ]) - }).to.throw('"[0].purposes[0].updatedAt" must be a valid date') - }) - - it('should throw an error if "updatedAt" is null', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: [{ ...licenceVersionPurpose, updatedAt: null }] - } - ]) - }).to.throw('"[0].purposes[0].updatedAt" must be a valid date') - }) - - it('should not throw an error if "updatedAt" is valid date', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: licenceVersionPurposes - } - ]) - }).to.not.throw() - }) - }) }) }) }) From a6993bdb1ec570d7250c01625b067e285b54849e Mon Sep 17 00:00:00 2001 From: jonathangoulding Date: Wed, 14 Aug 2024 10:39:18 +0100 Subject: [PATCH 72/75] Revert "refactor: move licence versions created and update at into presenter" This reverts commit 6b836cc9c942cf2dfed89aa80040ea6a8c42aefd. --- .../legacy/licence-versions.presenter.js | 4 +- .../persist-licence-versions.service.js | 5 +- .../import/licence-versions.validator.js | 4 +- .../legacy/licence-versions.presenter.test.js | 17 +---- .../import-licence-versions.fixture.js | 4 +- .../persist-licence-versions.service.test.js | 4 +- .../import/licence-versions.validator.test.js | 74 ------------------- 7 files changed, 11 insertions(+), 101 deletions(-) diff --git a/app/presenters/import/legacy/licence-versions.presenter.js b/app/presenters/import/legacy/licence-versions.presenter.js index d86eaf81f2..6c4a7873e1 100644 --- a/app/presenters/import/legacy/licence-versions.presenter.js +++ b/app/presenters/import/legacy/licence-versions.presenter.js @@ -40,9 +40,7 @@ function _mapLicenceVersions (licenceVersions) { issue: Number(issue), startDate: formatStandardDateToISO(licenceVersion.EFF_ST_DATE), status: statuses[licenceVersion.STATUS], - purposes: _mapPurposes(licenceVersion), - updatedAt: new Date(), - createdAt: new Date() + purposes: _mapPurposes(licenceVersion) } }) } diff --git a/app/services/import/persist-licence-versions.service.js b/app/services/import/persist-licence-versions.service.js index 7d674638f2..f33a4b0cf8 100644 --- a/app/services/import/persist-licence-versions.service.js +++ b/app/services/import/persist-licence-versions.service.js @@ -84,7 +84,10 @@ async function _saveLicenceVersion (version, licenceId) { return LicenceVersionModel.query() .insert({ ...version, - licenceId + licenceId, + // TODO: lift out to presenters + createdAt: new Date().toISOString(), + updatedAt: new Date().toISOString() }) .onConflict('externalId') .merge([ diff --git a/app/validators/import/licence-versions.validator.js b/app/validators/import/licence-versions.validator.js index c1e66271e2..3cea5751de 100644 --- a/app/validators/import/licence-versions.validator.js +++ b/app/validators/import/licence-versions.validator.js @@ -94,9 +94,7 @@ const _schema = Joi.array().min(1).items( issue: Joi.number().required(), startDate: Joi.date().iso().required(), status: Joi.string().required().custom(_isValidStatus), - purposes: _purposeSchema, - createdAt: Joi.date().required(), - updatedAt: Joi.date().required() + purposes: _purposeSchema }) .label('Licence version') ) diff --git a/test/presenters/import/legacy/licence-versions.presenter.test.js b/test/presenters/import/legacy/licence-versions.presenter.test.js index 7d37f77042..806e6c2c24 100644 --- a/test/presenters/import/legacy/licence-versions.presenter.test.js +++ b/test/presenters/import/legacy/licence-versions.presenter.test.js @@ -3,9 +3,8 @@ // Test framework dependencies const Lab = require('@hapi/lab') const Code = require('@hapi/code') -const Sinon = require('sinon') -const { describe, it, afterEach, beforeEach } = exports.lab = Lab.script() +const { describe, it, beforeEach } = exports.lab = Lab.script() const { expect } = Code // Test helpers @@ -17,9 +16,6 @@ const LicenceVersionsPresenter = require('../../../../app/presenters/import/legacy/licence-versions.presenter.js') describe('Import legacy licence versions presenter', () => { - const testDate = new Date('2023-08-21') - - let clock let licenceVersions let purpose let version @@ -29,13 +25,6 @@ describe('Import legacy licence versions presenter', () => { version = FixtureLegacyLicenceVersion.create() licenceVersions = [{ ...version, purposes: [{ ...purpose }] }] - - clock = Sinon.useFakeTimers(testDate) - }) - - afterEach(() => { - clock.restore() - Sinon.restore() }) it('returns the licence version', () => { @@ -66,9 +55,7 @@ describe('Import legacy licence versions presenter', () => { } ], startDate: '2005-06-05', - status: 'superseded', - createdAt: testDate, - updatedAt: testDate + status: 'superseded' }]) }) diff --git a/test/services/import/_fixtures/import-licence-versions.fixture.js b/test/services/import/_fixtures/import-licence-versions.fixture.js index 09a53d587d..502ac8985a 100644 --- a/test/services/import/_fixtures/import-licence-versions.fixture.js +++ b/test/services/import/_fixtures/import-licence-versions.fixture.js @@ -29,9 +29,7 @@ function _createtLicenceVersion () { increment: 0, issue: 100, startDate: '2001-01-01', - status: 'superseded', - createdAt: new Date(), - updatedAt: new Date() + status: 'superseded' } } diff --git a/test/services/import/persist-licence-versions.service.test.js b/test/services/import/persist-licence-versions.service.test.js index 70a7134baa..de150fdb53 100644 --- a/test/services/import/persist-licence-versions.service.test.js +++ b/test/services/import/persist-licence-versions.service.test.js @@ -61,7 +61,7 @@ describe('Persist licence versions and licence versions purposes service', () => const [savedLicenceVersionPurpose] = savedLicenceVersion.licenceVersionPurposes expect(savedLicenceVersion).to.equal({ - createdAt: licenceVersion.createdAt, + createdAt: savedLicenceVersion.createdAt, endDate: new Date('2002-01-01'), externalId: licenceVersion.externalId, id: savedLicenceVersion.id, @@ -93,7 +93,7 @@ describe('Persist licence versions and licence versions purposes service', () => ], startDate: new Date('2001-01-01'), status: 'superseded', - updatedAt: licenceVersion.updatedAt + updatedAt: savedLicenceVersion.updatedAt }) }) diff --git a/test/validators/import/licence-versions.validator.test.js b/test/validators/import/licence-versions.validator.test.js index 131c8049d3..be9ca2b538 100644 --- a/test/validators/import/licence-versions.validator.test.js +++ b/test/validators/import/licence-versions.validator.test.js @@ -299,80 +299,6 @@ describe('Import licence versions validator', () => { }) }) - describe('"createdAt" property', () => { - it('should throw an error if "createdAt" is not a valid date', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: licenceVersionPurposes, - createdAt: '' - } - ]) - }).to.throw('"[0].createdAt" must be a valid date') - }) - - it('should throw an error if "createdAt" is null', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: licenceVersionPurposes, - createdAt: null - } - ]) - }).to.throw() - }) - - it('should not throw an error if "createdAt" is valid date', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: licenceVersionPurposes - } - ]) - }).to.not.throw() - }) - }) - - describe('"updatedAt" property', () => { - it('should throw an error if "updatedAt" is not a valid date', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: licenceVersionPurposes, - updatedAt: '' - } - ]) - }).to.throw('"[0].updatedAt" must be a valid date') - }) - - it('should throw an error if "updatedAt" is null', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: licenceVersionPurposes, - updatedAt: null - } - ]) - }).to.throw() - }) - - it('should not throw an error if "updatedAt" is valid date', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: licenceVersionPurposes - } - ]) - }).to.not.throw() - }) - }) - describe('"purposes" property', () => { describe('when no purposes a', () => { let licenceVersionNoPurposes From 28bc42ae6e005438173eb8aca254650ee5a8343a Mon Sep 17 00:00:00 2001 From: jonathangoulding Date: Wed, 14 Aug 2024 10:45:12 +0100 Subject: [PATCH 73/75] refactor: add migration for updated and created at to be handled by db --- app/services/import/persist-licence-versions.service.js | 9 ++------- .../legacy/20221108007007_water-licence-versions.js | 4 ++-- ...0221108007008_water-licence-version-purposes-table.js | 4 ++-- 3 files changed, 6 insertions(+), 11 deletions(-) diff --git a/app/services/import/persist-licence-versions.service.js b/app/services/import/persist-licence-versions.service.js index f33a4b0cf8..0beca81788 100644 --- a/app/services/import/persist-licence-versions.service.js +++ b/app/services/import/persist-licence-versions.service.js @@ -56,9 +56,7 @@ async function _saveLicenceVersionPurposes (purpose, licenceVersionId) { ...purpose, primaryPurposeId: primaryPurpose.id, secondaryPurposeId: secondaryPurpose.id, - purposeId: purposeUse.id, - createdAt: new Date().toISOString(), - updatedAt: new Date().toISOString() + purposeId: purposeUse.id }) .onConflict('externalId') .merge([ @@ -84,10 +82,7 @@ async function _saveLicenceVersion (version, licenceId) { return LicenceVersionModel.query() .insert({ ...version, - licenceId, - // TODO: lift out to presenters - createdAt: new Date().toISOString(), - updatedAt: new Date().toISOString() + licenceId }) .onConflict('externalId') .merge([ diff --git a/db/migrations/legacy/20221108007007_water-licence-versions.js b/db/migrations/legacy/20221108007007_water-licence-versions.js index 78f2fbefaa..7efcbfa0be 100644 --- a/db/migrations/legacy/20221108007007_water-licence-versions.js +++ b/db/migrations/legacy/20221108007007_water-licence-versions.js @@ -22,8 +22,8 @@ exports.up = function (knex) { // Legacy timestamps // NOTE: They are not automatically set - table.timestamp('date_created', { useTz: false }).notNullable() - table.timestamp('date_updated', { useTz: false }).notNullable() + table.timestamp('date_created', { useTz: false }).notNullable().defaultTo(knex.fn.now()) + table.timestamp('date_updated', { useTz: false }).notNullable().defaultTo(knex.fn.now()) }) } diff --git a/db/migrations/legacy/20221108007008_water-licence-version-purposes-table.js b/db/migrations/legacy/20221108007008_water-licence-version-purposes-table.js index 453badc500..d90f4a135d 100644 --- a/db/migrations/legacy/20221108007008_water-licence-version-purposes-table.js +++ b/db/migrations/legacy/20221108007008_water-licence-version-purposes-table.js @@ -31,8 +31,8 @@ exports.up = function (knex) { // Legacy timestamps // NOTE: They are not automatically set - table.dateTime('date_created').notNullable() - table.dateTime('date_updated').notNullable() + table.dateTime('date_created').notNullable().defaultTo(knex.fn.now()) + table.dateTime('date_updated').notNullable().defaultTo(knex.fn.now()) // Constraints table.unique(['external_id'], { useConstraint: true }) From 0b9682911956580fb77b5edc0d80b5fe089f9c40 Mon Sep 17 00:00:00 2001 From: jonathangoulding Date: Thu, 22 Aug 2024 16:57:42 +0100 Subject: [PATCH 74/75] chore: fix lint --- app/controllers/import.controller.js | 5 +++++ app/presenters/import/legacy/licence.presenter.js | 5 ++++- .../import/legacy/fetch-licence-versions.service.js | 4 ++-- app/services/import/legacy/fetch-licence.service.js | 2 +- app/services/import/legacy/process-licence.service.js | 3 ++- .../licence-version-purpose-condition.validator.js | 2 +- app/validators/import/licence.validator.js | 7 +++++++ .../_fixtures/import-licence-versions.fixture.js | 11 ++++++++++- .../import/_fixtures/import-licence.fixture.js | 11 ++++++++++- .../legacy-licence-version-purpose.fixture.js | 7 ++++++- .../_fixtures/legacy-licence-version.fixture.js | 7 ++++++- .../import/_fixtures/legacy-licence.fixture.js | 7 ++++++- 12 files changed, 60 insertions(+), 11 deletions(-) diff --git a/app/controllers/import.controller.js b/app/controllers/import.controller.js index 9d3c6394ad..f2ae828f57 100644 --- a/app/controllers/import.controller.js +++ b/app/controllers/import.controller.js @@ -5,6 +5,11 @@ const ImportLegacyProcessLicenceService = require('../services/import/legacy/pro /** * Controller for /import + * @param request - the hapi request object + * @param h - the hapi response object + * + * @returns {object} + * * @module ImportController */ async function licence (request, h) { diff --git a/app/presenters/import/legacy/licence.presenter.js b/app/presenters/import/legacy/licence.presenter.js index 906919c2bb..e9bb7b9827 100644 --- a/app/presenters/import/legacy/licence.presenter.js +++ b/app/presenters/import/legacy/licence.presenter.js @@ -35,6 +35,9 @@ function _mapLicence (licence, licenceVersions) { /** * Creates a JSON object of the region data * This is stored as a JSON object in the licence.regions column. + * @param licenceData + * + * @returns {object} - the json structure to persist in the licence.regions column */ const _regions = (licenceData) => { const historicalAreaCode = licenceData.AREP_AREA_CODE @@ -56,7 +59,7 @@ const _regions = (licenceData) => { * * @param {object} licence - the legacy licence data * @param {object[]} licenceVersions - the legacy licence versions - * @return {String} YYYY-MM-DD + * @returns {string} YYYY-MM-DD */ const _startDate = (licence, licenceVersions) => { if (licence.ORIG_EFF_DATE !== 'null') { diff --git a/app/services/import/legacy/fetch-licence-versions.service.js b/app/services/import/legacy/fetch-licence-versions.service.js index daccae8687..fccdd03427 100644 --- a/app/services/import/legacy/fetch-licence-versions.service.js +++ b/app/services/import/legacy/fetch-licence-versions.service.js @@ -73,7 +73,7 @@ module.exports = { /** * A legacy licence version - * @typedef {Object} ImportLegacyLicenceVersionsType + * @typedef {object} ImportLegacyLicenceVersionsType * * @property {string} EFF_END_DATE - date in UK format - can be 'null' * @property {string} EFF_ST_DATE - date in UK format @@ -86,7 +86,7 @@ module.exports = { */ /** - * @typedef {Object} ImportLegacyLicenceVersionsPurposesType + * @typedef {object} ImportLegacyLicenceVersionsPurposesType * * @property {string} PERIOD_END_DAY - The end day of the period. * @property {string} PERIOD_END_MONTH - The end month of the period. diff --git a/app/services/import/legacy/fetch-licence.service.js b/app/services/import/legacy/fetch-licence.service.js index 6947b717cf..09b22080a4 100644 --- a/app/services/import/legacy/fetch-licence.service.js +++ b/app/services/import/legacy/fetch-licence.service.js @@ -48,7 +48,7 @@ module.exports = { /** * An Import legacy licence * - * @typedef {Object} ImportLegacyLicenceType + * @typedef {object} ImportLegacyLicenceType * * @property {string} AREP_AREA_CODE - historicalAreaCode * @property {string} AREP_EIUC_CODE - regionPrefix / regionalChargeArea diff --git a/app/services/import/legacy/process-licence.service.js b/app/services/import/legacy/process-licence.service.js index ec5eaba27b..5a23f86e27 100644 --- a/app/services/import/legacy/process-licence.service.js +++ b/app/services/import/legacy/process-licence.service.js @@ -18,7 +18,8 @@ const { currentTimeInNanoseconds, calculateAndLogTimeTaken } = require('../../.. * Imports a licence from the legacy import tables. Maps and validates the data and then saves to the database. * * @param {string} licenceRef - The licence reference of the licence - * @returns {Promise} an object representing the saved licence in the database + * + * @returns {Promise} an object representing the saved licence in the database */ async function go (licenceRef) { try { diff --git a/app/validators/import/licence-version-purpose-condition.validator.js b/app/validators/import/licence-version-purpose-condition.validator.js index f1af72deac..d6531ce6d0 100644 --- a/app/validators/import/licence-version-purpose-condition.validator.js +++ b/app/validators/import/licence-version-purpose-condition.validator.js @@ -14,7 +14,7 @@ const Joi = require('joi') * * @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({ licenceVersionPurposeId: Joi.string().guid().optional(), diff --git a/app/validators/import/licence.validator.js b/app/validators/import/licence.validator.js index 2cd685496d..c7862fca3a 100644 --- a/app/validators/import/licence.validator.js +++ b/app/validators/import/licence.validator.js @@ -28,6 +28,13 @@ const Joi = require('joi') * @throws {Error} - throw an error if any of the validations fail */ +/** + * Validate an import licence to persist in the database + * + * @param data + * + * @throws {error} - the first error from the validation failure + */ function go (data) { const result = _schema.validate(data) diff --git a/test/services/import/_fixtures/import-licence-versions.fixture.js b/test/services/import/_fixtures/import-licence-versions.fixture.js index 502ac8985a..5245b90612 100644 --- a/test/services/import/_fixtures/import-licence-versions.fixture.js +++ b/test/services/import/_fixtures/import-licence-versions.fixture.js @@ -33,7 +33,16 @@ function _createtLicenceVersion () { } } -function create (data) { +/** + * Creates a test import licence versions object with purposes + * + * This is the object we expect to see when we persist the data for the licence versions and purposes + * + * This object should pass the validation + * + * @returns {object} - an import licence object with purposes + */ +function create () { const defaults = [ { ..._createtLicenceVersion(), diff --git a/test/services/import/_fixtures/import-licence.fixture.js b/test/services/import/_fixtures/import-licence.fixture.js index 4f48a0d62a..59f355c5cb 100644 --- a/test/services/import/_fixtures/import-licence.fixture.js +++ b/test/services/import/_fixtures/import-licence.fixture.js @@ -25,7 +25,16 @@ function importLicence () { } } -function create (data) { +/** + * Creates a test import licence object + * + * This is the object we expect to see when we persist the data + * + * This object should pass the validation + * + * @returns {object} - an import licence object + */ +function create () { return { ...importLicence() } diff --git a/test/services/import/_fixtures/legacy-licence-version-purpose.fixture.js b/test/services/import/_fixtures/legacy-licence-version-purpose.fixture.js index 56706bd995..9396b55e92 100644 --- a/test/services/import/_fixtures/legacy-licence-version-purpose.fixture.js +++ b/test/services/import/_fixtures/legacy-licence-version-purpose.fixture.js @@ -21,7 +21,12 @@ function purpose () { } } -function create (data) { +/** + * Creates a test legacy import licence versions purpose object + * + * @returns {object} - a legacy import licence versions purpose object + */ +function create () { return { ...purpose() } diff --git a/test/services/import/_fixtures/legacy-licence-version.fixture.js b/test/services/import/_fixtures/legacy-licence-version.fixture.js index 454f3d789a..1497efc679 100644 --- a/test/services/import/_fixtures/legacy-licence-version.fixture.js +++ b/test/services/import/_fixtures/legacy-licence-version.fixture.js @@ -13,7 +13,12 @@ function legacyLicenceVersionFixture () { } } -function create (data) { +/** + * Creates a test legacy import licence versions object + * + * @returns {object} - a legacy import licence versions object + */ +function create () { return { ...legacyLicenceVersionFixture() } diff --git a/test/services/import/_fixtures/legacy-licence.fixture.js b/test/services/import/_fixtures/legacy-licence.fixture.js index 8fb18440b8..75d7ab6269 100644 --- a/test/services/import/_fixtures/legacy-licence.fixture.js +++ b/test/services/import/_fixtures/legacy-licence.fixture.js @@ -18,7 +18,12 @@ function legacyLicenceFixture () { } } -function create (data) { +/** + * Creates a test legacy import licence object + * + * @returns {object} - a legacy import licence object + */ +function create () { return { ...legacyLicenceFixture() } From 3e9a7a6cc18659eaf14fa1c33fea8536d141150f Mon Sep 17 00:00:00 2001 From: Alan Cruikshanks Date: Tue, 27 Aug 2024 11:17:35 +0100 Subject: [PATCH 75/75] Alans suggested import licence version changes (#1286) https://eaflood.atlassian.net/browse/WATER-4575 In this instance, we felt it was more constructive to provide the feedback for the original [Import Licence versions](https://github.com/DEFRA/water-abstraction-system/pull/1195) proposed PR as a series of commits from where the code has been left. This can be used to guide suggested changes, hopefully with better context than just PR comments. --- As I went through making these changes, I realised I was aiming for three outcomes; - simplify the work of the mappers by moving casting and some data generation into the fetch service queries - separate as much as possible the process for importing each entity (licence, licence version etc) - persist as one using a DB transaction to avoid risk of partial licences The commits themselves go into more details but very happy and glad to walk through the changes I'm suggesting. --- app/controllers/import.controller.js | 4 +- .../licence-version-purpose.presenter.js | 38 + .../legacy/licence-version.presenter.js | 35 + .../legacy/licence-versions.presenter.js | 76 -- .../import/legacy/licence.presenter.js | 77 +- app/routes/import.routes.js | 4 +- app/services/import/legacy-licence.service.js | 0 .../fetch-licence-version-purposes.service.js | 120 +++ .../legacy/fetch-licence-versions.service.js | 125 +-- .../import/legacy/fetch-licence.service.js | 108 +- .../import/legacy/process-licence.service.js | 32 +- ...nsform-licence-version-purposes.service.js | 46 + .../transform-licence-versions.service.js | 35 + .../legacy/transform-licence.service.js | 35 + .../persist-licence-versions.service.js | 99 -- .../import/persist-licence.service.js | 97 +- .../import/validate-licence.service.js | 26 - .../import/licence-structure.validator.js | 55 + .../licence-version-purpose.validator.js | 72 ++ .../import/licence-version.validator.js | 38 + .../import/licence-versions.validator.js | 108 -- app/validators/import/licence.validator.js | 75 +- test/controllers/import.controller.test.js | 6 +- .../licence-version-purpose.presenter.test.js | 63 ++ .../legacy/licence-version.presenter.test.js | 66 ++ .../legacy/licence-versions.presenter.test.js | 417 -------- .../import/legacy/licence.presenter.test.js | 216 ++-- .../import-licence-versions.fixture.js | 58 -- .../_fixtures/import-licence.fixture.js | 45 - .../legacy-licence-version-purpose.fixture.js | 37 - .../legacy-licence-version.fixture.js | 29 - .../_fixtures/legacy-licence.fixture.js | 34 - .../legacy/process-licence.service.test.js | 223 ++-- ...m-licence-version-purposes.service.test.js | 125 +++ ...transform-licence-versions.service.test.js | 88 ++ .../legacy/transform-licence.service.test.js | 102 ++ .../persist-licence-versions.service.test.js | 407 -------- .../import/persist-licence.service.test.js | 294 ++++-- .../import/validate-licence.service.test.js | 43 - .../licence-structure.validator.test.js | 120 +++ .../licence-version-purpose.validator.test.js | 639 ++++++++++++ .../import/licence-version.validator.test.js | 233 +++++ .../import/licence-versions.validator.test.js | 955 ------------------ .../import/licence.validator.test.js | 540 +++++----- 44 files changed, 2844 insertions(+), 3201 deletions(-) create mode 100644 app/presenters/import/legacy/licence-version-purpose.presenter.js create mode 100644 app/presenters/import/legacy/licence-version.presenter.js delete mode 100644 app/presenters/import/legacy/licence-versions.presenter.js delete mode 100644 app/services/import/legacy-licence.service.js create mode 100644 app/services/import/legacy/fetch-licence-version-purposes.service.js create mode 100644 app/services/import/legacy/transform-licence-version-purposes.service.js create mode 100644 app/services/import/legacy/transform-licence-versions.service.js create mode 100644 app/services/import/legacy/transform-licence.service.js delete mode 100644 app/services/import/persist-licence-versions.service.js delete mode 100644 app/services/import/validate-licence.service.js create mode 100644 app/validators/import/licence-structure.validator.js create mode 100644 app/validators/import/licence-version-purpose.validator.js create mode 100644 app/validators/import/licence-version.validator.js delete mode 100644 app/validators/import/licence-versions.validator.js create mode 100644 test/presenters/import/legacy/licence-version-purpose.presenter.test.js create mode 100644 test/presenters/import/legacy/licence-version.presenter.test.js delete mode 100644 test/presenters/import/legacy/licence-versions.presenter.test.js delete mode 100644 test/services/import/_fixtures/import-licence-versions.fixture.js delete mode 100644 test/services/import/_fixtures/import-licence.fixture.js delete mode 100644 test/services/import/_fixtures/legacy-licence-version-purpose.fixture.js delete mode 100644 test/services/import/_fixtures/legacy-licence-version.fixture.js delete mode 100644 test/services/import/_fixtures/legacy-licence.fixture.js create mode 100644 test/services/import/legacy/transform-licence-version-purposes.service.test.js create mode 100644 test/services/import/legacy/transform-licence-versions.service.test.js create mode 100644 test/services/import/legacy/transform-licence.service.test.js delete mode 100644 test/services/import/persist-licence-versions.service.test.js delete mode 100644 test/services/import/validate-licence.service.test.js create mode 100644 test/validators/import/licence-structure.validator.test.js create mode 100644 test/validators/import/licence-version-purpose.validator.test.js create mode 100644 test/validators/import/licence-version.validator.test.js delete mode 100644 test/validators/import/licence-versions.validator.test.js diff --git a/app/controllers/import.controller.js b/app/controllers/import.controller.js index f2ae828f57..6067fbb014 100644 --- a/app/controllers/import.controller.js +++ b/app/controllers/import.controller.js @@ -12,7 +12,7 @@ const ImportLegacyProcessLicenceService = require('../services/import/legacy/pro * * @module ImportController */ -async function licence (request, h) { +async function licenceLegacy (request, h) { const { licenceRef } = request.payload if (FeatureFlags.enableSystemImportLegacyLicence) { @@ -23,5 +23,5 @@ async function licence (request, h) { } module.exports = { - licence + licenceLegacy } diff --git a/app/presenters/import/legacy/licence-version-purpose.presenter.js b/app/presenters/import/legacy/licence-version-purpose.presenter.js new file mode 100644 index 0000000000..f2d507a17b --- /dev/null +++ b/app/presenters/import/legacy/licence-version-purpose.presenter.js @@ -0,0 +1,38 @@ +'use strict' + +/** + * Maps the legacy NALD licence version purpose data to the WRLS format + * @module LicenceVersionPurposePresenter + */ + +/** + * Maps the legacy NALD licence version purpose data to the WRLS format + * + * @param {ImportLegacyLicenceVersionPurposeType} licenceVersionPurpose - the legacy NALD licence version purpose + * + * @returns {object} the NALD licence version purpose data transformed into the WRLS format ready for validation and + * persisting + */ +function go (licenceVersionPurpose) { + return { + abstractionPeriodEndDay: licenceVersionPurpose.abstraction_period_end_day, + abstractionPeriodEndMonth: licenceVersionPurpose.abstraction_period_end_month, + abstractionPeriodStartDay: licenceVersionPurpose.abstraction_period_start_day, + abstractionPeriodStartMonth: licenceVersionPurpose.abstraction_period_start_month, + annualQuantity: licenceVersionPurpose.annual_quantity, + dailyQuantity: licenceVersionPurpose.daily_quantity, + externalId: licenceVersionPurpose.external_id, + hourlyQuantity: licenceVersionPurpose.hourly_quantity, + instantQuantity: licenceVersionPurpose.instant_quantity, + notes: licenceVersionPurpose.notes, + primaryPurposeId: licenceVersionPurpose.primary_purpose_id, + purposeId: licenceVersionPurpose.purpose_id, + secondaryPurposeId: licenceVersionPurpose.secondary_purpose_id, + timeLimitedEndDate: licenceVersionPurpose.time_limited_end_date, + timeLimitedStartDate: licenceVersionPurpose.time_limited_start_date + } +} + +module.exports = { + go +} diff --git a/app/presenters/import/legacy/licence-version.presenter.js b/app/presenters/import/legacy/licence-version.presenter.js new file mode 100644 index 0000000000..90598f998c --- /dev/null +++ b/app/presenters/import/legacy/licence-version.presenter.js @@ -0,0 +1,35 @@ +'use strict' + +/** + * Maps legacy NALD licence version data to the WRLS format + * @module LicenceVersionPresenter + */ + +const NALD_STATUSES = { + CURR: 'current', + SUPER: 'superseded' +} + +/** + * Maps legacy NALD licence version data to the WRLS format + * + * @param {ImportLegacyLicenceVersionTyp} licenceVersion - the legacy NALD licence version + * + * @returns {object} the NALD licence version data transformed into the WRLS format ready for validation and persisting + */ +function go (licenceVersion) { + return { + endDate: licenceVersion.effective_end_date, + externalId: licenceVersion.external_id, + increment: licenceVersion.increment_number, + issue: licenceVersion.issue_no, + // Add an empty array property ready for when transforming and attaching licence version purposes + licenceVersionPurposes: [], + startDate: licenceVersion.effective_start_date, + status: NALD_STATUSES[licenceVersion.status] + } +} + +module.exports = { + go +} diff --git a/app/presenters/import/legacy/licence-versions.presenter.js b/app/presenters/import/legacy/licence-versions.presenter.js deleted file mode 100644 index 6c4a7873e1..0000000000 --- a/app/presenters/import/legacy/licence-versions.presenter.js +++ /dev/null @@ -1,76 +0,0 @@ -'use strict' - -/** - * Maps the import licence versions and licence versions purposes data - * @module LicenceVersionsPresenter - */ - -const { formatStandardDateToISO } = require('../../../lib/dates.lib.js') - -const statuses = { - CURR: 'current', - SUPER: 'superseded' -} - -/** - * Maps the import licence versions data - * - * @param {ImportLegacyLicenceVersionsType[]} licenceVersions - the legacy licence versions and purposes - * @returns {object[]} - mapped licence versions - */ -function go (licenceVersions) { - return _mapLicenceVersions(licenceVersions) -} - -const _createExternalId = (licenceVersion) => { - const { FGAC_REGION_CODE, AABL_ID, ISSUE_NO, INCR_NO } = licenceVersion - - return `${FGAC_REGION_CODE}:${AABL_ID}:${ISSUE_NO}:${INCR_NO}` -} - -function _mapLicenceVersions (licenceVersions) { - return licenceVersions.map((licenceVersion) => { - const issue = licenceVersion.ISSUE_NO - const increment = licenceVersion.INCR_NO - - return { - endDate: formatStandardDateToISO(licenceVersion.EFF_END_DATE), - externalId: _createExternalId(licenceVersion), - increment: Number(increment), - issue: Number(issue), - startDate: formatStandardDateToISO(licenceVersion.EFF_ST_DATE), - status: statuses[licenceVersion.STATUS], - purposes: _mapPurposes(licenceVersion) - } - }) -} - -function _mapPurposes (licenceVersion) { - return licenceVersion.purposes.map((purpose) => { - return _mapPurpose(purpose) - }) -} - -const _mapPurpose = (purpose) => { - return { - abstractionPeriodEndDay: Number(purpose.PERIOD_END_DAY), - abstractionPeriodEndMonth: Number(purpose.PERIOD_END_MONTH), - abstractionPeriodStartDay: Number(purpose.PERIOD_ST_DAY), - abstractionPeriodStartMonth: Number(purpose.PERIOD_ST_MONTH), - annualQuantity: purpose.ANNUAL_QTY === 'null' ? null : Number(purpose.ANNUAL_QTY), - dailyQuantity: purpose.DAILY_QTY === 'null' ? null : Number(purpose.DAILY_QTY), - externalId: `${purpose.FGAC_REGION_CODE}:${purpose.ID}`, - hourlyQuantity: purpose.HOURLY_QTY === 'null' ? null : Number(purpose.HOURLY_QTY), - instantQuantity: purpose.INST_QTY === 'null' ? null : Number(purpose.INST_QTY), - notes: purpose.NOTES === 'null' ? null : purpose.NOTES, - primaryPurposeId: purpose.APUR_APPR_CODE, - secondaryPurposeId: purpose.APUR_APSE_CODE, - purposeId: purpose.APUR_APUS_CODE, - timeLimitedEndDate: formatStandardDateToISO(purpose.TIMELTD_END_DATE), - timeLimitedStartDate: formatStandardDateToISO(purpose.TIMELTD_ST_DATE) - } -} - -module.exports = { - go -} diff --git a/app/presenters/import/legacy/licence.presenter.js b/app/presenters/import/legacy/licence.presenter.js index e9bb7b9827..d9d430a44f 100644 --- a/app/presenters/import/legacy/licence.presenter.js +++ b/app/presenters/import/legacy/licence.presenter.js @@ -1,80 +1,55 @@ 'use strict' /** - * Maps the import data to the desired format + * Maps the legacy NALD licence data to the WRLS format * @module LicencePresenter */ -const { formatStandardDateToISO } = require('../../../lib/dates.lib.js') const { naldRegions } = require('../../../lib/static-lookups.lib.js') /** - * Maps the import data to the desired format + * Maps the legacy NALD licence data to the WRLS format * - * @param {ImportLegacyLicenceType} licence - the legacy licence - * @param {ImportLegacyLicenceVersionsType[]} licenceVersions - the legacy licence versions and purposes - * @returns {object} + * @param {ImportLegacyLicenceType} licence - the legacy NALD licence + * + * @returns {object} the NALD licence data transformed into the WRLS format ready for validation and persisting */ -function go (licence, licenceVersions = []) { - return _mapLicence(licence, licenceVersions) -} - -function _mapLicence (licence, licenceVersions) { +function go (licence) { return { - expiredDate: formatStandardDateToISO(licence.EXPIRY_DATE), - lapsedDate: formatStandardDateToISO(licence.LAPSED_DATE), - licenceRef: licence.LIC_NO, - regionId: parseInt(licence.FGAC_REGION_CODE, 10), + expiredDate: licence.expiry_date, + lapsedDate: licence.lapsed_date, + licenceRef: licence.licence_ref, + // Add an empty array property ready for when transforming and attaching licence versions + licenceVersions: [], + regionId: licence.region_id, regions: _regions(licence), - revokedDate: formatStandardDateToISO(licence.REV_DATE), - startDate: _startDate(licence, licenceVersions), - waterUndertaker: licence.AREP_EIUC_CODE.endsWith('SWC') + revokedDate: licence.revoked_date, + startDate: _startDate(licence), + waterUndertaker: licence.environmental_improvement_unit_charge_code.endsWith('SWC') } } /** - * Creates a JSON object of the region data - * This is stored as a JSON object in the licence.regions column. - * @param licenceData + * Creates a JSON object of the region data. This is stored as a JSON object in the licence.regions column. * - * @returns {object} - the json structure to persist in the licence.regions column + * @private */ -const _regions = (licenceData) => { - const historicalAreaCode = licenceData.AREP_AREA_CODE - const regionPrefix = licenceData.AREP_EIUC_CODE.substr(0, 2) +const _regions = (licence) => { + const historicalAreaCode = licence.historical_area_code + const regionPrefix = licence.environmental_improvement_unit_charge_code.substr(0, 2) const regionalChargeArea = naldRegions[regionPrefix] - const standardUnitChargeCode = licenceData.AREP_SUC_CODE - const localEnvironmentAgencyPlanCode = licenceData.AREP_LEAP_CODE + const standardUnitChargeCode = licence.standard_unit_charge_code + const localEnvironmentAgencyPlanCode = licence.local_environment_agency_plan_code return { historicalAreaCode, regionalChargeArea, standardUnitChargeCode, localEnvironmentAgencyPlanCode } } -/** - * Maps the licence and licence versions to a start date. - * If the licence ORIG_EFF_DATE is not null, this is used. - * Otherwise the start date of the earliest non-draft licence - * version is used. - * - * It is assumed one of these will always exist - * - * @param {object} licence - the legacy licence data - * @param {object[]} licenceVersions - the legacy licence versions - * @returns {string} YYYY-MM-DD - */ -const _startDate = (licence, licenceVersions) => { - if (licence.ORIG_EFF_DATE !== 'null') { - return formatStandardDateToISO(licence.ORIG_EFF_DATE) +function _startDate (licence) { + if (licence.original_effective_date) { + return licence.original_effective_date } - return licenceVersions - .filter((version) => { return version.STATUS !== 'DRAFT' }) - .map((version) => { - return formatStandardDateToISO(version.EFF_ST_DATE) - }) - .sort((a, b) => { - return new Date(a) - new Date(b) - }) - .shift() + return licence.earliest_version_start_date } module.exports = { diff --git a/app/routes/import.routes.js b/app/routes/import.routes.js index c58b8238aa..488457c2db 100644 --- a/app/routes/import.routes.js +++ b/app/routes/import.routes.js @@ -5,8 +5,8 @@ const ImportController = require('../controllers/import.controller.js') const routes = [ { method: 'POST', - path: '/import/licence', - handler: ImportController.licence, + path: '/import/licence/legacy', + handler: ImportController.licenceLegacy, options: { app: { plainOutput: true diff --git a/app/services/import/legacy-licence.service.js b/app/services/import/legacy-licence.service.js deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/app/services/import/legacy/fetch-licence-version-purposes.service.js b/app/services/import/legacy/fetch-licence-version-purposes.service.js new file mode 100644 index 0000000000..516cdfe604 --- /dev/null +++ b/app/services/import/legacy/fetch-licence-version-purposes.service.js @@ -0,0 +1,120 @@ +'use strict' + +/** + * Fetches the licence version purposes data from the import.NALD_ABS_LIC_PURPOSES table for the licence being imported + * @module FetchLicenceVersionPurposesService + */ + +const { db } = require('../../../../db/db.js') + +/** + * Fetches the licence version purposes data from the import.NALD_ABS_LIC_PURPOSES table for the licence being imported + * + * @param {string} regionCode - The NALD region code + * @param {string} licenceId - The NALD licence ID + * + * @returns {Promise} + */ +async function go (regionCode, licenceId) { + const query = _query() + + const { rows } = await db.raw(query, [regionCode, licenceId]) + + return rows +} + +function _query () { + return ` + SELECT + (nalp."PERIOD_END_DAY")::INTEGER AS abstraction_period_end_day, + (nalp."PERIOD_END_MONTH")::INTEGER AS abstraction_period_end_month, + (nalp."PERIOD_ST_DAY")::INTEGER AS abstraction_period_start_day, + (nalp."PERIOD_ST_MONTH")::INTEGER AS abstraction_period_start_month, + ( + CASE nalp."ANNUAL_QTY" + WHEN 'null' THEN NULL + ELSE (nalp."ANNUAL_QTY")::NUMERIC + END + ) AS annual_quantity, + ( + CASE nalp."DAILY_QTY" + WHEN 'null' THEN NULL + ELSE (nalp."DAILY_QTY")::NUMERIC + END + ) AS daily_quantity, + (concat_ws(':', nalp."FGAC_REGION_CODE", nalp."ID")) AS external_id, + ( + CASE nalp."HOURLY_QTY" + WHEN 'null' THEN NULL + ELSE (nalp."HOURLY_QTY")::NUMERIC + END + ) AS hourly_quantity, + ( + CASE nalp."INST_QTY" + WHEN 'null' THEN NULL + ELSE (nalp."INST_QTY")::NUMERIC + END + ) AS instant_quantity, + ( + CASE nalp."NOTES" + WHEN 'null' THEN NULL + ELSE nalp."NOTES" + END + ) AS notes, + pp.id AS primary_purpose_id, + p.id AS purpose_id, + sp.id AS secondary_purpose_id, + ( + CASE nalp."TIMELTD_END_DATE" + WHEN 'null' THEN NULL + ELSE to_date(nalp."TIMELTD_END_DATE", 'DD/MM/YYYY') + END + ) AS time_limited_end_date, + ( + CASE nalp."TIMELTD_ST_DATE" + WHEN 'null' THEN NULL + ELSE to_date(nalp."TIMELTD_ST_DATE", 'DD/MM/YYYY') + END + ) AS time_limited_start_date, + (concat_ws(':', nalv."FGAC_REGION_CODE", nalv."AABL_ID", nalv."ISSUE_NO", nalv."INCR_NO")) AS version_external_id + FROM + "import"."NALD_ABS_LIC_PURPOSES" nalp + INNER JOIN + "import"."NALD_ABS_LIC_VERSIONS" nalv ON + concat_ws(':', nalv."FGAC_REGION_CODE", nalv."AABL_ID", nalv."ISSUE_NO", nalv."INCR_NO") = concat_ws(':', nalp."FGAC_REGION_CODE", nalp."AABV_AABL_ID", nalp."AABV_ISSUE_NO", nalp."AABV_INCR_NO") + LEFT JOIN + public.purposes p ON p.legacy_id = nalp."APUR_APUS_CODE" + LEFT JOIN + public.primary_purposes pp ON pp.legacy_id = nalp."APUR_APPR_CODE" + LEFT JOIN + public.secondary_purposes sp ON sp.legacy_id = nalp."APUR_APSE_CODE" + WHERE + nalp."FGAC_REGION_CODE" = ? + AND nalp."AABV_AABL_ID" = ? + AND nalv."STATUS" <> 'DRAFT'; + ` +} + +module.exports = { + go +} + +/** + * @typedef {object} ImportLegacyLicenceVersionPurposeType + * + * @property {number} abstraction_period_end_day + * @property {number} abstraction_period_end_month + * @property {number} abstraction_period_start_day + * @property {number} abstraction_period_start_month + * @property {number} annual_quantity + * @property {number} daily_quantity + * @property {number} hourly_quantity + * @property {number} instant_quantity + * @property {string} notes + * @property {string} primary_purpose_id + * @property {string} purpose_id + * @property {string} secondary_purpose_id + * @property {Date} time_limited_end_date + * @property {Date} time_limited_start_date + * @property {string} version_external_id + */ diff --git a/app/services/import/legacy/fetch-licence-versions.service.js b/app/services/import/legacy/fetch-licence-versions.service.js index fccdd03427..8ebaeda4e7 100644 --- a/app/services/import/legacy/fetch-licence-versions.service.js +++ b/app/services/import/legacy/fetch-licence-versions.service.js @@ -1,107 +1,68 @@ 'use strict' /** - * Service for /import/licence + * Fetches the licence versions data from the import.NALD_ABS_LIC_VERSIONS table for the licence being imported * @module FetchLicenceVersionsService */ const { db } = require('../../../../db/db.js') /** - * Gets the legacy licence versions + * Fetches the licence versions data from the import.NALD_ABS_LIC_VERSIONS table for the licence being imported * - * Returns the legacy licence version and purposes. + * @param {string} regionCode - The NALD region code + * @param {string} licenceId - The NALD licence ID * - * @param {ImportLegacyLicenceType} licenceData - The data related to the licence. - * - * @returns {Promise} + * @returns {Promise} */ -async function go (licenceData) { - const { ID: licenceId, FGAC_REGION_CODE: regionCode } = licenceData - - return _getLicenceVersions(licenceId, regionCode) -} - -async function _getLicenceVersions (licenceId, regionCode) { - const query = ` - SELECT - versions."EFF_END_DATE", - versions."EFF_ST_DATE", - versions."INCR_NO", - versions."ISSUE_NO", - versions."STATUS", - versions."FGAC_REGION_CODE", - versions."AABL_ID", - (SELECT json_agg(json_build_object( - 'PERIOD_END_DAY', purposes."PERIOD_END_DAY", - 'PERIOD_END_MONTH', purposes."PERIOD_END_MONTH", - 'PERIOD_ST_DAY', purposes."PERIOD_ST_DAY", - 'PERIOD_ST_MONTH', purposes."PERIOD_ST_MONTH", - 'ANNUAL_QTY', purposes."ANNUAL_QTY", - 'DAILY_QTY', purposes."DAILY_QTY", - 'FGAC_REGION_CODE', purposes."FGAC_REGION_CODE", - 'ID', purposes."ID", - 'HOURLY_QTY', purposes."HOURLY_QTY", - 'INST_QTY', purposes."INST_QTY", - 'NOTES', purposes."NOTES", - 'APUR_APPR_CODE', purposes."APUR_APPR_CODE", - 'APUR_APSE_CODE', purposes."APUR_APSE_CODE", - 'APUR_APUS_CODE', purposes."APUR_APUS_CODE", - 'TIMELTD_END_DATE', purposes."TIMELTD_END_DATE", - 'TIMELTD_ST_DATE', purposes."TIMELTD_ST_DATE" - ) - ) - FROM import."NALD_ABS_LIC_PURPOSES" purposes - WHERE purposes."AABV_AABL_ID" = versions."AABL_ID" - AND purposes."AABV_ISSUE_NO" = versions."ISSUE_NO" - AND purposes."AABV_INCR_NO" = versions."INCR_NO" - AND purposes."FGAC_REGION_CODE" = versions."FGAC_REGION_CODE") AS purposes - FROM import."NALD_ABS_LIC_VERSIONS" versions - WHERE versions."FGAC_REGION_CODE" = ? - AND versions."AABL_ID" = ? - AND versions."STATUS" <> 'DRAFT'; - ` +async function go (regionCode, licenceId) { + const query = _query() const { rows } = await db.raw(query, [regionCode, licenceId]) return rows } +function _query () { + return ` + SELECT + ( + CASE nalv."EFF_END_DATE" + WHEN 'null' THEN NULL + ELSE to_date(nalv."EFF_END_DATE", 'DD/MM/YYYY') + END + ) AS effective_end_date, + ( + CASE nalv."EFF_ST_DATE" + WHEN 'null' THEN NULL + ELSE to_date(nalv."EFF_ST_DATE", 'DD/MM/YYYY') + END + ) AS effective_start_date, + (concat_ws(':', nalv."FGAC_REGION_CODE", nalv."AABL_ID", nalv."ISSUE_NO", nalv."INCR_NO")) AS external_id, + (nalv."INCR_NO")::INTEGER AS increment_number, + (nalv."ISSUE_NO")::INTEGER AS issue_no, + nalv."STATUS" AS status + FROM + "import"."NALD_ABS_LIC_VERSIONS" nalv + WHERE + nalv."FGAC_REGION_CODE" = ? + AND nalv."AABL_ID" = ? + AND nalv."STATUS" <> 'DRAFT'; + ` +} + module.exports = { go } /** - * A legacy licence version - * @typedef {object} ImportLegacyLicenceVersionsType - * - * @property {string} EFF_END_DATE - date in UK format - can be 'null' - * @property {string} EFF_ST_DATE - date in UK format - * @property {string} INCR_NO - a number between 1 - 5 - * @property {string} ISSUE_NO - a number - * @property {string} STATUS - enum - 'DRAFT', 'SUPER', 'CURR' (Draft will not be selected) - * @property {string} FGAC_REGION_CODE - * @property {string} AABL_ID - * @property {ImportLegacyLicenceVersionsPurposesType} purposes - */ - -/** - * @typedef {object} ImportLegacyLicenceVersionsPurposesType + * Representation of a licence version fetched from the NALD data + * @typedef {object} ImportLegacyLicenceVersionType * - * @property {string} PERIOD_END_DAY - The end day of the period. - * @property {string} PERIOD_END_MONTH - The end month of the period. - * @property {string} PERIOD_ST_DAY - The start day of the period. - * @property {string} PERIOD_ST_MONTH - The start month of the period. - * @property {string} ANNUAL_QTY - The annual quantity. - * @property {string} DAILY_QTY - The daily quantity. - * @property {string} FGAC_REGION_CODE - The FGAC region code. - * @property {string} ID - * @property {string} HOURLY_QTY - The hourly quantity. - * @property {string} INST_QTY - The instant quantity. - * @property {string} NOTES - Additional notes. - * @property {string} APUR_APPR_CODE - The APUR approval code. - * @property {string} APUR_APSE_CODE - The APUR secondary code. - * @property {string} APUR_APUS_CODE - The APUR usage code. - * @property {string} TIMELTD_END_DATE - The time-limited end date. - * @property {string} TIMELTD_ST_DATE - The time-limited start date. + * @property {Date} effective_end_date + * @property {Date} effective_start_date + * @property {string} external_id + * @property {number} increment_number + * @property {number} issue_no + * @property {string} status */ diff --git a/app/services/import/legacy/fetch-licence.service.js b/app/services/import/legacy/fetch-licence.service.js index 09b22080a4..f55fdd107d 100644 --- a/app/services/import/legacy/fetch-licence.service.js +++ b/app/services/import/legacy/fetch-licence.service.js @@ -1,65 +1,101 @@ 'use strict' /** - * Service for /import/licence + * Fetches the licence data from the import.NALD_ABS_LICENCES table for the licence ref * @module FetchLicenceService */ const { db } = require('../../../../db/db.js') /** - * Fetches the licence data for the licence ref from the import.NALD_ABS_LICENCES table + * Fetches the licence data from the import.NALD_ABS_LICENCES table for the licence ref * - * @param {string} licenceRef - the licence ref + * @param {string} licenceRef - the licence ref to fetch * * @returns {Promise} */ async function go (licenceRef) { - return _getLicenceByRef(licenceRef) -} - -async function _getLicenceByRef (licenceRef) { - const query = ` - SELECT - licence."AREP_AREA_CODE", - licence."AREP_EIUC_CODE", - licence."AREP_LEAP_CODE", - licence."AREP_SUC_CODE", - licence."EXPIRY_DATE", - licence."FGAC_REGION_CODE", - licence."ID", - licence."LAPSED_DATE", - licence."LIC_NO", - licence."ORIG_EFF_DATE", - licence."REV_DATE" - FROM import."NALD_ABS_LICENCES" licence - WHERE licence."LIC_NO" = ?; - ` + const query = _query() const { rows: [row] } = await db.raw(query, [licenceRef]) return row } +function _query () { + return ` + SELECT + nal."AREP_AREA_CODE" AS historical_area_code, + nal."AREP_EIUC_CODE" AS environmental_improvement_unit_charge_code, + nal."AREP_LEAP_CODE" AS local_environment_agency_plan_code, + nal."AREP_SUC_CODE" AS standard_unit_charge_code, + ( + CASE nal."EXPIRY_DATE" + WHEN 'null' THEN NULL + ELSE to_date(nal."EXPIRY_DATE", 'DD/MM/YYYY') + END + ) AS expiry_date, + nal."FGAC_REGION_CODE" AS region_code, + nal."ID" AS id, + ( + CASE nal."LAPSED_DATE" + WHEN 'null' THEN NULL + ELSE to_date(nal."LAPSED_DATE", 'DD/MM/YYYY') + END + ) AS lapsed_date, + nal."LIC_NO" AS licence_ref, + ( + CASE nal."ORIG_EFF_DATE" + WHEN 'null' THEN NULL + ELSE to_date(nal."ORIG_EFF_DATE", 'DD/MM/YYYY') + END + ) AS original_effective_date, + ( + CASE nal."REV_DATE" + WHEN 'null' THEN NULL + ELSE to_date(nal."REV_DATE", 'DD/MM/YYYY') + END + ) AS revoked_date, + ( + SELECT + MIN(to_date(nalv."EFF_ST_DATE", 'DD/MM/YYYY')) + FROM + "import"."NALD_ABS_LIC_VERSIONS" nalv + WHERE + nalv."FGAC_REGION_CODE" = nal."FGAC_REGION_CODE" + AND nalv."AABL_ID" = nal."ID" + AND nalv."STATUS" <> 'DRAFT' + ) AS earliest_version_start_date, + r.id AS region_id + FROM + "import"."NALD_ABS_LICENCES" nal + LEFT JOIN + public.regions r ON r.nald_region_id = (nal."FGAC_REGION_CODE")::INTEGER + WHERE + nal."LIC_NO" = ?; + ` +} + module.exports = { go } /** - * An Import legacy licence + * Representation of a licence fetched from the NALD data * * @typedef {object} ImportLegacyLicenceType * - * @property {string} AREP_AREA_CODE - historicalAreaCode - * @property {string} AREP_EIUC_CODE - regionPrefix / regionalChargeArea - * @property {string} AREP_LEAP_CODE - localEnvironmentAgencyPlanCode - * @property {string} AREP_SUC_CODE - standardUnitChargeCode - * @property {string} AREP_AREA_CODE - regions - historicalAreaCode - * @property {string} AREP_EIUC_CODE - regions - regionPrefix / regionalChargeArea - * @property {string} AREP_LEAP_CODE - regions - localEnvironmentAgencyPlanCode - * @property {string} AREP_SUC_CODE - regions - standardUnitChargeCode - * @property {string} EXPIRY_DATE - * @property {string} ID - * @property {string} LAPSED_DATE - * @property {string} LIC_NO - Licence Ref + * @property {string} historical_area_code + * @property {string} environmental_improvement_unit_charge_code + * @property {string} local_environment_agency_plan_code + * @property {string} standard_unit_charge_code + * @property {Date} expiry_date + * @property {number} region_code + * @property {string} id + * @property {Date} lapsed_date + * @property {string} licence_ref + * @property {Date} original_effective_date + * @property {Date} revoked_date + * @property {Date} earliest_version_start_date + * @property {string} region_id */ diff --git a/app/services/import/legacy/process-licence.service.js b/app/services/import/legacy/process-licence.service.js index 5a23f86e27..9ce9018143 100644 --- a/app/services/import/legacy/process-licence.service.js +++ b/app/services/import/legacy/process-licence.service.js @@ -5,13 +5,11 @@ * @module ImportLegacyProcessLicenceService */ -const FetchLicenceService = require('./fetch-licence.service.js') -const FetchLicenceVersionsService = require('./fetch-licence-versions.service.js') -const ValidateLicenceService = require('../validate-licence.service.js') -const LicencePresenter = require('../../../presenters/import/legacy/licence.presenter.js') -const LicenceVersionsPresenter = require('../../../presenters/import/legacy/licence-versions.presenter.js') +const LicenceStructureValidator = require('../../../validators/import/licence-structure.validator.js') const PersistLicenceService = require('../persist-licence.service.js') -const PersistLicenceVersionsService = require('../persist-licence-versions.service.js') +const TransformLicenceService = require('./transform-licence.service.js') +const TransformLicenceVersionsService = require('./transform-licence-versions.service.js') +const TransformLicenceVersionPurposesService = require('./transform-licence-version-purposes.service.js') const { currentTimeInNanoseconds, calculateAndLogTimeTaken } = require('../../../lib/general.lib.js') /** @@ -25,22 +23,22 @@ async function go (licenceRef) { try { const startTime = currentTimeInNanoseconds() - const licenceData = await FetchLicenceService.go(licenceRef) + // Transform the parent legacy licence record first + const { naldLicenceId, regionCode, transformedLicence } = await TransformLicenceService.go(licenceRef) - const licenceVersionsData = await FetchLicenceVersionsService.go(licenceData) + // Pass the transformed licence through each transformation step, building the licence as we go + await TransformLicenceVersionsService.go(regionCode, naldLicenceId, transformedLicence) + await TransformLicenceVersionPurposesService.go(regionCode, naldLicenceId, transformedLicence) - const mappedLicenceData = LicencePresenter.go(licenceData, licenceVersionsData) + // Ensure the built licence has all the valid child records we require + LicenceStructureValidator.go(transformedLicence) - const mappedLicenceVersionsData = LicenceVersionsPresenter.go(licenceVersionsData) + // Either insert or update the licence in WRLS + const licenceId = await PersistLicenceService.go(transformedLicence) - ValidateLicenceService.go(mappedLicenceData, mappedLicenceVersionsData) - - const savedLicence = await PersistLicenceService.go(mappedLicenceData) - - await PersistLicenceVersionsService.go(mappedLicenceVersionsData, savedLicence.id) - calculateAndLogTimeTaken(startTime, 'Process licence', { licenceRef }) + calculateAndLogTimeTaken(startTime, 'Legacy licence import complete', { licenceId, licenceRef }) } catch (error) { - global.GlobalNotifier.omfg('Licence import failed', { licenceRef }, error) + global.GlobalNotifier.omfg('Legacy licence import errored', { licenceRef }, error) } } diff --git a/app/services/import/legacy/transform-licence-version-purposes.service.js b/app/services/import/legacy/transform-licence-version-purposes.service.js new file mode 100644 index 0000000000..8a854d15f2 --- /dev/null +++ b/app/services/import/legacy/transform-licence-version-purposes.service.js @@ -0,0 +1,46 @@ +'use strict' + +/** + * Transforms all NALD licence version purpose data into an object that matches the WRLS structure + * @module ImportLegacyTransformLicenceVersionPurposesService + */ + +const FetchLicenceVersionPurposesService = require('./fetch-licence-version-purposes.service.js') +const LicenceVersionPurposePresenter = require('../../../presenters/import/legacy/licence-version-purpose.presenter.js') +const LicenceVersionPurposeValidator = require('../../../validators/import/licence-version-purpose.validator.js') + +/** + * Transforms all NALD licence version purpose data into an object that matches the WRLS structure + * + * After transforming and validating the NALD licence version purpose data, it attaches it to the licence version on + * the licence we're importing. + * + * @param {string} regionCode - The NALD region code for the licence being imported + * @param {string} naldLicenceId - The NALD ID for the licence being imported + * @param {object} transformedLicence - An object representing a valid WRLS licence + */ +async function go (regionCode, naldLicenceId, transformedLicence) { + const naldLicenceVersionPurposes = await FetchLicenceVersionPurposesService.go(regionCode, naldLicenceId) + + naldLicenceVersionPurposes.forEach((naldLicenceVersionPurpose) => { + const matchingLicenceVersion = _matchingLicenceVersion( + transformedLicence.licenceVersions, naldLicenceVersionPurpose + ) + + const transformedLicenceVersionPurpose = LicenceVersionPurposePresenter.go(naldLicenceVersionPurpose) + + LicenceVersionPurposeValidator.go(transformedLicenceVersionPurpose) + + matchingLicenceVersion.licenceVersionPurposes.push(transformedLicenceVersionPurpose) + }) +} + +function _matchingLicenceVersion (licenceVersions, naldLicenceVersionPurpose) { + return licenceVersions.find((licenceVersion) => { + return licenceVersion.externalId === naldLicenceVersionPurpose.version_external_id + }) +} + +module.exports = { + go +} diff --git a/app/services/import/legacy/transform-licence-versions.service.js b/app/services/import/legacy/transform-licence-versions.service.js new file mode 100644 index 0000000000..8e139b0c93 --- /dev/null +++ b/app/services/import/legacy/transform-licence-versions.service.js @@ -0,0 +1,35 @@ +'use strict' + +/** + * Transforms all NALD licence version data into an object that matches the WRLS structure + * @module ImportLegacyTransformLicenceVersionsService + */ + +const FetchLicenceVersionsService = require('./fetch-licence-versions.service.js') +const LicenceVersionPresenter = require('../../../presenters/import/legacy/licence-version.presenter.js') +const LicenceVersionValidator = require('../../../validators/import/licence-version.validator.js') + +/** + * Transforms all NALD licence version data into an object that matches the WRLS structure + * + * After transforming and validating the NALD licence version data, it attaches it to the licence we're importing. + * + * @param {string} regionCode - The NALD region code for the licence being imported + * @param {string} naldLicenceId - The NALD ID for the licence being imported + * @param {object} transformedLicence - An object representing a valid WRLS licence + */ +async function go (regionCode, naldLicenceId, transformedLicence) { + const naldLicenceVersions = await FetchLicenceVersionsService.go(regionCode, naldLicenceId) + + naldLicenceVersions.forEach((naldLicenceVersion) => { + const transformedLicenceVersion = LicenceVersionPresenter.go(naldLicenceVersion) + + LicenceVersionValidator.go(transformedLicenceVersion) + + transformedLicence.licenceVersions.push(transformedLicenceVersion) + }) +} + +module.exports = { + go +} diff --git a/app/services/import/legacy/transform-licence.service.js b/app/services/import/legacy/transform-licence.service.js new file mode 100644 index 0000000000..463641a1bb --- /dev/null +++ b/app/services/import/legacy/transform-licence.service.js @@ -0,0 +1,35 @@ +'use strict' + +/** + * Transforms NALD licence data into a valid object that matches the WRLS structure + * @module ImportLegacyTransformLicenceService + */ + +const FetchLicenceService = require('./fetch-licence.service.js') +const LicencePresenter = require('../../../presenters/import/legacy/licence.presenter.js') +const LicenceValidator = require('../../../validators/import/licence.validator.js') + +/** + * Transforms NALD licence data into a validated object that matches the WRLS structure + * + * @param {string} licenceRef - The reference of the licence to be imported from NALD + * + * @returns {Promise} an object representing a valid WRLS licence + */ +async function go (licenceRef) { + const naldLicence = await FetchLicenceService.go(licenceRef) + + const transformedLicence = LicencePresenter.go(naldLicence) + + LicenceValidator.go(transformedLicence) + + return { + naldLicenceId: naldLicence.id, + regionCode: naldLicence.region_code, + transformedLicence + } +} + +module.exports = { + go +} diff --git a/app/services/import/persist-licence-versions.service.js b/app/services/import/persist-licence-versions.service.js deleted file mode 100644 index 0beca81788..0000000000 --- a/app/services/import/persist-licence-versions.service.js +++ /dev/null @@ -1,99 +0,0 @@ -'use strict' - -/** - * Persists the licence versions, purposes and conditions - * @module PersistLicenceVersionsService - */ - -const LicenceVersionModel = require('../../models/licence-version.model.js') -const LicenceVersionPurposeModel = require('../../models/licence-version-purpose.model.js') -const PrimaryPurposeModel = require('../../models/primary-purpose.model.js') -const SecondaryPurposeModel = require('../../models/secondary-purpose.model.js') -const PurposeModel = require('../../models/purpose.model.js') - -/** - * Saves the licence versions, purposes and conditions - * - * @param {object[]} licenceVersions - * @param {string} licenceId - */ -async function go (licenceVersions, licenceId) { - await Promise.all(licenceVersions.map(async (version) => { - const purposes = version.purposes - - delete version.purposes - - const versionResult = await _saveLicenceVersion(version, licenceId) - - await Promise.all(purposes.map(async (purpose) => { - return _saveLicenceVersionPurposes(purpose, versionResult.id) - })) - })) -} - -async function _saveLicenceVersionPurposes (purpose, licenceVersionId) { - const primaryPurpose = await PrimaryPurposeModel.query() - .select('id') - .where('legacyId', purpose.primaryPurposeId) - .first() - .limit(1) - - const secondaryPurpose = await SecondaryPurposeModel.query() - .select('id') - .where('legacyId', purpose.secondaryPurposeId) - .first() - .limit(1) - - const purposeUse = await PurposeModel.query() - .select('id') - .where('legacyId', purpose.purposeId) - .first() - .limit(1) - - await LicenceVersionPurposeModel.query() - .insert({ - licenceVersionId, - ...purpose, - primaryPurposeId: primaryPurpose.id, - secondaryPurposeId: secondaryPurpose.id, - purposeId: purposeUse.id - }) - .onConflict('externalId') - .merge([ - 'abstractionPeriodEndDay', - 'abstractionPeriodEndMonth', - 'abstractionPeriodStartDay', - 'abstractionPeriodStartMonth', - 'annualQuantity', - 'dailyQuantity', - 'hourlyQuantity', - 'instantQuantity', - 'notes', - 'primaryPurposeId', - 'purposeId', - 'secondaryPurposeId', - 'timeLimitedEndDate', - 'timeLimitedStartDate', - 'updatedAt' - ]) -} - -async function _saveLicenceVersion (version, licenceId) { - return LicenceVersionModel.query() - .insert({ - ...version, - licenceId - }) - .onConflict('externalId') - .merge([ - 'licenceId', - 'status', - 'startDate', - 'endDate', - 'updatedAt' - ]) -} - -module.exports = { - go -} diff --git a/app/services/import/persist-licence.service.js b/app/services/import/persist-licence.service.js index f37e0d098d..2d5cc651b8 100644 --- a/app/services/import/persist-licence.service.js +++ b/app/services/import/persist-licence.service.js @@ -1,31 +1,38 @@ 'use strict' /** - * Persists the licence + * Creates or updates an imported licence and its child entities that have been transformed and validated * @module PersistLicenceService */ +const { timestampForPostgres } = require('../../lib/general.lib.js') const LicenceModel = require('../../models/licence.model.js') -const RegionModel = require('../../models/region.model.js') +const LicenceVersionModel = require('../../models/licence-version.model.js') +const LicenceVersionPurposeModel = require('../../models/licence-version-purpose.model.js') /** - * Saves the licence versions, purposes and conditions + * Creates or updates an imported licence and its child entities that have been transformed and validated * - * @param {object} licenceData - the mapped and validated licence to persist - * @returns {Promise} + * @param {object} transformedLicence - An object representing a valid WRLS licence + * + * @returns {Promise} */ -async function go (licenceData) { - const region = await RegionModel.query() - .select(['id']) - .where('naldRegionId', licenceData.regionId) - .limit(1) - .first() - - return LicenceModel.query() - .insert({ - ...licenceData, - regionId: region.id - }) +async function go (transformedLicence) { + return LicenceModel.transaction(async (trx) => { + const updatedAt = timestampForPostgres() + const { id } = await _persistLicence(trx, updatedAt, transformedLicence) + + await _persistLicenceVersions(trx, updatedAt, transformedLicence.licenceVersions, id) + + return id + }) +} + +async function _persistLicence (trx, updatedAt, licence) { + const { licenceVersions, ...propertiesToPersist } = licence + + return LicenceModel.query(trx) + .insert({ ...propertiesToPersist, updatedAt }) .onConflict('licenceRef') .merge([ 'expiredDate', @@ -36,6 +43,62 @@ async function go (licenceData) { 'updatedAt', 'waterUndertaker' ]) + .returning('id') +} + +async function _persistLicenceVersion (trx, updatedAt, licenceVersion, licenceId) { + const { licenceVersionPurposes, ...propertiesToPersist } = licenceVersion + + return LicenceVersionModel.query(trx) + .insert({ ...propertiesToPersist, licenceId, updatedAt }) + .onConflict('externalId') + .merge([ + 'endDate', + 'startDate', + 'status', + 'updatedAt' + ]) + .returning('id') +} + +async function _persistLicenceVersions (trx, updatedAt, licenceVersions, licenceId) { + for (const licenceVersion of licenceVersions) { + const { id } = await _persistLicenceVersion(trx, updatedAt, licenceVersion, licenceId) + + await _persistLicenceVersionPurposes(trx, updatedAt, licenceVersion.licenceVersionPurposes, id) + } +} + +async function _persistLicenceVersionPurpose (trx, updatedAt, licenceVersionPurpose, licenceVersionId) { + const { ...propertiesToPersist } = licenceVersionPurpose + + return LicenceVersionPurposeModel.query(trx) + .insert({ ...propertiesToPersist, licenceVersionId, updatedAt }) + .onConflict('externalId') + .merge([ + 'abstractionPeriodEndDay', + 'abstractionPeriodEndMonth', + 'abstractionPeriodStartDay', + 'abstractionPeriodStartMonth', + 'annualQuantity', + 'dailyQuantity', + 'hourlyQuantity', + 'instantQuantity', + 'notes', + 'primaryPurposeId', + 'purposeId', + 'secondaryPurposeId', + 'timeLimitedEndDate', + 'timeLimitedStartDate', + 'updatedAt' + ]) + .returning('id') +} + +async function _persistLicenceVersionPurposes (trx, updatedAt, licenceVersionPurposes, licenceVersionId) { + for (const licenceVersionPurpose of licenceVersionPurposes) { + await _persistLicenceVersionPurpose(trx, updatedAt, licenceVersionPurpose, licenceVersionId) + } } module.exports = { diff --git a/app/services/import/validate-licence.service.js b/app/services/import/validate-licence.service.js deleted file mode 100644 index 6a9212b4a0..0000000000 --- a/app/services/import/validate-licence.service.js +++ /dev/null @@ -1,26 +0,0 @@ -'use strict' - -/** - * Validates a import licence object - * @module ValidateLicenceService - */ - -const ImportLicenceValidator = require('../../validators/import/licence.validator.js') -const ImportLicenceVersionsValidator = require('../../validators/import/licence-versions.validator.js') - -/** - * Validates an import licence is in the correct shape and format to persist in the database - * - * If the validation fails throw an error - * - * @param {object} licence - The licence to validate - * @param {object[]} licenceVersions - The licence versions to validate - */ -function go (licence, licenceVersions) { - ImportLicenceValidator.go(licence) - ImportLicenceVersionsValidator.go(licenceVersions) -} - -module.exports = { - go -} diff --git a/app/validators/import/licence-structure.validator.js b/app/validators/import/licence-structure.validator.js new file mode 100644 index 0000000000..21ed5840ca --- /dev/null +++ b/app/validators/import/licence-structure.validator.js @@ -0,0 +1,55 @@ +'use strict' + +/** + * @module ImportLicenceStructureValidator + */ + +const Joi = require('joi') + +/** + * Checks that the transformed licence has a structure valid for persisting to WRLS + * + * The data assigned to the licence object will have already been validated by `ImportLicenceValidator`. This validator + * is ensuring the licence has a valid structure. For example, that it has at least 1 licence version, which in turn has + * at least 1 licence version purpose. + * + * Only if the data against a licence and its child records is valid, and the overall structure of the licence is valid + * should we be attempting to import it. + * + * A valid licence structure is the following. Some properties must contain at least one child object to be valid. Those + * that are optional we leave empty. + * + * ```javascript + * { + * licenceVersions: [{ + * licenceVersionPurposes: [{ + * licenceVersionPurposeConditions: [] + * }] + * }] + * } + * ``` + * + * @param {object} licence - The transformed licence with child records, for example, licence versions + * + * @throws {Joi.ValidationError} - throws a Joi validation error if the validation fails + */ +function go (licence) { + const schema = Joi.object({ + licenceVersions: Joi.array().min(1).items( + Joi.object({ + licenceVersionPurposes: Joi.array().min(1) + }) + .unknown(true)) + }) + .unknown(true) + + const result = schema.validate(licence) + + if (result.error) { + throw result.error + } +} + +module.exports = { + go +} diff --git a/app/validators/import/licence-version-purpose.validator.js b/app/validators/import/licence-version-purpose.validator.js new file mode 100644 index 0000000000..983f6cc9a4 --- /dev/null +++ b/app/validators/import/licence-version-purpose.validator.js @@ -0,0 +1,72 @@ +'use strict' + +/** + * @module ImportLicenceVersionPurposeValidator + */ + +const Joi = require('joi') + +const MONTHS_IN_YEAR = 12 + +/** + * Checks that imported licence version purpose data that has been transformed is valid for persisting to WRLS + * + * @param {object} licenceVersionPurpose - The transformed licence version purpose data + * + * @throws {Joi.ValidationError} - throws a Joi validation error if the validation fails + */ +function go (licenceVersionPurpose) { + const schema = Joi.object({ + abstractionPeriodEndDay: _daysInMonthSchema('abstractionPeriodEndMonth'), + abstractionPeriodEndMonth: Joi.number().integer().min(1).max(MONTHS_IN_YEAR).required(), + abstractionPeriodStartDay: _daysInMonthSchema('abstractionPeriodStartMonth'), + abstractionPeriodStartMonth: Joi.number().integer().min(1).max(MONTHS_IN_YEAR).required(), + annualQuantity: Joi.number().allow(null), + dailyQuantity: Joi.number().allow(null), + externalId: Joi.string().required(), + hourlyQuantity: Joi.number().allow(null), + instantQuantity: Joi.number().allow(null), + notes: Joi.string().allow(null), + primaryPurposeId: Joi.string().guid().required(), + purposeId: Joi.string().guid().required(), + secondaryPurposeId: Joi.string().guid().required(), + timeLimitedEndDate: Joi.date().allow(null), + timeLimitedStartDate: Joi.date().allow(null) + }) + + const result = schema.validate(licenceVersionPurpose, { convert: false }) + + if (result.error) { + throw result.error + } +} + +/** + * Allows us to validate that the abstraction period is valid, for example, it is not April 31 or June 31 (those months + * only have 30 days). + * + * Also, we have encountered issues previously where users have entered the end abstraction period as 29 Feb because it + * was a leap year at the time of creation. However, when this data is used in a non-leap year, for example, billing + * it causes the service to error. + * + * It is agreed by the team that administer WRLS that only 28 Feb will ever be used, regardless of leap year. + * + * @private + */ +function _daysInMonthSchema (endMonthProperty) { + return Joi.number() + .when(endMonthProperty, { + switch: [ + { is: 2, then: Joi.number().integer().min(1).max(28).required() }, + { is: 4, then: Joi.number().integer().min(1).max(30).required() }, + { is: 6, then: Joi.number().integer().min(1).max(30).required() }, + { is: 9, then: Joi.number().integer().min(1).max(30).required() }, + { is: 11, then: Joi.number().integer().min(1).max(30).required() } + ], + otherwise: Joi.number().integer().min(1).max(31).required() + }) +} + +module.exports = { + go +} diff --git a/app/validators/import/licence-version.validator.js b/app/validators/import/licence-version.validator.js new file mode 100644 index 0000000000..8a54857479 --- /dev/null +++ b/app/validators/import/licence-version.validator.js @@ -0,0 +1,38 @@ +'use strict' + +/** + * @module ImportLicenceVersionValidator + */ + +const Joi = require('joi') + +const WRLS_STATUSES = ['current', 'superseded'] + +/** + * Checks that imported licence version data that has been transformed is valid for persisting to WRLS + * + * @param {object} licenceVersion - The transformed licence version data + * + * @throws {Joi.ValidationError} - throws a Joi validation error if the validation fails + */ +function go (licenceVersion) { + const schema = Joi.object({ + endDate: Joi.date().required().allow(null), + externalId: Joi.string().required(), + increment: Joi.number().required(), + issue: Joi.number().required(), + licenceVersionPurposes: Joi.array().required(), + startDate: Joi.date().required(), + status: Joi.string().required().valid(...WRLS_STATUSES) + }) + + const result = schema.validate(licenceVersion, { convert: false }) + + if (result.error) { + throw result.error + } +} + +module.exports = { + go +} diff --git a/app/validators/import/licence-versions.validator.js b/app/validators/import/licence-versions.validator.js deleted file mode 100644 index 3cea5751de..0000000000 --- a/app/validators/import/licence-versions.validator.js +++ /dev/null @@ -1,108 +0,0 @@ -'use strict' - -/** - * @module ImportLicenceVersionsValidator - */ - -const Joi = require('joi') - -const calender = { - totalDaysInMonth: 31, - totalMonthsInYear: 12 -} -const validStatues = ['current', 'superseded'] - -/** - * Checks that the data for inserting/updating the public.licence_versions - * and public.licence_versions_purposes table is valid. - * - * @param {Array<{ - * createdAt: string, - * endDate: string | null, - * externalId: string, - * increment: number, - * issue: number, - * startDate: string | null, - * status: string, - * updatedAt: string, - * purposes: Array<{ - * abstractionPeriodEndDay: number, - * abstractionPeriodEndMonth: number, - * abstractionPeriodStartDay: number, - * abstractionPeriodStartMonth: number, - * annualQuantity: number | null, - * dailyQuantity: number | null, - * externalId: string, - * hourlyQuantity: number | null, - * instantQuantity: number | null, - * notes: string | null, - * primaryPurposeId: string, - * secondaryPurposeId: string, - * purposeId: string, - * timeLimitedEndDate: string | null, - * timeLimitedStartDate: string | null - * }> - * }>} data - The data to be validated. - * - * @returns {void} - * @throws {Error} If validation fails. - */ -function go (data) { - const result = _schema.validate(data) - - if (Object.hasOwn(result, 'error')) { - throw new Error(result.error.details[0].message) - } -} - -const _isValidStatus = (value) => { - if (validStatues.includes(value)) { - return value - } - - throw new Error(`Status must be one of ${validStatues.toString()}`) -} - -const _purposeSchema = - Joi.array().min(1).items( - Joi.object({ - primaryPurposeId: Joi.string().required(), - secondaryPurposeId: Joi.string().required(), - purposeId: Joi.string().required(), - abstractionPeriodStartDay: Joi.number().integer().min(1).max(calender.totalDaysInMonth).required(), - abstractionPeriodStartMonth: Joi.number().integer().min(1).max(calender.totalMonthsInYear).required(), - abstractionPeriodEndDay: Joi.number().integer().min(1).max(calender.totalDaysInMonth).required(), - abstractionPeriodEndMonth: Joi.number().integer().min(1).max(calender.totalMonthsInYear).required(), - timeLimitedStartDate: Joi.date().iso().allow(null), - timeLimitedEndDate: Joi.date().iso().allow(null), - notes: Joi.string().allow(null), - annualQuantity: Joi.number().allow(null), - externalId: Joi.string().required(), - instantQuantity: Joi.number().allow(null), - hourlyQuantity: Joi.number().allow(null), - dailyQuantity: Joi.number().allow(null) - }).label('Licence versions purpose') - ).label('Licence versions purposes').messages({ - 'array.min': 'A licence version must have at least one Licence version purpose' - }) - -const _schema = Joi.array().min(1).items( - Joi.object({ - endDate: Joi.date().iso().required().allow(null), - externalId: Joi.string().required(), - increment: Joi.number().required(), - issue: Joi.number().required(), - startDate: Joi.date().iso().required(), - status: Joi.string().required().custom(_isValidStatus), - purposes: _purposeSchema - }) - .label('Licence version') -) - .label('Licence versions') - .messages({ - 'array.min': 'A licence must have at least one Licence version' - }) - -module.exports = { - go -} diff --git a/app/validators/import/licence.validator.js b/app/validators/import/licence.validator.js index c7862fca3a..f6be178b9d 100644 --- a/app/validators/import/licence.validator.js +++ b/app/validators/import/licence.validator.js @@ -7,58 +7,43 @@ const Joi = require('joi') /** - * Checks that the data for inserting/updating the public.licence table is valid + * Checks that imported licence data that has been transformed is valid for persisting to WRLS * - * @param {{ - * expiredDate: string | null, - * lapsedDate: string | null, - * licenceRef: string, - * naldRegionId: number, - * regions: { - * regionalChargeArea: string, - * localEnvironmentAgencyPlanCode: string, - * historicalAreaCode: string, - * standardUnitChargeCode: string - * }, - * revokedDate: string | null, - * startDate: string, - * waterUndertaker: boolean - * }} data - The mapped licence data - * @returns {void} - * @throws {Error} - throw an error if any of the validations fail - */ - -/** - * Validate an import licence to persist in the database + * @param {object} licence - The transformed licence data * - * @param data - * - * @throws {error} - the first error from the validation failure + * @throws {Joi.ValidationError} - throws a Joi validation error if the validation fails */ -function go (data) { - const result = _schema.validate(data) +function go (licence) { + const schema = Joi.object({ + expiredDate: Joi.date().allow(null), + lapsedDate: Joi.date().allow(null), + // NOTE: With the combination of trim() and `convert: false` passed to validate() we ensure that the licence ref + // does not contain any leading or trailing whitespace. It is common for users to accidentally add whitespace in + // NALD.Because of this when the legacy import runs it sees the licence as distinct and so creates a new record. + // This then breaks the service because things like search, find the errant licence record and 'blow up' because the + // licence ref doesn't match validation held in a different part of the service. + // We don't want to make the same mistake with our version. + licenceRef: Joi.string().trim().required(), + licenceVersions: Joi.array().required(), + regionId: Joi.string().guid().required(), + regions: Joi.object({ + regionalChargeArea: Joi.string().required(), + localEnvironmentAgencyPlanCode: Joi.string().required(), + historicalAreaCode: Joi.string().required(), + standardUnitChargeCode: Joi.string().required() + }), + revokedDate: Joi.date().allow(null), + startDate: Joi.date().required(), + waterUndertaker: Joi.boolean().required() + }) + + const result = schema.validate(licence, { convert: false }) - if (Object.hasOwn(result, 'error')) { - throw new Error(result.error.details[0].message) + if (result.error) { + throw result.error } } -const _schema = Joi.object({ - expiredDate: Joi.date().iso().allow(null), - lapsedDate: Joi.date().iso().allow(null), - licenceRef: Joi.string().required(), - regionId: Joi.number().required(), - regions: Joi.object({ - regionalChargeArea: Joi.string().required(), - localEnvironmentAgencyPlanCode: Joi.string().required(), - historicalAreaCode: Joi.string().required(), - standardUnitChargeCode: Joi.string().required() - }), - revokedDate: Joi.date().iso().allow(null), - startDate: Joi.date().iso().required(), - waterUndertaker: Joi.boolean().required() -}) - module.exports = { go } diff --git a/test/controllers/import.controller.test.js b/test/controllers/import.controller.test.js index fbb927036b..5ad5b66f61 100644 --- a/test/controllers/import.controller.test.js +++ b/test/controllers/import.controller.test.js @@ -35,12 +35,12 @@ describe('Import controller', () => { Sinon.restore() }) - describe('/import/licence', () => { - describe('POST /import/licence', () => { + describe('/import/licence/legacy', () => { + describe('POST', () => { beforeEach(async () => { options = { method: 'POST', - url: '/import/licence', + url: '/import/licence/legacy', payload: { licenceRef: 'mock-licence-ref' } diff --git a/test/presenters/import/legacy/licence-version-purpose.presenter.test.js b/test/presenters/import/legacy/licence-version-purpose.presenter.test.js new file mode 100644 index 0000000000..073eeeee8d --- /dev/null +++ b/test/presenters/import/legacy/licence-version-purpose.presenter.test.js @@ -0,0 +1,63 @@ +'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 LicenceVersionPurposePresenter = + require('../../../../app/presenters/import/legacy/licence-version-purpose.presenter.js') + +describe('Import Legacy Licence Version Purpose presenter', () => { + let legacyLicenceVersionPurpose + + beforeEach(() => { + legacyLicenceVersionPurpose = _legacyLicenceVersionPurpose() + }) + + it('correctly transforms the data', () => { + const results = LicenceVersionPurposePresenter.go(legacyLicenceVersionPurpose) + + expect(results).to.equal({ + abstractionPeriodEndDay: 31, + abstractionPeriodEndMonth: 3, + abstractionPeriodStartDay: 1, + abstractionPeriodStartMonth: 4, + annualQuantity: 545520, + dailyQuantity: 1500.2, + externalId: '6:10000004', + hourlyQuantity: 140.929, + instantQuantity: null, + notes: null, + primaryPurposeId: '8d9d407c-3da7-4977-84a0-97738c9b44cc', + purposeId: '025bfdc9-d7f4-46b5-a7e0-451dec1a34a6', + secondaryPurposeId: '04bdc9f6-a4e7-41de-831c-9ebf15b92782', + timeLimitedEndDate: null, + timeLimitedStartDate: null + }) + }) +}) + +function _legacyLicenceVersionPurpose () { + return { + abstraction_period_end_day: 31, + abstraction_period_end_month: 3, + abstraction_period_start_day: 1, + abstraction_period_start_month: 4, + annual_quantity: 545520, + daily_quantity: 1500.2, + external_id: '6:10000004', + hourly_quantity: 140.929, + instant_quantity: null, + notes: null, + primary_purpose_id: '8d9d407c-3da7-4977-84a0-97738c9b44cc', + purpose_id: '025bfdc9-d7f4-46b5-a7e0-451dec1a34a6', + secondary_purpose_id: '04bdc9f6-a4e7-41de-831c-9ebf15b92782', + time_limited_end_date: null, + time_limited_start_date: null, + version_external_id: '6:2113:100:0' + } +} diff --git a/test/presenters/import/legacy/licence-version.presenter.test.js b/test/presenters/import/legacy/licence-version.presenter.test.js new file mode 100644 index 0000000000..42a6a7bc06 --- /dev/null +++ b/test/presenters/import/legacy/licence-version.presenter.test.js @@ -0,0 +1,66 @@ +'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 LicenceVersionPresenter = require('../../../../app/presenters/import/legacy/licence-version.presenter.js') + +describe('Import Legacy Licence Version presenter', () => { + let legacyLicenceVersion + + beforeEach(() => { + legacyLicenceVersion = _legacyLicenceVersion() + }) + + it('correctly transforms the data', () => { + const result = LicenceVersionPresenter.go(legacyLicenceVersion) + + expect(result).to.equal({ + endDate: null, + externalId: '6:2113:100:0', + increment: 0, + issue: 100, + licenceVersionPurposes: [], + startDate: new Date('1999-01-01'), + status: 'current' + }) + }) + + describe('the "status" property', () => { + describe('when the legacy licence version status is "CURR"', () => { + it('returns "current"', () => { + const result = LicenceVersionPresenter.go(legacyLicenceVersion) + + expect(result.status).to.equal('current') + }) + }) + + describe('when the legacy licence version status is "SUPER"', () => { + beforeEach(() => { + legacyLicenceVersion.status = 'SUPER' + }) + + it('returns "superseded"', () => { + const result = LicenceVersionPresenter.go(legacyLicenceVersion) + + expect(result.status).to.equal('superseded') + }) + }) + }) +}) + +function _legacyLicenceVersion () { + return { + effective_end_date: null, + effective_start_date: new Date('1999-01-01'), + external_id: '6:2113:100:0', + increment_number: 0, + issue_no: 100, + status: 'CURR' + } +} diff --git a/test/presenters/import/legacy/licence-versions.presenter.test.js b/test/presenters/import/legacy/licence-versions.presenter.test.js deleted file mode 100644 index 806e6c2c24..0000000000 --- a/test/presenters/import/legacy/licence-versions.presenter.test.js +++ /dev/null @@ -1,417 +0,0 @@ -'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 FixtureLegacyLicenceVersion = require('../../../services/import/_fixtures/legacy-licence-version.fixture.js') -const FixtureLegacyLicenceVersionPurpose = require('../../../services/import/_fixtures/legacy-licence-version-purpose.fixture.js') - -// Thing under test -const LicenceVersionsPresenter = - require('../../../../app/presenters/import/legacy/licence-versions.presenter.js') - -describe('Import legacy licence versions presenter', () => { - let licenceVersions - let purpose - let version - - beforeEach(() => { - purpose = FixtureLegacyLicenceVersionPurpose.create() - version = FixtureLegacyLicenceVersion.create() - - licenceVersions = [{ ...version, purposes: [{ ...purpose }] }] - }) - - it('returns the licence version', () => { - const results = LicenceVersionsPresenter.go(licenceVersions) - - expect(results).to.equal([{ - endDate: '2007-06-04', - externalId: '3:10000003:100:0', - increment: 0, - issue: 100, - purposes: [ - { - abstractionPeriodEndDay: 31, - abstractionPeriodEndMonth: 3, - abstractionPeriodStartDay: 1, - abstractionPeriodStartMonth: 4, - annualQuantity: 545520, - dailyQuantity: 1500.2, - externalId: '3:10000004', - hourlyQuantity: 140.929, - instantQuantity: null, - notes: null, - primaryPurposeId: 'I', - purposeId: '160', - secondaryPurposeId: 'OTI', - timeLimitedEndDate: null, - timeLimitedStartDate: null - } - ], - startDate: '2005-06-05', - status: 'superseded' - }]) - }) - - describe('licence versions', () => { - describe('the "endDate" property', () => { - describe('when the licence version has EFF_END_DATE', () => { - it('returns EFF_END_DATE as the start date in the correct format', () => { - const [result] = LicenceVersionsPresenter.go(licenceVersions) - - expect(result.endDate).to.equal('2007-06-04') - }) - }) - }) - - describe('the "externalId" property', () => { - describe('when the licence version has FGAC_REGION_CODE, AABL_ID, ISSUE_NO, INCR_NO', () => { - it('returns externalId in the format {FGAC_REGION_CODE}:{AABL_ID}:{ISSUE_NO}:{INCR_NO}', () => { - const [result] = LicenceVersionsPresenter.go(licenceVersions) - - expect(result.externalId).to.equal('3:10000003:100:0') - }) - }) - }) - - describe('the "increment" property', () => { - describe('when the licence version has INCR_NO', () => { - it('returns INCR_NO as a number', () => { - const [result] = LicenceVersionsPresenter.go(licenceVersions) - - expect(result.increment).to.be.number() - expect(result.increment).to.equal(0) - }) - }) - }) - - describe('the "increment" property', () => { - describe('when the licence version has INCR_NO', () => { - it('returns INCR_NO as a number', () => { - const [result] = LicenceVersionsPresenter.go(licenceVersions) - - expect(result.increment).to.be.number() - expect(result.increment).to.equal(0) - }) - }) - }) - - describe('the "issue" property', () => { - describe('when the licence version has ISSUE_NO', () => { - it('returns ISSUE_NO as a number', () => { - const [result] = LicenceVersionsPresenter.go(licenceVersions) - - expect(result.issue).to.be.number() - expect(result.issue).to.equal(100) - }) - }) - }) - - describe('the "status" property', () => { - describe('when the licence version has STATUS and is CURR', () => { - beforeEach(() => { - licenceVersions[0].STATUS = 'CURR' - }) - - it('returns the status as "curren"t', () => { - const [result] = LicenceVersionsPresenter.go(licenceVersions) - - expect(result.status).to.equal('current') - }) - }) - - describe('when the licence version has STATUS and is SUPER', () => { - it('returns the status as "superseded"', () => { - const [result] = LicenceVersionsPresenter.go(licenceVersions) - - expect(result.status).to.equal('superseded') - }) - }) - }) - - describe('the "startDate" property', () => { - describe('when the licence version has EFF_ST_DATE', () => { - it('returns EFF_ST_DATE as the start date in the correct format', () => { - const [result] = LicenceVersionsPresenter.go(licenceVersions) - - expect(result.startDate).to.equal('2005-06-05') - }) - }) - }) - - describe('licence versions "purposes" ', () => { - describe('the "abstractionPeriodEndDay" property', () => { - describe('when purpose has PERIOD_END_DAY', () => { - it('returns PERIOD_END_DAY as a number', () => { - const [{ purposes: [result] }] = LicenceVersionsPresenter.go(licenceVersions) - - expect(result.abstractionPeriodEndDay).to.be.number() - expect(result.abstractionPeriodEndDay).to.equal(31) - }) - }) - }) - - describe('the "abstractionPeriodEndMonth" property', () => { - describe('when purpose has PERIOD_END_MONTH', () => { - it('returns PERIOD_END_MONTH as a number', () => { - const [{ purposes: [result] }] = LicenceVersionsPresenter.go(licenceVersions) - - expect(result.abstractionPeriodEndMonth).to.be.number() - expect(result.abstractionPeriodEndMonth).to.equal(3) - }) - }) - }) - - describe('the "abstractionPeriodStartDay" property', () => { - describe('when purpose has PERIOD_ST_DAY', () => { - it('returns PERIOD_ST_DAY as a number', () => { - const [{ purposes: [result] }] = LicenceVersionsPresenter.go(licenceVersions) - - expect(result.abstractionPeriodStartDay).to.be.number() - expect(result.abstractionPeriodStartDay).to.equal(1) - }) - }) - }) - - describe('the "abstractionPeriodStartMonth" property', () => { - describe('when purpose has PERIOD_ST_MONTH', () => { - it('returns PERIOD_ST_MONTH as a number', () => { - const [{ purposes: [result] }] = LicenceVersionsPresenter.go(licenceVersions) - - expect(result.abstractionPeriodStartMonth).to.be.number() - expect(result.abstractionPeriodStartMonth).to.equal(4) - }) - }) - }) - - describe('the "abstractionPeriodStartMonth" property', () => { - describe('when purpose has PERIOD_ST_MONTH', () => { - it('returns PERIOD_ST_MONTH as a number', () => { - const [{ purposes: [result] }] = LicenceVersionsPresenter.go(licenceVersions) - - expect(result.abstractionPeriodStartMonth).to.be.number() - expect(result.abstractionPeriodStartMonth).to.equal(4) - }) - }) - }) - - describe('the "annualQuantity" property', () => { - describe('when purpose has ANNUAL_QTY is "null"', () => { - beforeEach(() => { - licenceVersions[0].purposes = [ - { ...purpose, ANNUAL_QTY: 'null' } - ] - }) - - it('returns null', () => { - const [{ purposes: [result] }] = LicenceVersionsPresenter.go(licenceVersions) - - expect(result.annualQuantity).to.be.null() - }) - }) - - describe('when purpose has ANNUAL_QTY', () => { - it('returns ANNUAL_QTY as a number', () => { - const [{ purposes: [result] }] = LicenceVersionsPresenter.go(licenceVersions) - - expect(result.annualQuantity).to.be.number() - expect(result.annualQuantity).to.equal(545520) - }) - }) - }) - - describe('the "dailyQuantity" property', () => { - describe('when purpose has DAILY_QTY is "null"', () => { - beforeEach(() => { - licenceVersions[0].purposes = [ - { ...purpose, DAILY_QTY: 'null' } - ] - }) - - it('returns null', () => { - const [{ purposes: [result] }] = LicenceVersionsPresenter.go(licenceVersions) - - expect(result.dailyQuantity).to.be.null() - }) - }) - - describe('when purpose has DAILY_QTY', () => { - it('returns DAILY_QTY as a number', () => { - const [{ purposes: [result] }] = LicenceVersionsPresenter.go(licenceVersions) - - expect(result.dailyQuantity).to.be.number() - expect(result.dailyQuantity).to.equal(1500.2) - }) - }) - }) - - describe('the "hourlyQuantity" property', () => { - describe('when purpose has HOURLY_QTY is "null"', () => { - beforeEach(() => { - licenceVersions[0].purposes = [ - { ...purpose, HOURLY_QTY: 'null' } - ] - }) - - it('returns null', () => { - const [{ purposes: [result] }] = LicenceVersionsPresenter.go(licenceVersions) - - expect(result.hourlyQuantity).to.be.null() - }) - }) - - describe('when purpose has HOURLY_QTY', () => { - it('returns HOURLY_QTY as a number', () => { - const [{ purposes: [result] }] = LicenceVersionsPresenter.go(licenceVersions) - - expect(result.hourlyQuantity).to.be.number() - expect(result.hourlyQuantity).to.equal(140.929) - }) - }) - }) - - describe('the "instantQuantity" property', () => { - describe('when purpose has INST_QTY is "null"', () => { - it('returns null', () => { - const [{ purposes: [result] }] = LicenceVersionsPresenter.go(licenceVersions) - - expect(result.instantQuantity).to.be.null() - }) - }) - - describe('when purpose has INST_QTY', () => { - beforeEach(() => { - licenceVersions[0].purposes = [ - { ...purpose, INST_QTY: '123' } - ] - }) - - it('returns INST_QTY as a number', () => { - const [{ purposes: [result] }] = LicenceVersionsPresenter.go(licenceVersions) - - expect(result.instantQuantity).to.be.number() - expect(result.instantQuantity).to.equal(123) - }) - }) - }) - - describe('the "externalId" property', () => { - describe('when the purpose has FGAC_REGION_CODE, ID', () => { - it('returns externalId in the format {FGAC_REGION_CODE}:{ID}', () => { - const [{ purposes: [result] }] = LicenceVersionsPresenter.go(licenceVersions) - - expect(result.externalId).to.equal('3:10000004') - }) - }) - }) - - describe('the "notes" property', () => { - describe('when purpose has NOTES is "null"', () => { - it('returns null', () => { - const [{ purposes: [result] }] = LicenceVersionsPresenter.go(licenceVersions) - - expect(result.notes).to.be.null() - }) - }) - - describe('when purpose has NOTES', () => { - beforeEach(() => { - licenceVersions[0].purposes = [ - { ...purpose, NOTES: 'a b c' } - ] - }) - - it('returns notes', () => { - const [{ purposes: [result] }] = LicenceVersionsPresenter.go(licenceVersions) - - expect(result.notes).to.equal('a b c') - }) - }) - }) - - describe('the "primaryPurposeId" property', () => { - describe('when purpose has APUR_APPR_CODE', () => { - it('returns the legacy primaryPurposeId', () => { - const [{ purposes: [result] }] = LicenceVersionsPresenter.go(licenceVersions) - - expect(result.primaryPurposeId).to.equal('I') - }) - }) - }) - - describe('the "purposeId" property', () => { - describe('when purpose has APUR_APUS_CODE', () => { - it('returns the legacy purposeId', () => { - const [{ purposes: [result] }] = LicenceVersionsPresenter.go(licenceVersions) - - expect(result.purposeId).to.equal('160') - }) - }) - }) - - describe('the "secondaryPurposeId" property', () => { - describe('when purpose has APUR_APSE_CODE', () => { - it('returns the legacy secondaryPurposeId', () => { - const [{ purposes: [result] }] = LicenceVersionsPresenter.go(licenceVersions) - - expect(result.secondaryPurposeId).to.equal('OTI') - }) - }) - }) - - describe('the "timeLimitedEndDate" property', () => { - describe('when purpose has TIMELTD_END_DATE', () => { - beforeEach(() => { - licenceVersions[0].purposes = [ - { ...purpose, TIMELTD_END_DATE: '31/03/2015' } - ] - }) - - it('returns the time Limited End Date in the ISO format', () => { - const [{ purposes: [result] }] = LicenceVersionsPresenter.go(licenceVersions) - - expect(result.timeLimitedEndDate).to.equal('2015-03-31') - }) - }) - - describe('when purpose has TIMELTD_END_DATE', () => { - it('returns null', () => { - const [{ purposes: [result] }] = LicenceVersionsPresenter.go(licenceVersions) - - expect(result.timeLimitedEndDate).to.be.null() - }) - }) - }) - - describe('the "timeLimitedStartDate" property', () => { - describe('when purpose has TIMELTD_ST_DATE', () => { - beforeEach(() => { - licenceVersions[0].purposes = [ - { ...purpose, TIMELTD_ST_DATE: '31/03/2015' } - ] - }) - - it('returns the time Limited End Date in the ISO format', () => { - const [{ purposes: [result] }] = LicenceVersionsPresenter.go(licenceVersions) - - expect(result.timeLimitedStartDate).to.equal('2015-03-31') - }) - }) - - describe('when purpose has TIMELTD_ST_DATE', () => { - it('returns null', () => { - const [{ purposes: [result] }] = LicenceVersionsPresenter.go(licenceVersions) - - expect(result.timeLimitedStartDate).to.be.null() - }) - }) - }) - }) - }) -}) diff --git a/test/presenters/import/legacy/licence.presenter.test.js b/test/presenters/import/legacy/licence.presenter.test.js index 03e12288c5..0871ac9f65 100644 --- a/test/presenters/import/legacy/licence.presenter.test.js +++ b/test/presenters/import/legacy/licence.presenter.test.js @@ -8,187 +8,115 @@ const { describe, it, beforeEach } = exports.lab = Lab.script() const { expect } = Code // Test helpers -const FixtureLegacyLicence = require('../../../services/import/_fixtures/legacy-licence.fixture.js') -const FixtureLegacyLicenceVersion = require('../../../services/import/_fixtures/legacy-licence-version.fixture.js') +const { generateLicenceRef } = require('../../../support/helpers/licence.helper.js') // Thing under test -const LicencePresenter = - require('../../../../app/presenters/import/legacy/licence.presenter.js') +const LicencePresenter = require('../../../../app/presenters/import/legacy/licence.presenter.js') -describe('Import legacy licence presenter', () => { - let licence +describe('Import Legacy Licence presenter', () => { + let legacyLicence beforeEach(() => { - licence = { ...FixtureLegacyLicence.create() } + legacyLicence = _legacyLicence() }) - it('returns the matching agreements data', () => { - const results = LicencePresenter.go(licence) + it('correctly transforms the data', () => { + const result = LicencePresenter.go(legacyLicence) - expect(results).to.equal({ - licenceRef: licence.LIC_NO, - startDate: '2005-06-03', - waterUndertaker: false, + expect(result).to.equal({ + expiredDate: null, + lapsedDate: null, + licenceRef: legacyLicence.licence_ref, + licenceVersions: [], + regionId: '82d8c1b7-0eed-43a7-a5f9-4e397c08e17e', regions: { - historicalAreaCode: 'RIDIN', - regionalChargeArea: 'Yorkshire', - standardUnitChargeCode: 'YORKI', - localEnvironmentAgencyPlanCode: 'AIREL' + historicalAreaCode: 'KAEA', + regionalChargeArea: 'Southern', + standardUnitChargeCode: 'SUCSO', + localEnvironmentAgencyPlanCode: 'LEME' }, - regionId: 3, - expiredDate: '2015-03-31', - lapsedDate: null, - revokedDate: null - + revokedDate: null, + startDate: new Date('1992-08-19'), + waterUndertaker: false }) }) - describe('licence', () => { - describe('the "expiredDate" property', () => { - describe('when the licence has an expiry date', () => { - it('returns the licence expired date in the ISO format', () => { - const result = LicencePresenter.go(licence) - - expect(result.expiredDate).to.equal('2015-03-31') - }) - }) - - describe('when the licence does not have an expiry date', () => { - beforeEach(() => { - licence.EXPIRY_DATE = 'null' - }) - it('returns null', () => { - const result = LicencePresenter.go(licence) - - expect(result.expiredDate).to.be.null() - }) - }) - }) - - describe('the "lapsedDate" property', () => { - describe('when the licence has an lapsed date', () => { - beforeEach(() => { - licence.LAPSED_DATE = '01/09/2006' - }) - - it('returns the licence expired date in the ISO format', () => { - const result = LicencePresenter.go(licence) - - expect(result.lapsedDate).to.equal('2006-09-01') - }) - }) - - describe('when the licence does not have an lapsed date', () => { - it('returns null', () => { - const result = LicencePresenter.go(licence) - - expect(result.lapsedDate).to.be.null() - }) - }) + describe('the "regions" property', () => { + beforeEach(() => { + legacyLicence.environmental_improvement_unit_charge_code = 'YOOTH' }) - describe('the "licenceRef" property', () => { - it('returns licence ref from the licence LIC_NO', () => { - const result = LicencePresenter.go(licence) + it('returns a JSON object where the "regionalChargeArea" is based on the first 2 chars of the EIUC code', () => { + const result = LicencePresenter.go(legacyLicence) - expect(result.licenceRef).to.equal(licence.LIC_NO) + expect(result.regions).to.equal({ + historicalAreaCode: 'KAEA', + regionalChargeArea: 'Yorkshire', + standardUnitChargeCode: 'SUCSO', + localEnvironmentAgencyPlanCode: 'LEME' }) }) + }) - describe('the "regionId" property', () => { - it('returns the FGAC_REGION_CODE as an integer assigned to regionId', () => { - const result = LicencePresenter.go(licence) + describe('the "startDate" property', () => { + describe('when "original_effective_date" is populated in the licence data', () => { + it('returns "original_effective_date" as the "startDate"', () => { + const result = LicencePresenter.go(legacyLicence) - expect(result.regionId).to.equal(3) + expect(result.startDate).to.equal(legacyLicence.original_effective_date) }) }) - describe('the "regions" property', () => { - it('returns region', () => { - const result = LicencePresenter.go(licence) - - expect(result.regions).to.equal({ - historicalAreaCode: 'RIDIN', - regionalChargeArea: 'Yorkshire', - standardUnitChargeCode: 'YORKI', - localEnvironmentAgencyPlanCode: 'AIREL' - }) + describe('when "original_effective_date" is not populated in the licence data', () => { + beforeEach(() => { + legacyLicence.original_effective_date = null }) - }) - describe('the "revokedDate" property', () => { - describe('when the licence has an revoked date', () => { - beforeEach(() => { - licence.REV_DATE = '01/09/2006' - }) + it('returns "earliest_version_start_date" as the "startDate"', () => { + const result = LicencePresenter.go(legacyLicence) - it('returns the licence revoked date in the ISO format', () => { - const result = LicencePresenter.go(licence) - - expect(result.revokedDate).to.equal('2006-09-01') - }) - }) - - describe('when the licence does not have an revoked date', () => { - it('returns null', () => { - const result = LicencePresenter.go(licence) - - expect(result.revokedDate).to.be.null() - }) + expect(result.startDate).to.equal(legacyLicence.earliest_version_start_date) }) }) + }) - describe('the "startDate" property', () => { - describe('when the licence has ORIG_EFF_DATE', () => { - it('returns ORIG_EFF_DATE as the start date in the correct format', () => { - const result = LicencePresenter.go(licence) + describe('the "waterUndertaker" property', () => { + describe('when the "environmental_improvement_unit_charge_code" does not end with SWC', () => { + it('returns false', () => { + const result = LicencePresenter.go(legacyLicence) - expect(result.startDate).to.equal('2005-06-03') - }) - }) - describe('when the licence ORIG_EFF_DATE is null', () => { - let licenceVersions - - beforeEach(() => { - licence.ORIG_EFF_DATE = 'null' - - licenceVersions = [ - { ...FixtureLegacyLicenceVersion.create(), EFF_ST_DATE: '07/07/2001' }, - // This licence version should be used by the sort as it is the earliest - { ...FixtureLegacyLicenceVersion.create(), EFF_ST_DATE: '01/01/2001' } - ] - }) - - describe('then start date of the earliest non-draft licence version is used', () => { - it('returns the start date in the ISO format', () => { - const result = LicencePresenter.go(licence, licenceVersions) - - expect(result.startDate).to.equal('2001-01-01') - }) - }) + expect(result.waterUndertaker).to.be.false() }) }) - describe('the "waterUndertaker" property', () => { - describe('when the licence AREP_EIUC_CODE ends with "SWC" ', () => { - beforeEach(() => { - licence.AREP_EIUC_CODE = 'ANSWC' - }) - - it('returns waterUndertaker as true', () => { - const result = LicencePresenter.go(licence) - - expect(result.waterUndertaker).to.be.true() - }) + describe('when the "environmental_improvement_unit_charge_code" ends with SWC', () => { + beforeEach(() => { + legacyLicence.environmental_improvement_unit_charge_code = 'SOSWC' }) - describe('when the licence AREP_EIUC_CODE does not end with "SWC" ', () => { - it('returns waterUndertaker as false', () => { - const result = LicencePresenter.go(licence) + it('returns true', () => { + const result = LicencePresenter.go(legacyLicence) - expect(result.waterUndertaker).to.be.false() - }) + expect(result.waterUndertaker).to.be.true() }) }) }) }) + +function _legacyLicence () { + return { + historical_area_code: 'KAEA', + environmental_improvement_unit_charge_code: 'SOOTH', + local_environment_agency_plan_code: 'LEME', + standard_unit_charge_code: 'SUCSO', + expiry_date: null, + region_code: '6', + id: '2113', + lapsed_date: null, + licence_ref: generateLicenceRef(), + original_effective_date: new Date('1992-08-19'), + revoked_date: null, + earliest_version_start_date: new Date('1999-01-01'), + region_id: '82d8c1b7-0eed-43a7-a5f9-4e397c08e17e' + } +} diff --git a/test/services/import/_fixtures/import-licence-versions.fixture.js b/test/services/import/_fixtures/import-licence-versions.fixture.js deleted file mode 100644 index 5245b90612..0000000000 --- a/test/services/import/_fixtures/import-licence-versions.fixture.js +++ /dev/null @@ -1,58 +0,0 @@ -'use strict' - -const { randomInteger } = require('../../../support/general.js') - -function _createLicenceVersionPurpose () { - return { - abstractionPeriodEndDay: 31, - abstractionPeriodEndMonth: 3, - abstractionPeriodStartDay: 1, - abstractionPeriodStartMonth: 4, - annualQuantity: 545520, - dailyQuantity: 1500.2, - externalId: `${randomInteger(1, 9)}:${randomInteger(10000004, 99999999)}`, - hourlyQuantity: 140.929, - instantQuantity: 120, - notes: ' a note on purposes', - primaryPurposeId: 'I', - secondaryPurposeId: 'OTI', - purposeId: '160', - timeLimitedEndDate: '2001-01-02', - timeLimitedStartDate: '2001-01-03' - } -} - -function _createtLicenceVersion () { - return { - endDate: '2002-01-01', - externalId: `9:${randomInteger(10000, 99999)}:1:0`, - increment: 0, - issue: 100, - startDate: '2001-01-01', - status: 'superseded' - } -} - -/** - * Creates a test import licence versions object with purposes - * - * This is the object we expect to see when we persist the data for the licence versions and purposes - * - * This object should pass the validation - * - * @returns {object} - an import licence object with purposes - */ -function create () { - const defaults = [ - { - ..._createtLicenceVersion(), - purposes: [{ ..._createLicenceVersionPurpose() }] - } - ] - - return [...defaults] -} - -module.exports = { - create -} diff --git a/test/services/import/_fixtures/import-licence.fixture.js b/test/services/import/_fixtures/import-licence.fixture.js deleted file mode 100644 index 59f355c5cb..0000000000 --- a/test/services/import/_fixtures/import-licence.fixture.js +++ /dev/null @@ -1,45 +0,0 @@ -'use strict' - -const { generateLicenceRef } = require('../../../support/helpers/licence.helper.js') -const RegionHelper = require('../../../support/helpers/region.helper.js') - -const region = RegionHelper.data.find((region) => { - return region.displayName === 'Test Region' -}) - -function importLicence () { - return { - expiredDate: '2015-03-31', - lapsedDate: null, - licenceRef: generateLicenceRef(), - regionId: region.naldRegionId, - regions: { - historicalAreaCode: 'RIDIN', - regionalChargeArea: 'Yorkshire', - standardUnitChargeCode: 'YORKI', - localEnvironmentAgencyPlanCode: 'AIREL' - }, - revokedDate: null, - startDate: '2005-06-03', - waterUndertaker: false - } -} - -/** - * Creates a test import licence object - * - * This is the object we expect to see when we persist the data - * - * This object should pass the validation - * - * @returns {object} - an import licence object - */ -function create () { - return { - ...importLicence() - } -} - -module.exports = { - create -} diff --git a/test/services/import/_fixtures/legacy-licence-version-purpose.fixture.js b/test/services/import/_fixtures/legacy-licence-version-purpose.fixture.js deleted file mode 100644 index 9396b55e92..0000000000 --- a/test/services/import/_fixtures/legacy-licence-version-purpose.fixture.js +++ /dev/null @@ -1,37 +0,0 @@ -'use strict' - -function purpose () { - return { - PERIOD_END_DAY: '31', - PERIOD_END_MONTH: '3', - PERIOD_ST_DAY: '1', - PERIOD_ST_MONTH: '4', - ANNUAL_QTY: '545520', - DAILY_QTY: '1500.2', - FGAC_REGION_CODE: '3', - ID: '10000004', - HOURLY_QTY: '140.929', - INST_QTY: 'null', - NOTES: 'null', - APUR_APPR_CODE: 'I', - APUR_APSE_CODE: 'OTI', - APUR_APUS_CODE: '160', - TIMELTD_END_DATE: 'null', - TIMELTD_ST_DATE: 'null' - } -} - -/** - * Creates a test legacy import licence versions purpose object - * - * @returns {object} - a legacy import licence versions purpose object - */ -function create () { - return { - ...purpose() - } -} - -module.exports = { - create -} diff --git a/test/services/import/_fixtures/legacy-licence-version.fixture.js b/test/services/import/_fixtures/legacy-licence-version.fixture.js deleted file mode 100644 index 1497efc679..0000000000 --- a/test/services/import/_fixtures/legacy-licence-version.fixture.js +++ /dev/null @@ -1,29 +0,0 @@ -'use strict' - -function legacyLicenceVersionFixture () { - return { - EFF_END_DATE: '04/06/2007', - EFF_ST_DATE: '05/06/2005', - INCR_NO: '0', - ISSUE_NO: '100', - STATUS: 'SUPER', - FGAC_REGION_CODE: '3', - AABL_ID: '10000003', - purposes: [] - } -} - -/** - * Creates a test legacy import licence versions object - * - * @returns {object} - a legacy import licence versions object - */ -function create () { - return { - ...legacyLicenceVersionFixture() - } -} - -module.exports = { - create -} diff --git a/test/services/import/_fixtures/legacy-licence.fixture.js b/test/services/import/_fixtures/legacy-licence.fixture.js deleted file mode 100644 index 75d7ab6269..0000000000 --- a/test/services/import/_fixtures/legacy-licence.fixture.js +++ /dev/null @@ -1,34 +0,0 @@ -'use strict' - -const { generateLicenceRef } = require('../../../support/helpers/licence.helper.js') - -function legacyLicenceFixture () { - return { - AREP_AREA_CODE: 'RIDIN', - AREP_EIUC_CODE: 'YOOTH', - AREP_LEAP_CODE: 'AIREL', - AREP_SUC_CODE: 'YORKI', - EXPIRY_DATE: '31/03/2015', - FGAC_REGION_CODE: '3', - ID: '10013151', - LAPSED_DATE: 'null', - LIC_NO: generateLicenceRef(), - ORIG_EFF_DATE: '03/06/2005', - REV_DATE: 'null' - } -} - -/** - * Creates a test legacy import licence object - * - * @returns {object} - a legacy import licence object - */ -function create () { - return { - ...legacyLicenceFixture() - } -} - -module.exports = { - create -} diff --git a/test/services/import/legacy/process-licence.service.test.js b/test/services/import/legacy/process-licence.service.test.js index d74df9cbbc..19e2ef6bc4 100644 --- a/test/services/import/legacy/process-licence.service.test.js +++ b/test/services/import/legacy/process-licence.service.test.js @@ -5,173 +5,112 @@ const Lab = require('@hapi/lab') const Code = require('@hapi/code') const Sinon = require('sinon') -const { describe, it, before, beforeEach } = exports.lab = Lab.script() +const { describe, it, beforeEach, afterEach } = exports.lab = Lab.script() const { expect } = Code // Test helpers -const FetchLicenceService = require('../../../../app/services/import/legacy/fetch-licence.service.js') -const FetchLicenceVersionsService = require('../../../../app/services/import/legacy/fetch-licence-versions.service.js') -const FixtureLegacyLicence = require('../_fixtures/legacy-licence.fixture.js') -const FixtureLegacyLicenceVersion = require('../_fixtures/legacy-licence-version.fixture.js') -const FixtureLegacyLicenceVersionPurpose = require('../_fixtures/legacy-licence-version-purpose.fixture.js') -const LicenceModel = require('../../../../app/models/licence.model.js') -const PrimaryPurposeHelper = require('../../../support/helpers/primary-purpose.helper.js') -const PurposeHelper = require('../../../support/helpers/purpose.helper.js') -const RegionHelper = require('../../../support/helpers/region.helper.js') -const SecondaryPurposeHelper = require('../../../support/helpers/secondary-purpose.helper.js') +const { generateUUID } = require('../../../../app/lib/general.lib.js') +const { generateLicenceRef } = require('../../../support/helpers/licence.helper.js') + +// Things to stub +const PersistLicenceService = require('../../../../app/services/import/persist-licence.service.js') +const TransformLicenceService = require('../../../../app/services/import/legacy/transform-licence.service.js') +const TransformLicenceVersionsService = require('../../../../app/services/import/legacy/transform-licence-versions.service.js') +const TransformLicenceVersionPurposesService = require('../../../../app/services/import/legacy/transform-licence-version-purposes.service.js') // Thing under test -const ImportLegacyProcessLicenceService = - require('../../../../app/services/import/legacy/process-licence.service.js') +const ProcessLicenceService = require('../../../../app/services/import/legacy/process-licence.service.js') -describe('Import legacy process licence service', () => { - const region = RegionHelper.select() +describe('Import Legacy Process Licence service', () => { + const naldLicenceId = '2113' + const regionCode = '6' - let legacyLicence + let licenceId let licenceRef - let licenceVersionPurpose - let licenceVersions - let version - - before(() => { - legacyLicence = FixtureLegacyLicence.create() - licenceRef = legacyLicence.LIC_NO + let notifierStub + let persistLicenceServiceStub + let transformedLicence - licenceVersionPurpose = FixtureLegacyLicenceVersionPurpose.create() - version = FixtureLegacyLicenceVersion.create() + beforeEach(() => { + licenceId = generateUUID() + licenceRef = generateLicenceRef() - licenceVersions = [{ ...version, purposes: [{ ...licenceVersionPurpose }] }] + transformedLicence = _transformedLicence(licenceRef) - Sinon.stub(FetchLicenceService, 'go').resolves({ - ...legacyLicence, - FGAC_REGION_CODE: region.naldRegionId - }) + Sinon.stub(TransformLicenceService, 'go').resolves({ naldLicenceId, regionCode, transformedLicence }) + Sinon.stub(TransformLicenceVersionsService, 'go').resolves() + Sinon.stub(TransformLicenceVersionPurposesService, 'go').resolves(transformedLicence) - Sinon.stub(FetchLicenceVersionsService, 'go').resolves(licenceVersions) + // BaseRequest depends on the GlobalNotifier to have been set. This happens in app/plugins/global-notifier.plugin.js + // when the app starts up and the plugin is registered. As we're not creating an instance of Hapi server in this + // test we recreate the condition by setting it directly with our own stub + notifierStub = { omg: Sinon.stub(), omfg: Sinon.stub() } + global.GlobalNotifier = notifierStub + }) - global.GlobalNotifier = { omfg: Sinon.stub() } + afterEach(() => { + Sinon.restore() + delete global.GlobalNotifier }) - describe('the "licence" data is imported and saved to the database', () => { - it('returns the matching licence data', async () => { - await ImportLegacyProcessLicenceService.go(licenceRef) - - const licence = await LicenceModel.query().select('*').where('licenceRef', licenceRef).first() - - expect(licence).to.equal({ - createdAt: new Date(licence.createdAt), - expiredDate: new Date('2015-03-31'), - id: licence.id, - includeInPresrocBilling: 'no', - includeInSrocBilling: false, - lapsedDate: null, - licenceRef, - regionId: region.id, - regions: { - historicalAreaCode: 'RIDIN', - localEnvironmentAgencyPlanCode: 'AIREL', - regionalChargeArea: 'Yorkshire', - standardUnitChargeCode: 'YORKI' - }, - revokedDate: null, - startDate: new Date('2005-06-03'), - suspendFromBilling: false, - updatedAt: new Date(licence.updatedAt), - waterUndertaker: false - }) + describe('when there is a valid NALD licence to import', () => { + beforeEach(() => { + persistLicenceServiceStub = Sinon.stub(PersistLicenceService, 'go').resolves(licenceId) }) - it('returns defaulted columns', async () => { - await ImportLegacyProcessLicenceService.go(licenceRef) + it('saves the imported licence', async () => { + await ProcessLicenceService.go(licenceRef) - const licence = await LicenceModel.query().select('*').where('licenceRef', licenceRef).first() - - expect(licence.includeInPresrocBilling).to.equal('no') - expect(licence.includeInSrocBilling).to.be.false() - expect(licence.suspendFromBilling).to.be.false() + expect(persistLicenceServiceStub.calledWith(transformedLicence)).to.be.true() }) - }) - describe('the "licence versions" ', () => { - it('returns the matching licence versions data', async () => { - await ImportLegacyProcessLicenceService.go(licenceRef) + it('logs the time taken in milliseconds and seconds', async () => { + await ProcessLicenceService.go(licenceRef) - const licence = await LicenceModel.query().select(['id']).where('licenceRef', licenceRef).first() - .withGraphFetched('licenceVersions') + const logDataArg = notifierStub.omg.firstCall.args[1] - const [licenceVersion] = licence.licenceVersions - - expect(licence.licenceVersions).to.be.array() + expect( + notifierStub.omg.calledWith('Legacy licence import complete') + ).to.be.true() + expect(logDataArg.timeTakenMs).to.exist() + expect(logDataArg.timeTakenSs).to.exist() + expect(logDataArg.licenceId).to.equal(licenceId) + expect(logDataArg.licenceRef).to.equal(licenceRef) + }) + }) - expect(licenceVersion).to.equal( - { - createdAt: licenceVersion.createdAt, - endDate: new Date('2007-06-04'), - externalId: '3:10000003:100:0', - id: licenceVersion.id, - increment: 0, - issue: 100, - licenceId: licence.id, - startDate: new Date('2005-06-05'), - status: 'superseded', - updatedAt: licenceVersion.updatedAt - }) + describe('when the service errors', () => { + beforeEach(() => { + persistLicenceServiceStub = Sinon.stub(PersistLicenceService, 'go').rejects() }) - describe('the "licence version purposes"', () => { - let primaryPurpose - let purpose - let secondaryPurpose - - beforeEach(() => { - primaryPurpose = PrimaryPurposeHelper.data.find((primaryPurpose) => { - return primaryPurpose.legacyId === licenceVersionPurpose.APUR_APPR_CODE - }) - - purpose = PurposeHelper.data.find((purpose) => { - return purpose.legacyId === licenceVersionPurpose.APUR_APUS_CODE - }) - - secondaryPurpose = SecondaryPurposeHelper.data.find((secondaryPurpose) => { - return secondaryPurpose.legacyId === licenceVersionPurpose.APUR_APSE_CODE - }) - }) - - it('returns the matching licence versions purposes data', async () => { - await ImportLegacyProcessLicenceService.go(licenceRef) - - const licence = await LicenceModel.query().select(['id']).where('licenceRef', licenceRef).first() - .withGraphFetched('licenceVersions').withGraphFetched('licenceVersions.licenceVersionPurposes') - - const [licenceVersion] = licence.licenceVersions - const { licenceVersionPurposes } = licenceVersion - const [licenceVersionPurpose] = licenceVersionPurposes - - expect(licence.licenceVersions[0].licenceVersionPurposes).to.be.array() - - expect(licenceVersionPurpose).to.equal( - { - id: licenceVersionPurpose.id, - licenceVersionId: licenceVersion.id, - primaryPurposeId: primaryPurpose.id, - secondaryPurposeId: secondaryPurpose.id, - purposeId: purpose.id, - abstractionPeriodStartDay: 1, - abstractionPeriodStartMonth: 4, - abstractionPeriodEndDay: 31, - abstractionPeriodEndMonth: 3, - timeLimitedStartDate: null, - timeLimitedEndDate: null, - notes: null, - instantQuantity: null, - dailyQuantity: 1500.2, - hourlyQuantity: 140.929, - annualQuantity: 545520, - externalId: '3:10000004', - createdAt: new Date(licenceVersionPurpose.createdAt), - updatedAt: new Date(licenceVersionPurpose.updatedAt) - }) - }) + it('handles the error', async () => { + await ProcessLicenceService.go(licenceRef) + + const args = notifierStub.omfg.firstCall.args + + expect(args[0]).to.equal('Legacy licence import errored') + expect(args[1]).to.equal({ licenceRef }) + expect(args[2]).to.be.an.error() }) }) }) + +// NOTE: This is an incomplete transformed licence. But this minimum valid structure saves us having to also stub +// the LicenceStructureValidator +function _transformedLicence (licenceRef) { + return { + licenceRef, + licenceVersions: [{ + externalId: '6:2113:100:0', + licenceVersionPurposes: [ + { + externalId: '6:10000004' + }, + { + externalId: '6:10000005' + } + ] + }] + } +} diff --git a/test/services/import/legacy/transform-licence-version-purposes.service.test.js b/test/services/import/legacy/transform-licence-version-purposes.service.test.js new file mode 100644 index 0000000000..9d2d51ff91 --- /dev/null +++ b/test/services/import/legacy/transform-licence-version-purposes.service.test.js @@ -0,0 +1,125 @@ +'use strict' + +// Test framework dependencies +const Lab = require('@hapi/lab') +const Code = require('@hapi/code') +const Sinon = require('sinon') + +const { describe, it, beforeEach, afterEach } = exports.lab = Lab.script() +const { expect } = Code + +// Things to stub +const FetchLicenceVersionPurposesService = + require('../../../../app/services/import/legacy/fetch-licence-version-purposes.service.js') + +// Thing under test +const TransformLicenceVersionPurposesService = + require('../../../../app/services/import/legacy/transform-licence-version-purposes.service.js') + +describe('Import Legacy Transform Licence Version Purposes service', () => { + // NOTE: Clearly this is an incomplete representation of the licence returned from TransformedLicenceService. But for + // the purposes of this service it is all that is needed. The externalId is used to match the licence version to the + // fetched purpose + const transformedLicence = { + licenceVersions: [{ + externalId: '6:2113:100:0', + licenceVersionPurposes: [] + }] + } + + const naldLicenceId = '2113' + const regionCode = '6' + + let legacyLicenceVersionPurpose + + beforeEach(() => { + legacyLicenceVersionPurpose = _legacyLicenceVersionPurpose() + }) + + afterEach(() => { + Sinon.restore() + }) + + describe('when a matching valid legacy licence version purpose is found', () => { + beforeEach(() => { + Sinon.stub(FetchLicenceVersionPurposesService, 'go').resolves([legacyLicenceVersionPurpose]) + }) + + it('attaches the record transformed and validated for WRLS to the transformed licence', async () => { + await TransformLicenceVersionPurposesService.go(regionCode, naldLicenceId, transformedLicence) + + expect(transformedLicence.licenceVersions[0].licenceVersionPurposes[0]).to.equal({ + abstractionPeriodEndDay: 31, + abstractionPeriodEndMonth: 3, + abstractionPeriodStartDay: 1, + abstractionPeriodStartMonth: 4, + annualQuantity: 545520, + dailyQuantity: 1500.2, + externalId: '6:10000004', + hourlyQuantity: 140.929, + instantQuantity: null, + notes: null, + primaryPurposeId: '8d9d407c-3da7-4977-84a0-97738c9b44cc', + purposeId: '025bfdc9-d7f4-46b5-a7e0-451dec1a34a6', + secondaryPurposeId: '04bdc9f6-a4e7-41de-831c-9ebf15b92782', + timeLimitedEndDate: null, + timeLimitedStartDate: null + }) + }) + }) + + describe('when no matching legacy licence version purpose is found', () => { + beforeEach(() => { + Sinon.stub(FetchLicenceVersionPurposesService, 'go').resolves(null) + }) + + it('throws an error', async () => { + await expect(TransformLicenceVersionPurposesService.go(regionCode, naldLicenceId, transformedLicence)).to.reject() + }) + }) + + describe('when the matching legacy licence version purpose is invalid', () => { + beforeEach(() => { + legacyLicenceVersionPurpose.abstraction_period_start_day = null + + Sinon.stub(FetchLicenceVersionPurposesService, 'go').resolves([legacyLicenceVersionPurpose]) + }) + + it('throws an error', async () => { + await expect(TransformLicenceVersionPurposesService.go(regionCode, naldLicenceId, transformedLicence)).to.reject() + }) + }) + + describe('when the matching legacy licence version purpose does not match any licence versions', () => { + beforeEach(() => { + legacyLicenceVersionPurpose.version_external_id = '6:100023:100:0' + + Sinon.stub(FetchLicenceVersionPurposesService, 'go').resolves([legacyLicenceVersionPurpose]) + }) + + it('throws an error', async () => { + await expect(TransformLicenceVersionPurposesService.go(regionCode, naldLicenceId, transformedLicence)).to.reject() + }) + }) +}) + +function _legacyLicenceVersionPurpose () { + return { + abstraction_period_end_day: 31, + abstraction_period_end_month: 3, + abstraction_period_start_day: 1, + abstraction_period_start_month: 4, + annual_quantity: 545520, + daily_quantity: 1500.2, + external_id: '6:10000004', + hourly_quantity: 140.929, + instant_quantity: null, + notes: null, + primary_purpose_id: '8d9d407c-3da7-4977-84a0-97738c9b44cc', + purpose_id: '025bfdc9-d7f4-46b5-a7e0-451dec1a34a6', + secondary_purpose_id: '04bdc9f6-a4e7-41de-831c-9ebf15b92782', + time_limited_end_date: null, + time_limited_start_date: null, + version_external_id: '6:2113:100:0' + } +} diff --git a/test/services/import/legacy/transform-licence-versions.service.test.js b/test/services/import/legacy/transform-licence-versions.service.test.js new file mode 100644 index 0000000000..a08d08ab9b --- /dev/null +++ b/test/services/import/legacy/transform-licence-versions.service.test.js @@ -0,0 +1,88 @@ +'use strict' + +// Test framework dependencies +const Lab = require('@hapi/lab') +const Code = require('@hapi/code') +const Sinon = require('sinon') + +const { describe, it, beforeEach, afterEach } = exports.lab = Lab.script() +const { expect } = Code + +// Things to stub +const FetchLicenceVersionsService = require('../../../../app/services/import/legacy/fetch-licence-versions.service.js') + +// Thing under test +const TransformLicenceVersionsService = + require('../../../../app/services/import/legacy/transform-licence-versions.service.js') + +describe('Import Legacy Transform Licence Versions service', () => { + // NOTE: Clearly this is an incomplete representation of the licence returned from TransformedLicenceService. But for + // the purposes of this service it is all that is needed + const transformedLicence = { licenceVersions: [] } + + const naldLicenceId = '2113' + const regionCode = '6' + + let legacyLicenceVersion + + beforeEach(() => { + legacyLicenceVersion = _legacyLicenceVersion() + }) + + afterEach(() => { + Sinon.restore() + }) + + describe('when a matching valid legacy licence version is found', () => { + beforeEach(() => { + Sinon.stub(FetchLicenceVersionsService, 'go').resolves([legacyLicenceVersion]) + }) + + it('attaches the record transformed and validated for WRLS to the transformed licence', async () => { + await TransformLicenceVersionsService.go(regionCode, naldLicenceId, transformedLicence) + + expect(transformedLicence.licenceVersions[0]).to.equal({ + endDate: null, + externalId: '6:2113:100:0', + increment: 0, + issue: 100, + licenceVersionPurposes: [], + startDate: new Date('1999-01-01'), + status: 'current' + }) + }) + }) + + describe('when no matching legacy licence version is found', () => { + beforeEach(() => { + Sinon.stub(FetchLicenceVersionsService, 'go').resolves(null) + }) + + it('throws an error', async () => { + await expect(TransformLicenceVersionsService.go(regionCode, naldLicenceId, transformedLicence)).to.reject() + }) + }) + + describe('when the matching legacy licence version is invalid', () => { + beforeEach(() => { + legacyLicenceVersion.increment_number = null + + Sinon.stub(FetchLicenceVersionsService, 'go').resolves([legacyLicenceVersion]) + }) + + it('throws an error', async () => { + await expect(TransformLicenceVersionsService.go(regionCode, naldLicenceId, transformedLicence)).to.reject() + }) + }) +}) + +function _legacyLicenceVersion () { + return { + effective_end_date: null, + effective_start_date: new Date('1999-01-01'), + external_id: '6:2113:100:0', + increment_number: 0, + issue_no: 100, + status: 'CURR' + } +} diff --git a/test/services/import/legacy/transform-licence.service.test.js b/test/services/import/legacy/transform-licence.service.test.js new file mode 100644 index 0000000000..781106ca32 --- /dev/null +++ b/test/services/import/legacy/transform-licence.service.test.js @@ -0,0 +1,102 @@ +'use strict' + +// Test framework dependencies +const Lab = require('@hapi/lab') +const Code = require('@hapi/code') +const Sinon = require('sinon') + +const { describe, it, beforeEach, afterEach } = exports.lab = Lab.script() +const { expect } = Code + +// Test helpers +const { generateLicenceRef } = require('../../../support/helpers/licence.helper.js') + +// Things to stub +const FetchLicenceService = require('../../../../app/services/import/legacy/fetch-licence.service.js') + +// Thing under test +const TransformLicenceService = require('../../../../app/services/import/legacy/transform-licence.service.js') + +describe('Import Legacy Transform Licence service', () => { + let legacyLicence + let licenceRef + + beforeEach(() => { + licenceRef = generateLicenceRef() + legacyLicence = _legacyLicence(licenceRef) + }) + + afterEach(() => { + Sinon.restore() + }) + + describe('when a matching valid legacy licence is found', () => { + beforeEach(() => { + Sinon.stub(FetchLicenceService, 'go').resolves(legacyLicence) + }) + + it('returns the NALD licence ID, region code, and the licence transformed and validated for WRLS', async () => { + const result = await TransformLicenceService.go(licenceRef) + + expect(result.naldLicenceId).to.equal('2113') + expect(result.regionCode).to.equal('6') + + expect(result.transformedLicence).to.equal({ + expiredDate: null, + lapsedDate: null, + licenceRef, + licenceVersions: [], + regionId: '82d8c1b7-0eed-43a7-a5f9-4e397c08e17e', + regions: { + historicalAreaCode: 'KAEA', + regionalChargeArea: 'Southern', + standardUnitChargeCode: 'SUCSO', + localEnvironmentAgencyPlanCode: 'LEME' + }, + revokedDate: null, + startDate: new Date('1992-08-19'), + waterUndertaker: false + }) + }) + }) + + describe('when no matching legacy licence is found', () => { + beforeEach(() => { + Sinon.stub(FetchLicenceService, 'go').resolves(null) + }) + + it('throws an error', async () => { + await expect(TransformLicenceService.go(licenceRef)).to.reject() + }) + }) + + describe('when the matching legacy licence is invalid', () => { + beforeEach(() => { + legacyLicence.region_id = null + + Sinon.stub(FetchLicenceService, 'go').resolves(legacyLicence) + }) + + it('throws an error', async () => { + await expect(TransformLicenceService.go(licenceRef)).to.reject() + }) + }) +}) + +function _legacyLicence (licenceRef) { + return { + historical_area_code: 'KAEA', + environmental_improvement_unit_charge_code: 'SOOTH', + local_environment_agency_plan_code: 'LEME', + standard_unit_charge_code: 'SUCSO', + expiry_date: null, + region_code: '6', + id: '2113', + lapsed_date: null, + licence_ref: licenceRef, + original_effective_date: new Date('1992-08-19'), + revoked_date: null, + earliest_version_start_date: new Date('1999-01-01'), + region_id: '82d8c1b7-0eed-43a7-a5f9-4e397c08e17e' + } +} diff --git a/test/services/import/persist-licence-versions.service.test.js b/test/services/import/persist-licence-versions.service.test.js deleted file mode 100644 index de150fdb53..0000000000 --- a/test/services/import/persist-licence-versions.service.test.js +++ /dev/null @@ -1,407 +0,0 @@ -'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 FixtureImportLicenceVersions = require('./_fixtures/import-licence-versions.fixture.js') -const LicenceHelper = require('../../support/helpers/licence.helper.js') -const LicenceVersionModel = require('../../../app/models/licence-version.model.js') -const PurposeHelper = require('../../support/helpers/purpose.helper.js') -const PrimaryPurposeHelper = require('../../support/helpers/primary-purpose.helper.js') -const SecondaryPurposeHelper = require('../../support/helpers/secondary-purpose.helper.js') - -// Thing under test -const PersistLicenceVersionsService = - require('../../../app/services/import/persist-licence-versions.service.js') - -describe('Persist licence versions and licence versions purposes service', () => { - let licence - let licenceVersion - let licenceVersionsPurpose - let licenceVersionsAndPurposes - let primaryPurpose - let purpose - let secondaryPurpose - - beforeEach(async () => { - licence = await LicenceHelper.add() - - licenceVersionsAndPurposes = FixtureImportLicenceVersions.create() - - licenceVersion = { ...licenceVersionsAndPurposes[0] } - licenceVersionsPurpose = { ...licenceVersion.purposes[0] } - - primaryPurpose = PrimaryPurposeHelper.data.find((primaryPurpose) => { - return primaryPurpose.legacyId === licenceVersionsPurpose.primaryPurposeId - }) - - purpose = PurposeHelper.data.find((purpose) => { - return purpose.legacyId === licenceVersionsPurpose.purposeId - }) - - secondaryPurpose = SecondaryPurposeHelper.data.find((secondaryPurpose) => { - return secondaryPurpose.legacyId === licenceVersionsPurpose.secondaryPurposeId - }) - }) - - describe('when the licence version does not exist', () => { - it('returns the updated licence version', async () => { - await PersistLicenceVersionsService.go(licenceVersionsAndPurposes, licence.id) - - const savedLicenceVersion = await LicenceVersionModel.query() - .select('*') - .where('externalId', licenceVersion.externalId).first() - .withGraphFetched('licenceVersionPurposes') - - const [savedLicenceVersionPurpose] = savedLicenceVersion.licenceVersionPurposes - - expect(savedLicenceVersion).to.equal({ - createdAt: savedLicenceVersion.createdAt, - endDate: new Date('2002-01-01'), - externalId: licenceVersion.externalId, - id: savedLicenceVersion.id, - increment: 0, - issue: 100, - licenceId: licence.id, - licenceVersionPurposes: [ - { - id: savedLicenceVersionPurpose.id, - licenceVersionId: savedLicenceVersionPurpose.licenceVersionId, - primaryPurposeId: primaryPurpose.id, - secondaryPurposeId: secondaryPurpose.id, - purposeId: purpose.id, - abstractionPeriodStartDay: 1, - abstractionPeriodStartMonth: 4, - abstractionPeriodEndDay: 31, - abstractionPeriodEndMonth: 3, - timeLimitedStartDate: new Date('2001-01-03'), - timeLimitedEndDate: new Date('2001-01-02'), - notes: ' a note on purposes', - instantQuantity: 120, - dailyQuantity: 1500.2, - hourlyQuantity: 140.929, - annualQuantity: 545520, - externalId: licenceVersionsPurpose.externalId, - createdAt: savedLicenceVersionPurpose.createdAt, - updatedAt: savedLicenceVersionPurpose.updatedAt - } - ], - startDate: new Date('2001-01-01'), - status: 'superseded', - updatedAt: savedLicenceVersion.updatedAt - }) - }) - - describe('and does not have "purposes"', () => { - beforeEach(() => { - licenceVersionsAndPurposes = [ - { - ...licenceVersion, - purposes: [] - } - ] - }) - - it('does not return purposes', async () => { - await PersistLicenceVersionsService.go(licenceVersionsAndPurposes, licence.id) - - const savedLicenceVersionPurposes = await LicenceVersionModel.query() - .select('*') - .where('externalId', licenceVersion.externalId).first() - .withGraphFetched('licenceVersionPurposes') - - expect(savedLicenceVersionPurposes.licenceVersionPurposes).to.equal([]) - }) - }) - - describe('and has "purposes"', () => { - it('returns the created purposes', async () => { - await PersistLicenceVersionsService.go(licenceVersionsAndPurposes, licence.id) - - const savedLicenceVersionPurposes = await LicenceVersionModel.query() - .select('*') - .where('externalId', licenceVersion.externalId).first() - .withGraphFetched('licenceVersionPurposes') - - const [savedLicenceVersionPurpose] = savedLicenceVersionPurposes.licenceVersionPurposes - - expect(savedLicenceVersionPurposes.licenceVersionPurposes).to.equal([ - { - id: savedLicenceVersionPurpose.id, - licenceVersionId: savedLicenceVersionPurpose.licenceVersionId, - primaryPurposeId: primaryPurpose.id, - secondaryPurposeId: secondaryPurpose.id, - purposeId: purpose.id, - abstractionPeriodStartDay: 1, - abstractionPeriodStartMonth: 4, - abstractionPeriodEndDay: 31, - abstractionPeriodEndMonth: 3, - timeLimitedStartDate: new Date('2001-01-03'), - timeLimitedEndDate: new Date('2001-01-02'), - notes: ' a note on purposes', - instantQuantity: 120, - dailyQuantity: 1500.2, - hourlyQuantity: 140.929, - annualQuantity: 545520, - externalId: licenceVersionsPurpose.externalId, - createdAt: savedLicenceVersionPurpose.createdAt, - updatedAt: savedLicenceVersionPurpose.updatedAt - } - ]) - }) - }) - }) - - describe('when the licence version has multiple increments', () => { - let licenceVersionsAndPurposesUpdated - // There is a convention where the increment is updated in the third number of an external id. - // This as far as we can tell is the only element in the id that changes - // This test has been added to highlight this 'functionality' from the nald data. - let updatedExternalId - - beforeEach(async () => { - await PersistLicenceVersionsService.go(licenceVersionsAndPurposes, licence.id) - - const parts = licenceVersion.externalId.split(':') - - parts[2] = '2' - updatedExternalId = parts.join(':') - - licenceVersionsAndPurposesUpdated = [ - { - ...licenceVersion, - purposes: [{ ...licenceVersionsPurpose }], - externalId: updatedExternalId, - increment: 2 - } - ] - }) - - it('returns the licence versions with multiple increments', async () => { - await PersistLicenceVersionsService.go(licenceVersionsAndPurposesUpdated, licence.id) - - const savedLicenceVersions = await LicenceVersionModel.query() - .select('*') - .where('licenceId', licence.id).orderBy('increment', 'asc') - .withGraphFetched('licenceVersionPurposes') - - const [savedLicenceVersionOne, savedLicenceVersionTwo] = savedLicenceVersions - - expect(savedLicenceVersions).to.equal([ - { - createdAt: savedLicenceVersionOne.createdAt, - endDate: new Date('2002-01-01'), - externalId: licenceVersion.externalId, - id: savedLicenceVersionOne.id, - increment: 0, - issue: 100, - licenceId: licence.id, - licenceVersionPurposes: [ - { - abstractionPeriodEndDay: 31, - abstractionPeriodEndMonth: 3, - abstractionPeriodStartDay: 1, - abstractionPeriodStartMonth: 4, - annualQuantity: 545520, - createdAt: savedLicenceVersionOne.licenceVersionPurposes[0].createdAt, - dailyQuantity: 1500.2, - externalId: licenceVersionsPurpose.externalId, - hourlyQuantity: 140.929, - id: savedLicenceVersionOne.licenceVersionPurposes[0].id, - instantQuantity: 120, - licenceVersionId: savedLicenceVersionOne.id, - notes: ' a note on purposes', - primaryPurposeId: primaryPurpose.id, - purposeId: purpose.id, - secondaryPurposeId: secondaryPurpose.id, - timeLimitedEndDate: new Date('2001-01-02'), - timeLimitedStartDate: new Date(' 2001-01-03'), - updatedAt: savedLicenceVersionOne.licenceVersionPurposes[0].updatedAt - } - ], - startDate: new Date('2001-01-01'), - status: 'superseded', - updatedAt: savedLicenceVersionOne.updatedAt - }, - { - createdAt: savedLicenceVersionTwo.createdAt, - endDate: new Date('2002-01-01'), - externalId: updatedExternalId, - id: savedLicenceVersionTwo.id, - increment: 2, - issue: 100, - licenceId: licence.id, - licenceVersionPurposes: [], - startDate: new Date('2001-01-01'), - status: 'superseded', - updatedAt: savedLicenceVersionTwo.updatedAt - } - ]) - }) - }) - - describe('when the licence version already exists', () => { - let licenceVersionsAndPurposesUpdated - - beforeEach(async () => { - await PersistLicenceVersionsService.go(licenceVersionsAndPurposes, licence.id) - - licenceVersionsAndPurposesUpdated = [ - { - ...licenceVersion, - purposes: [{ ...licenceVersionsPurpose }], - status: 'current' - } - ] - }) - - it('returns the updated licence version and purposes', async () => { - await PersistLicenceVersionsService.go(licenceVersionsAndPurposesUpdated, licence.id) - - const savedLicenceVersions = await LicenceVersionModel.query() - .select('*') - .where('externalId', licenceVersion.externalId) - .withGraphFetched('licenceVersionPurposes') - - const savedLicenceVersion = savedLicenceVersions[0] - - const [savedLicenceVersionPurpose] = savedLicenceVersion.licenceVersionPurposes - - expect(savedLicenceVersion).to.equal({ - createdAt: savedLicenceVersion.createdAt, - endDate: new Date('2002-01-01'), - externalId: licenceVersion.externalId, - id: savedLicenceVersion.id, - increment: 0, - issue: 100, - licenceId: licence.id, - licenceVersionPurposes: [ - { - id: savedLicenceVersionPurpose.id, - licenceVersionId: savedLicenceVersionPurpose.licenceVersionId, - primaryPurposeId: primaryPurpose.id, - secondaryPurposeId: secondaryPurpose.id, - purposeId: purpose.id, - abstractionPeriodStartDay: 1, - abstractionPeriodStartMonth: 4, - abstractionPeriodEndDay: 31, - abstractionPeriodEndMonth: 3, - timeLimitedStartDate: new Date('2001-01-03'), - timeLimitedEndDate: new Date('2001-01-02'), - notes: ' a note on purposes', - instantQuantity: 120, - dailyQuantity: 1500.2, - hourlyQuantity: 140.929, - annualQuantity: 545520, - externalId: licenceVersionsPurpose.externalId, - createdAt: savedLicenceVersionPurpose.createdAt, - updatedAt: savedLicenceVersionPurpose.updatedAt - } - ], - startDate: new Date('2001-01-01'), - status: 'current', - updatedAt: savedLicenceVersion.updatedAt - }) - }) - - it('returns the updated licence version status', async () => { - await PersistLicenceVersionsService.go(licenceVersionsAndPurposesUpdated, licence.id) - - const savedLicenceVersions = await LicenceVersionModel.query() - .select('*') - .where('externalId', licenceVersion.externalId) - .withGraphFetched('licenceVersionPurposes') - - const savedLicenceVersion = savedLicenceVersions[0] - - expect(savedLicenceVersion.status).to.equal('current') - }) - - describe('and does not have purposes', () => { - beforeEach(async () => { - await PersistLicenceVersionsService.go(licenceVersionsAndPurposesUpdated, licence.id) - - licenceVersionsAndPurposesUpdated[0].purposes = [] - }) - - it('returns the updated licence version and no purposes', async () => { - await PersistLicenceVersionsService.go(licenceVersionsAndPurposesUpdated, licence.id) - - const savedLicenceVersion = await LicenceVersionModel.query() - .select('*') - .where('externalId', licenceVersion.externalId).first() - - expect(savedLicenceVersion).to.equal({ - createdAt: savedLicenceVersion.createdAt, - endDate: new Date('2002-01-01'), - externalId: licenceVersion.externalId, - id: savedLicenceVersion.id, - increment: 0, - issue: 100, - licenceId: licence.id, - startDate: new Date('2001-01-01'), - status: 'current', - updatedAt: savedLicenceVersion.updatedAt - }) - }) - }) - - describe('and has purposes', () => { - it('returns the updated licence version purposes', async () => { - await PersistLicenceVersionsService.go(licenceVersionsAndPurposesUpdated, licence.id) - - const savedLicenceVersion = await LicenceVersionModel.query() - .select('*') - .where('externalId', licenceVersion.externalId).first() - .withGraphFetched('licenceVersionPurposes') - - const [savedLicenceVersionPurpose] = savedLicenceVersion.licenceVersionPurposes - - expect(savedLicenceVersion.licenceVersionPurposes).to.equal([ - { - createdAt: savedLicenceVersionPurpose.createdAt, - id: savedLicenceVersionPurpose.id, - licenceVersionId: savedLicenceVersionPurpose.licenceVersionId, - primaryPurposeId: primaryPurpose.id, - secondaryPurposeId: secondaryPurpose.id, - purposeId: purpose.id, - abstractionPeriodStartDay: 1, - abstractionPeriodStartMonth: 4, - abstractionPeriodEndDay: 31, - abstractionPeriodEndMonth: 3, - timeLimitedStartDate: new Date('2001-01-03'), - timeLimitedEndDate: new Date('2001-01-02'), - notes: ' a note on purposes', - instantQuantity: 120, - dailyQuantity: 1500.2, - hourlyQuantity: 140.929, - annualQuantity: 545520, - externalId: licenceVersionsPurpose.externalId, - updatedAt: savedLicenceVersionPurpose.updatedAt - } - ] - ) - - it('checks the purposes id, primary purpose id and secondary purpose id match the legacy id provided', async () => { - await PersistLicenceVersionsService.go(licenceVersionsAndPurposesUpdated, licence.id) - - const savedLicenceVersion = await LicenceVersionModel.query() - .select('*') - .where('externalId', licenceVersion.externalId).first() - .withGraphFetched('licenceVersionPurposes') - - const [savedLicenceVersionPurpose] = savedLicenceVersion.licenceVersionPurposes - - expect(savedLicenceVersionPurpose.primaryPurposeId).to.equal(primaryPurpose.id) - expect(savedLicenceVersionPurpose.secondaryPurposeId).to.equal(secondaryPurpose.id) - expect(savedLicenceVersionPurpose.purposeId).to.equal(purpose.id) - }) - }) - }) - }) -}) diff --git a/test/services/import/persist-licence.service.test.js b/test/services/import/persist-licence.service.test.js index e619c05b9d..15ce76f766 100644 --- a/test/services/import/persist-licence.service.test.js +++ b/test/services/import/persist-licence.service.test.js @@ -8,127 +8,221 @@ const { describe, it, beforeEach } = exports.lab = Lab.script() const { expect } = Code // Test helpers -const FixtureImportLicence = require('./_fixtures/import-licence.fixture.js') +const LicenceHelper = require('../../support/helpers/licence.helper.js') const LicenceModel = require('../../../app/models/licence.model.js') +const LicenceVersionHelper = require('../../support/helpers/licence-version.helper.js') +const LicenceVersionPurposeHelper = require('../../support/helpers/licence-version-purpose.helper.js') +const PrimaryPurposeHelper = require('../../support/helpers/primary-purpose.helper.js') +const PurposeHelper = require('../../support/helpers/purpose.helper.js') const RegionHelper = require('../../support/helpers/region.helper.js') +const SecondaryPurposeHelper = require('../../support/helpers/secondary-purpose.helper.js') // Thing under test -const PersistLicenceService = - require('../../../app/services/import/persist-licence.service.js') +const PersistLicenceService = require('../../../app/services/import/persist-licence.service.js') describe('Persist licence service', () => { + let primaryPurpose + let purpose let region - let licence + let secondaryPurpose + let transformedLicence beforeEach(async () => { - licence = { ...FixtureImportLicence.create() } + primaryPurpose = PrimaryPurposeHelper.select() + purpose = PurposeHelper.select() + region = RegionHelper.select() + secondaryPurpose = SecondaryPurposeHelper.select() - region = RegionHelper.data.find((region) => { - return region.displayName === 'Test Region' - }) + transformedLicence = _transformedLicence(region.id, primaryPurpose.id, purpose.id, secondaryPurpose.id) }) - it('returns the licence', async () => { - const result = await PersistLicenceService.go(licence) - - const savedLicence = await LicenceModel.query() - .select('*') - .where('licenceRef', licence.licenceRef).first() - - expect(result).to.equal({ - expiredDate: '2015-03-31', - id: savedLicence.id, - lapsedDate: null, - licenceRef: licence.licenceRef, - regionId: region.id, - regions: { - historicalAreaCode: 'RIDIN', - localEnvironmentAgencyPlanCode: 'AIREL', - regionalChargeArea: 'Yorkshire', - standardUnitChargeCode: 'YORKI' - }, - revokedDate: null, - startDate: '2005-06-03', - waterUndertaker: false + describe('when given a valid transformed licence', () => { + describe('and that licence does not already exist', () => { + it('creates a new licence record plus child records in WRLS and returns the licence ID', async () => { + const result = await PersistLicenceService.go(transformedLicence) + + const newLicence = await _fetchPersistedLicence(transformedLicence.licenceRef) + + // Licence + expect(result).to.equal(newLicence.id) + + // Licence version + const newLicenceVersion = newLicence.licenceVersions[0] + + expect(newLicenceVersion.externalId).to.equal(transformedLicence.licenceVersions[0].externalId) + + // Licence version purpose + const newLicenceVersionPurpose = newLicence.licenceVersions[0].licenceVersionPurposes[0] + + expect(newLicenceVersionPurpose.externalId).to.equal( + transformedLicence.licenceVersions[0].licenceVersionPurposes[0].externalId + ) + }) }) - }) - describe('when the licence ref does not exist', () => { - it('creates the licence', async () => { - await PersistLicenceService.go(licence) - - const savedLicence = await LicenceModel.query() - .select('*') - .where('licenceRef', licence.licenceRef).first() - - expect(savedLicence).to.equal({ - createdAt: savedLicence.createdAt, - expiredDate: new Date('2015-03-31'), - id: savedLicence.id, - includeInPresrocBilling: 'no', - includeInSrocBilling: false, - lapsedDate: null, - licenceRef: licence.licenceRef, - regionId: region.id, - regions: { - historicalAreaCode: 'RIDIN', - localEnvironmentAgencyPlanCode: 'AIREL', - regionalChargeArea: 'Yorkshire', - standardUnitChargeCode: 'YORKI' - }, - revokedDate: null, - startDate: new Date('2005-06-03'), - suspendFromBilling: false, - updatedAt: savedLicence.updatedAt, - waterUndertaker: false - } - ) + describe('and that licence already exists', () => { + let existingLicence + let existingLicenceVersion + let existingLicenceVersionPurpose + + beforeEach(async () => { + existingLicence = await LicenceHelper.add({ + expiredDate: new Date('2052-06-23'), + lapsedDate: new Date('2050-07-24'), + licenceRef: transformedLicence.licenceRef, + regionId: region.id, + regions: { + historicalAreaCode: 'RIDIN', + regionalChargeArea: 'Yorkshire', + standardUnitChargeCode: 'YORKI', + localEnvironmentAgencyPlanCode: 'AIREL' + }, + revokedDate: new Date('2049-08-25'), + startDate: new Date('1992-08-19') + }) + existingLicenceVersion = await LicenceVersionHelper.add({ + endDate: new Date('2052-06-23'), + externalId: transformedLicence.licenceVersions[0].externalId, + licenceId: existingLicence.id, + startDate: new Date('1999-01-01'), + status: 'current' + }) + existingLicenceVersionPurpose = await LicenceVersionPurposeHelper.add({ + abstractionPeriodEndDay: 30, + abstractionPeriodEndMonth: 9, + abstractionPeriodStartDay: 1, + abstractionPeriodStartMonth: 5, + annualQuantity: 61371, + dailyQuantity: 1091, + externalId: transformedLicence.licenceVersions[0].licenceVersionPurposes[0].externalId, + hourlyQuantity: 68, + instantQuantity: 18.89, + licenceVersionId: existingLicenceVersion.id, + notes: 'I was here first', + primaryPurposeId: PrimaryPurposeHelper.select().id, + purposeId: PurposeHelper.select().id, + secondaryPurposeId: SecondaryPurposeHelper.select().id, + timeLimitedEndDate: new Date('1992-08-19'), + timeLimitedStartDate: new Date('2052-06-23') + }) + }) + + it('updates the licence record plus child records in WRLS and returns the licence ID', async () => { + const result = await PersistLicenceService.go(transformedLicence) + + expect(result).to.equal(existingLicence.id) + + // Licence comparison + const updatedLicence = await _fetchPersistedLicence(transformedLicence.licenceRef) + + expect(updatedLicence.expiredDate).to.equal(transformedLicence.expiredDate) + expect(updatedLicence.lapsedDate).to.equal(transformedLicence.lapsedDate) + expect(updatedLicence.regions).to.equal(transformedLicence.regions) + expect(updatedLicence.revokedDate).to.equal(transformedLicence.revokedDate) + expect(updatedLicence.startDate).to.equal(transformedLicence.startDate) + + // Licence version comparison + const updatedLicVer = updatedLicence.licenceVersions[0] + const transformedLicVer = transformedLicence.licenceVersions[0] + + expect(updatedLicVer.id).to.equal(existingLicenceVersion.id) + expect(updatedLicVer.endDate).to.equal(transformedLicVer.endDate) + expect(updatedLicVer.startDate).to.equal(transformedLicVer.startDate) + expect(updatedLicVer.status).to.equal(transformedLicVer.status) + + // Licence version purpose comparison + const updatedLicVerPur = updatedLicence.licenceVersions[0].licenceVersionPurposes[0] + const transformedLicVerPur = transformedLicence.licenceVersions[0].licenceVersionPurposes[0] + + expect(updatedLicVerPur.id).to.equal(existingLicenceVersionPurpose.id) + expect(updatedLicVerPur.abstractionPeriodEndDay).to.equal(transformedLicVerPur.abstractionPeriodEndDay) + expect(updatedLicVerPur.abstractionPeriodEndMonth).to.equal(transformedLicVerPur.abstractionPeriodEndMonth) + expect(updatedLicVerPur.abstractionPeriodStartDay).to.equal(transformedLicVerPur.abstractionPeriodStartDay) + expect(updatedLicVerPur.abstractionPeriodStartMonth).to.equal(transformedLicVerPur.abstractionPeriodStartMonth) + expect(updatedLicVerPur.annualQuantity).to.equal(transformedLicVerPur.annualQuantity) + expect(updatedLicVerPur.dailyQuantity).to.equal(transformedLicVerPur.dailyQuantity) + expect(updatedLicVerPur.hourlyQuantity).to.equal(transformedLicVerPur.hourlyQuantity) + expect(updatedLicVerPur.instantQuantity).to.equal(transformedLicVerPur.instantQuantity) + expect(updatedLicVerPur.notes).to.equal(transformedLicVerPur.notes) + expect(updatedLicVerPur.primaryPurposeId).to.equal(transformedLicVerPur.primaryPurposeId) + expect(updatedLicVerPur.purposeId).to.equal(transformedLicVerPur.purposeId) + expect(updatedLicVerPur.secondaryPurposeId).to.equal(transformedLicVerPur.secondaryPurposeId) + expect(updatedLicVerPur.timeLimitedEndDate).to.equal(transformedLicVerPur.timeLimitedEndDate) + expect(updatedLicVerPur.timeLimitedStartDate).to.equal(transformedLicVerPur.timeLimitedStartDate) + }) }) }) - describe('when the licence ref already exist', () => { - beforeEach(async () => { - // create a licence that exists already (DB rule to only allow on occurrence of licence ref) - await PersistLicenceService.go(licence) + describe('when an error is thrown when persisting the licence', () => { + beforeEach(() => { + // We cause the error by making the last record to be persisted have an invalid value. This demonstrates the + // purpose of the DB transaction: either all records are persisted or none of them + transformedLicence.licenceVersions[0].licenceVersionPurposes[0].primaryPurposeId = 'boom' }) - it('updates the licence', async () => { - await PersistLicenceService.go({ - licenceRef: licence.licenceRef, - regionId: region.naldRegionId, - // not null constraints - waterUndertaker: true, - regions: licence.regions, - startDate: '2005-06-03' - }) + it('throws an error and persists nothing', async () => { + await expect(PersistLicenceService.go(transformedLicence)).to.reject() - const savedLicence = await LicenceModel.query() - .select('*') - .where('licenceRef', licence.licenceRef).first() - - expect(savedLicence).to.equal({ - createdAt: savedLicence.createdAt, - expiredDate: null, - id: savedLicence.id, - includeInPresrocBilling: 'no', - includeInSrocBilling: false, - lapsedDate: null, - licenceRef: licence.licenceRef, - regionId: region.id, - regions: { - historicalAreaCode: 'RIDIN', - localEnvironmentAgencyPlanCode: 'AIREL', - regionalChargeArea: 'Yorkshire', - standardUnitChargeCode: 'YORKI' - }, - revokedDate: null, - startDate: new Date('2005-06-03'), - suspendFromBilling: false, - updatedAt: savedLicence.updatedAt, - waterUndertaker: true - }) + const newLicence = await _fetchPersistedLicence(transformedLicence.licenceRef) - expect(savedLicence.waterUndertaker).to.be.true() + expect(newLicence).to.be.undefined() }) }) }) + +async function _fetchPersistedLicence (licenceRef) { + return LicenceModel + .query() + .where('licenceRef', licenceRef) + .withGraphFetched('licenceVersions') + .withGraphFetched('licenceVersions.licenceVersionPurposes') + .limit(1) + .first() +} + +function _transformedLicence (regionId, primaryPurposeId, purposeId, secondaryPurposeId) { + return { + expiredDate: null, + lapsedDate: null, + licenceRef: LicenceHelper.generateLicenceRef(), + regionId, + regions: { + historicalAreaCode: 'KAEA', + regionalChargeArea: 'Southern', + standardUnitChargeCode: 'SUCSO', + localEnvironmentAgencyPlanCode: 'LEME' + }, + revokedDate: null, + startDate: new Date('1992-08-19'), + waterUndertaker: false, + licenceVersions: [ + { + endDate: new Date('2052-06-23'), + externalId: LicenceVersionHelper.generateLicenceVersionExternalId(), + increment: 0, + issue: 100, + startDate: new Date('1999-01-01'), + status: 'superseded', + licenceVersionPurposes: [ + { + abstractionPeriodEndDay: 31, + abstractionPeriodEndMonth: 3, + abstractionPeriodStartDay: 1, + abstractionPeriodStartMonth: 4, + annualQuantity: 545520.1, + dailyQuantity: 1500.2, + externalId: LicenceVersionPurposeHelper.generateLicenceVersionPurposeExternalId(), + hourlyQuantity: 140.929, + instantQuantity: null, + notes: 'This is a note', + primaryPurposeId, + purposeId, + secondaryPurposeId, + timeLimitedEndDate: null, + timeLimitedStartDate: null + } + ] + } + ] + } +} diff --git a/test/services/import/validate-licence.service.test.js b/test/services/import/validate-licence.service.test.js deleted file mode 100644 index 20c81d4120..0000000000 --- a/test/services/import/validate-licence.service.test.js +++ /dev/null @@ -1,43 +0,0 @@ -'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 FixtureImportLicence = require('./_fixtures/import-licence.fixture.js') -const FixtureImportLicenceVersion = require('./_fixtures/import-licence-versions.fixture.js') - -// Thing under test -const ValidateLicenceService = - require('../../../app/services/import/validate-licence.service.js') - -describe('Import licence validator service', () => { - let licence - let licenceVersionsAndPurposes - - beforeEach(async () => { - licence = { - ...FixtureImportLicence.create() - } - - licenceVersionsAndPurposes = [...FixtureImportLicenceVersion.create()] - }) - - it('should not throw an error - licence is valid', async () => { - expect(() => { return ValidateLicenceService.go(licence, licenceVersionsAndPurposes) }).to.not.throw() - }) - - describe('when a licence has badly formatted data', () => { - beforeEach(() => { - licence = {} - }) - - it('should not throw an error - licence is valid', async () => { - expect(() => { return ValidateLicenceService.go(licence, licenceVersionsAndPurposes) }).to.throw('"licenceRef" is required') - }) - }) -}) diff --git a/test/validators/import/licence-structure.validator.test.js b/test/validators/import/licence-structure.validator.test.js new file mode 100644 index 0000000000..3c4270756d --- /dev/null +++ b/test/validators/import/licence-structure.validator.test.js @@ -0,0 +1,120 @@ +'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 LicenceStructureValidator = require('../../../app/validators/import/licence-structure.validator.js') + +describe('Import Licence Structure validator', () => { + let transformedLicence + + beforeEach(() => { + transformedLicence = _transformedLicence() + }) + + describe('when valid data is provided', () => { + it('does not throw an error', () => { + expect(() => { + LicenceStructureValidator.go(transformedLicence) + }).to.not.throw() + }) + }) + + describe('the "licenceVersions" property', () => { + describe('when it is not an array', () => { + beforeEach(() => { + transformedLicence.licenceVersions = 1 + }) + + it('throws an error', async () => { + expect(() => { + LicenceStructureValidator.go(transformedLicence) + }).to.throw('"licenceVersions" must be an array') + }) + }) + + describe('when it is null', () => { + beforeEach(() => { + transformedLicence.licenceVersions = null + }) + + it('throws an error', async () => { + expect(() => { + LicenceStructureValidator.go(transformedLicence) + }).to.throw('"licenceVersions" must be an array') + }) + }) + + describe('when it is empty', () => { + beforeEach(() => { + transformedLicence.licenceVersions = [] + }) + + it('throws an error', async () => { + expect(() => { + LicenceStructureValidator.go(transformedLicence) + }).to.throw('"licenceVersions" must contain at least 1 items') + }) + }) + + describe('and its "licenceVersionPurposes" property', () => { + describe('when it is not an array', () => { + beforeEach(() => { + transformedLicence.licenceVersions[0].licenceVersionPurposes = 1 + }) + + it('throws an error', async () => { + expect(() => { + LicenceStructureValidator.go(transformedLicence) + }).to.throw('"licenceVersions[0].licenceVersionPurposes" must be an array') + }) + }) + + describe('when it is null', () => { + beforeEach(() => { + transformedLicence.licenceVersions[0].licenceVersionPurposes = null + }) + + it('throws an error', async () => { + expect(() => { + LicenceStructureValidator.go(transformedLicence) + }).to.throw('"licenceVersions[0].licenceVersionPurposes" must be an array') + }) + }) + + describe('when it is empty', () => { + beforeEach(() => { + transformedLicence.licenceVersions[0].licenceVersionPurposes = [] + }) + + it('throws an error', async () => { + expect(() => { + LicenceStructureValidator.go(transformedLicence) + }).to.throw('"licenceVersions[0].licenceVersionPurposes" must contain at least 1 items') + }) + }) + }) + }) +}) + +function _transformedLicence () { + return { + licenceRef: '01/123', + licenceVersions: [{ + externalId: '6:2113:100:0', + licenceVersionPurposes: [ + { + externalId: '6:10000004' + }, + { + externalId: '6:10000005' + } + ] + }] + } +} diff --git a/test/validators/import/licence-version-purpose.validator.test.js b/test/validators/import/licence-version-purpose.validator.test.js new file mode 100644 index 0000000000..a4a68897ea --- /dev/null +++ b/test/validators/import/licence-version-purpose.validator.test.js @@ -0,0 +1,639 @@ +'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 LicenceVersionPurposeValidator = require('../../../app/validators/import/licence-version-purpose.validator.js') + +describe('Import Licence Version Purpose validator', () => { + let transformedLicenceVersionPurpose + + beforeEach(async () => { + transformedLicenceVersionPurpose = _transformedLicenceVersionPurpose() + }) + + describe('when valid data is provided', () => { + it('does not throw an error', () => { + expect(() => { + LicenceVersionPurposeValidator.go(transformedLicenceVersionPurpose) + }).to.not.throw() + }) + }) + + describe('the "abstractionPeriodEndDay" property', () => { + describe('when it is not a number', () => { + beforeEach(() => { + transformedLicenceVersionPurpose.abstractionPeriodEndDay = '31a' + }) + + it('throws an error', async () => { + expect(() => { + LicenceVersionPurposeValidator.go(transformedLicenceVersionPurpose) + }).to.throw('"abstractionPeriodEndDay" must be a number') + }) + }) + + describe('when it is null', () => { + beforeEach(() => { + transformedLicenceVersionPurpose.abstractionPeriodEndDay = null + }) + + it('throws an error', async () => { + expect(() => { + LicenceVersionPurposeValidator.go(transformedLicenceVersionPurpose) + }).to.throw('"abstractionPeriodEndDay" must be a number') + }) + }) + + describe('when it is less than the minimum (1)', () => { + beforeEach(() => { + transformedLicenceVersionPurpose.abstractionPeriodEndDay = 0 + }) + + it('throws an error', async () => { + expect(() => { + LicenceVersionPurposeValidator.go(transformedLicenceVersionPurpose) + }).to.throw('"abstractionPeriodEndDay" must be greater than or equal to 1') + }) + }) + + describe('when "abstractionPeriodEndMonth"', () => { + describe('is February (2)', () => { + describe('and "abstractionPeriodEndDay" is more than the number of days in the month (29)', () => { + beforeEach(() => { + transformedLicenceVersionPurpose.abstractionPeriodEndMonth = 2 + transformedLicenceVersionPurpose.abstractionPeriodEndDay = 29 + }) + + it('throws an error', async () => { + expect(() => { + LicenceVersionPurposeValidator.go(transformedLicenceVersionPurpose) + }).to.throw('"abstractionPeriodEndDay" must be less than or equal to 28') + }) + }) + }) + + describe('is April (4)', () => { + describe('and "abstractionPeriodEndDay" is more than the number of days in the month (30)', () => { + beforeEach(() => { + transformedLicenceVersionPurpose.abstractionPeriodEndMonth = 4 + transformedLicenceVersionPurpose.abstractionPeriodEndDay = 31 + }) + + it('throws an error', async () => { + expect(() => { + LicenceVersionPurposeValidator.go(transformedLicenceVersionPurpose) + }).to.throw('"abstractionPeriodEndDay" must be less than or equal to 30') + }) + }) + }) + + describe('is March (3)', () => { + describe('and "abstractionPeriodEndDay" is more than the number of days in the month (31)', () => { + beforeEach(() => { + transformedLicenceVersionPurpose.abstractionPeriodEndMonth = 3 + transformedLicenceVersionPurpose.abstractionPeriodEndDay = 32 + }) + + it('throws an error', async () => { + expect(() => { + LicenceVersionPurposeValidator.go(transformedLicenceVersionPurpose) + }).to.throw('"abstractionPeriodEndDay" must be less than or equal to 31') + }) + }) + }) + }) + }) + + describe('the "abstractionPeriodEndMonth" property', () => { + describe('when it is not a number', () => { + beforeEach(() => { + transformedLicenceVersionPurpose.abstractionPeriodEndMonth = '12a' + }) + + it('throws an error', async () => { + expect(() => { + LicenceVersionPurposeValidator.go(transformedLicenceVersionPurpose) + }).to.throw('"abstractionPeriodEndMonth" must be a number') + }) + }) + + describe('when it is null', () => { + beforeEach(() => { + transformedLicenceVersionPurpose.abstractionPeriodEndMonth = null + }) + + it('throws an error', async () => { + expect(() => { + LicenceVersionPurposeValidator.go(transformedLicenceVersionPurpose) + }).to.throw('"abstractionPeriodEndMonth" must be a number') + }) + }) + + describe('when it is less than the minimum (1)', () => { + beforeEach(() => { + transformedLicenceVersionPurpose.abstractionPeriodEndMonth = 0 + }) + + it('throws an error', async () => { + expect(() => { + LicenceVersionPurposeValidator.go(transformedLicenceVersionPurpose) + }).to.throw('"abstractionPeriodEndMonth" must be greater than or equal to 1') + }) + }) + + describe('when it is more than the maximum (12)', () => { + beforeEach(() => { + transformedLicenceVersionPurpose.abstractionPeriodEndMonth = 13 + }) + + it('throws an error', async () => { + expect(() => { + LicenceVersionPurposeValidator.go(transformedLicenceVersionPurpose) + }).to.throw('"abstractionPeriodEndMonth" must be less than or equal to 12') + }) + }) + }) + + describe('the "abstractionPeriodStartDay" property', () => { + describe('when it is not a number', () => { + beforeEach(() => { + transformedLicenceVersionPurpose.abstractionPeriodStartDay = '31a' + }) + + it('throws an error', async () => { + expect(() => { + LicenceVersionPurposeValidator.go(transformedLicenceVersionPurpose) + }).to.throw('"abstractionPeriodStartDay" must be a number') + }) + }) + + describe('when it is null', () => { + beforeEach(() => { + transformedLicenceVersionPurpose.abstractionPeriodStartDay = null + }) + + it('throws an error', async () => { + expect(() => { + LicenceVersionPurposeValidator.go(transformedLicenceVersionPurpose) + }).to.throw('"abstractionPeriodStartDay" must be a number') + }) + }) + + describe('when it is less than the minimum (1)', () => { + beforeEach(() => { + transformedLicenceVersionPurpose.abstractionPeriodStartDay = 0 + }) + + it('throws an error', async () => { + expect(() => { + LicenceVersionPurposeValidator.go(transformedLicenceVersionPurpose) + }).to.throw('"abstractionPeriodStartDay" must be greater than or equal to 1') + }) + }) + + describe('when "abstractionPeriodStartMonth"', () => { + describe('is February (2)', () => { + describe('and "abstractionPeriodStartDay" is more than the number of days in the month (29)', () => { + beforeEach(() => { + transformedLicenceVersionPurpose.abstractionPeriodStartMonth = 2 + transformedLicenceVersionPurpose.abstractionPeriodStartDay = 29 + }) + + it('throws an error', async () => { + expect(() => { + LicenceVersionPurposeValidator.go(transformedLicenceVersionPurpose) + }).to.throw('"abstractionPeriodStartDay" must be less than or equal to 28') + }) + }) + }) + + describe('is April (4)', () => { + describe('and "abstractionPeriodStartDay" is more than the number of days in the month (30)', () => { + beforeEach(() => { + transformedLicenceVersionPurpose.abstractionPeriodStartMonth = 4 + transformedLicenceVersionPurpose.abstractionPeriodStartDay = 31 + }) + + it('throws an error', async () => { + expect(() => { + LicenceVersionPurposeValidator.go(transformedLicenceVersionPurpose) + }).to.throw('"abstractionPeriodStartDay" must be less than or equal to 30') + }) + }) + }) + + describe('is March (3)', () => { + describe('and "abstractionPeriodStartDay" is more than the number of days in the month (31)', () => { + beforeEach(() => { + transformedLicenceVersionPurpose.abstractionPeriodStartMonth = 3 + transformedLicenceVersionPurpose.abstractionPeriodStartDay = 32 + }) + + it('throws an error', async () => { + expect(() => { + LicenceVersionPurposeValidator.go(transformedLicenceVersionPurpose) + }).to.throw('"abstractionPeriodStartDay" must be less than or equal to 31') + }) + }) + }) + }) + }) + + describe('the "abstractionPeriodStartMonth" property', () => { + describe('when it is not a number', () => { + beforeEach(() => { + transformedLicenceVersionPurpose.abstractionPeriodStartMonth = '12a' + }) + + it('throws an error', async () => { + expect(() => { + LicenceVersionPurposeValidator.go(transformedLicenceVersionPurpose) + }).to.throw('"abstractionPeriodStartMonth" must be a number') + }) + }) + + describe('when it is null', () => { + beforeEach(() => { + transformedLicenceVersionPurpose.abstractionPeriodStartMonth = null + }) + + it('throws an error', async () => { + expect(() => { + LicenceVersionPurposeValidator.go(transformedLicenceVersionPurpose) + }).to.throw('"abstractionPeriodStartMonth" must be a number') + }) + }) + + describe('when it is less than the minimum (1)', () => { + beforeEach(() => { + transformedLicenceVersionPurpose.abstractionPeriodStartMonth = 0 + }) + + it('throws an error', async () => { + expect(() => { + LicenceVersionPurposeValidator.go(transformedLicenceVersionPurpose) + }).to.throw('"abstractionPeriodStartMonth" must be greater than or equal to 1') + }) + }) + + describe('when it is more than the maximum (12)', () => { + beforeEach(() => { + transformedLicenceVersionPurpose.abstractionPeriodStartMonth = 13 + }) + + it('throws an error', async () => { + expect(() => { + LicenceVersionPurposeValidator.go(transformedLicenceVersionPurpose) + }).to.throw('"abstractionPeriodStartMonth" must be less than or equal to 12') + }) + }) + }) + + describe('the "annualQuantity" property', () => { + describe('when it is not a number', () => { + beforeEach(() => { + transformedLicenceVersionPurpose.annualQuantity = '545520.1a' + }) + + it('throws an error', async () => { + expect(() => { + LicenceVersionPurposeValidator.go(transformedLicenceVersionPurpose) + }).to.throw('"annualQuantity" must be a number') + }) + }) + + describe('when it is null', () => { + beforeEach(() => { + transformedLicenceVersionPurpose.annualQuantity = null + }) + + it('does not throw an error', () => { + expect(() => { + LicenceVersionPurposeValidator.go(transformedLicenceVersionPurpose) + }).to.not.throw() + }) + }) + }) + + describe('the "dailyQuantity" property', () => { + describe('when it is not a number', () => { + beforeEach(() => { + transformedLicenceVersionPurpose.dailyQuantity = '1500.2a' + }) + + it('throws an error', async () => { + expect(() => { + LicenceVersionPurposeValidator.go(transformedLicenceVersionPurpose) + }).to.throw('"dailyQuantity" must be a number') + }) + }) + + describe('when it is null', () => { + beforeEach(() => { + transformedLicenceVersionPurpose.dailyQuantity = null + }) + + it('does not throw an error', () => { + expect(() => { + LicenceVersionPurposeValidator.go(transformedLicenceVersionPurpose) + }).to.not.throw() + }) + }) + }) + + describe('the "externalId" property', () => { + describe('when it is not a string', () => { + beforeEach(() => { + transformedLicenceVersionPurpose.externalId = 1 + }) + + it('throws an error', async () => { + expect(() => { + LicenceVersionPurposeValidator.go(transformedLicenceVersionPurpose) + }).to.throw('"externalId" must be a string') + }) + }) + + describe('when it is null', () => { + beforeEach(() => { + transformedLicenceVersionPurpose.externalId = null + }) + + it('throws an error', async () => { + expect(() => { + LicenceVersionPurposeValidator.go(transformedLicenceVersionPurpose) + }).to.throw('"externalId" must be a string') + }) + }) + }) + + describe('the "hourlyQuantity" property', () => { + describe('when it is not a number', () => { + beforeEach(() => { + transformedLicenceVersionPurpose.hourlyQuantity = '140.929a' + }) + + it('throws an error', async () => { + expect(() => { + LicenceVersionPurposeValidator.go(transformedLicenceVersionPurpose) + }).to.throw('"hourlyQuantity" must be a number') + }) + }) + + describe('when it is null', () => { + beforeEach(() => { + transformedLicenceVersionPurpose.hourlyQuantity = null + }) + + it('does not throw an error', () => { + expect(() => { + LicenceVersionPurposeValidator.go(transformedLicenceVersionPurpose) + }).to.not.throw() + }) + }) + }) + + describe('the "instantQuantity" property', () => { + describe('when it is not a number', () => { + beforeEach(() => { + transformedLicenceVersionPurpose.instantQuantity = '1.1a' + }) + + it('throws an error', async () => { + expect(() => { + LicenceVersionPurposeValidator.go(transformedLicenceVersionPurpose) + }).to.throw('"instantQuantity" must be a number') + }) + }) + + describe('when it is null', () => { + beforeEach(() => { + transformedLicenceVersionPurpose.instantQuantity = null + }) + + it('does not throw an error', () => { + expect(() => { + LicenceVersionPurposeValidator.go(transformedLicenceVersionPurpose) + }).to.not.throw() + }) + }) + }) + + describe('the "notes" property', () => { + describe('when it is not a string', () => { + beforeEach(() => { + transformedLicenceVersionPurpose.notes = 1 + }) + + it('throws an error', async () => { + expect(() => { + LicenceVersionPurposeValidator.go(transformedLicenceVersionPurpose) + }).to.throw('"notes" must be a string') + }) + }) + + describe('when it is null', () => { + beforeEach(() => { + transformedLicenceVersionPurpose.notes = null + }) + + it('does not throw an error', () => { + expect(() => { + LicenceVersionPurposeValidator.go(transformedLicenceVersionPurpose) + }).to.not.throw() + }) + }) + }) + + describe('the "primaryPurposeId" property', () => { + describe('when it is not a string', () => { + beforeEach(() => { + transformedLicenceVersionPurpose.primaryPurposeId = 1 + }) + + it('throws an error', async () => { + expect(() => { + LicenceVersionPurposeValidator.go(transformedLicenceVersionPurpose) + }).to.throw('"primaryPurposeId" must be a string') + }) + }) + + describe('when it is not a valid GUID', () => { + beforeEach(() => { + transformedLicenceVersionPurpose.primaryPurposeId = 'i am not a GUID' + }) + + it('throws an error', async () => { + expect(() => { + LicenceVersionPurposeValidator.go(transformedLicenceVersionPurpose) + }).to.throw('"primaryPurposeId" must be a valid GUID') + }) + }) + + describe('when it is null', () => { + beforeEach(() => { + transformedLicenceVersionPurpose.primaryPurposeId = null + }) + + it('throws an error', async () => { + expect(() => { + LicenceVersionPurposeValidator.go(transformedLicenceVersionPurpose) + }).to.throw('"primaryPurposeId" must be a string') + }) + }) + }) + + describe('the "purposeId" property', () => { + describe('when it is not a string', () => { + beforeEach(() => { + transformedLicenceVersionPurpose.purposeId = 1 + }) + + it('throws an error', async () => { + expect(() => { + LicenceVersionPurposeValidator.go(transformedLicenceVersionPurpose) + }).to.throw('"purposeId" must be a string') + }) + }) + + describe('when it is not a valid GUID', () => { + beforeEach(() => { + transformedLicenceVersionPurpose.purposeId = 'i am not a GUID' + }) + + it('throws an error', async () => { + expect(() => { + LicenceVersionPurposeValidator.go(transformedLicenceVersionPurpose) + }).to.throw('"purposeId" must be a valid GUID') + }) + }) + + describe('when it is null', () => { + beforeEach(() => { + transformedLicenceVersionPurpose.purposeId = null + }) + + it('throws an error', async () => { + expect(() => { + LicenceVersionPurposeValidator.go(transformedLicenceVersionPurpose) + }).to.throw('"purposeId" must be a string') + }) + }) + }) + + describe('the "secondaryPurposeId" property', () => { + describe('when it is not a string', () => { + beforeEach(() => { + transformedLicenceVersionPurpose.secondaryPurposeId = 1 + }) + + it('throws an error', async () => { + expect(() => { + LicenceVersionPurposeValidator.go(transformedLicenceVersionPurpose) + }).to.throw('"secondaryPurposeId" must be a string') + }) + }) + + describe('when it is not a valid GUID', () => { + beforeEach(() => { + transformedLicenceVersionPurpose.secondaryPurposeId = 'i am not a GUID' + }) + + it('throws an error', async () => { + expect(() => { + LicenceVersionPurposeValidator.go(transformedLicenceVersionPurpose) + }).to.throw('"secondaryPurposeId" must be a valid GUID') + }) + }) + + describe('when it is null', () => { + beforeEach(() => { + transformedLicenceVersionPurpose.secondaryPurposeId = null + }) + + it('throws an error', async () => { + expect(() => { + LicenceVersionPurposeValidator.go(transformedLicenceVersionPurpose) + }).to.throw('"secondaryPurposeId" must be a string') + }) + }) + }) + + describe('the "timeLimitedEndDate" property', () => { + describe('when it is not a date or null', () => { + beforeEach(() => { + transformedLicenceVersionPurpose.timeLimitedEndDate = 1 + }) + + it('throws an error', async () => { + expect(() => { + LicenceVersionPurposeValidator.go(transformedLicenceVersionPurpose) + }).to.throw('"timeLimitedEndDate" must be a valid date') + }) + }) + + describe('when it is null', () => { + beforeEach(() => { + transformedLicenceVersionPurpose.timeLimitedEndDate = null + }) + + it('does not throw an error', () => { + expect(() => { + LicenceVersionPurposeValidator.go(transformedLicenceVersionPurpose) + }).to.not.throw() + }) + }) + }) + + describe('the "timeLimitedStartDate" property', () => { + describe('when it is not a date or null', () => { + beforeEach(() => { + transformedLicenceVersionPurpose.timeLimitedStartDate = 1 + }) + + it('throws an error', async () => { + expect(() => { + LicenceVersionPurposeValidator.go(transformedLicenceVersionPurpose) + }).to.throw('"timeLimitedStartDate" must be a valid date') + }) + }) + + describe('when it is null', () => { + beforeEach(() => { + transformedLicenceVersionPurpose.timeLimitedStartDate = null + }) + + it('does not throw an error', () => { + expect(() => { + LicenceVersionPurposeValidator.go(transformedLicenceVersionPurpose) + }).to.not.throw() + }) + }) + }) +}) + +function _transformedLicenceVersionPurpose () { + return { + abstractionPeriodEndDay: 31, + abstractionPeriodEndMonth: 3, + abstractionPeriodStartDay: 1, + abstractionPeriodStartMonth: 4, + annualQuantity: 545520.1, + dailyQuantity: 1500.2, + externalId: '6:10000004', + hourlyQuantity: 140.929, + instantQuantity: 1.1, + notes: 'This is a note', + primaryPurposeId: '8d9d407c-3da7-4977-84a0-97738c9b44cc', + purposeId: '025bfdc9-d7f4-46b5-a7e0-451dec1a34a6', + secondaryPurposeId: '04bdc9f6-a4e7-41de-831c-9ebf15b92782', + timeLimitedEndDate: new Date('1992-08-19'), + timeLimitedStartDate: new Date('2052-06-23') + } +} diff --git a/test/validators/import/licence-version.validator.test.js b/test/validators/import/licence-version.validator.test.js new file mode 100644 index 0000000000..841668e318 --- /dev/null +++ b/test/validators/import/licence-version.validator.test.js @@ -0,0 +1,233 @@ +'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 LicenceVersionValidator = require('../../../app/validators/import/licence-version.validator.js') + +describe('Import Licence Version validator', () => { + let transformedLicenceVersion + + beforeEach(async () => { + transformedLicenceVersion = _transformedLicenceVersion() + }) + + describe('when valid data is provided', () => { + it('does not throw an error', () => { + expect(() => { + LicenceVersionValidator.go(transformedLicenceVersion) + }).to.not.throw() + }) + }) + + describe('the "endDate" property', () => { + describe('when it is not a date or null', () => { + beforeEach(() => { + transformedLicenceVersion.endDate = 1 + }) + + it('throws an error', async () => { + expect(() => { + LicenceVersionValidator.go(transformedLicenceVersion) + }).to.throw('"endDate" must be a valid date') + }) + }) + + describe('when it is null', () => { + beforeEach(() => { + transformedLicenceVersion.endDate = null + }) + + it('does not throw an error', () => { + expect(() => { + LicenceVersionValidator.go(transformedLicenceVersion) + }).to.not.throw() + }) + }) + }) + + describe('the "externalId" property', () => { + describe('when it is not a string', () => { + beforeEach(() => { + transformedLicenceVersion.externalId = 1 + }) + + it('throws an error', async () => { + expect(() => { + LicenceVersionValidator.go(transformedLicenceVersion) + }).to.throw('"externalId" must be a string') + }) + }) + + describe('when it is null', () => { + beforeEach(() => { + transformedLicenceVersion.externalId = null + }) + + it('throws an error', async () => { + expect(() => { + LicenceVersionValidator.go(transformedLicenceVersion) + }).to.throw('"externalId" must be a string') + }) + }) + }) + + describe('the "increment" property', () => { + describe('when it is not a number', () => { + beforeEach(() => { + transformedLicenceVersion.increment = '1a' + }) + + it('throws an error', async () => { + expect(() => { + LicenceVersionValidator.go(transformedLicenceVersion) + }).to.throw('"increment" must be a number') + }) + }) + + describe('when it is null', () => { + beforeEach(() => { + transformedLicenceVersion.increment = null + }) + + it('throws an error', async () => { + expect(() => { + LicenceVersionValidator.go(transformedLicenceVersion) + }).to.throw('"increment" must be a number') + }) + }) + }) + + describe('the "issue" property', () => { + describe('when it is not a number', () => { + beforeEach(() => { + transformedLicenceVersion.issue = '1a' + }) + + it('throws an error', async () => { + expect(() => { + LicenceVersionValidator.go(transformedLicenceVersion) + }).to.throw('"issue" must be a number') + }) + }) + + describe('when it is null', () => { + beforeEach(() => { + transformedLicenceVersion.issue = null + }) + + it('throws an error', async () => { + expect(() => { + LicenceVersionValidator.go(transformedLicenceVersion) + }).to.throw('"issue" must be a number') + }) + }) + }) + + describe('the "licenceVersionPurposes" property', () => { + describe('when it is not an array', () => { + beforeEach(() => { + transformedLicenceVersion.licenceVersionPurposes = 1 + }) + + it('throws an error', async () => { + expect(() => { + LicenceVersionValidator.go(transformedLicenceVersion) + }).to.throw('"licenceVersionPurposes" must be an array') + }) + }) + + describe('when it is null', () => { + beforeEach(() => { + transformedLicenceVersion.licenceVersionPurposes = null + }) + + it('throws an error', async () => { + expect(() => { + LicenceVersionValidator.go(transformedLicenceVersion) + }).to.throw('"licenceVersionPurposes" must be an array') + }) + }) + }) + + describe('the "startDate" property', () => { + describe('when it is not a date', () => { + beforeEach(() => { + transformedLicenceVersion.startDate = 1 + }) + + it('throws an error', async () => { + expect(() => { + LicenceVersionValidator.go(transformedLicenceVersion) + }).to.throw('"startDate" must be a valid date') + }) + }) + + describe('when it is null', () => { + beforeEach(() => { + transformedLicenceVersion.startDate = null + }) + + it('throws an error', async () => { + expect(() => { + LicenceVersionValidator.go(transformedLicenceVersion) + }).to.throw('"startDate" must be a valid date') + }) + }) + }) + + describe('the "status" property', () => { + describe('when it is not a string', () => { + beforeEach(() => { + transformedLicenceVersion.status = 1 + }) + + it('throws an error', async () => { + expect(() => { + LicenceVersionValidator.go(transformedLicenceVersion) + }).to.throw('"status" must be one of [current, superseded]') + }) + }) + + describe('when it is null', () => { + beforeEach(() => { + transformedLicenceVersion.status = null + }) + + it('throws an error', async () => { + expect(() => { + LicenceVersionValidator.go(transformedLicenceVersion) + }).to.throw('"status" must be one of [current, superseded]') + }) + }) + + describe('when it is not a recognised status', () => { + beforeEach(() => { + transformedLicenceVersion.status = 'draft' + }) + + it('throws an error', async () => { + expect(() => { + LicenceVersionValidator.go(transformedLicenceVersion) + }).to.throw('"status" must be one of [current, superseded]') + }) + }) + }) +}) + +function _transformedLicenceVersion () { + return { + endDate: new Date('2052-06-23'), + externalId: '6:2113:100:0', + increment: 0, + issue: 100, + licenceVersionPurposes: [], + startDate: new Date('1999-01-01'), + status: 'current' + } +} diff --git a/test/validators/import/licence-versions.validator.test.js b/test/validators/import/licence-versions.validator.test.js deleted file mode 100644 index be9ca2b538..0000000000 --- a/test/validators/import/licence-versions.validator.test.js +++ /dev/null @@ -1,955 +0,0 @@ -'use strict' - -// Test framework dependencies -const Lab = require('@hapi/lab') -const Code = require('@hapi/code') - -const { describe, it, before, beforeEach } = exports.lab = Lab.script() -const { expect } = Code - -// Test helpers -const FixtureImportLicenceVersions = require('../../services/import/_fixtures/import-licence-versions.fixture.js') - -// Thing under test -const ImportLicenceVersionsValidator = require('../../../app/validators/import/licence-versions.validator.js') - -describe('Import licence versions validator', () => { - let licenceVersion - let licenceVersionPurpose - let licenceVersionPurposes - let licenceVersionsAndPurposes - - before(async () => { - licenceVersionsAndPurposes = FixtureImportLicenceVersions.create() - - licenceVersion = licenceVersionsAndPurposes[0] - licenceVersionPurpose = licenceVersion.purposes[0] - licenceVersionPurposes = licenceVersion.purposes - }) - - it('should not throw if all the required fields validations are met', () => { - expect(() => { - return ImportLicenceVersionsValidator.go(licenceVersionsAndPurposes) - }).to.not.throw() - }) - - it('should throw if there are no licence versions', () => { - expect(() => { - return ImportLicenceVersionsValidator.go([]) - }).to.throw('A licence must have at least one Licence version') - }) - - describe('the "version"', () => { - describe('"endDate" property', () => { - it('should throw an error if "endDate" is not a valid date or null', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: licenceVersionPurposes, - endDate: 1 - } - ]) - }).to.throw('"[0].endDate" must be a valid date') - }) - - it('should throw an error if "endDate" does not meet ISO 8601', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: licenceVersionPurposes, - endDate: '01/01/2001' - } - ]) - }).to.throw('"[0].endDate" must be in ISO 8601 date format') - }) - - it('should not throw an error if "endDate" is null', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: licenceVersionPurposes, - endDate: null - } - ]) - }).to.not.throw() - }) - - it('should not throw an error if "endDate" is valid date', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: licenceVersionPurposes, - endDate: '2001-01-01' - } - ]) - }).to.not.throw() - }) - }) - - describe('"externalId" property', () => { - it('should throw an error - externalId - must be a string', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: licenceVersionPurposes, - externalId: null - } - ]) - }).to.throw('"[0].externalId" must be a string') - }) - - it('should throw an error - externalId - is required', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - endDate: null - } - ]) - }).to.throw('"[0].externalId" is required') - }) - - it('should not throw an error if "externalId" is a string', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: licenceVersionPurposes - } - ]) - }).to.not.throw() - }) - }) - - describe('"increment" property', () => { - it('should throw an error - increment - must be a number', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: licenceVersionPurposes, - increment: '1a' - } - ]) - }).to.throw('"[0].increment" must be a number') - }) - - it('should throw an error - increment - is required', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - endDate: null, - externalId: '1:2:3' - } - ]) - }).to.throw('"[0].increment" is required') - }) - - it('should not throw an error if "increment" is a number', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: licenceVersionPurposes - } - ]) - }).to.not.throw() - }) - }) - - describe('"issue" property', () => { - it('should throw an error - issue - must be a number', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: licenceVersionPurposes, - issue: '1a' - } - ]) - }).to.throw('"[0].issue" must be a number') - }) - - it('should throw an error - issue - is required', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - endDate: null, - externalId: '1:2:3', - increment: 1 - } - ]) - }).to.throw('"[0].issue" is required') - }) - - it('should not throw an error if "issue" is a number', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: licenceVersionPurposes - } - ]) - }).to.not.throw() - }) - }) - - describe('"status" property', () => { - it('should throw an error - status - must be a string', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: licenceVersionPurposes, - status: 1 - } - ]) - }).to.throw('"[0].status" must be a string') - }) - - it('should throw an error - status - is required', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - endDate: null, - externalId: '1:2:3', - increment: 1, - issue: 1, - startDate: '2001-01-01' - } - ]) - }).to.throw('"[0].status" is required') - }) - - it('should throw an error - status - is not a valid status', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: licenceVersionPurposes, - status: 'draft' - } - ]) - }).to.throw('"[0].status" failed custom validation because Status must be one of current,superseded') - }) - - it('should not throw an error if "status" is a valid status', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: licenceVersionPurposes - } - ]) - }).to.not.throw() - }) - }) - - describe('"startDate" property', () => { - it('should throw an error if "startDate" is not a valid date', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: licenceVersionPurposes, - startDate: 1 - } - ]) - }).to.throw('"[0].startDate" must be a valid date') - }) - - it('should throw an error if "startDate" does not meet ISO 8601', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: licenceVersionPurposes, - startDate: '01/01/2001' - } - ]) - }).to.throw('"[0].startDate" must be in ISO 8601 date format') - }) - - it('should throw an error if "startDate" is null', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: licenceVersionPurposes, - startDate: null - } - ]) - }).to.throw('"[0].startDate" must be a valid date') - }) - - it('should not throw an error if "startDate" is valid date string', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: licenceVersionPurposes, - startDate: '2001-01-01' - } - ]) - }).to.not.throw() - }) - }) - - describe('"purposes" property', () => { - describe('when no purposes a', () => { - let licenceVersionNoPurposes - - beforeEach(() => { - licenceVersionNoPurposes = FixtureImportLicenceVersions.create() - - licenceVersionNoPurposes[0].purposes = [] - }) - - it('should throw if there are no licence versions', () => { - expect(() => { - return ImportLicenceVersionsValidator.go(licenceVersionNoPurposes) - }).to.throw('A licence version must have at least one Licence version purpose') - }) - }) - - describe('"abstractionPeriodEndDay" property', () => { - it('should throw an error if "abstractionPeriodEndDay" is not a number', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: [{ ...licenceVersionPurpose, abstractionPeriodEndDay: '1a' }] - } - ]) - }).to.throw('"[0].purposes[0].abstractionPeriodEndDay" must be a number') - }) - - it('should throw an error if "abstractionPeriodEndDay" is null', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: [{ ...licenceVersionPurpose, abstractionPeriodEndDay: null }] - } - ]) - }).to.throw('"[0].purposes[0].abstractionPeriodEndDay" must be a number') - }) - - it('should throw an error if "abstractionPeriodEndDay" is less than 1 (days allowed 1 - 31)', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: [{ ...licenceVersionPurpose, abstractionPeriodEndDay: -1 }] - } - ]) - }).to.throw('"[0].purposes[0].abstractionPeriodEndDay" must be greater than or equal to 1') - }) - - it('should throw an error if "abstractionPeriodEndDay" is more than 31 (days allowed 1 -31)', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: [{ ...licenceVersionPurpose, abstractionPeriodEndDay: 34 }] - } - ]) - }).to.throw('"[0].purposes[0].abstractionPeriodEndDay" must be less than or equal to 31') - }) - - it('should not throw an error if "abstractionPeriodEndDay" is a number within 1 - 31', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: [{ ...licenceVersionPurpose, abstractionPeriodEndDay: 1 }] - } - ]) - }).to.not.throw() - }) - }) - - describe('"abstractionPeriodEndMonth" property', () => { - it('should throw an error if "abstractionPeriodEndMonth" is not a number', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: [{ ...licenceVersionPurpose, abstractionPeriodEndMonth: '1a' }] - } - ]) - }).to.throw('"[0].purposes[0].abstractionPeriodEndMonth" must be a number') - }) - - it('should throw an error if "abstractionPeriodEndMonth" is null', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: [{ ...licenceVersionPurpose, abstractionPeriodEndMonth: null }] - } - ]) - }).to.throw('"[0].purposes[0].abstractionPeriodEndMonth" must be a number') - }) - - it('should throw an error if "abstractionPeriodEndMonth" is less than 1 (months are 1 - 12)', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: [{ ...licenceVersionPurpose, abstractionPeriodEndMonth: -1 }] - } - ]) - }).to.throw('"[0].purposes[0].abstractionPeriodEndMonth" must be greater than or equal to 1') - }) - - it('should throw an error if "abstractionPeriodEndMonth" is more than 12 (months are 1 - 12)', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: [{ ...licenceVersionPurpose, abstractionPeriodEndMonth: 14 }] - } - ]) - }).to.throw('"[0].purposes[0].abstractionPeriodEndMonth" must be less than or equal to 12') - }) - - it('should not throw an error if "abstractionPeriodEndMonth" is a number within 1 - 12', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: [{ ...licenceVersionPurpose, abstractionPeriodEndMonth: 1 }] - } - ]) - }).to.not.throw() - }) - }) - - describe('"abstractionPeriodStartDay" property', () => { - it('should throw an error if "abstractionPeriodStartDay" is not a number', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: [{ ...licenceVersionPurpose, abstractionPeriodStartDay: '1a' }] - } - ]) - }).to.throw('"[0].purposes[0].abstractionPeriodStartDay" must be a number') - }) - - it('should throw an error if "abstractionPeriodStartDay" is null', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: [{ ...licenceVersionPurpose, abstractionPeriodStartDay: null }] - } - ]) - }).to.throw('"[0].purposes[0].abstractionPeriodStartDay" must be a number') - }) - - it('should throw an error if "abstractionPeriodStartDay" is less than 1 (days allowed 1 - 31)', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: [{ ...licenceVersionPurpose, abstractionPeriodStartDay: -1 }] - } - ]) - }).to.throw('"[0].purposes[0].abstractionPeriodStartDay" must be greater than or equal to 1') - }) - - it('should throw an error if "abstractionPeriodStartDay" is more than 31 (days allowed 1 -31)', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: [{ ...licenceVersionPurpose, abstractionPeriodStartDay: 34 }] - } - ]) - }).to.throw('"[0].purposes[0].abstractionPeriodStartDay" must be less than or equal to 31') - }) - - it('should not throw an error if "abstractionPeriodStartDay" is a number within 1 - 31', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: [{ ...licenceVersionPurpose, abstractionPeriodStartDay: 1 }] - } - ]) - }).to.not.throw() - }) - }) - - describe('"abstractionPeriodStartMonth" property', () => { - it('should throw an error if "abstractionPeriodStartMonth" is not a number', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: [{ ...licenceVersionPurpose, abstractionPeriodStartMonth: '1a' }] - } - ]) - }).to.throw('"[0].purposes[0].abstractionPeriodStartMonth" must be a number') - }) - - it('should throw an error if "abstractionPeriodStartMonth" is null', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: [{ ...licenceVersionPurpose, abstractionPeriodStartMonth: null }] - } - ]) - }).to.throw('"[0].purposes[0].abstractionPeriodStartMonth" must be a number') - }) - - it('should throw an error if "abstractionPeriodStartMonth" is less than 1 (months are 1 - 12)', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: [{ ...licenceVersionPurpose, abstractionPeriodStartMonth: -1 }] - } - ]) - }).to.throw('"[0].purposes[0].abstractionPeriodStartMonth" must be greater than or equal to 1') - }) - - it('should throw an error if "abstractionPeriodStartMonth" is more than 12 (months are 1 - 12)', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: [{ ...licenceVersionPurpose, abstractionPeriodStartMonth: 14 }] - } - ]) - }).to.throw('"[0].purposes[0].abstractionPeriodStartMonth" must be less than or equal to 12') - }) - - it('should not throw an error if "abstractionPeriodStartMonth" is a number within 1 - 12', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: [{ ...licenceVersionPurpose, abstractionPeriodStartMonth: 1 }] - } - ]) - }).to.not.throw() - }) - }) - - describe('"annualQuantity" property', () => { - it('should throw an error if "annualQuantity" is not a number or null', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: [{ ...licenceVersionPurpose, annualQuantity: '1a' }] - } - ]) - }).to.throw('"[0].purposes[0].annualQuantity" must be a number') - }) - - it('should not throw an error if "annualQuantity" is null', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: [{ ...licenceVersionPurpose, annualQuantity: null }] - } - ]) - }).to.not.throw() - }) - - it('should not throw an error if "annualQuantity" is a number', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: [{ ...licenceVersionPurpose, annualQuantity: 52311 }] - } - ]) - }).to.not.throw() - }) - }) - - describe('"dailyQuantity" property', () => { - it('should throw an error if "dailyQuantity" is not a number or null', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: [{ ...licenceVersionPurpose, dailyQuantity: '1a' }] - } - ]) - }).to.throw('"[0].purposes[0].dailyQuantity" must be a number') - }) - - it('should not throw an error if "dailyQuantity" is null', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: [{ ...licenceVersionPurpose, dailyQuantity: null }] - } - ]) - }).to.not.throw() - }) - - it('should not throw an error if "dailyQuantity" is a number', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: [{ ...licenceVersionPurpose, dailyQuantity: 503.45 }] - } - ]) - }).to.not.throw() - }) - }) - - describe('"hourlyQuantity" property', () => { - it('should throw an error if "hourlyQuantity" is not a number or null', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: [{ ...licenceVersionPurpose, hourlyQuantity: '1a' }] - } - ]) - }).to.throw('"[0].purposes[0].hourlyQuantity" must be a number') - }) - - it('should not throw an error if "hourlyQuantity" is null', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: [{ ...licenceVersionPurpose, hourlyQuantity: null }] - } - ]) - }).to.not.throw() - }) - - it('should not throw an error if "hourlyQuantity" is a number', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: [{ ...licenceVersionPurpose, hourlyQuantity: 109.25 }] - } - ]) - }).to.not.throw() - }) - }) - - describe('"instantQuantity" property', () => { - it('should throw an error if "instantQuantity" is not a number or null', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: [{ ...licenceVersionPurpose, instantQuantity: '1a' }] - } - ]) - }).to.throw('"[0].purposes[0].instantQuantity" must be a number') - }) - - it('should not throw an error if "instantQuantity" is null', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: [{ ...licenceVersionPurpose, instantQuantity: null }] - } - ]) - }).to.not.throw() - }) - - it('should not throw an error if "instantQuantity" is a number', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: [{ ...licenceVersionPurpose, instantQuantity: 109 }] - } - ]) - }).to.not.throw() - }) - }) - - describe('"primaryPurposeId" property', () => { - it('should throw an error if "primaryPurposeId" is not a string or null', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: [{ ...licenceVersionPurpose, primaryPurposeId: 1 }] - } - ]) - }).to.throw('"[0].purposes[0].primaryPurposeId" must be a string') - }) - - it('should throw an error if "primaryPurposeId" is null', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: [{ ...licenceVersionPurpose, primaryPurposeId: null }] - } - ]) - }).to.throw('"[0].purposes[0].primaryPurposeId" must be a string') - }) - - it('should not throw an error if "primaryPurposeId" is a string', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: [{ ...licenceVersionPurpose, primaryPurposeId: 'I' }] - } - ]) - }).to.not.throw() - }) - }) - - describe('"secondaryPurposeId" property', () => { - it('should throw an error if "secondaryPurposeId" is not a string or null', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: [{ ...licenceVersionPurpose, secondaryPurposeId: 1 }] - } - ]) - }).to.throw('"[0].purposes[0].secondaryPurposeId" must be a string') - }) - - it('should throw an error if "secondaryPurposeId" is null', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: [{ ...licenceVersionPurpose, secondaryPurposeId: null }] - } - ]) - }).to.throw('"[0].purposes[0].secondaryPurposeId" must be a string') - }) - - it('should not throw an error if "secondaryPurposeId" is a string', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: [{ ...licenceVersionPurpose, secondaryPurposeId: 'OTI' }] - } - ]) - }).to.not.throw() - }) - }) - - describe('"purposeId" property', () => { - it('should throw an error if "purposeId" is not a string or null', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: [{ ...licenceVersionPurpose, purposeId: 1 }] - } - ]) - }).to.throw('"[0].purposes[0].purposeId" must be a string') - }) - - it('should throw an error if "purposeId" is null', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: [{ ...licenceVersionPurpose, purposeId: null }] - } - ]) - }).to.throw('"[0].purposes[0].purposeId" must be a string') - }) - - it('should not throw an error if "purposeId" is a string', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: [{ ...licenceVersionPurpose, purposeId: '160' }] - } - ]) - }).to.not.throw() - }) - }) - - describe('"notes" property', () => { - it('should throw an error if "notes" is string or null', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: [{ ...licenceVersionPurpose, notes: 1 }] - } - ]) - }).to.throw('"[0].purposes[0].notes" must be a string') - }) - - it('should not throw an error if "notes" is null', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: [{ ...licenceVersionPurpose, notes: null }] - } - ]) - }).to.not.throw() - }) - - it('should not throw an error if "notes" is a string', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: [{ ...licenceVersionPurpose, notes: 'a fancy note' }] - } - ]) - }).to.not.throw() - }) - }) - - describe('"externalId" property', () => { - it('should throw an error if "externalId" is not a string or null', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: [{ ...licenceVersionPurpose, externalId: 1 }] - } - ]) - }).to.throw('"[0].purposes[0].externalId" must be a string') - }) - - it('should throw an error if "externalId" is null', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: [{ ...licenceVersionPurpose, externalId: null }] - } - ]) - }).to.throw('"[0].purposes[0].externalId" must be a string') - }) - - it('should not throw an error if "externalId" is a string', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: [{ ...licenceVersionPurpose, externalId: '1:900' }] - } - ]) - }).to.not.throw() - }) - }) - - describe('"timeLimitedEndDate" property', () => { - it('should throw an error if "timeLimitedEndDate" is not a valid date', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: [{ ...licenceVersionPurpose, timeLimitedEndDate: 1 }] - } - ]) - }).to.throw('"[0].purposes[0].timeLimitedEndDate" must be a valid date') - }) - - it('should throw an error if "timeLimitedEndDate" does not meet ISO 8601', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: [{ ...licenceVersionPurpose, timeLimitedEndDate: '01/01/2001' }] - } - ]) - }).to.throw('"[0].purposes[0].timeLimitedEndDate" must be in ISO 8601 date format') - }) - - it('should not throw an error if "timeLimitedEndDate" is null', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: [{ ...licenceVersionPurpose, timeLimitedEndDate: null }] - } - ]) - }).to.not.throw() - }) - - it('should not throw an error if "timeLimitedEndDate" is valid date string', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: [{ ...licenceVersionPurpose, timeLimitedEndDate: '2001-01-01' }] - } - ]) - }).to.not.throw() - }) - }) - - describe('"timeLimitedStartDate" property', () => { - it('should throw an error if "timeLimitedStartDate" is not a valid date', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: [{ ...licenceVersionPurpose, timeLimitedStartDate: 1 }] - } - ]) - }).to.throw('"[0].purposes[0].timeLimitedStartDate" must be a valid date') - }) - - it('should throw an error if "timeLimitedStartDate" does not meet ISO 8601', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: [{ ...licenceVersionPurpose, timeLimitedStartDate: '01/01/2001' }] - } - ]) - }).to.throw('"[0].purposes[0].timeLimitedStartDate" must be in ISO 8601 date format') - }) - - it('should not throw an error if "timeLimitedStartDate" is null', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: [{ ...licenceVersionPurpose, timeLimitedStartDate: null }] - } - ]) - }).to.not.throw() - }) - - it('should not throw an error if "timeLimitedStartDate" is valid date string', async () => { - expect(() => { - return ImportLicenceVersionsValidator.go([ - { - ...licenceVersion, - purposes: [{ ...licenceVersionPurpose, timeLimitedStartDate: '2001-01-01' }] - } - ]) - }).to.not.throw() - }) - }) - }) - }) -}) diff --git a/test/validators/import/licence.validator.test.js b/test/validators/import/licence.validator.test.js index 67ab6dc26e..4dcb52c9c6 100644 --- a/test/validators/import/licence.validator.test.js +++ b/test/validators/import/licence.validator.test.js @@ -4,316 +4,404 @@ const Lab = require('@hapi/lab') const Code = require('@hapi/code') -const { describe, it, before } = exports.lab = Lab.script() +const { describe, it, beforeEach } = exports.lab = Lab.script() const { expect } = Code // Test helpers -const FixtureImportLicence = require('../../services/import/_fixtures/import-licence.fixture.js') +const { generateLicenceRef } = require('../../support/helpers/licence.helper.js') // Thing under test -const ImportLicenceValidator = require('../../../app/validators/import/licence.validator.js') +const LicenceValidator = require('../../../app/validators/import/licence.validator.js') -describe('Import licence validator', () => { - let licence +describe('Import Licence validator', () => { + let transformedLicence - before(async () => { - licence = { - ...FixtureImportLicence.create() - } + beforeEach(async () => { + transformedLicence = _transformedLicence() }) - it('should not throw if all the required fields validations are met', () => { - expect(() => { - return ImportLicenceValidator.go({ - ...licence - }) - }).to.not.throw() - }) - - describe('"expiredDate" property', () => { - it('should throw an error if "expiredDate" is not a string or null', async () => { + describe('when valid data is provided', () => { + it('does not throw an error', () => { expect(() => { - return ImportLicenceValidator.go({ - ...licence, - expiredDate: 1 - }) - }).to.throw('"expiredDate" must be a valid date') + LicenceValidator.go(transformedLicence) + }).to.not.throw() }) + }) - it('should throw an error if "expiredDate" does not meet ISO 8601', async () => { - expect(() => { - return ImportLicenceValidator.go({ - ...licence, - expiredDate: '01/01/2001' - }) - }).to.throw('"expiredDate" must be in ISO 8601 date format') - }) + describe('the "expiredDate" property', () => { + describe('when it is not a date or null', () => { + beforeEach(() => { + transformedLicence.expiredDate = 1 + }) - it('should not throw an error if "expiredDate" is null', async () => { - expect(() => { - return ImportLicenceValidator.go({ - ...licence, - expiredDate: null - }) - }).to.not.throw() + it('throws an error', async () => { + expect(() => { + LicenceValidator.go(transformedLicence) + }).to.throw('"expiredDate" must be a valid date') + }) }) - it('should not throw an error if "expiredDate" is valid date string', async () => { - expect(() => { - return ImportLicenceValidator.go({ - ...licence, - expiredDate: '2001-01-01' - }) - }).to.not.throw() + describe('when it is null', () => { + beforeEach(() => { + transformedLicence.expiredDate = null + }) + + it('does not throw an error', () => { + expect(() => { + LicenceValidator.go(transformedLicence) + }).to.not.throw() + }) }) }) - describe('"lapsedDate" property', () => { - it('should throw an error if "expiredDate" is not a string or null', async () => { - expect(() => { - return ImportLicenceValidator.go({ - ...licence, - lapsedDate: 1 - }) - }).to.throw('"lapsedDate" must be a valid date') - }) + describe('the "lapsedDate" property', () => { + describe('when it is not a date or null', () => { + beforeEach(() => { + transformedLicence.lapsedDate = 1 + }) - it('should throw an error if "lapsedDate" does not meet ISO 8601', async () => { - expect(() => { - return ImportLicenceValidator.go({ - ...licence, - lapsedDate: '01/01/2001' - }) - }).to.throw('"lapsedDate" must be in ISO 8601 date format') + it('throws an error', async () => { + expect(() => { + LicenceValidator.go(transformedLicence) + }).to.throw('"lapsedDate" must be a valid date') + }) }) - it('should not throw an error if "lapsedDate" is null', async () => { - expect(() => { - return ImportLicenceValidator.go({ - ...licence, - lapsedDate: null - }) - }).to.not.throw() - }) + describe('when it is null', () => { + beforeEach(() => { + transformedLicence.lapsedDate = null + }) - it('should not throw an error if "lapsedDate" is valid date string', async () => { - expect(() => { - return ImportLicenceValidator.go({ - ...licence, - lapsedDate: '2001-01-01' - }) - }).to.not.throw() + it('does not throw an error', () => { + expect(() => { + LicenceValidator.go(transformedLicence) + }).to.not.throw() + }) }) }) - describe('"licenceRef" property', () => { - it('should throw an error - licenceRef - must be a string', async () => { - expect(() => { - return ImportLicenceValidator.go({ - licenceRef: 1 - }) - }).to.throw('"licenceRef" must be a string') - }) + describe('the "licenceRef" property', () => { + describe('when it is not a string', () => { + beforeEach(() => { + transformedLicence.licenceRef = 1 + }) - it('should throw an error - licenceRef - is required', async () => { - expect(() => { return ImportLicenceValidator.go({}) }).to.throw('"licenceRef" is required') + it('throws an error', async () => { + expect(() => { + LicenceValidator.go(transformedLicence) + }).to.throw('"licenceRef" must be a string') + }) }) - }) - describe('"regionId" property', () => { - it('should throw an error - regionId - must be a number', async () => { - expect(() => { - return ImportLicenceValidator.go({ - licenceRef: 'l', - regionId: 'one' - }) - }).to.throw('"regionId" must be a number') + describe('when it is null', () => { + beforeEach(() => { + transformedLicence.licenceRef = null + }) + + it('throws an error', async () => { + expect(() => { + LicenceValidator.go(transformedLicence) + }).to.throw('"licenceRef" must be a string') + }) }) - it('should throw an error - regionId - is required', async () => { - expect(() => { - return ImportLicenceValidator.go({ - licenceRef: 'l' - }) - }).to.throw('"regionId" is required') + describe('when it contains whitespace', () => { + beforeEach(() => { + transformedLicence.licenceRef = `${transformedLicence.licenceRef} ` + }) + + it('throws an error', async () => { + expect(() => { + LicenceValidator.go(transformedLicence) + }).to.throw('"licenceRef" must not have leading or trailing whitespace') + }) }) }) - describe('"regions" property', () => { - describe('"regions.regionalChargeArea" property', () => { - it('should throw an error if "regions.regionalChargeArea" is not a string', async () => { - expect(() => { - return ImportLicenceValidator.go({ - ...licence, - regions: { ...licence.regions, regionalChargeArea: 1 } - }) - }).to.throw('"regions.regionalChargeArea" must be a string') + describe('the "licenceVersions" property', () => { + describe('when it is not an array', () => { + beforeEach(() => { + transformedLicence.licenceVersions = 1 }) - it('should not throw an error if "regions.regionalChargeArea" is a string', async () => { + it('throws an error', async () => { expect(() => { - return ImportLicenceValidator.go({ - ...licence, - regions: { ...licence.regions, regionalChargeArea: 'a string' } - }) - }).to.not.throw() + LicenceValidator.go(transformedLicence) + }).to.throw('"licenceVersions" must be an array') }) }) - describe('"regions.localEnvironmentAgencyPlanCode" property', () => { - it('should throw an error if "regions.localEnvironmentAgencyPlanCode" is not a string', async () => { + describe('when it is null', () => { + beforeEach(() => { + transformedLicence.licenceVersions = null + }) + + it('throws an error', async () => { expect(() => { - return ImportLicenceValidator.go({ - ...licence, - regions: { ...licence.regions, localEnvironmentAgencyPlanCode: 1 } - }) - }).to.throw('"regions.localEnvironmentAgencyPlanCode" must be a string') + LicenceValidator.go(transformedLicence) + }).to.throw('"licenceVersions" must be an array') + }) + }) + }) + + describe('the "regionId" property', () => { + describe('when it is not a string', () => { + beforeEach(() => { + transformedLicence.regionId = 1 }) - it('should not throw an error if "regions.regionalChargeArea" is a string', async () => { + it('throws an error', async () => { expect(() => { - return ImportLicenceValidator.go({ - ...licence, - regions: { ...licence.regions, localEnvironmentAgencyPlanCode: 'a string' } - }) - }).to.not.throw() + LicenceValidator.go(transformedLicence) + }).to.throw('"regionId" must be a string') }) }) - describe('"regions.historicalAreaCode" property', () => { - it('should throw an error if "regions.historicalAreaCode" is not a string', async () => { + describe('when it is not a valid GUID', () => { + beforeEach(() => { + transformedLicence.regionId = 'i am not a GUID' + }) + + it('throws an error', async () => { expect(() => { - return ImportLicenceValidator.go({ - ...licence, - regions: { ...licence.regions, historicalAreaCode: 1 } - }) - }).to.throw('"regions.historicalAreaCode" must be a string') + LicenceValidator.go(transformedLicence) + }).to.throw('"regionId" must be a valid GUID') }) + }) - it('should not throw an error if "regions.historicalAreaCode" is a string', async () => { + describe('when it is null', () => { + beforeEach(() => { + transformedLicence.regionId = null + }) + + it('throws an error', async () => { expect(() => { - return ImportLicenceValidator.go({ - ...licence, - regions: { ...licence.regions, historicalAreaCode: 'a string' } - }) - }).to.not.throw() + LicenceValidator.go(transformedLicence) + }).to.throw('"regionId" must be a string') }) }) + }) + + describe('the "regions" property', () => { + describe('when it is not an object', () => { + beforeEach(() => { + transformedLicence.regions = 1 + }) - describe('"regions.standardUnitChargeCode" property', () => { - it('should throw an error if "regions.standardUnitChargeCode" is not a string', async () => { + it('throws an error', async () => { expect(() => { - return ImportLicenceValidator.go({ - ...licence, - regions: { ...licence.regions, standardUnitChargeCode: 1 } - }) - }).to.throw('"regions.standardUnitChargeCode" must be a string') + LicenceValidator.go(transformedLicence) + }).to.throw('"regions" must be of type object') + }) + }) + + describe('when it is null', () => { + beforeEach(() => { + transformedLicence.regions = null }) - it('should not throw an error if "regions.standardUnitChargeCode" is a string', async () => { + it('throws an error', async () => { expect(() => { - return ImportLicenceValidator.go({ - ...licence, - regions: { ...licence.regions, standardUnitChargeCode: 'a string' } - }) - }).to.not.throw() + LicenceValidator.go(transformedLicence) + }).to.throw('"regions" must be of type object') }) }) - }) - describe('"revokedDate" property', () => { - it('should throw an error if "revokedDate" is not a string or null', async () => { - expect(() => { - return ImportLicenceValidator.go({ - ...licence, - revokedDate: 1 + describe('and its "regionalChargeArea" property', () => { + describe('when it is not a string', () => { + beforeEach(() => { + transformedLicence.regions.regionalChargeArea = 1 + }) + + it('throws an error', async () => { + expect(() => { + LicenceValidator.go(transformedLicence) + }).to.throw('"regions.regionalChargeArea" must be a string') + }) + }) + + describe('when it is null', () => { + beforeEach(() => { + transformedLicence.regions.regionalChargeArea = null + }) + + it('throws an error', async () => { + expect(() => { + LicenceValidator.go(transformedLicence) + }).to.throw('"regions.regionalChargeArea" must be a string') }) - }).to.throw('"revokedDate" must be a valid date') + }) }) - it('should throw an error if "revokedDate" does not meet ISO 8601', async () => { - expect(() => { - return ImportLicenceValidator.go({ - ...licence, - revokedDate: '01/01/2001' + describe('and its "localEnvironmentAgencyPlanCode" property', () => { + describe('when it is not a string', () => { + beforeEach(() => { + transformedLicence.regions.localEnvironmentAgencyPlanCode = 1 + }) + + it('throws an error', async () => { + expect(() => { + LicenceValidator.go(transformedLicence) + }).to.throw('"regions.localEnvironmentAgencyPlanCode" must be a string') + }) + }) + + describe('when it is null', () => { + beforeEach(() => { + transformedLicence.regions.localEnvironmentAgencyPlanCode = null }) - }).to.throw('"revokedDate" must be in ISO 8601 date format') + + it('throws an error', async () => { + expect(() => { + LicenceValidator.go(transformedLicence) + }).to.throw('"regions.localEnvironmentAgencyPlanCode" must be a string') + }) + }) }) - it('should not throw an error if "revokedDate" is null', async () => { - expect(() => { - return ImportLicenceValidator.go({ - ...licence, - revokedDate: null + describe('and its "historicalAreaCode" property', () => { + describe('when it is not a string', () => { + beforeEach(() => { + transformedLicence.regions.historicalAreaCode = 1 }) - }).to.not.throw() + + it('throws an error', async () => { + expect(() => { + LicenceValidator.go(transformedLicence) + }).to.throw('"regions.historicalAreaCode" must be a string') + }) + }) + + describe('when it is null', () => { + beforeEach(() => { + transformedLicence.regions.historicalAreaCode = null + }) + + it('throws an error', async () => { + expect(() => { + LicenceValidator.go(transformedLicence) + }).to.throw('"regions.historicalAreaCode" must be a string') + }) + }) }) - it('should not throw an error if "revokedDate" is valid date string', async () => { - expect(() => { - return ImportLicenceValidator.go({ - ...licence, - revokedDate: '2001-01-01' + describe('and its "standardUnitChargeCode" property', () => { + describe('when it is not a string', () => { + beforeEach(() => { + transformedLicence.regions.standardUnitChargeCode = 1 }) - }).to.not.throw() + + it('throws an error', async () => { + expect(() => { + LicenceValidator.go(transformedLicence) + }).to.throw('"regions.standardUnitChargeCode" must be a string') + }) + }) + + describe('when it is null', () => { + beforeEach(() => { + transformedLicence.regions.standardUnitChargeCode = null + }) + + it('throws an error', async () => { + expect(() => { + LicenceValidator.go(transformedLicence) + }).to.throw('"regions.standardUnitChargeCode" must be a string') + }) + }) }) }) - describe('"startDate" property', () => { - it('should throw an error if "startDate" is not a string', async () => { - expect(() => { - return ImportLicenceValidator.go({ - ...licence, - startDate: 1 - }) - }).to.throw('"startDate" must be a valid date') + describe('the "revokedDate" property', () => { + describe('when it is not a date or null', () => { + beforeEach(() => { + transformedLicence.revokedDate = 1 + }) + + it('throws an error', async () => { + expect(() => { + LicenceValidator.go(transformedLicence) + }).to.throw('"revokedDate" must be a valid date') + }) }) - it('should throw an error if "startDate" does not meet ISO 8601', async () => { - expect(() => { - return ImportLicenceValidator.go({ - ...licence, - startDate: '01/01/2001' - }) - }).to.throw('"startDate" must be in ISO 8601 date format') + describe('when it is null', () => { + beforeEach(() => { + transformedLicence.revokedDate = null + }) + + it('does not throw an error', () => { + expect(() => { + LicenceValidator.go(transformedLicence) + }).to.not.throw() + }) }) + }) - it('should throw an error if "startDate" is null', async () => { - expect(() => { - return ImportLicenceValidator.go({ - ...licence, - startDate: null - }) - }).to.throw('"startDate" must be a valid date') + describe('the "startDate" property', () => { + describe('when it is not a date', () => { + beforeEach(() => { + transformedLicence.startDate = 1 + }) + + it('throws an error', async () => { + expect(() => { + LicenceValidator.go(transformedLicence) + }).to.throw('"startDate" must be a valid date') + }) }) - it('should not throw an error if "startDate" is valid date string', async () => { - expect(() => { - return ImportLicenceValidator.go({ - ...licence, - startDate: '2001-01-01' - }) - }).to.not.throw() + describe('when it is null', () => { + beforeEach(() => { + transformedLicence.startDate = null + }) + + it('throws an error', async () => { + expect(() => { + LicenceValidator.go(transformedLicence) + }).to.throw('"startDate" must be a valid date') + }) }) }) - describe('"waterUndertaker" property', () => { - it('should throw an error if "waterUndertaker" is not a boolean', async () => { - expect(() => { - return ImportLicenceValidator.go({ - ...licence, - waterUndertaker: 1 - }) - }).to.throw('"waterUndertaker" must be a boolean') + describe('the "waterUndertaker" property', () => { + describe('when it is not a boolean', () => { + beforeEach(() => { + transformedLicence.waterUndertaker = 1 + }) + + it('throws an error', async () => { + expect(() => { + LicenceValidator.go(transformedLicence) + }).to.throw('"waterUndertaker" must be a boolean') + }) }) - it('should not throw an error if "waterUndertaker" is boolean', async () => { - expect(() => { - return ImportLicenceValidator.go({ - ...licence, - waterUndertaker: true - }) - }).to.not.throw() + describe('when it is a boolean', () => { + it('does not throw an error', () => { + expect(() => { + LicenceValidator.go(transformedLicence) + }).to.not.throw() + }) }) }) }) + +function _transformedLicence () { + return { + expiredDate: new Date('2052-06-23'), + lapsedDate: new Date('2050-07-24'), + licenceRef: generateLicenceRef(), + licenceVersions: [], + regionId: '82d8c1b7-0eed-43a7-a5f9-4e397c08e17e', + regions: { + historicalAreaCode: 'KAEA', + regionalChargeArea: 'Southern', + standardUnitChargeCode: 'SUCSO', + localEnvironmentAgencyPlanCode: 'LEME' + }, + revokedDate: new Date('2049-08-25'), + startDate: new Date('1992-08-19'), + waterUndertaker: false + } +}