Skip to content

Commit

Permalink
Add Licence Version Purpose Point model (#1288)
Browse files Browse the repository at this point in the history
https://eaflood.atlassian.net/browse/WATER-4645

> Part of the work to migrate return versions from NALD to WRLS

We've been extending and amending the import of return versions from NALD to WRLS as part of our work to switch from NALD to WRLS to manage them. To support this we [Created a return-requirement-points table](DEFRA/water-abstraction-service#2540) and [updated the import](DEFRA/water-abstraction-import#933) to import them.

Users select these points as part of the return requirements setup journey we've built. We extract them from the JSON blob stored in the `permit.licence` table. The problem we've encountered is the import service only populates the points for licences that.

- Have not ended
- Have a current licence version

Otherwise, `permit.licence` is not populated with the points data our journey relies on, causing it to throw an error. Places like the view licence page are also affected by this.

For example, it is perfectly valid that we have an 'ended' licence that we need to correct the historic return versions. And no matter the state, we can see what points the licence was linked to.

We don't know why the previous team never opted to extract licence points to their own table. But we are now [importing them as part of the licence import](DEFRA/water-abstraction-import#1009). This change adds the model and supporting changes to make the new table available to us.
  • Loading branch information
Cruikshanks authored Aug 27, 2024
1 parent cf537bf commit c913761
Show file tree
Hide file tree
Showing 8 changed files with 277 additions and 1 deletion.
31 changes: 31 additions & 0 deletions app/models/licence-version-purpose-point.model.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
'use strict'

/**
* Model for licence_version_purpose_points (water.licence_version_purpose_points)
* @module LicenceVersionPurposePointModel
*/

const { Model } = require('objection')

const BaseModel = require('./base.model.js')

class LicenceVersionPurposePointModel extends BaseModel {
static get tableName () {
return 'licenceVersionPurposePoints'
}

static get relationMappings () {
return {
licenceVersionPurpose: {
relation: Model.BelongsToOneRelation,
modelClass: 'licence-version-purpose.model',
join: {
from: 'licenceVersionPurposePoints.licenceVersionPurposeId',
to: 'licenceVersionPurposes.id'
}
}
}
}
}

module.exports = LicenceVersionPurposePointModel
8 changes: 8 additions & 0 deletions app/models/licence-version-purpose.model.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,14 @@ class LicenceVersionPurposeModel extends BaseModel {
to: 'licenceVersionPurposeConditions.licenceVersionPurposeId'
}
},
licenceVersionPurposePoints: {
relation: Model.HasManyRelation,
modelClass: 'licence-version-purpose-point.model',
join: {
from: 'licenceVersionPurposes.id',
to: 'licenceVersionPurposePoints.licenceVersionPurposeId'
}
},
primaryPurpose: {
relation: Model.BelongsToOneRelation,
modelClass: 'primary-purpose.model.js',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
'use strict'

const tableName = 'licence_version_purpose_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('licence_version_purpose_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)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
'use strict'

const viewName = 'licence_version_purpose_points'

