From 2e4755e81a209f9c6fad89cd4a9f9511c114a86c Mon Sep 17 00:00:00 2001 From: Alan Cruikshanks Date: Wed, 3 Jan 2024 13:56:19 +0000 Subject: [PATCH] Add LicenceRoleModel from crm_v2.roles (#629) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://eaflood.atlassian.net/browse/WATER-4292 > This is part of a series of changes to add the ability to identify the licence holder for a licence This change adds the migration, model, test helper and unit tests for a new `LicenceRoleModel`. We've already added [LicenceDocumentModel](https://github.com/DEFRA/water-abstraction-system/pull/618). Though pointless, it's the only thing that points us to who the licence holder is. In the `crm_v2` schema it does this in `crm_v2.document_roles` which is the join table between `crm_v2.documents` and `crm_v2.roles`. `roles` is a lookup table of the 'role' a `crm_v2.contact` or `crm_c2.company` has, for example, licence holder! So, our next step is to create a model for 'roles' so we can then get on and join them in a future model. Our first blocker though is we can't use the name `roles` and that is already taken (`RoleModel` is used for the lookup table of user roles). Hence, we're creating a new `LicenceRoleModel` in this change! 😁 --- app/models/licence-role.model.js | 16 ++++++ .../20240103123926_create-crm-v2-roles.js | 28 ++++++++++ ...0240103124409_create-licence-roles-view.js | 23 ++++++++ test/models/licence-role.model.test.js | 34 ++++++++++++ test/support/helpers/licence-role.helper.js | 52 +++++++++++++++++++ 5 files changed, 153 insertions(+) create mode 100644 app/models/licence-role.model.js create mode 100644 db/migrations/legacy/20240103123926_create-crm-v2-roles.js create mode 100644 db/migrations/public/20240103124409_create-licence-roles-view.js create mode 100644 test/models/licence-role.model.test.js create mode 100644 test/support/helpers/licence-role.helper.js diff --git a/app/models/licence-role.model.js b/app/models/licence-role.model.js new file mode 100644 index 0000000000..5aa37b2739 --- /dev/null +++ b/app/models/licence-role.model.js @@ -0,0 +1,16 @@ +'use strict' + +/** + * Model for licence_roles (crm_v2.roles) + * @module LicenceRoleModel + */ + +const BaseModel = require('./base.model.js') + +class LicenceRoleModel extends BaseModel { + static get tableName () { + return 'licenceRoles' + } +} + +module.exports = LicenceRoleModel diff --git a/db/migrations/legacy/20240103123926_create-crm-v2-roles.js b/db/migrations/legacy/20240103123926_create-crm-v2-roles.js new file mode 100644 index 0000000000..0eea3fa4ba --- /dev/null +++ b/db/migrations/legacy/20240103123926_create-crm-v2-roles.js @@ -0,0 +1,28 @@ +'use strict' + +const tableName = 'roles' + +exports.up = function (knex) { + return knex + .schema + .withSchema('crm_v2') + .createTable(tableName, (table) => { + // Primary Key + table.uuid('role_id').primary().defaultTo(knex.raw('gen_random_uuid()')) + + // Data + table.string('name').notNullable() + table.string('label') + + // Legacy timestamps + table.timestamp('date_created').notNullable().defaultTo(knex.fn.now()) + table.timestamp('date_updated').notNullable().defaultTo(knex.fn.now()) + }) +} + +exports.down = function (knex) { + return knex + .schema + .withSchema('crm_v2') + .dropTableIfExists(tableName) +} diff --git a/db/migrations/public/20240103124409_create-licence-roles-view.js b/db/migrations/public/20240103124409_create-licence-roles-view.js new file mode 100644 index 0000000000..08f7bbfdc2 --- /dev/null +++ b/db/migrations/public/20240103124409_create-licence-roles-view.js @@ -0,0 +1,23 @@ +'use strict' + +const viewName = 'licence_roles' + +exports.up = function (knex) { + return knex + .schema + .createView(viewName, (view) => { + view.as(knex('roles').withSchema('crm_v2').select([ + 'role_id AS id', + 'name', + 'label', + 'date_created AS created_at', + 'date_updated AS updated_at' + ])) + }) +} + +exports.down = function (knex) { + return knex + .schema + .dropViewIfExists(viewName) +} diff --git a/test/models/licence-role.model.test.js b/test/models/licence-role.model.test.js new file mode 100644 index 0000000000..0ae0614675 --- /dev/null +++ b/test/models/licence-role.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 DatabaseHelper = require('../support/helpers/database.helper.js') +const LicenceRoleHelper = require('../support/helpers/licence-role.helper.js') + +// Thing under test +const LicenceRoleModel = require('../../app/models/licence-role.model.js') + +describe('Licence Role model', () => { + let testRecord + + beforeEach(async () => { + await DatabaseHelper.clean() + + testRecord = await LicenceRoleHelper.add() + }) + + describe('Basic query', () => { + it('can successfully run a basic query', async () => { + const result = await LicenceRoleModel.query().findById(testRecord.id) + + expect(result).to.be.an.instanceOf(LicenceRoleModel) + expect(result.id).to.equal(testRecord.id) + }) + }) +}) diff --git a/test/support/helpers/licence-role.helper.js b/test/support/helpers/licence-role.helper.js new file mode 100644 index 0000000000..99a54c6635 --- /dev/null +++ b/test/support/helpers/licence-role.helper.js @@ -0,0 +1,52 @@ +'use strict' + +/** + * @module LicenceRoleHelper + */ + +const LicenceRoleModel = require('../../../app/models/licence-role.model.js') + +/** + * Add a new licence role + * + * If no `data` is provided, default values will be used. These are + * + * - `name` - licenceHolder + * - `label` - Licence Holder + * + * @param {Object} [data] Any data you want to use instead of the defaults used here or in the database + * + * @returns {module:LicenceRoleModel} The instance of the newly created record + */ +async function add (data = {}) { + const insertData = defaults(data) + + return LicenceRoleModel.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 defaults = { + name: 'licenceHolder', + label: 'Licence Holder' + } + + return { + ...defaults, + ...data + } +} + +module.exports = { + add, + defaults +}