Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Set up session table (return requirements) #594

Merged
merged 10 commits into from
Dec 15, 2023
23 changes: 23 additions & 0 deletions app/models/session.model.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
'use strict'

/**
* Model for sessions
* @module SessionModel
*/

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

class SessionModel extends BaseModel {
static get tableName () {
return 'sessions'
}

// Defining which fields contain json allows us to insert an object without needing to stringify it first
static get jsonAttributes () {
return [
'data'
]
}
}

module.exports = SessionModel
40 changes: 40 additions & 0 deletions db/migrations/public/20231215113321_create-sessions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
'use strict'

const tableName = 'sessions'

/**
* @param { import("knex").Knex } knex
* @returns { Promise<void> }
*/
exports.up = function (knex) {
return knex
.schema
.createTable(tableName, (table) => {
// Primary Key
table.uuid('id').primary().defaultTo(knex.raw('gen_random_uuid()'))
// Data
table.jsonb('data').defaultTo({})

// Automatic timestamps
table.timestamps(false, true)
})
.then(() => {
knex.raw(`
CREATE TRIGGER update_timestamp
BEFORE UPDATE
ON ${tableName}
FOR EACH ROW
EXECUTE PROCEDURE update_timestamp();
`)
})
}

/**
* @param { import("knex").Knex } knex
* @returns { Promise<void> }
*/
exports.down = function (knex) {
return knex
.schema
.dropTableIfExists(tableName)
}
37 changes: 37 additions & 0 deletions test/models/session.model.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
'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 SessionHelper = require('../support/helpers/session.helper.js')

// Thing under test
const SessionModel = require('../../app/models/session.model.js')

describe('Sessions model', () => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
describe('Sessions model', () => {
describe('Session model', () => {

let testRecord

beforeEach(async () => {
await DatabaseHelper.clean()
})

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

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

expect(result).to.be.an.instanceOf(SessionModel)
expect(result.id).to.equal(testRecord.id)
expect(result.data).to.equal({})
})
})
})
53 changes: 53 additions & 0 deletions test/support/helpers/session.helper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
'use strict'

/**
* @module SessionHelper
*/

const { generateUUID } = require('../../../app/lib/general.lib.js')
const SessionModel = require('../../../app/models/session.model.js')

/**
* Add a new session
*
* If no `data` is provided, default values will be used. These are
*
* - `id` - [random UUID]
* - `data` - [empty object {}]
*
* @param {Object} [data] Any data you want to use instead of the defaults used here or in the database
*
* @returns {module:SessionModel} The instance of the newly created record
*/
function add (data = {}) {
const insertData = defaults(data)

return SessionModel.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 in the database
*/
function defaults (data = {}) {
const defaults = {
id: generateUUID(),
data: {}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where a table automatically generates an ID we don't tend to set one in the helper. If you've seen us do this it should normally come with a note saying the previous team failed to implement an automatic UUID on insert in the underlying table, hence the need to do it.

So, we just focus on setting meaningful defaults to reflect what an instantiated record would typically look like.

In this particular case data: {} could be what we often find. So, I'd suggest one of the following, I'll leave you to decide which one to go with!

  const defaults = {
    data: { licenceId: '01/128' }
  }

Or whatever pretend test values you'd like to set in data:

or

  const defaults = {}


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

module.exports = {
add,
defaults
}
Loading