diff --git a/app/models/session.model.js b/app/models/session.model.js new file mode 100644 index 0000000000..c6d371a8cd --- /dev/null +++ b/app/models/session.model.js @@ -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 diff --git a/db/migrations/public/20231215113321_create-sessions.js b/db/migrations/public/20231215113321_create-sessions.js new file mode 100644 index 0000000000..6c66868435 --- /dev/null +++ b/db/migrations/public/20231215113321_create-sessions.js @@ -0,0 +1,40 @@ +'use strict' + +const tableName = 'sessions' + +/** + * @param { import("knex").Knex } knex + * @returns { Promise } + */ +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 } + */ +exports.down = function (knex) { + return knex + .schema + .dropTableIfExists(tableName) +} diff --git a/test/models/session.model.test.js b/test/models/session.model.test.js new file mode 100644 index 0000000000..e12e2daadb --- /dev/null +++ b/test/models/session.model.test.js @@ -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('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({}) + }) + }) +}) diff --git a/test/support/helpers/session.helper.js b/test/support/helpers/session.helper.js new file mode 100644 index 0000000000..31f60808ab --- /dev/null +++ b/test/support/helpers/session.helper.js @@ -0,0 +1,49 @@ +'use strict' + +/** + * @module SessionHelper + */ + +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 = {} + + return { + ...defaults, + ...data + } +} + +module.exports = { + add, + defaults +}