Skip to content

Commit

Permalink
test: move Fastify plugin tests to node:test and node:assert (#635)
Browse files Browse the repository at this point in the history
This test-only change drops Brittle from our Fastify plugin tests and
replaces them with `node:test` and `node:assert`.
  • Loading branch information
EvanHahn authored May 16, 2024
1 parent 1bdcbf8 commit 5e7c546
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 93 deletions.
73 changes: 42 additions & 31 deletions tests/fastify-plugins/blobs.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// @ts-check
import { randomBytes } from 'node:crypto'
import test from 'brittle'
import test from 'node:test'
import assert from 'node:assert/strict'
import { readdirSync } from 'fs'
import { readFile } from 'fs/promises'
import path from 'path'
Expand All @@ -11,12 +12,14 @@ import { projectKeyToPublicId } from '../../src/utils.js'
import { createBlobStore } from '../helpers/blob-store.js'
import { waitForCores, replicate } from '../helpers/core-manager.js'

test('Plugin throws error if missing getBlobStore option', async (t) => {
test('Plugin throws error if missing getBlobStore option', async () => {
const server = fastify()
await t.exception(() => server.register(BlobServerPlugin))
await assert.rejects(async () => {
await server.register(BlobServerPlugin)
})
})

test('Plugin handles prefix option properly', async (t) => {
test('Plugin handles prefix option properly', async () => {
const prefix = '/blobs'
const { data, server, projectPublicId } = await setup({ prefix })

Expand All @@ -30,11 +33,11 @@ test('Plugin handles prefix option properly', async (t) => {
}),
})

t.is(res.statusCode, 200, 'request successful')
assert.equal(res.statusCode, 200, 'request successful')
}
})

test('Unsupported blob type and variant params are handled properly', async (t) => {
test('Unsupported blob type and variant params are handled properly', async () => {
const { data, server, projectPublicId } = await setup()

for (const { blobId } of data) {
Expand All @@ -47,8 +50,8 @@ test('Unsupported blob type and variant params are handled properly', async (t)
}),
})

t.is(unsupportedVariantRes.statusCode, 400)
t.is(unsupportedVariantRes.json().code, 'FST_ERR_VALIDATION')
assert.equal(unsupportedVariantRes.statusCode, 400)
assert.equal(unsupportedVariantRes.json().code, 'FST_ERR_VALIDATION')

const unsupportedTypeRes = await server.inject({
method: 'GET',
Expand All @@ -59,12 +62,12 @@ test('Unsupported blob type and variant params are handled properly', async (t)
}),
})

t.is(unsupportedTypeRes.statusCode, 400)
t.is(unsupportedTypeRes.json().code, 'FST_ERR_VALIDATION')
assert.equal(unsupportedTypeRes.statusCode, 400)
assert.equal(unsupportedTypeRes.json().code, 'FST_ERR_VALIDATION')
}
})

