From 27637ad7630b0c5e71e2d200754e50f2922173c4 Mon Sep 17 00:00:00 2001 From: Alan Cruikshanks Date: Tue, 4 Jun 2024 20:49:35 +0100 Subject: [PATCH 01/17] Add return requirements models to project https://eaflood.atlassian.net/browse/WATER-4467 So far, the new returns requirements functionality supports setting up a new return version and its requirements. But the data is held only in a temporary session. Alongside this, we've been making changes to the legacy return requirements tables so they can support the new properties we will record in our version of the returns requirement setup journey. We now want to create new return requirements by copying an existing one, persist those that have been setup during the journey and in the future generate return logs using this information. All this will need the tables to be represented as [Objection.js models](https://vincit.github.io/objection.js/). This change adds the models, the views and all the supporting elements in preparation for this work. From 07a372af5be7739796b72bac571f92adcc8319ea Mon Sep 17 00:00:00 2001 From: Alan Cruikshanks Date: Wed, 5 Jun 2024 23:14:26 +0100 Subject: [PATCH 02/17] Housekeeping - legacy migration had wrong name --- ...pany-contacts.js => 20221108003009_crm-v2-company-contacts.js} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename db/migrations/legacy/{20221108007032_water-company-contacts.js => 20221108003009_crm-v2-company-contacts.js} (100%) diff --git a/db/migrations/legacy/20221108007032_water-company-contacts.js b/db/migrations/legacy/20221108003009_crm-v2-company-contacts.js similarity index 100% rename from db/migrations/legacy/20221108007032_water-company-contacts.js rename to db/migrations/legacy/20221108003009_crm-v2-company-contacts.js From 5157c4884ebfcbb5b9387ec93096d445671e1f5b Mon Sep 17 00:00:00 2001 From: Alan Cruikshanks Date: Thu, 6 Jun 2024 11:29:51 +0100 Subject: [PATCH 03/17] Update existing legacy tables to match latest --- .../legacy/20221108007023_water-return-versions.js | 9 ++++++--- .../20221108007024_water-return-requirements.js | 13 +++++++++---- ...21108007025_water-return-requirement-purposes.js | 4 ++-- 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/db/migrations/legacy/20221108007023_water-return-versions.js b/db/migrations/legacy/20221108007023_water-return-versions.js index 0e29f5f5ac..7534dc4065 100644 --- a/db/migrations/legacy/20221108007023_water-return-versions.js +++ b/db/migrations/legacy/20221108007023_water-return-versions.js @@ -15,12 +15,15 @@ exports.up = function (knex) { table.integer('version_number').notNullable() table.date('start_date').notNullable() table.date('end_date') - table.string('status water').notNullable() + table.string('status').notNullable() table.string('external_id') + table.text('reason') + table.boolean('multiple_upload').notNullable().defaultTo(false) + table.text('notes') // Legacy timestamps - table.timestamp('date_created', { useTz: false }).notNullable() - table.timestamp('date_updated', { useTz: false }) + table.timestamp('date_created', { useTz: false }).notNullable().defaultTo(knex.fn.now()) + table.timestamp('date_updated', { useTz: false }).notNullable().defaultTo(knex.fn.now()) // Constraints table.unique(['external_id'], { useConstraint: true }) diff --git a/db/migrations/legacy/20221108007024_water-return-requirements.js b/db/migrations/legacy/20221108007024_water-return-requirements.js index abfe78396b..cd640a5718 100644 --- a/db/migrations/legacy/20221108007024_water-return-requirements.js +++ b/db/migrations/legacy/20221108007024_water-return-requirements.js @@ -13,8 +13,8 @@ exports.up = function (knex) { // Data table.uuid('return_version_id').notNullable() table.string('returns_frequency').notNullable() - table.boolean('is_summer').notNullable() - table.boolean('is_upload').notNullable() + table.boolean('is_summer').notNullable().defaultTo(false) + table.boolean('is_upload').notNullable().defaultTo(false) table.smallint('abstraction_period_start_day') table.smallint('abstraction_period_start_month') table.smallint('abstraction_period_end_day') @@ -23,10 +23,15 @@ exports.up = function (knex) { table.string('description') table.integer('legacy_id') table.string('external_id') + table.text('collection_frequency').notNullable().defaultTo('day') + table.boolean('gravity_fill').notNullable().defaultTo(false) + table.boolean('reabstraction').notNullable().defaultTo(false) + table.boolean('two_part_tariff').notNullable().defaultTo(false) + table.boolean('fifty_six_exception').notNullable().defaultTo(false) // Legacy timestamps - table.timestamp('date_created', { useTz: false }).notNullable() - table.timestamp('date_updated', { useTz: false }) + table.timestamp('date_created', { useTz: false }).notNullable().defaultTo(knex.fn.now()) + table.timestamp('date_updated', { useTz: false }).notNullable().defaultTo(knex.fn.now()) // Constraints table.unique(['external_id'], { useConstraint: true }) diff --git a/db/migrations/legacy/20221108007025_water-return-requirement-purposes.js b/db/migrations/legacy/20221108007025_water-return-requirement-purposes.js index 3b1c1772a5..749a1736b4 100644 --- a/db/migrations/legacy/20221108007025_water-return-requirement-purposes.js +++ b/db/migrations/legacy/20221108007025_water-return-requirement-purposes.js @@ -19,8 +19,8 @@ exports.up = function (knex) { table.string('external_id') // Legacy timestamps - table.timestamp('date_created', { useTz: false }).notNullable() - table.timestamp('date_updated', { useTz: false }) + table.timestamp('date_created', { useTz: false }).notNullable().defaultTo(knex.fn.now()) + table.timestamp('date_updated', { useTz: false }).notNullable().defaultTo(knex.fn.now()) // Constraints table.unique(['external_id'], { useConstraint: true }) From 656b3ad99110db3dee8517517fb911c1576eb908 Mon Sep 17 00:00:00 2001 From: Alan Cruikshanks Date: Thu, 6 Jun 2024 11:34:00 +0100 Subject: [PATCH 04/17] Add legacy migration for new points table --- ...8007034_water-return-requirement-points.js | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 db/migrations/legacy/20221108007034_water-return-requirement-points.js diff --git a/db/migrations/legacy/20221108007034_water-return-requirement-points.js b/db/migrations/legacy/20221108007034_water-return-requirement-points.js new file mode 100644 index 0000000000..55f1d4ec69 --- /dev/null +++ b/db/migrations/legacy/20221108007034_water-return-requirement-points.js @@ -0,0 +1,37 @@ +'use strict' + +const tableName = 'return_requirement_points' + +exports.up = function (knex) { + return knex + .schema + .withSchema('water') + .createTable(tableName, (table) => { + // Primary Key + table.uuid('id').primary().defaultTo(knex.raw('gen_random_uuid()')) + + // Data + table.uuid('return_requirement_id').notNullable() + table.text('description') + table.text('ngr_1').notNullable() + table.text('ngr_2') + table.text('ngr_3') + table.text('ngr_4') + table.text('external_id') + table.integer('nald_point_id') + + // Legacy timestamps + table.timestamp('date_created', { useTz: false }).notNullable().defaultTo(knex.fn.now()) + table.timestamp('date_updated', { useTz: false }).notNullable().defaultTo(knex.fn.now()) + + // Constraints + table.unique(['external_id'], { useConstraint: true }) + }) +} + +exports.down = function (knex) { + return knex + .schema + .withSchema('water') + .dropTableIfExists(tableName) +} From 72c89c7e1bc9c34be61329fed24140c74a69fc2d Mon Sep 17 00:00:00 2001 From: Alan Cruikshanks Date: Thu, 6 Jun 2024 11:57:48 +0100 Subject: [PATCH 05/17] Add views for the tables --- ...40606103641_create-return-versions-view.js | 30 +++++++++++++++ ...6104018_create-return-requirements-view.js | 37 +++++++++++++++++++ ...create-return-requirement-purposes-view.js | 27 ++++++++++++++ ...0_create-return-requirement-points-view.js | 29 +++++++++++++++ 4 files changed, 123 insertions(+) create mode 100644 db/migrations/public/20240606103641_create-return-versions-view.js create mode 100644 db/migrations/public/20240606104018_create-return-requirements-view.js create mode 100644 db/migrations/public/20240606104927_create-return-requirement-purposes-view.js create mode 100644 db/migrations/public/20240606105250_create-return-requirement-points-view.js diff --git a/db/migrations/public/20240606103641_create-return-versions-view.js b/db/migrations/public/20240606103641_create-return-versions-view.js new file mode 100644 index 0000000000..0806e55fb3 --- /dev/null +++ b/db/migrations/public/20240606103641_create-return-versions-view.js @@ -0,0 +1,30 @@ +'use strict' + +const viewName = 'return_versions' + +exports.up = function (knex) { + return knex + .schema + .createView(viewName, (view) => { + view.as(knex('return_versions').withSchema('water').select([ + 'return_version_id AS id', + 'licence_id', + 'version_number AS version', + 'start_date', + 'end_date', + 'status', + 'external_id', + 'reason', + 'multiple_upload', + 'notes', + 'date_created AS created_at', + 'date_updated AS updated_at' + ])) + }) +} + +exports.down = function (knex) { + return knex + .schema + .dropViewIfExists(viewName) +} diff --git a/db/migrations/public/20240606104018_create-return-requirements-view.js b/db/migrations/public/20240606104018_create-return-requirements-view.js new file mode 100644 index 0000000000..9a322d880d --- /dev/null +++ b/db/migrations/public/20240606104018_create-return-requirements-view.js @@ -0,0 +1,37 @@ +'use strict' + +const viewName = 'return_requirements' + +exports.up = function (knex) { + return knex + .schema + .createView(viewName, (view) => { + view.as(knex('return_requirements').withSchema('water').select([ + 'return_requirement_id AS id', + 'return_version_id', + 'returns_frequency', + 'is_summer AS summer', + 'is_upload AS upload', + 'abstraction_period_start_day', + 'abstraction_period_start_month', + 'abstraction_period_end_day', + 'abstraction_period_end_month', + 'site_description', + 'legacy_id', + 'external_id', + 'collection_frequency', + 'gravity_fill', + 'reabstraction', + 'two_part_tariff', + 'fifty_six_exception', + 'date_created AS created_at', + 'date_updated AS updated_at' + ])) + }) +} + +exports.down = function (knex) { + return knex + .schema + .dropViewIfExists(viewName) +} diff --git a/db/migrations/public/20240606104927_create-return-requirement-purposes-view.js b/db/migrations/public/20240606104927_create-return-requirement-purposes-view.js new file mode 100644 index 0000000000..0659ef52dd --- /dev/null +++ b/db/migrations/public/20240606104927_create-return-requirement-purposes-view.js @@ -0,0 +1,27 @@ +'use strict' + +const viewName = 'return_requirement_purposes' + +exports.up = function (knex) { + return knex + .schema + .createView(viewName, (view) => { + view.as(knex('return_requirement_purposes').withSchema('water').select([ + 'return_requirement_purpose_id AS id', + 'return_requirement_id', + 'purpose_primary_id', + 'purpose_secondary_id', + 'purpose_use_id AS purpose_id', + 'purpose_alias AS alias', + 'external_id', + 'date_created AS created_at', + 'date_updated AS updated_at' + ])) + }) +} + +exports.down = function (knex) { + return knex + .schema + .dropViewIfExists(viewName) +} diff --git a/db/migrations/public/20240606105250_create-return-requirement-points-view.js b/db/migrations/public/20240606105250_create-return-requirement-points-view.js new file mode 100644 index 0000000000..e0ce85f7f0 --- /dev/null +++ b/db/migrations/public/20240606105250_create-return-requirement-points-view.js @@ -0,0 +1,29 @@ +'use strict' + +const viewName = 'return_requirement_points' + +exports.up = function (knex) { + return knex + .schema + .createView(viewName, (view) => { + view.as(knex('return_requirement_points').withSchema('water').select([ + 'id', + 'return_requirement_id', + 'description', + 'ngr_1', + 'ngr_2', + 'ngr_3', + 'ngr_4', + 'external_id', + 'nald_point_id', + 'date_created AS created_at', + 'date_updated AS updated_at' + ])) + }) +} + +exports.down = function (knex) { + return knex + .schema + .dropViewIfExists(viewName) +} From 4b9bd43c18ce83d0c7514ce3fb78b637294772c7 Mon Sep 17 00:00:00 2001 From: Alan Cruikshanks Date: Thu, 6 Jun 2024 12:21:01 +0100 Subject: [PATCH 06/17] Add return version model (no relationships) --- app/models/return-version.model.js | 16 +++++ test/models/return-version.model.test.js | 34 ++++++++++ test/support/helpers/return-version.helper.js | 64 +++++++++++++++++++ 3 files changed, 114 insertions(+) create mode 100644 app/models/return-version.model.js create mode 100644 test/models/return-version.model.test.js create mode 100644 test/support/helpers/return-version.helper.js diff --git a/app/models/return-version.model.js b/app/models/return-version.model.js new file mode 100644 index 0000000000..5352daf008 --- /dev/null +++ b/app/models/return-version.model.js @@ -0,0 +1,16 @@ +'use strict' + +/** + * Model for return_versions (water.return_versions) + * @module ReturnVersionModel + */ + +const BaseModel = require('./base.model.js') + +class ReturnVersionModel extends BaseModel { + static get tableName () { + return 'returnVersions' + } +} + +module.exports = ReturnVersionModel diff --git a/test/models/return-version.model.test.js b/test/models/return-version.model.test.js new file mode 100644 index 0000000000..95bc154637 --- /dev/null +++ b/test/models/return-version.model.test.js @@ -0,0 +1,34 @@ +'use strict' + +// Test framework dependencies +const Lab = require('@hapi/lab') +const Code = require('@hapi/code') + +const { describe, it, beforeEach } = exports.lab = Lab.script() +const { expect } = Code + +// Test helpers +const DatabaseSupport = require('../support/database.js') +const ReturnVersionHelper = require('../support/helpers/return-version.helper.js') + +// Thing under test +const ReturnVersionModel = require('../../app/models/return-version.model.js') + +describe('Return Version model', () => { + let testRecord + + beforeEach(async () => { + await DatabaseSupport.clean() + + testRecord = await ReturnVersionHelper.add() + }) + + describe('Basic query', () => { + it('can successfully run a basic query', async () => { + const result = await ReturnVersionModel.query().findById(testRecord.id) + + expect(result).to.be.an.instanceOf(ReturnVersionModel) + expect(result.id).to.equal(testRecord.id) + }) + }) +}) diff --git a/test/support/helpers/return-version.helper.js b/test/support/helpers/return-version.helper.js new file mode 100644 index 0000000000..d83417b6ea --- /dev/null +++ b/test/support/helpers/return-version.helper.js @@ -0,0 +1,64 @@ +'use strict' + +/** + * @module ReturnVersionHelper + */ + +const { generateUUID } = require('../../../app/lib/general.lib.js') +const { randomInteger } = require('../general.js') +const ReturnVersionModel = require('../../../app/models/return-version.model.js') + +/** + * Add a new return version + * + * If no `data` is provided, default values will be used. These are + * + * - `externalId` - [randomly generated - 9:99999:100] + * - `licenceId` - [random UUID] + * - `reason` - new-licence + * - `startDate` - 2022-04-01 + * - `status` - current + * - `version` - 100 + * + * @param {Object} [data] Any data you want to use instead of the defaults used here or in the database + * + * @returns {Promise} The instance of the newly created record + */ +function add (data = {}) { + const insertData = defaults(data) + + return ReturnVersionModel.query() + .insert({ ...insertData }) + .returning('*') +} + +/** + * Returns the defaults used + * + * It will override or append to them any data provided. Mainly used by the `add()` method, we make it available + * for use in tests to avoid having to duplicate values. + * + * @param {Object} [data] Any data you want to use instead of the defaults used here or in the database + */ +function defaults (data = {}) { + const version = data.version ? data.version : 100 + + const defaults = { + externalId: `9:${randomInteger(100, 99999)}:${version}`, + licenceId: generateUUID(), + reason: 'new-licence', + startDate: new Date('2022-04-01'), + status: 'current', + version + } + + return { + ...defaults, + ...data + } +} + +module.exports = { + add, + defaults +} From 3a31dce8975ef8a573f633f241f271c23b744a38 Mon Sep 17 00:00:00 2001 From: Alan Cruikshanks Date: Thu, 6 Jun 2024 12:33:08 +0100 Subject: [PATCH 07/17] Add return requirement model (no relationships) --- app/models/return-requirement.model.js | 16 +++++ test/models/return-requirement.model.test.js | 34 +++++++++ .../helpers/return-requirement.helper.js | 70 +++++++++++++++++++ 3 files changed, 120 insertions(+) create mode 100644 app/models/return-requirement.model.js create mode 100644 test/models/return-requirement.model.test.js create mode 100644 test/support/helpers/return-requirement.helper.js diff --git a/app/models/return-requirement.model.js b/app/models/return-requirement.model.js new file mode 100644 index 0000000000..fc37509576 --- /dev/null +++ b/app/models/return-requirement.model.js @@ -0,0 +1,16 @@ +'use strict' + +/** + * Model for return_requirements (water.return_requirements) + * @module ReturnRequirementModel + */ + +const BaseModel = require('./base.model.js') + +class ReturnRequirementModel extends BaseModel { + static get tableName () { + return 'returnRequirements' + } +} + +module.exports = ReturnRequirementModel diff --git a/test/models/return-requirement.model.test.js b/test/models/return-requirement.model.test.js new file mode 100644 index 0000000000..c8ed244b35 --- /dev/null +++ b/test/models/return-requirement.model.test.js @@ -0,0 +1,34 @@ +'use strict' + +// Test framework dependencies +const Lab = require('@hapi/lab') +const Code = require('@hapi/code') + +const { describe, it, beforeEach } = exports.lab = Lab.script() +const { expect } = Code + +// Test helpers +const DatabaseSupport = require('../support/database.js') +const ReturnRequirementHelper = require('../support/helpers/return-requirement.helper.js') + +// Thing under test +const ReturnRequirementModel = require('../../app/models/return-requirement.model.js') + +describe('Return Requirement model', () => { + let testRecord + + beforeEach(async () => { + await DatabaseSupport.clean() + + testRecord = await ReturnRequirementHelper.add() + }) + + describe('Basic query', () => { + it('can successfully run a basic query', async () => { + const result = await ReturnRequirementModel.query().findById(testRecord.id) + + expect(result).to.be.an.instanceOf(ReturnRequirementModel) + expect(result.id).to.equal(testRecord.id) + }) + }) +}) diff --git a/test/support/helpers/return-requirement.helper.js b/test/support/helpers/return-requirement.helper.js new file mode 100644 index 0000000000..8adb3384b9 --- /dev/null +++ b/test/support/helpers/return-requirement.helper.js @@ -0,0 +1,70 @@ +'use strict' + +/** + * @module ReturnRequirementHelper + */ + +const { generateUUID } = require('../../../app/lib/general.lib.js') +const { randomInteger } = require('../general.js') +const ReturnRequirementModel = require('../../../app/models/return-requirement.model.js') + +/** + * Add a new return requirement + * + * If no `data` is provided, default values will be used. These are + * + * - `abstractionPeriodStartDay` - 1 + * - `abstractionPeriodStartMonth` - 4 + * - `abstractionPeriodEndDay` - 31 + * - `abstractionPeriodEndMonth` - 3 + * - `externalId` - [randomly generated - 9:99999] + * - `legacyId` - [randomly generated - 99999] + * - `returnsFrequency` - day + * - `returnVersionId` - [random UUID] + * - `siteDescription` - BOREHOLE AT AVALON + * + * @param {Object} [data] Any data you want to use instead of the defaults used here or in the database + * + * @returns {Promise} The instance of the newly created record + */ +function add (data = {}) { + const insertData = defaults(data) + + return ReturnRequirementModel.query() + .insert({ ...insertData }) + .returning('*') +} + +/** + * Returns the defaults used + * + * It will override or append to them any data provided. Mainly used by the `add()` method, we make it available + * for use in tests to avoid having to duplicate values. + * + * @param {Object} [data] Any data you want to use instead of the defaults used here or in the database + */ +function defaults (data = {}) { + const legacyId = data.legacyId ? data.legacyId : randomInteger(100, 99999) + + const defaults = { + abstractionPeriodStartDay: 1, + abstractionPeriodStartMonth: 4, + abstractionPeriodEndDay: 31, + abstractionPeriodEndMonth: 3, + externalId: `9:${legacyId}`, + legacyId, + returnsFrequency: 'day', + returnVersionId: generateUUID(), + siteDescription: 'BOREHOLE AT AVALON' + } + + return { + ...defaults, + ...data + } +} + +module.exports = { + add, + defaults +} From eee701d2315aa6f899f63bba252842ca840b8e6b Mon Sep 17 00:00:00 2001 From: Alan Cruikshanks Date: Thu, 6 Jun 2024 14:20:52 +0100 Subject: [PATCH 08/17] Add rtn req purpose model (no relationships) --- .../return-requirement-purpose.model.js | 16 ++++ .../return-requirement-purpose.model.test.js | 34 ++++++++ test/support/helpers/purpose.helper.js | 7 +- .../return-requirement-purpose.helper.js | 77 +++++++++++++++++++ 4 files changed, 131 insertions(+), 3 deletions(-) create mode 100644 app/models/return-requirement-purpose.model.js create mode 100644 test/models/return-requirement-purpose.model.test.js create mode 100644 test/support/helpers/return-requirement-purpose.helper.js diff --git a/app/models/return-requirement-purpose.model.js b/app/models/return-requirement-purpose.model.js new file mode 100644 index 0000000000..ae58fbeba7 --- /dev/null +++ b/app/models/return-requirement-purpose.model.js @@ -0,0 +1,16 @@ +'use strict' + +/** + * Model for return_requirement_purposes (water.return_requirement_purposes) + * @module ReturnRequirementPurposeModel + */ + +const BaseModel = require('./base.model.js') + +class ReturnRequirementPurposeModel extends BaseModel { + static get tableName () { + return 'returnRequirementPurposes' + } +} + +module.exports = ReturnRequirementPurposeModel diff --git a/test/models/return-requirement-purpose.model.test.js b/test/models/return-requirement-purpose.model.test.js new file mode 100644 index 0000000000..7959a4eb71 --- /dev/null +++ b/test/models/return-requirement-purpose.model.test.js @@ -0,0 +1,34 @@ +'use strict' + +// Test framework dependencies +const Lab = require('@hapi/lab') +const Code = require('@hapi/code') + +const { describe, it, beforeEach } = exports.lab = Lab.script() +const { expect } = Code + +// Test helpers +const DatabaseSupport = require('../support/database.js') +const ReturnRequirementPurposeHelper = require('../support/helpers/return-requirement-purpose.helper.js') + +// Thing under test +const ReturnRequirementPurposeModel = require('../../app/models/return-requirement-purpose.model.js') + +describe('Return Requirement Purpose model', () => { + let testRecord + + beforeEach(async () => { + await DatabaseSupport.clean() + + testRecord = await ReturnRequirementPurposeHelper.add() + }) + + describe('Basic query', () => { + it('can successfully run a basic query', async () => { + const result = await ReturnRequirementPurposeModel.query().findById(testRecord.id) + + expect(result).to.be.an.instanceOf(ReturnRequirementPurposeModel) + expect(result.id).to.equal(testRecord.id) + }) + }) +}) diff --git a/test/support/helpers/purpose.helper.js b/test/support/helpers/purpose.helper.js index c37749def2..c116b65e69 100644 --- a/test/support/helpers/purpose.helper.js +++ b/test/support/helpers/purpose.helper.js @@ -39,7 +39,7 @@ function add (data = {}) { */ function defaults (data = {}) { const defaults = { - legacyId: generateLegacyId(), + legacyId: generatePurposeCode(), description: 'Spray Irrigation - Storage', lossFactor: 'high', twoPartTariff: true @@ -51,7 +51,7 @@ function defaults (data = {}) { } } -function generateLegacyId () { +function generatePurposeCode () { const numbering = randomInteger(1, 999) return `${numbering}0` @@ -59,5 +59,6 @@ function generateLegacyId () { module.exports = { add, - defaults + defaults, + generatePurposeCode } diff --git a/test/support/helpers/return-requirement-purpose.helper.js b/test/support/helpers/return-requirement-purpose.helper.js new file mode 100644 index 0000000000..b0acf9ac0e --- /dev/null +++ b/test/support/helpers/return-requirement-purpose.helper.js @@ -0,0 +1,77 @@ +'use strict' + +/** + * @module ReturnRequirementPurposeHelper + */ + +const { generateUUID } = require('../../../app/lib/general.lib.js') +const { randomInteger } = require('../general.js') +const { generatePurposeCode } = require('./purpose.helper.js') +const ReturnRequirementPurposeModel = require('../../../app/models/return-requirement-purpose.model.js') + +/** + * Add a new return requirement purpose + * + * If no `data` is provided, default values will be used. These are + * + * - `externalId` - [randomly generated - 9:99999:A:AGR:400] + * - `purposeId` - [random UUID] + * - `purposePrimaryId` - [random UUID] + * - `purposeSecondaryId` - [random UUID] + * - `returnRequirementId` - [random UUID] + * + * @param {Object} [data] Any data you want to use instead of the defaults used here or in the database + * + * @returns {Promise} The instance of the newly created record + */ +function add (data = {}) { + const insertData = defaults(data) + + return ReturnRequirementPurposeModel.query() + .insert({ ...insertData }) + .returning('*') +} + +/** + * Returns the defaults used + * + * It will override or append to them any data provided. Mainly used by the `add()` method, we make it available + * for use in tests to avoid having to duplicate values. + * + * @param {Object} [data] Any data you want to use instead of the defaults used here or in the database + */ +function defaults (data = {}) { + const externalId = `9:${randomInteger(100, 99999)}:${_generatePrimaryCode()}:${_generateSecondaryCode()}:${generatePurposeCode()}` + + const defaults = { + externalId, + purposeId: generateUUID(), + purposePrimaryId: generateUUID(), + purposeSecondaryId: generateUUID(), + returnRequirementId: generateUUID() + } + + return { + ...defaults, + ...data + } +} + +function _generatePrimaryCode () { + // NOTE: Taken from water.purposes_primary + const codes = ['A', 'E', 'I', 'M', 'P', 'W', 'X', 'C'] + + return codes[randomInteger(0, 7)] +} + +function _generateSecondaryCode () { + // NOTE: This is only a subset. There 63 of these codes that could be used. Taken from water.purposes_secondary + const codes = ['AGR', 'AQF', 'AQP', 'BRW', 'BUS', 'CHE', 'CON', 'CRN', 'DAR', 'ELC', 'EXT', 'FAD', 'FOR', 'GOF'] + + return codes[randomInteger(0, 13)] +} + +module.exports = { + add, + defaults +} From e3aafd4003c25132d25566fc229440caa95648f6 Mon Sep 17 00:00:00 2001 From: Alan Cruikshanks Date: Thu, 6 Jun 2024 16:43:38 +0100 Subject: [PATCH 09/17] Add rtn req points (no relationships) --- app/models/return-requirement-point.model.js | 16 ++++ .../return-requirement-point.model.test.js | 34 +++++++++ .../return-requirement-point.helper.js | 75 +++++++++++++++++++ 3 files changed, 125 insertions(+) create mode 100644 app/models/return-requirement-point.model.js create mode 100644 test/models/return-requirement-point.model.test.js create mode 100644 test/support/helpers/return-requirement-point.helper.js diff --git a/app/models/return-requirement-point.model.js b/app/models/return-requirement-point.model.js new file mode 100644 index 0000000000..7b341dc8c3 --- /dev/null +++ b/app/models/return-requirement-point.model.js @@ -0,0 +1,16 @@ +'use strict' + +/** + * Model for return_requirement_points (water.return_requirement_points) + * @module ReturnRequirementPointModel + */ + +const BaseModel = require('./base.model.js') + +class ReturnRequirementPointModel extends BaseModel { + static get tableName () { + return 'returnRequirementPoints' + } +} + +module.exports = ReturnRequirementPointModel diff --git a/test/models/return-requirement-point.model.test.js b/test/models/return-requirement-point.model.test.js new file mode 100644 index 0000000000..cc4f14035a --- /dev/null +++ b/test/models/return-requirement-point.model.test.js @@ -0,0 +1,34 @@ +'use strict' + +// Test framework dependencies +const Lab = require('@hapi/lab') +const Code = require('@hapi/code') + +const { describe, it, beforeEach } = exports.lab = Lab.script() +const { expect } = Code + +// Test helpers +const DatabaseSupport = require('../support/database.js') +const ReturnRequirementPointHelper = require('../support/helpers/return-requirement-point.helper.js') + +// Thing under test +const ReturnRequirementPointModel = require('../../app/models/return-requirement-point.model.js') + +describe('Return Requirement Point model', () => { + let testRecord + + beforeEach(async () => { + await DatabaseSupport.clean() + + testRecord = await ReturnRequirementPointHelper.add() + }) + + describe('Basic query', () => { + it('can successfully run a basic query', async () => { + const result = await ReturnRequirementPointModel.query().findById(testRecord.id) + + expect(result).to.be.an.instanceOf(ReturnRequirementPointModel) + expect(result.id).to.equal(testRecord.id) + }) + }) +}) diff --git a/test/support/helpers/return-requirement-point.helper.js b/test/support/helpers/return-requirement-point.helper.js new file mode 100644 index 0000000000..cb13c30098 --- /dev/null +++ b/test/support/helpers/return-requirement-point.helper.js @@ -0,0 +1,75 @@ +'use strict' + +/** + * @module ReturnRequirementPointHelper + */ + +const { generateUUID } = require('../../../app/lib/general.lib.js') +const { randomInteger } = require('../general.js') +const ReturnRequirementPointModel = require('../../../app/models/return-requirement-point.model.js') + +/** + * Add a new return requirement point + * + * If no `data` is provided, default values will be used. These are + * + * - `externalId` - [randomly generated - 9:99999:100414] + * - `naldPointId` - [randomly generated - 100414] + * - `ngr1` - [randomly generated - TL 5143 7153] + * - `returnRequirementId` - [random UUID] + * + * @param {Object} [data] Any data you want to use instead of the defaults used here or in the database + * + * @returns {Promise} The instance of the newly created record + */ +function add (data = {}) { + const insertData = defaults(data) + + return ReturnRequirementPointModel.query() + .insert({ ...insertData }) + .returning('*') +} + +/** + * Returns the defaults used + * + * It will override or append to them any data provided. Mainly used by the `add()` method, we make it available + * for use in tests to avoid having to duplicate values. + * + * @param {Object} [data] Any data you want to use instead of the defaults used here or in the database + */ +function defaults (data = {}) { + const naldPointId = data.naldPointId ? data.naldPointId : generateNaldPointId() + const ngr1 = data.ngr1 ? data.ngr1 : generateNationalGridReference() + + const defaults = { + externalId: `9:${randomInteger(100, 99999)}:${naldPointId}`, + naldPointId, + ngr1, + returnRequirementId: generateUUID() + } + + return { + ...defaults, + ...data + } +} + +function generateNationalGridReference () { + // NOTE: These are taken from https://en.wikipedia.org/wiki/Ordnance_Survey_National_Grid and are the 100KM + // square references that cover the majority of the UK (sorry far North!) + const codes = ['SD', 'SE', 'SJ', 'SK', 'SO', 'SP', 'ST', 'SU', 'SY', 'SZ', 'TA', 'TF', 'TL', 'TQ', 'TV', 'TG', 'TM'] + + return `${codes[randomInteger(0, 16)]} ${randomInteger(100, 999)} ${randomInteger(100, 999)}` +} + +function generateNaldPointId () { + return randomInteger(1, 9999) +} + +module.exports = { + add, + defaults, + generateNationalGridReference, + generateNaldPointId +} From dc4944e0d1c86f53110765c1edd28a2b40b89dff Mon Sep 17 00:00:00 2001 From: Alan Cruikshanks Date: Thu, 6 Jun 2024 16:59:49 +0100 Subject: [PATCH 10/17] Add relationships for rtn req points --- app/models/return-requirement-point.model.js | 15 ++++++++ .../return-requirement-point.model.test.js | 34 +++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/app/models/return-requirement-point.model.js b/app/models/return-requirement-point.model.js index 7b341dc8c3..29080627ad 100644 --- a/app/models/return-requirement-point.model.js +++ b/app/models/return-requirement-point.model.js @@ -5,12 +5,27 @@ * @module ReturnRequirementPointModel */ +const { Model } = require('objection') + const BaseModel = require('./base.model.js') class ReturnRequirementPointModel extends BaseModel { static get tableName () { return 'returnRequirementPoints' } + + static get relationMappings () { + return { + returnRequirement: { + relation: Model.BelongsToOneRelation, + modelClass: 'return-requirement.model', + join: { + from: 'returnRequirementPoints.returnRequirementId', + to: 'returnRequirements.id' + } + } + } + } } module.exports = ReturnRequirementPointModel diff --git a/test/models/return-requirement-point.model.test.js b/test/models/return-requirement-point.model.test.js index cc4f14035a..0038405b90 100644 --- a/test/models/return-requirement-point.model.test.js +++ b/test/models/return-requirement-point.model.test.js @@ -9,6 +9,8 @@ const { expect } = Code // Test helpers const DatabaseSupport = require('../support/database.js') +const ReturnRequirementHelper = require('../support/helpers/return-requirement.helper.js') +const ReturnRequirementModel = require('../../app/models/return-requirement.model.js') const ReturnRequirementPointHelper = require('../support/helpers/return-requirement-point.helper.js') // Thing under test @@ -31,4 +33,36 @@ describe('Return Requirement Point model', () => { expect(result.id).to.equal(testRecord.id) }) }) + + describe('Relationships', () => { + describe('when linking to return requirement', () => { + let testReturnRequirement + + beforeEach(async () => { + testReturnRequirement = await ReturnRequirementHelper.add() + + const { id: returnRequirementId } = testReturnRequirement + testRecord = await ReturnRequirementPointHelper.add({ returnRequirementId }) + }) + + it('can successfully run a related query', async () => { + const query = await ReturnRequirementPointModel.query() + .innerJoinRelated('returnRequirement') + + expect(query).to.exist() + }) + + it('can eager load the charge reference', async () => { + const result = await ReturnRequirementPointModel.query() + .findById(testRecord.id) + .withGraphFetched('returnRequirement') + + expect(result).to.be.instanceOf(ReturnRequirementPointModel) + expect(result.id).to.equal(testRecord.id) + + expect(result.returnRequirement).to.be.an.instanceOf(ReturnRequirementModel) + expect(result.returnRequirement).to.equal(testReturnRequirement) + }) + }) + }) }) From f8207bec17c27a7d30f78f7df423fa9d4d94f720 Mon Sep 17 00:00:00 2001 From: Alan Cruikshanks Date: Thu, 6 Jun 2024 17:05:32 +0100 Subject: [PATCH 11/17] Add relationships for rtn req purposes --- .../return-requirement-purpose.model.js | 23 +++++++ .../return-requirement-purpose.model.test.js | 66 +++++++++++++++++++ 2 files changed, 89 insertions(+) diff --git a/app/models/return-requirement-purpose.model.js b/app/models/return-requirement-purpose.model.js index ae58fbeba7..c634519e9d 100644 --- a/app/models/return-requirement-purpose.model.js +++ b/app/models/return-requirement-purpose.model.js @@ -5,12 +5,35 @@ * @module ReturnRequirementPurposeModel */ +const { Model } = require('objection') + const BaseModel = require('./base.model.js') class ReturnRequirementPurposeModel extends BaseModel { static get tableName () { return 'returnRequirementPurposes' } + + static get relationMappings () { + return { + purpose: { + relation: Model.BelongsToOneRelation, + modelClass: 'purpose.model', + join: { + from: 'returnRequirementPurposes.purposeId', + to: 'purposes.id' + } + }, + returnRequirement: { + relation: Model.BelongsToOneRelation, + modelClass: 'return-requirement.model', + join: { + from: 'returnRequirementPurposes.returnRequirementId', + to: 'returnRequirements.id' + } + } + } + } } module.exports = ReturnRequirementPurposeModel diff --git a/test/models/return-requirement-purpose.model.test.js b/test/models/return-requirement-purpose.model.test.js index 7959a4eb71..9b2b1a6aa7 100644 --- a/test/models/return-requirement-purpose.model.test.js +++ b/test/models/return-requirement-purpose.model.test.js @@ -9,6 +9,10 @@ const { expect } = Code // Test helpers const DatabaseSupport = require('../support/database.js') +const PurposeModel = require('../../app/models/purpose.model.js') +const PurposeHelper = require('../support/helpers/purpose.helper.js') +const ReturnRequirementHelper = require('../support/helpers/return-requirement.helper.js') +const ReturnRequirementModel = require('../../app/models/return-requirement.model.js') const ReturnRequirementPurposeHelper = require('../support/helpers/return-requirement-purpose.helper.js') // Thing under test @@ -31,4 +35,66 @@ describe('Return Requirement Purpose model', () => { expect(result.id).to.equal(testRecord.id) }) }) + + describe('Relationships', () => { + describe('when linking to purpose', () => { + let testPurpose + + beforeEach(async () => { + testPurpose = await PurposeHelper.add() + + const { id: purposeId } = testPurpose + testRecord = await ReturnRequirementPurposeHelper.add({ purposeId }) + }) + + it('can successfully run a related query', async () => { + const query = await ReturnRequirementPurposeModel.query() + .innerJoinRelated('purpose') + + expect(query).to.exist() + }) + + it('can eager load the purposes use', async () => { + const result = await ReturnRequirementPurposeModel.query() + .findById(testRecord.id) + .withGraphFetched('purpose') + + expect(result).to.be.instanceOf(ReturnRequirementPurposeModel) + expect(result.id).to.equal(testRecord.id) + + expect(result.purpose).to.be.an.instanceOf(PurposeModel) + expect(result.purpose).to.equal(testPurpose) + }) + }) + + describe('when linking to return requirement', () => { + let testReturnRequirement + + beforeEach(async () => { + testReturnRequirement = await ReturnRequirementHelper.add() + + const { id: returnRequirementId } = testReturnRequirement + testRecord = await ReturnRequirementPurposeHelper.add({ returnRequirementId }) + }) + + it('can successfully run a related query', async () => { + const query = await ReturnRequirementPurposeModel.query() + .innerJoinRelated('returnRequirement') + + expect(query).to.exist() + }) + + it('can eager load the charge reference', async () => { + const result = await ReturnRequirementPurposeModel.query() + .findById(testRecord.id) + .withGraphFetched('returnRequirement') + + expect(result).to.be.instanceOf(ReturnRequirementPurposeModel) + expect(result.id).to.equal(testRecord.id) + + expect(result.returnRequirement).to.be.an.instanceOf(ReturnRequirementModel) + expect(result.returnRequirement).to.equal(testReturnRequirement) + }) + }) + }) }) From ae0ef7a1a054b278073ea8faa466e3433ca0107d Mon Sep 17 00:00:00 2001 From: Alan Cruikshanks Date: Thu, 6 Jun 2024 17:26:00 +0100 Subject: [PATCH 12/17] Add relationships for return requirements --- app/models/return-requirement.model.js | 31 +++++ test/models/return-requirement.model.test.js | 116 ++++++++++++++++++- 2 files changed, 145 insertions(+), 2 deletions(-) diff --git a/app/models/return-requirement.model.js b/app/models/return-requirement.model.js index fc37509576..507cc7143d 100644 --- a/app/models/return-requirement.model.js +++ b/app/models/return-requirement.model.js @@ -5,12 +5,43 @@ * @module ReturnRequirementModel */ +const { Model } = require('objection') + const BaseModel = require('./base.model.js') class ReturnRequirementModel extends BaseModel { static get tableName () { return 'returnRequirements' } + + static get relationMappings () { + return { + returnRequirementPoints: { + relation: Model.HasManyRelation, + modelClass: 'return-requirement-point.model', + join: { + from: 'returnRequirements.id', + to: 'returnRequirementPoints.returnRequirementId' + } + }, + returnRequirementPurposes: { + relation: Model.HasManyRelation, + modelClass: 'return-requirement-purpose.model', + join: { + from: 'returnRequirements.id', + to: 'returnRequirementPurposes.returnRequirementId' + } + }, + returnVersion: { + relation: Model.BelongsToOneRelation, + modelClass: 'return-version.model', + join: { + from: 'returnRequirements.returnVersionId', + to: 'returnVersions.id' + } + } + } + } } module.exports = ReturnRequirementModel diff --git a/test/models/return-requirement.model.test.js b/test/models/return-requirement.model.test.js index c8ed244b35..a388b1151f 100644 --- a/test/models/return-requirement.model.test.js +++ b/test/models/return-requirement.model.test.js @@ -10,6 +10,12 @@ const { expect } = Code // Test helpers const DatabaseSupport = require('../support/database.js') const ReturnRequirementHelper = require('../support/helpers/return-requirement.helper.js') +const ReturnRequirementPointHelper = require('../support/helpers/return-requirement-point.helper.js') +const ReturnRequirementPointModel = require('../../app/models/return-requirement-point.model.js') +const ReturnRequirementPurposeHelper = require('../support/helpers/return-requirement-purpose.helper.js') +const ReturnRequirementPurposeModel = require('../../app/models/return-requirement-purpose.model.js') +const ReturnVersionHelper = require('../support/helpers/return-version.helper.js') +const ReturnVersionModel = require('../../app/models/return-version.model.js') // Thing under test const ReturnRequirementModel = require('../../app/models/return-requirement.model.js') @@ -19,11 +25,13 @@ describe('Return Requirement model', () => { beforeEach(async () => { await DatabaseSupport.clean() - - testRecord = await ReturnRequirementHelper.add() }) describe('Basic query', () => { + beforeEach(async () => { + testRecord = await ReturnRequirementHelper.add() + }) + it('can successfully run a basic query', async () => { const result = await ReturnRequirementModel.query().findById(testRecord.id) @@ -31,4 +39,108 @@ describe('Return Requirement model', () => { expect(result.id).to.equal(testRecord.id) }) }) + + describe('Relationships', () => { + describe('when linking to return requirement points', () => { + let testReturnRequirementPoints + + beforeEach(async () => { + testRecord = await ReturnRequirementHelper.add() + + testReturnRequirementPoints = [] + for (let i = 0; i < 2; i++) { + const returnRequirementPoint = await ReturnRequirementPointHelper.add( + { description: `TEST RET PNT ${i}`, returnRequirementId: testRecord.id } + ) + testReturnRequirementPoints.push(returnRequirementPoint) + } + }) + + it('can successfully run a related query', async () => { + const query = await ReturnRequirementModel.query() + .innerJoinRelated('returnRequirementPoints') + + expect(query).to.exist() + }) + + it('can eager load the return requirement points', async () => { + const result = await ReturnRequirementModel.query() + .findById(testRecord.id) + .withGraphFetched('returnRequirementPoints') + + expect(result).to.be.instanceOf(ReturnRequirementModel) + expect(result.id).to.equal(testRecord.id) + + expect(result.returnRequirementPoints).to.be.an.array() + expect(result.returnRequirementPoints[0]).to.be.an.instanceOf(ReturnRequirementPointModel) + expect(result.returnRequirementPoints).to.include(testReturnRequirementPoints[0]) + expect(result.returnRequirementPoints).to.include(testReturnRequirementPoints[1]) + }) + }) + + describe('when linking to return requirement purposes', () => { + let testReturnRequirementPurposes + + beforeEach(async () => { + testRecord = await ReturnRequirementHelper.add() + + testReturnRequirementPurposes = [] + for (let i = 0; i < 2; i++) { + const returnRequirementPurpose = await ReturnRequirementPurposeHelper.add( + { alias: `TEST RET REQ ${i}`, returnRequirementId: testRecord.id } + ) + testReturnRequirementPurposes.push(returnRequirementPurpose) + } + }) + + it('can successfully run a related query', async () => { + const query = await ReturnRequirementModel.query() + .innerJoinRelated('returnRequirementPurposes') + + expect(query).to.exist() + }) + + it('can eager load the return requirement purposes', async () => { + const result = await ReturnRequirementModel.query() + .findById(testRecord.id) + .withGraphFetched('returnRequirementPurposes') + + expect(result).to.be.instanceOf(ReturnRequirementModel) + expect(result.id).to.equal(testRecord.id) + + expect(result.returnRequirementPurposes).to.be.an.array() + expect(result.returnRequirementPurposes[0]).to.be.an.instanceOf(ReturnRequirementPurposeModel) + expect(result.returnRequirementPurposes).to.include(testReturnRequirementPurposes[0]) + expect(result.returnRequirementPurposes).to.include(testReturnRequirementPurposes[1]) + }) + }) + + describe('when linking to return version', () => { + let testReturnVersion + + beforeEach(async () => { + testReturnVersion = await ReturnVersionHelper.add() + testRecord = await ReturnRequirementHelper.add({ returnVersionId: testReturnVersion.id }) + }) + + it('can successfully run a related query', async () => { + const query = await ReturnRequirementModel.query() + .innerJoinRelated('returnVersion') + + expect(query).to.exist() + }) + + it('can eager load the charge version', async () => { + const result = await ReturnRequirementModel.query() + .findById(testRecord.id) + .withGraphFetched('returnVersion') + + expect(result).to.be.instanceOf(ReturnRequirementModel) + expect(result.id).to.equal(testRecord.id) + + expect(result.returnVersion).to.be.an.instanceOf(ReturnVersionModel) + expect(result.returnVersion).to.equal(testReturnVersion) + }) + }) + }) }) From fc06e2ea49a5b6a2af06f9e873f25f3c9b19b7ea Mon Sep 17 00:00:00 2001 From: Alan Cruikshanks Date: Thu, 6 Jun 2024 17:37:14 +0100 Subject: [PATCH 13/17] Add relationships for return version --- app/models/return-version.model.js | 23 +++++++ test/models/return-version.model.test.js | 79 +++++++++++++++++++++++- 2 files changed, 100 insertions(+), 2 deletions(-) diff --git a/app/models/return-version.model.js b/app/models/return-version.model.js index 5352daf008..1f4edd7fff 100644 --- a/app/models/return-version.model.js +++ b/app/models/return-version.model.js @@ -5,12 +5,35 @@ * @module ReturnVersionModel */ +const { Model } = require('objection') + const BaseModel = require('./base.model.js') class ReturnVersionModel extends BaseModel { static get tableName () { return 'returnVersions' } + + static get relationMappings () { + return { + licence: { + relation: Model.BelongsToOneRelation, + modelClass: 'licence.model', + join: { + from: 'returnVersions.licenceId', + to: 'licences.id' + } + }, + returnRequirements: { + relation: Model.HasManyRelation, + modelClass: 'return-requirement.model', + join: { + from: 'returnVersions.id', + to: 'returnRequirements.returnVersionId' + } + } + } + } } module.exports = ReturnVersionModel diff --git a/test/models/return-version.model.test.js b/test/models/return-version.model.test.js index 95bc154637..b6a8288780 100644 --- a/test/models/return-version.model.test.js +++ b/test/models/return-version.model.test.js @@ -9,6 +9,10 @@ const { expect } = Code // Test helpers const DatabaseSupport = require('../support/database.js') +const LicenceHelper = require('../support/helpers/licence.helper.js') +const LicenceModel = require('../../app/models/licence.model.js') +const ReturnRequirementHelper = require('../support/helpers/return-requirement.helper.js') +const ReturnRequirementModel = require('../../app/models/return-requirement.model.js') const ReturnVersionHelper = require('../support/helpers/return-version.helper.js') // Thing under test @@ -19,11 +23,13 @@ describe('Return Version model', () => { beforeEach(async () => { await DatabaseSupport.clean() - - testRecord = await ReturnVersionHelper.add() }) describe('Basic query', () => { + beforeEach(async () => { + testRecord = await ReturnVersionHelper.add() + }) + it('can successfully run a basic query', async () => { const result = await ReturnVersionModel.query().findById(testRecord.id) @@ -31,4 +37,73 @@ describe('Return Version model', () => { expect(result.id).to.equal(testRecord.id) }) }) + + describe('Relationships', () => { + describe('when linking to licence', () => { + let testLicence + + beforeEach(async () => { + testLicence = await LicenceHelper.add() + + const { id: licenceId } = testLicence + testRecord = await ReturnVersionHelper.add({ licenceId }) + }) + + it('can successfully run a related query', async () => { + const query = await ReturnVersionModel.query() + .innerJoinRelated('licence') + + expect(query).to.exist() + }) + + it('can eager load the licence', async () => { + const result = await ReturnVersionModel.query() + .findById(testRecord.id) + .withGraphFetched('licence') + + expect(result).to.be.instanceOf(ReturnVersionModel) + expect(result.id).to.equal(testRecord.id) + + expect(result.licence).to.be.an.instanceOf(LicenceModel) + expect(result.licence).to.equal(testLicence) + }) + }) + + describe('when linking to return requirements', () => { + let testReturnRequirements + + beforeEach(async () => { + testRecord = await ReturnVersionHelper.add() + + testReturnRequirements = [] + for (let i = 0; i < 2; i++) { + const returnRequirement = await ReturnRequirementHelper.add( + { siteDescription: `TEST RTN REQ ${i}`, returnVersionId: testRecord.id } + ) + testReturnRequirements.push(returnRequirement) + } + }) + + it('can successfully run a related query', async () => { + const query = await ReturnVersionModel.query() + .innerJoinRelated('returnRequirements') + + expect(query).to.exist() + }) + + it('can eager load the return requirements', async () => { + const result = await ReturnVersionModel.query() + .findById(testRecord.id) + .withGraphFetched('returnRequirements') + + expect(result).to.be.instanceOf(ReturnVersionModel) + expect(result.id).to.equal(testRecord.id) + + expect(result.returnRequirements).to.be.an.array() + expect(result.returnRequirements[0]).to.be.an.instanceOf(ReturnRequirementModel) + expect(result.returnRequirements).to.include(testReturnRequirements[0]) + expect(result.returnRequirements).to.include(testReturnRequirements[1]) + }) + }) + }) }) From 8ea63471f2ea65b3eb592f297c1c903e1666e998 Mon Sep 17 00:00:00 2001 From: Alan Cruikshanks Date: Thu, 6 Jun 2024 17:39:38 +0100 Subject: [PATCH 14/17] Housekeeping - make tests consistent --- test/models/return-requirement-point.model.test.js | 6 ++++-- test/models/return-requirement-purpose.model.test.js | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/test/models/return-requirement-point.model.test.js b/test/models/return-requirement-point.model.test.js index 0038405b90..c91f5b7834 100644 --- a/test/models/return-requirement-point.model.test.js +++ b/test/models/return-requirement-point.model.test.js @@ -21,11 +21,13 @@ describe('Return Requirement Point model', () => { beforeEach(async () => { await DatabaseSupport.clean() - - testRecord = await ReturnRequirementPointHelper.add() }) describe('Basic query', () => { + beforeEach(async () => { + testRecord = await ReturnRequirementPointHelper.add() + }) + it('can successfully run a basic query', async () => { const result = await ReturnRequirementPointModel.query().findById(testRecord.id) diff --git a/test/models/return-requirement-purpose.model.test.js b/test/models/return-requirement-purpose.model.test.js index 9b2b1a6aa7..756ee1e097 100644 --- a/test/models/return-requirement-purpose.model.test.js +++ b/test/models/return-requirement-purpose.model.test.js @@ -23,11 +23,13 @@ describe('Return Requirement Purpose model', () => { beforeEach(async () => { await DatabaseSupport.clean() - - testRecord = await ReturnRequirementPurposeHelper.add() }) describe('Basic query', () => { + beforeEach(async () => { + testRecord = await ReturnRequirementPurposeHelper.add() + }) + it('can successfully run a basic query', async () => { const result = await ReturnRequirementPurposeModel.query().findById(testRecord.id) From 2fac3d0a7ae616bb95572bd2510e692a57ebaf11 Mon Sep 17 00:00:00 2001 From: Alan Cruikshanks Date: Thu, 6 Jun 2024 17:45:52 +0100 Subject: [PATCH 15/17] Add relationship to licence --- app/models/licence.model.js | 8 +++++++ test/models/licence.model.test.js | 39 ++++++++++++++++++++++++++++++- 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/app/models/licence.model.js b/app/models/licence.model.js index a83110a4e6..f746ef607f 100644 --- a/app/models/licence.model.js +++ b/app/models/licence.model.js @@ -72,6 +72,14 @@ class LicenceModel extends BaseModel { to: 'returnLogs.licenceRef' } }, + returnVersions: { + relation: Model.HasManyRelation, + modelClass: 'return-version.model', + join: { + from: 'licences.id', + to: 'returnVersions.licenceId' + } + }, reviewLicences: { relation: Model.HasManyRelation, modelClass: 'review-licence.model', diff --git a/test/models/licence.model.test.js b/test/models/licence.model.test.js index 4de63cc74b..85eeedf943 100644 --- a/test/models/licence.model.test.js +++ b/test/models/licence.model.test.js @@ -28,6 +28,8 @@ const RegionHelper = require('../support/helpers/region.helper.js') const RegionModel = require('../../app/models/region.model.js') const ReturnLogHelper = require('../support/helpers/return-log.helper.js') const ReturnLogModel = require('../../app/models/return-log.model.js') +const ReturnVersionHelper = require('../support/helpers/return-version.helper.js') +const ReturnVersionModel = require('../../app/models/return-version.model.js') const RegisteredToAndLicenceNameSeeder = require('../support/seeders/registered-to-and-licence-name.seeder.js') const ReviewLicenceHelper = require('../support/helpers/review-licence.helper.js') const ReviewLicenceModel = require('../../app/models/review-licence.model.js') @@ -271,7 +273,7 @@ describe('Licence model', () => { expect(query).to.exist() }) - it('can eager load the workflows', async () => { + it('can eager load the return logs', async () => { const result = await LicenceModel.query() .findById(testRecord.id) .withGraphFetched('returnLogs') @@ -286,6 +288,41 @@ describe('Licence model', () => { }) }) + describe('when linking to return versions', () => { + let testReturnVersions + + beforeEach(async () => { + const { id: licenceId } = testRecord + + testReturnVersions = [] + for (let i = 0; i < 2; i++) { + const returnVersion = await ReturnVersionHelper.add({ licenceId }) + testReturnVersions.push(returnVersion) + } + }) + + it('can successfully run a related query', async () => { + const query = await LicenceModel.query() + .innerJoinRelated('returnVersions') + + expect(query).to.exist() + }) + + it('can eager load the return versions', async () => { + const result = await LicenceModel.query() + .findById(testRecord.id) + .withGraphFetched('returnVersions') + + expect(result).to.be.instanceOf(LicenceModel) + expect(result.id).to.equal(testRecord.id) + + expect(result.returnVersions).to.be.an.array() + expect(result.returnVersions[0]).to.be.an.instanceOf(ReturnVersionModel) + expect(result.returnVersions).to.include(testReturnVersions[0]) + expect(result.returnVersions).to.include(testReturnVersions[1]) + }) + }) + describe('when linking to review licences', () => { let testReviewLicences From 10ae0ae2e5ae66d063b3b76ef326ff11a669d5a1 Mon Sep 17 00:00:00 2001 From: Alan Cruikshanks Date: Thu, 6 Jun 2024 17:51:51 +0100 Subject: [PATCH 16/17] Add relationship to purpose --- app/models/purpose.model.js | 8 +++++ test/models/purpose.model.test.js | 51 +++++++++++++++++++++++++++---- 2 files changed, 53 insertions(+), 6 deletions(-) diff --git a/app/models/purpose.model.js b/app/models/purpose.model.js index 0d4a9d02b5..de976e60f5 100644 --- a/app/models/purpose.model.js +++ b/app/models/purpose.model.js @@ -39,6 +39,14 @@ class PurposeModel extends BaseModel { from: 'purposes.id', to: 'licenceVersionPurposes.purposeId' } + }, + returnRequirementPurposes: { + relation: Model.HasManyRelation, + modelClass: 'return-requirement-purpose.model', + join: { + from: 'purposes.id', + to: 'returnRequirementPurposes.purposeId' + } } } } diff --git a/test/models/purpose.model.test.js b/test/models/purpose.model.test.js index 3cf5192d5d..dd72f532aa 100644 --- a/test/models/purpose.model.test.js +++ b/test/models/purpose.model.test.js @@ -14,6 +14,8 @@ const ChargeReferenceHelper = require('../support/helpers/charge-reference.helpe const ChargeReferenceModel = require('../../app/models/charge-reference.model.js') const DatabaseSupport = require('../support/database.js') const PurposeHelper = require('../support/helpers/purpose.helper.js') +const ReturnRequirementPurposeHelper = require('../support/helpers/return-requirement-purpose.helper.js') +const ReturnRequirementPurposeModel = require('../../app/models/return-requirement-purpose.model.js') // Thing under test const PurposeModel = require('../../app/models/purpose.model.js') @@ -23,11 +25,13 @@ describe('Purpose model', () => { beforeEach(async () => { await DatabaseSupport.clean() - - testRecord = await PurposeHelper.add() }) describe('Basic query', () => { + beforeEach(async () => { + testRecord = await PurposeHelper.add() + }) + it('can successfully run a basic query', async () => { const result = await PurposeModel.query().findById(testRecord.id) @@ -41,11 +45,11 @@ describe('Purpose model', () => { let testChargeElements beforeEach(async () => { - const { id } = testRecord + testRecord = await PurposeHelper.add() testChargeElements = [] for (let i = 0; i < 2; i++) { - const chargeElement = await ChargeElementHelper.add({ purposeId: id }) + const chargeElement = await ChargeElementHelper.add({ purposeId: testRecord.id }) testChargeElements.push(chargeElement) } }) @@ -76,11 +80,11 @@ describe('Purpose model', () => { let testChargeReferences beforeEach(async () => { - const { id } = testRecord + testRecord = await PurposeHelper.add() testChargeReferences = [] for (let i = 0; i < 2; i++) { - const chargeReference = await ChargeReferenceHelper.add({ purposeId: id }) + const chargeReference = await ChargeReferenceHelper.add({ purposeId: testRecord.id }) testChargeReferences.push(chargeReference) } }) @@ -106,5 +110,40 @@ describe('Purpose model', () => { expect(result.chargeReferences).to.include(testChargeReferences[1]) }) }) + + describe('when linking to return requirement purposes', () => { + let testReturnRequirementPurposes + + beforeEach(async () => { + testRecord = await PurposeHelper.add() + + testReturnRequirementPurposes = [] + for (let i = 0; i < 2; i++) { + const returnRequirementPurpose = await ReturnRequirementPurposeHelper.add({ purposeId: testRecord.id }) + testReturnRequirementPurposes.push(returnRequirementPurpose) + } + }) + + it('can successfully run a related query', async () => { + const query = await PurposeModel.query() + .innerJoinRelated('returnRequirementPurposes') + + expect(query).to.exist() + }) + + it('can eager load the return requirement purposes', async () => { + const result = await PurposeModel.query() + .findById(testRecord.id) + .withGraphFetched('returnRequirementPurposes') + + expect(result).to.be.instanceOf(PurposeModel) + expect(result.id).to.equal(testRecord.id) + + expect(result.returnRequirementPurposes).to.be.an.array() + expect(result.returnRequirementPurposes[0]).to.be.an.instanceOf(ReturnRequirementPurposeModel) + expect(result.returnRequirementPurposes).to.include(testReturnRequirementPurposes[0]) + expect(result.returnRequirementPurposes).to.include(testReturnRequirementPurposes[1]) + }) + }) }) }) From 20bdb1ffce32d25f6afc4192f1771c1c12875120 Mon Sep 17 00:00:00 2001 From: Alan Cruikshanks Date: Thu, 6 Jun 2024 17:55:10 +0100 Subject: [PATCH 17/17] Housekeeping - add missing purpose model tests --- test/models/purpose.model.test.js | 37 +++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/test/models/purpose.model.test.js b/test/models/purpose.model.test.js index dd72f532aa..4d78ec4338 100644 --- a/test/models/purpose.model.test.js +++ b/test/models/purpose.model.test.js @@ -13,6 +13,8 @@ const ChargeElementModel = require('../../app/models/charge-element.model.js') const ChargeReferenceHelper = require('../support/helpers/charge-reference.helper.js') const ChargeReferenceModel = require('../../app/models/charge-reference.model.js') const DatabaseSupport = require('../support/database.js') +const LicenceVersionPurposeHelper = require('../support/helpers/licence-version-purpose.helper.js') +const LicenceVersionPurposeModel = require('../../app/models/licence-version-purpose.model.js') const PurposeHelper = require('../support/helpers/purpose.helper.js') const ReturnRequirementPurposeHelper = require('../support/helpers/return-requirement-purpose.helper.js') const ReturnRequirementPurposeModel = require('../../app/models/return-requirement-purpose.model.js') @@ -111,6 +113,41 @@ describe('Purpose model', () => { }) }) + describe('when linking to licence version purposes', () => { + let testLicenceVersionPurposes + + beforeEach(async () => { + testRecord = await PurposeHelper.add() + + testLicenceVersionPurposes = [] + for (let i = 0; i < 2; i++) { + const licenceVersionPurpose = await LicenceVersionPurposeHelper.add({ purposeId: testRecord.id }) + testLicenceVersionPurposes.push(licenceVersionPurpose) + } + }) + + it('can successfully run a related query', async () => { + const query = await PurposeModel.query() + .innerJoinRelated('licenceVersionPurposes') + + expect(query).to.exist() + }) + + it('can eager load the licence version purposes', async () => { + const result = await PurposeModel.query() + .findById(testRecord.id) + .withGraphFetched('licenceVersionPurposes') + + expect(result).to.be.instanceOf(PurposeModel) + expect(result.id).to.equal(testRecord.id) + + expect(result.licenceVersionPurposes).to.be.an.array() + expect(result.licenceVersionPurposes[0]).to.be.an.instanceOf(LicenceVersionPurposeModel) + expect(result.licenceVersionPurposes).to.include(testLicenceVersionPurposes[0]) + expect(result.licenceVersionPurposes).to.include(testLicenceVersionPurposes[1]) + }) + }) + describe('when linking to return requirement purposes', () => { let testReturnRequirementPurposes