Skip to content

Commit

Permalink
add zone routes and tests (#32)
Browse files Browse the repository at this point in the history
* dnskey: fix test case
* test.sh: constrain test runner, so that it doesn't try running ./test.js
* rename test.js -> test-fixtures.js
* add zone routes and tests
  • Loading branch information
msimerson authored Nov 16, 2024
1 parent b38c5bf commit c739a73
Show file tree
Hide file tree
Showing 10 changed files with 299 additions and 14 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,8 @@ and if we peek inside the cookie jar:

We can see that our session cookie has been saved. Now we can make other requests to the API using that session cookie:

```
curl -b nt-session -X GET http://localhost:3000/user/4096 --header "Content-Type: application/json" | json_pp
```sh
curl -b nt-session -X GET http://localhost:3000/user/4096 --header "Content-Type: application/json" | json_pp
{
"group" : {
"id" : 4096
Expand Down
12 changes: 6 additions & 6 deletions lib/test/rrs/dnskey.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
{
"id": 4096,
"zid": 4096,
"owner": "mail.example.com.",
"owner": "example.com.",
"ttl": 86400,
"type": "CERT",
"cert type": "PGP",
"key tag": 0,
"algorithm": 0,
"certificate": "hexidecimalkeystring1"
"type": "DNSKEY",
"flags": 256,
"protocol": 3,
"algorithm": 5,
"publickey": "( AQPSKmynfzW4kyBv015MUG2DeIQ3 Cbl+BBZH4b/0PY1kxkmvHjcZc8no kfzj31GajIQKY+5CptLr3buXA10h WqTkF7H6RfoRqXQeogmMHfpftf6z Mv1LyBUgia7za6ZEzOJBOztyvhjL 742iU/TpPSEDhm2SNKLijfUppn1U aNvv4w== )"
}
3 changes: 2 additions & 1 deletion lib/zone_record.js
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ function unApplyMap(obj, map) {
}
}

// map of NicTool 2.0 fields to RR field names
function getMap(rrType) {
switch (rrType) {
case 'CAA':
Expand All @@ -236,7 +237,7 @@ function getMap(rrType) {
return { address: 'target' }
case 'DNSKEY':
return {
address: 'public key',
address: 'publickey',
weight: 'flags',
priority: 'protocol',
other: 'algorithm',
Expand Down
2 changes: 2 additions & 0 deletions routes/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { User, UserRoutes } from './user.js'
import { Session, SessionRoutes } from './session.js'
import { PermissionRoutes } from './permission.js'
import { NameserverRoutes } from './nameserver.js'
import { ZoneRoutes } from './zone.js'

let server

Expand Down Expand Up @@ -86,6 +87,7 @@ async function setup() {
SessionRoutes(server)
PermissionRoutes(server)
NameserverRoutes(server)
ZoneRoutes(server)

server.route({
method: '*',
Expand Down
15 changes: 15 additions & 0 deletions routes/test/zone.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"id": 4095,
"gid": 4095,
"zone": "route.example.com",
"mailaddr": "route-master.example.com.",
"description": "route test",
"serial": 20240306,
"refresh": 2,
"retry": 3,
"expire": 4,
"minimum": 5,
"ttl": 3601,
"location": "",
"last_publish": null
}
2 changes: 1 addition & 1 deletion routes/user.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ describe('user routes', () => {
assert.equal(res.statusCode, 200)
})

it(`GET /user/${userId2}`, async () => {
it(`GET /user/${userId2} (deleted)`, async () => {
const res = await server.inject({
method: 'GET',
url: `/user/${userId2}`,
Expand Down
117 changes: 117 additions & 0 deletions routes/zone.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import validate from '@nictool/validate'

import Zone from '../lib/zone.js'
import { meta } from '../lib/util.js'

function ZoneRoutes(server) {
server.route([
{
method: 'GET',
path: '/zone/{id}',
options: {
validate: {
query: validate.zone.GET_req,
},
response: {
schema: validate.zone.GET_res,
},
tags: ['api'],
},
handler: async (request, h) => {
const getArgs = {
deleted: request.query.deleted === true ? 1 : 0,
id: parseInt(request.params.id, 10),
}

const zones = await Zone.get(getArgs)

return h
.response({
zone: zones[0],
meta: {
api: meta.api,
msg: `here's your zone`,
},
})
.code(200)
},
},
{
method: 'POST',
path: '/zone',
options: {
validate: {
payload: validate.zone.POST,
},
response: {
schema: validate.zone.GET_res,
},
tags: ['api'],
},
handler: async (request, h) => {
const id = await Zone.create(request.payload)

const zones = await Zone.get({ id })

return h
.response({
zone: zones[0],
meta: {
api: meta.api,
msg: `the zone was created`,
},
})
.code(201)
},
},
{
method: 'DELETE',
path: '/zone/{id}',
options: {
validate: {
query: validate.zone.DELETE,
},
response: {
schema: validate.zone.GET_res,
},
tags: ['api'],
},
handler: async (request, h) => {
const zones = await Zone.get({
deleted: request.query.deleted === true ? 1 : 0,
id: parseInt(request.params.id, 10),
})

if (zones.length === 0) {
return h
.response({
meta: {
api: meta.api,
msg: `I couldn't find that zone`,
},
})
.code(404)
}

await Zone.delete({
id: zones[0].id,
deleted: 1,
})

return h
.response({
zone: zones[0],
meta: {
api: meta.api,
msg: `I deleted that zone`,
},
})
.code(200)
},
},
])
}

export default ZoneRoutes

export { Zone, ZoneRoutes }
150 changes: 150 additions & 0 deletions routes/zone.test.js
Original file line number Diff line number Diff line change
@@ -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 Zone from '../lib/zone.js'

import groupCase from './test/group.json' with { type: 'json' }
import userCase from './test/user.json' with { type: 'json' }
import nsCase from './test/zone.json' with { type: 'json' }

let server
let case2Id = 4094

before(async () => {
await Zone.destroy({ id: case2Id })
await Group.create(groupCase)
await User.create(userCase)
await Zone.create(nsCase)
server = await init()
})

after(async () => {
// await Zone.destroy({ id: case2Id })
server.stop()
})

describe('zone 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 /zone/${nsCase.id}`, async () => {
const res = await server.inject({
method: 'GET',
url: `/zone/${nsCase.id}`,
headers: {
Cookie: sessionCookie,
},
})
// console.log(res.result)
assert.equal(res.statusCode, 200)
assert.equal(res.result.zone.name, nsCase.name)
})

it(`POST /zone (${case2Id})`, async () => {
const testCase = JSON.parse(JSON.stringify(nsCase))
testCase.id = case2Id // make it unique
testCase.gid = case2Id
testCase.zone = 'route2.example.com.'

const res = await server.inject({
method: 'POST',
url: '/zone',
headers: {
Cookie: sessionCookie,
},
payload: testCase,
})
// console.log(res.result)
assert.equal(res.statusCode, 201)
assert.ok(res.result.zone.gid)
})

it(`GET /zone/${case2Id}`, async () => {
const res = await server.inject({
method: 'GET',
url: `/zone/${case2Id}`,
headers: {
Cookie: sessionCookie,
},
})
// console.log(res.result)
assert.equal(res.statusCode, 200)
assert.ok(res.result.zone.gid)
})

it(`DELETE /zone/${case2Id}`, async () => {
const res = await server.inject({
method: 'DELETE',
url: `/zone/${case2Id}`,
headers: {
Cookie: sessionCookie,
},
})
// console.log(res.result)
assert.equal(res.statusCode, 200)
})

it(`DELETE /zone/${case2Id}`, async () => {
const res = await server.inject({
method: 'DELETE',
url: `/zone/${case2Id}`,
headers: {
Cookie: sessionCookie,
},
})
// console.log(res.result)
assert.equal(res.statusCode, 404)
})

it(`GET /zone/${case2Id}`, async () => {
const res = await server.inject({
method: 'GET',
url: `/zone/${case2Id}`,
headers: {
Cookie: sessionCookie,
},
})
// console.log(res.result)
// assert.equal(res.statusCode, 200)
assert.equal(res.result.zone, undefined)
})

it(`GET /zone/${case2Id} (deleted)`, async () => {
const res = await server.inject({
method: 'GET',
url: `/zone/${case2Id}?deleted=true`,
headers: {
Cookie: sessionCookie,
},
})
// console.log(res.result)
assert.equal(res.statusCode, 200)
assert.equal(res?.result?.zone, undefined)
})

it('DELETE /session', async () => {
const res = await server.inject({
method: 'DELETE',
url: '/session',
headers: {
Cookie: sessionCookie,
},
})
assert.equal(res.statusCode, 200)
})
})
File renamed without changes.
8 changes: 4 additions & 4 deletions test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
set -eu

NODE="node --no-warnings=ExperimentalWarning"
$NODE test.js teardown
$NODE test.js setup
$NODE test-fixtures.js teardown
$NODE test-fixtures.js setup

cleanup() {
echo "cleaning DB objects"
$NODE test.js teardown
$NODE test-fixtures.js teardown
}

trap cleanup EXIT 1 2 3 6
Expand All @@ -20,7 +20,7 @@ else
# npm i --no-save node-test-github-reporter
# $NODE --test --test-reporter=node-test-github-reporter
# else
$NODE --test --test-reporter=spec
$NODE --test --test-reporter=spec lib/*.test.js routes/*.test.js
# fi
fi

Expand Down

0 comments on commit c739a73

Please sign in to comment.