test('Invalid variant-type combination returns error', async (t) => {
test('Invalid variant-type combination returns error', async () => {
const { server, projectPublicId } = await setup()

const url = buildRouteUrl({
Expand All @@ -77,11 +80,11 @@ test('Invalid variant-type combination returns error', async (t) => {

const response = await server.inject({ method: 'GET', url })

t.is(response.statusCode, 400)
t.ok(response.json().message.startsWith('Unsupported variant'))
assert.equal(response.statusCode, 400)
assert(response.json().message.startsWith('Unsupported variant'))
})

test('Incorrect project public id returns 404', async (t) => {
test('Incorrect project public id returns 404', async () => {
const { data, server } = await setup()

const incorrectProjectPublicId = projectKeyToPublicId(randomBytes(32))
Expand All @@ -95,11 +98,11 @@ test('Incorrect project public id returns 404', async (t) => {
}),
})

t.is(incorrectProjectPublicIdRes.statusCode, 404)
assert.equal(incorrectProjectPublicIdRes.statusCode, 404)
}
})

test('Incorrectly formatted project public id returns 400', async (t) => {
test('Incorrectly formatted project public id returns 400', async () => {
const { data, server } = await setup()

const hexString = randomBytes(32).toString('hex')
Expand All @@ -113,11 +116,11 @@ test('Incorrectly formatted project public id returns 400', async (t) => {
}),
})

t.is(incorrectProjectPublicIdRes.statusCode, 400)
assert.equal(incorrectProjectPublicIdRes.statusCode, 400)
}
})

test('Missing blob name or variant returns 404', async (t) => {
test('Missing blob name or variant returns 404', async () => {
const { data, server, projectPublicId } = await setup()

for (const { blobId } of data) {
Expand All @@ -130,7 +133,7 @@ test('Missing blob name or variant returns 404', async (t) => {
}),
})

t.is(nameMismatchRes.statusCode, 404)
assert.equal(nameMismatchRes.statusCode, 404)

const variantMismatchRes = await server.inject({
method: 'GET',
Expand All @@ -141,11 +144,11 @@ test('Missing blob name or variant returns 404', async (t) => {
}),
})

t.is(variantMismatchRes.statusCode, 404)
assert.equal(variantMismatchRes.statusCode, 404)
}
})

test('GET photo returns correct blob payload', async (t) => {
test('GET photo returns correct blob payload', async () => {
const { data, server, projectPublicId } = await setup()

for (const { blobId, image } of data) {
Expand All @@ -157,11 +160,11 @@ test('GET photo returns correct blob payload', async (t) => {
}),
})

t.alike(res.rawPayload, image.data, 'should be equal')
assert.deepEqual(res.rawPayload, image.data, 'should be equal')
}
})

test('GET photo returns inferred content header if metadata is not found', async (t) => {
test('GET photo returns inferred content header if metadata is not found', async () => {
const { data, server, projectPublicId } = await setup()

for (const { blobId, image } of data) {
Expand All @@ -176,11 +179,15 @@ test('GET photo returns inferred content header if metadata is not found', async
const expectedContentHeader =
getImageMimeType(image.ext) || 'application/octet-stream'

t.is(res.headers['content-type'], expectedContentHeader, 'should be equal')
assert.equal(
res.headers['content-type'],
expectedContentHeader,
'should be equal'
)
}
})

test('GET photo uses mime type from metadata if found', async (t) => {
test('GET photo uses mime type from metadata if found', async () => {
const { data, server, projectPublicId, blobStore } = await setup()

for (const { blobId, image } of data) {
Expand All @@ -204,11 +211,15 @@ test('GET photo uses mime type from metadata if found', async (t) => {
? metadata.mimeType
: 'application/octet-stream'

t.is(res.headers['content-type'], expectedContentHeader, 'should be equal')
assert.equal(
res.headers['content-type'],
expectedContentHeader,
'should be equal'
)
}
})

test('GET photo returns 404 when trying to get non-replicated blob', async (t) => {
test('GET photo returns 404 when trying to get non-replicated blob', async () => {
const projectKey = randomBytes(32)

const {
Expand Down Expand Up @@ -242,10 +253,10 @@ test('GET photo returns 404 when trying to get non-replicated blob', async (t) =
url: buildRouteUrl({ ...blobId, projectPublicId }),
})

t.is(res.statusCode, 404)
assert.equal(res.statusCode, 404)
})

test('GET photo returns 404 when trying to get non-existent blob', async (t) => {
test('GET photo returns 404 when trying to get non-existent blob', async () => {
const projectKey = randomBytes(32)

const { projectPublicId, blobStore } = await setup({ projectKey })
Expand All @@ -271,7 +282,7 @@ test('GET photo returns 404 when trying to get non-existent blob', async (t) =>
}),
})

t.is(res.statusCode, 404)
assert.equal(res.statusCode, 404)
}

const driveId = await blobStore.put(blobId, expected)
Expand All @@ -284,7 +295,7 @@ test('GET photo returns 404 when trying to get non-existent blob', async (t) =>
url: buildRouteUrl({ ...blobId, projectPublicId, driveId }),
})

t.is(res.statusCode, 404)
assert.equal(res.statusCode, 404)
}
})

Expand Down
23 changes: 12 additions & 11 deletions tests/fastify-plugins/icons.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
// @ts-check
import { test } from 'brittle'
import test from 'node:test'
import assert from 'node:assert/strict'
import { randomBytes } from 'crypto'
import fastify from 'fastify'

import IconServerPlugin from '../../src/fastify-plugins/icons.js'
import { projectKeyToPublicId } from '../../src/utils.js'

test('Plugin throws error if missing getProject option', async (t) => {
test('Plugin throws error if missing getProject option', async () => {
const server = fastify()
await t.exception(() => server.register(IconServerPlugin))
await assert.rejects(async () => {
await server.register(IconServerPlugin)
})
})

test('Plugin handles prefix option properly', async (t) => {
test('Plugin handles prefix option properly', async () => {
const prefix = 'icons'

const server = fastify()
Expand All @@ -33,10 +36,10 @@ test('Plugin handles prefix option properly', async (t) => {
})}`,
})

t.not(response.statusCode, 404, 'returns non-404 status code')
assert.notEqual(response.statusCode, 404, 'returns non-404 status code')
})

test('url param validation', async (t) => {
test('url param validation', async () => {
const server = fastify()

server.register(IconServerPlugin, {
Expand Down Expand Up @@ -99,16 +102,14 @@ test('url param validation', async (t) => {
]

await Promise.all(
fixtures.map(async ([name, input]) => {
fixtures.map(async ([_, input]) => {
const response = await server.inject({
method: 'GET',
url: buildIconUrl(input),
})

t.comment(name)

t.is(response.statusCode, 400, 'returns expected status code')
t.is(
assert.equal(response.statusCode, 400, 'returns expected status code')
assert.equal(
response.json().code,
'FST_ERR_VALIDATION',
'error is validation error'
Expand Down
33 changes: 17 additions & 16 deletions tests/fastify-plugins/maps.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { test } from 'brittle'
import test from 'node:test'
import assert from 'node:assert/strict'
import path from 'node:path'
import Fastify from 'fastify'
import { MockAgent, setGlobalDispatcher } from 'undici'
Expand Down Expand Up @@ -28,7 +29,7 @@ setupFetchMock()
test('fails to register when dependent plugins are not registered', async (t) => {
const server = setup(t)

await t.exception(async () => {
await assert.rejects(async () => {
await server.register(MapServerPlugin)
}, 'fails to register if dependencies are not registered')
})
Expand Down Expand Up @@ -56,12 +57,12 @@ test('prefix opt is handled correctly', async (t) => {
url: '/style.json',
})

t.is(response.statusCode, 404, 'endpoint missing at root prefix')
assert.equal(response.statusCode, 404, 'endpoint missing at root prefix')
}

{
// TODO: Use inject approach when necessary fixtures are set up
t.ok(
assert(
server.hasRoute({
method: 'GET',
url: '/maps/style.json',
Expand Down Expand Up @@ -89,11 +90,11 @@ test('mapeoMaps decorator context', async (t) => {

const address = await server.listen()

t.ok(server.hasDecorator('mapeoMaps'), 'decorator added')
assert(server.hasDecorator('mapeoMaps'), 'decorator added')

t.test('mapeoMaps.getStyleJsonUrl()', async (st) => {
t.test('mapeoMaps.getStyleJsonUrl()', async () => {
const styleJsonUrl = await server.mapeoMaps.getStyleJsonUrl()
st.is(styleJsonUrl, new URL('/maps/style.json', address).href)
assert.equal(styleJsonUrl, new URL('/maps/style.json', address).href)
})
})

Expand All @@ -118,7 +119,7 @@ test('/style.json resolves style.json of local "default" static map when availab
url: '/style.json',
})

t.is(response.statusCode, 200)
assert.equal(response.statusCode, 200)
})

test('/style.json resolves online style.json when local static is not available', async (t) => {
Expand All @@ -145,9 +146,9 @@ test('/style.json resolves online style.json when local static is not available'
query: `?key=pk.abc-123`,
})

t.is(response.statusCode, 200)
assert.equal(response.statusCode, 200)

t.is(
assert.equal(
response.json().name,
// Based on the mapbox-outdoors-v12.json fixture
'Mapbox Outdoors',
Expand Down Expand Up @@ -182,8 +183,8 @@ test('defaultOnlineStyleUrl opt works', async (t) => {
query: `?key=abc-123`,
})

t.is(response.statusCode, 200)
t.is(
assert.equal(response.statusCode, 200)
assert.equal(
response.json().name,
// Based on the protomaps-dark.v2.json fixture
'[email protected] theme@dark',
Expand Down Expand Up @@ -214,17 +215,17 @@ test('/style.json resolves style.json of offline fallback map when static and on
// Omitting the `key` query param here to simulate not being able to get the online style.json
})

t.is(response.json().id, 'blank', 'gets fallback style.json')
t.is(response.statusCode, 200)
assert.equal(response.json().id, 'blank', 'gets fallback style.json')
assert.equal(response.statusCode, 200)
})

/**
* @param {import('brittle').TestInstance} t
* @param {import('node:test').TestContext} t
*/
function setup(t) {
const server = Fastify({ logger: false, forceCloseConnections: true })

t.teardown(async () => {
t.after(async () => {
await server.close()
})

Expand Down
Loading

0 comments on commit 5e7c546

Please sign in to comment.