exports.up = function (knex) {
return knex
.schema
.createView(viewName, (view) => {
view.as(knex('licence_version_purpose_points').withSchema('water').select([
'id',
'licence_version_purpose_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)
}
66 changes: 66 additions & 0 deletions test/models/licence-version-purpose-point.model.test.js
Original file line number Diff line number Diff line change
@@ -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

// Test helpers
const LicenceVersionPurposeHelper = require('../support/helpers/licence-version-purpose.helper.js')
const LicenceVersionPurposeModel = require('../../app/models/licence-version-purpose.model.js')
const LicenceVersionPurposePointHelper = require('../support/helpers/licence-version-purpose-point.helper.js')

// Thing under test
const LicenceVersionPurposePointModel = require('../../app/models/licence-version-purpose-point.model.js')

describe('Licence Version Purpose Point model', () => {
let testRecord

describe('Basic query', () => {
beforeEach(async () => {
testRecord = await LicenceVersionPurposePointHelper.add()
})

it('can successfully run a basic query', async () => {
const result = await LicenceVersionPurposePointModel.query().findById(testRecord.id)

expect(result).to.be.an.instanceOf(LicenceVersionPurposePointModel)
expect(result.id).to.equal(testRecord.id)
})
})

describe('Relationships', () => {
describe('when linking to licence version purpose', () => {
let testLicenceVersionPurpose

beforeEach(async () => {
testLicenceVersionPurpose = await LicenceVersionPurposeHelper.add()

const { id: licenceVersionPurposeId } = testLicenceVersionPurpose

testRecord = await LicenceVersionPurposePointHelper.add({ licenceVersionPurposeId })
})

it('can successfully run a related query', async () => {
const query = await LicenceVersionPurposePointModel.query()
.innerJoinRelated('licenceVersionPurpose')

expect(query).to.exist()
})

it('can eager load the licence version purpose', async () => {
const result = await LicenceVersionPurposePointModel.query()
.findById(testRecord.id)
.withGraphFetched('licenceVersionPurpose')

expect(result).to.be.instanceOf(LicenceVersionPurposePointModel)
expect(result.id).to.equal(testRecord.id)

expect(result.licenceVersionPurpose).to.be.an.instanceOf(LicenceVersionPurposeModel)
expect(result.licenceVersionPurpose).to.equal(testLicenceVersionPurpose)
})
})
})
})
40 changes: 40 additions & 0 deletions test/models/licence-version-purpose.model.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ const LicenceVersionModel = require('../../app/models/licence-version.model.js')
const LicenceVersionPurposeConditionHelper = require('../support/helpers/licence-version-purpose-condition.helper.js')
const LicenceVersionPurposeConditionModel = require('../../app/models/licence-version-purpose-condition.model.js')
const LicenceVersionPurposeHelper = require('../support/helpers/licence-version-purpose.helper.js')
const LicenceVersionPurposePointModel = require('../../app/models/licence-version-purpose-point.model.js')
const LicenceVersionPurposePointHelper = require('../support/helpers/licence-version-purpose-point.helper.js')
const PrimaryPurposeHelper = require('../support/helpers/primary-purpose.helper.js')
const PrimaryPurposeModel = require('../../app/models/primary-purpose.model.js')
const PurposeHelper = require('../support/helpers/purpose.helper.js')
Expand Down Expand Up @@ -118,6 +120,44 @@ describe('Licence Version Purpose model', () => {
})
})

describe('when linking to licence version purpose points', () => {
let testLicenceVersionPurposePoints

beforeEach(async () => {
testRecord = await LicenceVersionPurposeHelper.add()

testLicenceVersionPurposePoints = []
for (let i = 0; i < 2; i++) {
const licenceVersionPurposePoint = await LicenceVersionPurposePointHelper.add({
licenceVersionPurposeId: testRecord.id
})

testLicenceVersionPurposePoints.push(licenceVersionPurposePoint)
}
})

it('can successfully run a related query', async () => {
const query = await LicenceVersionPurposeModel.query()
.innerJoinRelated('licenceVersionPurposePoints')

expect(query).to.exist()
})

it('can eager load the licence version purpose points', async () => {
const result = await LicenceVersionPurposeModel.query()
.findById(testRecord.id)
.withGraphFetched('licenceVersionPurposePoints')

expect(result).to.be.instanceOf(LicenceVersionPurposeModel)
expect(result.id).to.equal(testRecord.id)

expect(result.licenceVersionPurposePoints).to.be.an.array()
expect(result.licenceVersionPurposePoints[0]).to.be.an.instanceOf(LicenceVersionPurposePointModel)
expect(result.licenceVersionPurposePoints).to.include(testLicenceVersionPurposePoints[0])
expect(result.licenceVersionPurposePoints).to.include(testLicenceVersionPurposePoints[1])
})
})

describe('when linking to primary purpose', () => {
beforeEach(async () => {
testRecord = await LicenceVersionPurposeHelper.add({ primaryPurposeId })
Expand Down
2 changes: 1 addition & 1 deletion test/models/return-requirement-point.model.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ describe('Return Requirement Point model', () => {
expect(query).to.exist()
})

it('can eager load the charge reference', async () => {
it('can eager load the return requirement', async () => {
const result = await ReturnRequirementPointModel.query()
.findById(testRecord.id)
.withGraphFetched('returnRequirement')
Expand Down
65 changes: 65 additions & 0 deletions test/support/helpers/licence-version-purpose-point.helper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
'use strict'

/**
* @module LicenceVersionPurposePointHelper
*/

const { generateUUID } = require('../../../app/lib/general.lib.js')
const { randomInteger } = require('../general.js')
const LicenceVersionPurposePointModel = require('../../../app/models/licence-version-purpose-point.model.js')
const { generateNaldPointId, generateNationalGridReference } = require('./return-requirement-point.helper.js')

/**
* Add a new licence version purpose point
*
* If no `data` is provided, default values will be used. These are
*
* - `externalId` - [randomly generated - 9:99999:100414]
* - `licenceVersionPurposeId` - [random UUID]
* - `naldPointId` - [randomly generated - 100414]
* - `ngr1` - [randomly generated - TL 5143 7153]
*
* @param {object} [data] - Any data you want to use instead of the defaults used here or in the database
*
* @returns {Promise<module:LicenceVersionPurposePointModel>} The instance of the newly created record
*/
function add (data = {}) {
const insertData = defaults(data)

return LicenceVersionPurposePointModel.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
*
* @returns {object} - Returns the set defaults with the override data spread
*/
function defaults (data = {}) {
const naldPointId = data.naldPointId ? data.naldPointId : generateNaldPointId()
const ngr1 = data.ngr1 ? data.ngr1 : generateNationalGridReference()

const defaults = {
description: 'Point description',
externalId: `9:${randomInteger(100, 99999)}:${naldPointId}`,
licenceVersionPurposeId: generateUUID(),
naldPointId,
ngr1
}

return {
...defaults,
...data
}
}

module.exports = {
add,
defaults
}

0 comments on commit c913761

Please sign in to comment.