diff --git a/CHANGELOG.md b/CHANGELOG.md index 76c646c..87125d3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ ### Unreleased + +### [3.0.0-alpha.4] - 2024-03-05 + +- feat(lib/nameserver): added, with tests +- feat(routes/nameserver): added, with tests + ### 3.0.0-alpha.3 - routes/permission: added GET, POST, DELETE @@ -14,3 +20,4 @@ [3.0.0-alpha.3]: https://github.com/NicTool/api/releases/tag/3.0.0-alpha.3 +[3.0.0-alpha.4]: https://github.com/NicTool/api/releases/tag/3.0.0-alpha.4 diff --git a/lib/nameserver.js b/lib/nameserver.js new file mode 100644 index 0000000..2aa28c8 --- /dev/null +++ b/lib/nameserver.js @@ -0,0 +1,143 @@ +import Mysql from './mysql.js' +import { mapToDbColumn } from './util.js' + +const nsDbMap = { id: 'nt_nameserver_id', gid: 'nt_group_id' } +const boolFields = ['deleted', 'export_serials'] + +class Nameserver { + constructor() { + this.mysql = Mysql + } + + async create(args) { + if (args.id) { + const g = await this.get({ id: args.id }) + if (g.length === 1) return g[0].id + } + + if (args.export.type) { + args = JSON.parse(JSON.stringify(args)) + const rows = await Mysql.execute( + ...Mysql.select('SELECT id FROM nt_nameserver_export_type', { + name: args.export.type, + }), + ) + args.export_type_id = rows[0].id + delete args.export.type + } + + return await Mysql.execute( + ...Mysql.insert( + `nt_nameserver`, + mapToDbColumn(objectToDb(args), nsDbMap), + ), + ) + } + + async get(args) { + if (args.name !== undefined) { + args['ns.name'] = args.name + delete args.name + } + const rows = await Mysql.execute( + ...Mysql.select( + `SELECT ns.nt_nameserver_id AS id + , ns.nt_group_id AS gid + , ns.name + , ns.ttl + , ns.description + , ns.address + , ns.address6 + , ns.remote_login + , ns.logdir + , ns.datadir + , ns.export_interval + , ns.export_serials + , ns.export_status + , ns.deleted + , t.name AS export_type + FROM nt_nameserver ns + JOIN nt_nameserver_export_type t ON ns.export_type_id=t.id`, + mapToDbColumn(args, nsDbMap), + ), + ) + for (const r of rows) { + for (const b of boolFields) { + r[b] = r[b] === 1 + } + } + return dbToObject(rows) + } + + async put(args) { + if (!args.id) return false + const id = args.id + delete args.id + // Mysql.debug(1) + const r = await Mysql.execute( + ...Mysql.update( + `nt_nameserver`, + `nt_nameserver_id=${id}`, + mapToDbColumn(args, nsDbMap), + ), + ) + // console.log(r) + return r.changedRows === 1 + } + + async delete(args) { + await Mysql.execute( + `UPDATE nt_nameserver SET deleted=? WHERE nt_nameserver_id=?`, + [args.deleted ?? 1, args.id], + ) + return true + } + + async destroy(args) { + return await Mysql.execute( + ...Mysql.delete(`nt_nameserver`, { nt_nameserver_id: args.id }), + ) + } +} + +export default new Nameserver() + +function dbToObject(rows) { + for (const row of rows) { + for (const f of [ + 'description', + 'address6', + 'remote_login', + 'datadir', + 'logdir', + 'export_status', + ]) { + if ([undefined, null].includes(row[f])) row[f] = '' + } + for (const f of ['export']) { + for (const p of ['type', 'interval', 'serials', 'status']) { + if (row[`${f}_${p}`] !== undefined) { + if (row[f] === undefined) row[f] = {} + row[f][p] = row[`${f}_${p}`] + delete row[`${f}_${p}`] + } + } + } + } + return rows +} + +function objectToDb(row) { + row = JSON.parse(JSON.stringify(row)) // don't mutate the original + + for (const f of ['export']) { + for (const p of ['interval', 'serials', 'status']) { + if (row[f] === undefined) continue + if (row[f][p] === undefined) continue + row[`${f}_${p}`] = row[f][p] + delete row[f][p] + } + delete row[f] + } + return row +} diff --git a/lib/nameserver.test.js b/lib/nameserver.test.js new file mode 100644 index 0000000..7684348 --- /dev/null +++ b/lib/nameserver.test.js @@ -0,0 +1,46 @@ +import assert from 'node:assert/strict' +import { describe, it, after, before } from 'node:test' + +import Nameserver from './nameserver.js' + +import testCase from './test/nameserver.json' with { type: 'json' } + +before(async () => { + await Nameserver.destroy({ id: testCase.id }) + await Nameserver.create(testCase) +}) + +after(async () => { + await Nameserver.destroy({ id: testCase.id }) + Nameserver.mysql.disconnect() +}) + +describe('nameserver', function () { + it('gets nameserver by id', async () => { + const g = await Nameserver.get({ id: testCase.id }) + assert.deepEqual(g[0], testCase) + }) + + it('gets nameserver by name', async () => { + const g = await Nameserver.get({ name: testCase.name }) + assert.deepEqual(g[0], testCase) + }) + + it('changes a nameserver', async () => { + assert.ok( + await Nameserver.put({ id: testCase.id, name: 'b.ns.example.com.' }), + ) + const ns = await Nameserver.get({ id: testCase.id }) + assert.deepEqual(ns[0].name, 'b.ns.example.com.') + assert.ok(await Nameserver.put({ id: testCase.id, name: testCase.name })) + }) + + it('deletes a nameserver', async () => { + assert.ok(await Nameserver.delete({ id: testCase.id })) + let g = await Nameserver.get({ id: testCase.id, deleted: 1 }) + assert.equal(g[0]?.deleted, true) + await Nameserver.delete({ id: testCase.id, deleted: 0 }) // restore + g = await Nameserver.get({ id: testCase.id }) + assert.equal(g[0].deleted, false) + }) +}) diff --git a/lib/test/nameserver.json b/lib/test/nameserver.json new file mode 100644 index 0000000..6888ab9 --- /dev/null +++ b/lib/test/nameserver.json @@ -0,0 +1,19 @@ +{ + "id": 4096, + "gid": 4096, + "name": "a.ns.example.com.", + "description": "", + "address": "1.2.3.4", + "address6": "2001:DB8::1", + "remote_login": "nsd", + "logdir": "/foo", + "datadir": "/bar", + "export": { + "interval": 0, + "serials": true, + "status": "last run:03-05 15:25
last cp :09-20 12:59", + "type": "NSD" + }, + "ttl": 3600, + "deleted": false +} diff --git a/lib/util.js b/lib/util.js index cb06b11..469b2eb 100644 --- a/lib/util.js +++ b/lib/util.js @@ -24,16 +24,15 @@ const meta = { } function mapToDbColumn(args, maps) { - // create an instance, so we don't mangle the original args - const newArgs = JSON.parse(JSON.stringify(args)) + args = JSON.parse(JSON.stringify(args)) // don't mutate the original for (const [key, val] of Object.entries(maps)) { - if (newArgs[key] !== undefined) { - newArgs[val] = newArgs[key] - delete newArgs[key] + if (args[key] !== undefined) { + args[val] = args[key] + delete args[key] } } - return newArgs + return args } export { setEnv, meta, mapToDbColumn } diff --git a/package.json b/package.json index 0d79d33..9e20c74 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@nictool/api", - "version": "3.0.0-alpha.3", + "version": "3.0.0-alpha.4", "description": "NicTool API", "main": "index.js", "type": "module", @@ -43,7 +43,7 @@ "@hapi/hoek": "^11.0.4", "@hapi/inert": "^7.1.0", "@hapi/vision": "^7.0.3", - "@nictool/validate": "^0.7.4", + "@nictool/validate": "^0.8.0", "hapi-swagger": "^17.2.1", "mysql2": "^3.9.2", "qs": "^6.11.2", diff --git a/routes/group.js b/routes/group.js index ffdbbaf..58f63f4 100644 --- a/routes/group.js +++ b/routes/group.js @@ -9,8 +9,11 @@ function GroupRoutes(server) { method: 'GET', path: '/group/{id}', options: { + validate: { + query: validate.group.GET_req, + }, response: { - schema: validate.group.GET, + schema: validate.group.GET_res, }, tags: ['api'], }, @@ -50,15 +53,12 @@ function GroupRoutes(server) { payload: validate.group.POST, }, response: { - schema: validate.group.GET, + schema: validate.group.GET_res, }, tags: ['api'], }, handler: async (request, h) => { const gid = await Group.create(request.payload) - if (!gid) { - console.log(`POST /group oops`) // TODO - } const groups = await Group.get({ id: gid }) @@ -77,13 +77,16 @@ function GroupRoutes(server) { method: 'DELETE', path: '/group/{id}', options: { + validate: { + query: validate.group.DELETE, + }, response: { - schema: validate.group.GET, + schema: validate.group.GET_res, }, tags: ['api'], }, handler: async (request, h) => { - const groups = await Group.get(request.params) + const groups = await Group.get({ id: parseInt(request.params.id, 10) }) /* c8 ignore next 10 */ if (groups.length !== 1) { return h @@ -96,8 +99,7 @@ function GroupRoutes(server) { .code(204) } - const action = request.query.destroy === 'true' ? 'destroy' : 'delete' - await Group[action]({ id: groups[0].id }) + await Group.delete({ id: groups[0].id }) delete groups[0].gid return h diff --git a/routes/group.test.js b/routes/group.test.js index 2f69a17..12d8a58 100644 --- a/routes/group.test.js +++ b/routes/group.test.js @@ -9,6 +9,7 @@ import groupCase from './test/group.json' with { type: 'json' } import userCase from './test/user.json' with { type: 'json' } let server +const case2Id = 4094 before(async () => { server = await init() @@ -17,7 +18,8 @@ before(async () => { }) after(async () => { - await server.stop() + await Group.destroy({ id: case2Id }) + server.stop() }) describe('group routes', () => { @@ -45,11 +47,9 @@ describe('group routes', () => { }, }) // console.log(res.result) - assert.equal(res.statusCode, 200) + assert.ok([200, 204].includes(res.statusCode)) }) - const case2Id = 4094 - it('POST /group', async () => { const testCase = JSON.parse(JSON.stringify(groupCase)) testCase.id = case2Id // make it unique @@ -78,7 +78,7 @@ describe('group routes', () => { }, }) // console.log(res.result) - assert.equal(res.statusCode, 200) + assert.ok([200, 204].includes(res.statusCode)) }) it(`DELETE /group/${case2Id}`, async () => { @@ -108,25 +108,13 @@ describe('group routes', () => { it(`GET /group/${case2Id} (deleted)`, async () => { const res = await server.inject({ method: 'GET', - url: `/group/${case2Id}?deleted=1`, + url: `/group/${case2Id}?deleted=true`, headers: { Cookie: sessionCookie, }, }) // console.log(res.result) - assert.equal(res.statusCode, 200) - }) - - it(`DELETE /group/${case2Id}`, async () => { - const res = await server.inject({ - method: 'DELETE', - url: `/group/${case2Id}?destroy=true`, - headers: { - Cookie: sessionCookie, - }, - }) - // console.log(res.result) - assert.equal(res.statusCode, 200) + assert.ok([200, 204].includes(res.statusCode)) }) it('DELETE /session', async () => { diff --git a/routes/index.js b/routes/index.js index 9cdcc08..af0e120 100644 --- a/routes/index.js +++ b/routes/index.js @@ -20,6 +20,7 @@ import GroupRoutes from './group.js' import { User, UserRoutes } from './user.js' import { Session, SessionRoutes } from './session.js' import { PermissionRoutes } from './permission.js' +import { NameserverRoutes } from './nameserver.js' let server @@ -84,6 +85,7 @@ async function setup() { UserRoutes(server) SessionRoutes(server) PermissionRoutes(server) + NameserverRoutes(server) server.route({ method: '*', diff --git a/routes/nameserver.js b/routes/nameserver.js new file mode 100644 index 0000000..bc792e6 --- /dev/null +++ b/routes/nameserver.js @@ -0,0 +1,117 @@ +import validate from '@nictool/validate' + +import Nameserver from '../lib/nameserver.js' +import { meta } from '../lib/util.js' + +function NameserverRoutes(server) { + server.route([ + { + method: 'GET', + path: '/nameserver/{id}', + options: { + validate: { + query: validate.nameserver.GET_req, + }, + response: { + schema: validate.nameserver.GET_res, + }, + tags: ['api'], + }, + handler: async (request, h) => { + const getArgs = { + deleted: request.query.deleted === true ? 1 : 0, + id: parseInt(request.params.id, 10), + } + + const nameservers = await Nameserver.get(getArgs) + + return h + .response({ + nameserver: nameservers[0], + meta: { + api: meta.api, + msg: `here's your nameserver`, + }, + }) + .code(200) + }, + }, + { + method: 'POST', + path: '/nameserver', + options: { + validate: { + payload: validate.nameserver.POST, + }, + response: { + schema: validate.nameserver.GET_res, + }, + tags: ['api'], + }, + handler: async (request, h) => { + const id = await Nameserver.create(request.payload) + + const nameservers = await Nameserver.get({ id }) + + return h + .response({ + nameserver: nameservers[0], + meta: { + api: meta.api, + msg: `the nameserver was created`, + }, + }) + .code(201) + }, + }, + { + method: 'DELETE', + path: '/nameserver/{id}', + options: { + validate: { + query: validate.nameserver.DELETE, + }, + response: { + schema: validate.nameserver.GET_res, + }, + tags: ['api'], + }, + handler: async (request, h) => { + const nameservers = await Nameserver.get({ + deleted: request.query.deleted === true ? 1 : 0, + id: parseInt(request.params.id, 10), + }) + + if (nameservers.length === 0) { + return h + .response({ + meta: { + api: meta.api, + msg: `I couldn't find that nameserver`, + }, + }) + .code(404) + } + + await Nameserver.delete({ + id: nameservers[0].id, + deleted: 1, + }) + + return h + .response({ + nameserver: nameservers[0], + meta: { + api: meta.api, + msg: `I deleted that nameserver`, + }, + }) + .code(200) + }, + }, + ]) +} + +export default NameserverRoutes + +export { Nameserver, NameserverRoutes } diff --git a/routes/nameserver.test.js b/routes/nameserver.test.js new file mode 100644 index 0000000..c02499a --- /dev/null +++ b/routes/nameserver.test.js @@ -0,0 +1,150 @@ +import assert from 'node:assert/strict' +import { describe, it, before, after } from 'node:test' + +import { init } from './index.js' +import Group from '../lib/group.js' +import User from '../lib/user.js' +import Nameserver from '../lib/nameserver.js' + +import groupCase from './test/group.json' with { type: 'json' } +import userCase from './test/user.json' with { type: 'json' } +import nsCase from './test/nameserver.json' with { type: 'json' } + +let server +let case2Id = 4094 + +before(async () => { + await Nameserver.destroy({ id: case2Id }) + await Group.create(groupCase) + await User.create(userCase) + await Nameserver.create(nsCase) + server = await init() +}) + +after(async () => { + await Nameserver.destroy({ id: case2Id }) + server.stop() +}) + +describe('nameserver routes', () => { + let sessionCookie + + it('POST /session establishes a session', async () => { + const res = await server.inject({ + method: 'POST', + url: '/session', + payload: { + username: `${userCase.username}@${groupCase.name}`, + password: userCase.password, + }, + }) + assert.ok(res.headers['set-cookie'][0]) + sessionCookie = res.headers['set-cookie'][0].split(';')[0] + }) + + it(`GET /nameserver/${nsCase.id}`, async () => { + const res = await server.inject({ + method: 'GET', + url: `/nameserver/${nsCase.id}`, + headers: { + Cookie: sessionCookie, + }, + }) + // console.log(res.result) + assert.equal(res.statusCode, 200) + assert.equal(res.result.nameserver.name, nsCase.name) + }) + + it(`POST /nameserver (${case2Id})`, async () => { + const testCase = JSON.parse(JSON.stringify(nsCase)) + testCase.id = case2Id // make it unique + testCase.gid = case2Id + testCase.name = 'c.ns.example.com.' + + const res = await server.inject({ + method: 'POST', + url: '/nameserver', + headers: { + Cookie: sessionCookie, + }, + payload: testCase, + }) + // console.log(res.result) + assert.equal(res.statusCode, 201) + assert.ok(res.result.nameserver.gid) + }) + + it(`GET /nameserver/${case2Id}`, async () => { + const res = await server.inject({ + method: 'GET', + url: `/nameserver/${case2Id}`, + headers: { + Cookie: sessionCookie, + }, + }) + // console.log(res.result) + assert.equal(res.statusCode, 200) + assert.ok(res.result.nameserver.gid) + }) + + it(`DELETE /nameserver/${case2Id}`, async () => { + const res = await server.inject({ + method: 'DELETE', + url: `/nameserver/${case2Id}`, + headers: { + Cookie: sessionCookie, + }, + }) + // console.log(res.result) + assert.equal(res.statusCode, 200) + }) + + it(`DELETE /nameserver/${case2Id}`, async () => { + const res = await server.inject({ + method: 'DELETE', + url: `/nameserver/${case2Id}`, + headers: { + Cookie: sessionCookie, + }, + }) + // console.log(res.result) + assert.equal(res.statusCode, 404) + }) + + it(`GET /nameserver/${case2Id}`, async () => { + const res = await server.inject({ + method: 'GET', + url: `/nameserver/${case2Id}`, + headers: { + Cookie: sessionCookie, + }, + }) + // console.log(res.result) + // assert.equal(res.statusCode, 200) + assert.equal(res.result.nameserver, undefined) + }) + + it(`GET /nameserver/${case2Id} (deleted)`, async () => { + const res = await server.inject({ + method: 'GET', + url: `/nameserver/${case2Id}?deleted=true`, + headers: { + Cookie: sessionCookie, + }, + }) + // console.log(res.result) + assert.equal(res.statusCode, 200) + assert.ok(res.result.nameserver) + }) + + it('DELETE /session', async () => { + const res = await server.inject({ + method: 'DELETE', + url: '/session', + headers: { + Cookie: sessionCookie, + }, + }) + assert.equal(res.statusCode, 200) + }) +}) diff --git a/routes/permission.js b/routes/permission.js index 78369d4..99fdbe9 100644 --- a/routes/permission.js +++ b/routes/permission.js @@ -10,10 +10,10 @@ function PermissionRoutes(server) { path: '/permission/{id}', options: { validate: { - query: validate.permission.v3, + query: validate.permission.GET_req, }, response: { - schema: validate.permission.GET, + schema: validate.permission.GET_res, }, tags: ['api'], }, @@ -44,15 +44,12 @@ function PermissionRoutes(server) { payload: validate.permission.POST, }, response: { - schema: validate.permission.GET, + schema: validate.permission.GET_res, }, tags: ['api'], }, handler: async (request, h) => { const pid = await Permission.create(request.payload) - if (!pid) { - console.log(`POST /permission oops`) // TODO - } const permission = await Permission.get({ id: pid }) @@ -75,7 +72,7 @@ function PermissionRoutes(server) { query: validate.permission.DELETE, }, response: { - schema: validate.permission.GET, + schema: validate.permission.GET_res, }, tags: ['api'], }, diff --git a/routes/permission.test.js b/routes/permission.test.js index f595b67..43b3ca9 100644 --- a/routes/permission.test.js +++ b/routes/permission.test.js @@ -11,6 +11,7 @@ import userCase from './test/user.json' with { type: 'json' } import permCase from './test/permission.json' with { type: 'json' } let server +let case2Id = 4094 before(async () => { server = await init() @@ -19,8 +20,6 @@ before(async () => { await Permission.create(permCase) }) -let case2Id = 4094 - after(async () => { Permission.destroy({ id: case2Id }) await server.stop() @@ -105,6 +104,18 @@ describe('permission routes', () => { assert.equal(res.statusCode, 200) }) + it(`DELETE /permission/${case2Id}`, async () => { + const res = await server.inject({ + method: 'DELETE', + url: `/permission/${case2Id}`, + headers: { + Cookie: sessionCookie, + }, + }) + // console.log(res.result) + assert.equal(res.statusCode, 404) + }) + it(`GET /permission/${case2Id}`, async () => { const res = await server.inject({ method: 'GET', diff --git a/routes/session.js b/routes/session.js index 46a6a09..ee2cea4 100644 --- a/routes/session.js +++ b/routes/session.js @@ -12,7 +12,7 @@ function SessionRoutes(server) { path: '/session', options: { response: { - schema: validate.session.GET, + schema: validate.session.GET_res, }, tags: ['api'], }, diff --git a/routes/test/nameserver.json b/routes/test/nameserver.json new file mode 100644 index 0000000..ee6237d --- /dev/null +++ b/routes/test/nameserver.json @@ -0,0 +1,19 @@ +{ + "id": 4095, + "gid": 4095, + "name": "b.ns.example.com.", + "description": "", + "address": "2.3.4.5", + "address6": "2001:DB8::2", + "remote_login": "nsd", + "logdir": "/foo", + "datadir": "/bar", + "export": { + "interval": 0, + "serials": true, + "status": "last run:03-05 15:25
last cp :09-20 12:59", + "type": "NSD" + }, + "ttl": 3600, + "deleted": false +} diff --git a/routes/user.js b/routes/user.js index 8a3e093..288cd66 100644 --- a/routes/user.js +++ b/routes/user.js @@ -9,8 +9,11 @@ function UserRoutes(server) { method: 'GET', path: '/user', options: { + validate: { + query: validate.user.GET_req, + }, response: { - schema: validate.user.GET, + schema: validate.user.GET_res, }, // tags: ['api'], }, @@ -35,16 +38,21 @@ function UserRoutes(server) { method: 'GET', path: '/user/{id}', options: { + validate: { + query: validate.user.GET_req, + }, response: { - schema: validate.user.GET, + schema: validate.user.GET_res, }, tags: ['api'], }, handler: async (request, h) => { + const users = await User.get({ deleted: request.query.deleted ?? 0, id: parseInt(request.params.id, 10), }) + if (users.length !== 1) { return h .response({ @@ -76,10 +84,10 @@ function UserRoutes(server) { path: '/user', options: { validate: { - payload: validate.user.userPOST, + payload: validate.user.POST, }, response: { - schema: validate.user.GET, + schema: validate.user.GET_res, }, tags: ['api'], }, @@ -109,8 +117,11 @@ function UserRoutes(server) { method: 'DELETE', path: '/user/{id}', options: { + validate: { + query: validate.user.DELETE, + }, response: { - schema: validate.user.GET, + schema: validate.user.GET_res, }, tags: ['api'], }, diff --git a/routes/user.test.js b/routes/user.test.js index 32829a3..27f541e 100644 --- a/routes/user.test.js +++ b/routes/user.test.js @@ -122,7 +122,7 @@ describe('user routes', () => { it(`GET /user/${userId2}?deleted=1`, async () => { const res = await server.inject({ method: 'GET', - url: `/user/${userId2}?deleted=1`, + url: `/user/${userId2}?deleted=true`, headers: { Cookie: sessionCookie, }, diff --git a/test.js b/test.js index 27ab6a4..cba2bd4 100644 --- a/test.js +++ b/test.js @@ -6,11 +6,13 @@ import Group from './lib/group.js' import User from './lib/user.js' import Session from './lib/session.js' import Permission from './lib/permission.js' +import Nameserver from './lib/nameserver.js' import groupCase from './lib/test/group.json' with { type: 'json' } import userCase from './lib/test/user.json' with { type: 'json' } import groupCaseR from './routes/test/group.json' with { type: 'json' } import userCaseR from './routes/test/user.json' with { type: 'json' } +import nsCaseR from './routes/test/nameserver.json' with { type: 'json' } switch (process.argv[2]) { case 'setup': @@ -26,22 +28,14 @@ switch (process.argv[2]) { } async function setup() { - await createTestGroup() - await createTestUser() - // await createTestSession() - await User.mysql.disconnect() - await Group.mysql.disconnect() - process.exit(0) -} - -async function createTestGroup() { await Group.create(groupCase) await Group.create(groupCaseR) -} - -async function createTestUser() { await User.create(userCase) await User.create(userCaseR) + // await createTestSession() + await User.mysql.disconnect() + await Group.mysql.disconnect() + process.exit(0) } // async function createTestSession() { @@ -53,30 +47,16 @@ async function createTestUser() { // } async function teardown() { - await destroyTestSession() - await destroyTestUser() - await destroyTestGroup() - await destroyTestPermission() + await Nameserver.destroy({ id: nsCaseR.id }) + await Nameserver.destroy({ id: nsCaseR.id - 1 }) + await Permission.destroy({ id: userCase.id }) + await Permission.destroy({ id: userCase.id - 1 }) + await Session.delete({ nt_user_id: userCase.id }) + await User.destroy({ id: userCase.id }) + await User.destroy({ id: userCaseR.id }) + await Group.destroy({ id: groupCase.id }) + await Group.destroy({ id: groupCaseR.id }) await User.mysql.disconnect() await Group.mysql.disconnect() process.exit(0) } - -async function destroyTestGroup() { - await Group.destroy({ id: groupCase.id }) - await Group.destroy({ id: groupCaseR.id }) -} - -async function destroyTestUser() { - await User.destroy({ id: userCase.id }) - await User.destroy({ id: userCaseR.id }) -} - -async function destroyTestSession() { - await Session.delete({ nt_user_id: userCase.id }) -} - -async function destroyTestPermission() { - await Permission.destroy({ id: userCase.id }) - await Permission.destroy({ id: userCase.id - 1 }) -} diff --git a/test.sh b/test.sh index f3edafe..1feccad 100755 --- a/test.sh +++ b/test.sh @@ -1,10 +1,19 @@ #!/bin/sh +set -eu + NODE="node --no-warnings=ExperimentalWarning" $NODE test.js teardown $NODE test.js setup -if [ "$1" = "watch" ]; then +cleanup() { + echo "cleaning DB objects" + $NODE test.js teardown +} + +trap cleanup EXIT 1 2 3 6 + +if [ $# -ge 1 ] && [ "$1" = "watch" ]; then $NODE --test --watch else # if [ -n "$GITHUB_WORKFLOW" ]; then @@ -16,5 +25,3 @@ else fi # npx mocha --exit --no-warnings=ExperimentalWarning lib/*.test.js routes/*.test.js - -$NODE test.js teardown