-
david.bauer authored
- Unit and Integration tests now use "inject" instead of starting a server and using supertest. - Add Coverage Reports and "test:dev" mode. This enables a mocha --watch like workflow using nodemon, as --watch does not work with esm modules. - Reorganized and renamed files and functions
david.bauer authored- Unit and Integration tests now use "inject" instead of starting a server and using supertest. - Add Coverage Reports and "test:dev" mode. This enables a mocha --watch like workflow using nodemon, as --watch does not work with esm modules. - Reorganized and renamed files and functions
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
util.js 3.19 KiB
import * as td from 'testdouble'
import { register } from 'prom-client'
import RedisMock from 'ioredis-mock'
import zlib from 'node:zlib'
import yaml from 'js-yaml'
import fastify from 'fastify'
import autoLoad from '@fastify/autoload'
import sensible from '@fastify/sensible'
import urlData from '@fastify/url-data'
import formbody from '@fastify/formbody'
import { fileURLToPath } from 'node:url'
import { dirname, join } from 'node:path'
const __filename = fileURLToPath(import.meta.url)
const __dirname = dirname(__filename)
export function generateSimpleViteManifest (mapping) {
const viteManifest = {}
for (const [file, value] of Object.entries(mapping)) {
viteManifest[file] = {
file,
meta: typeof value === 'string' ? { manifests: [{ namespace: value }] } : {}
}
if (typeof value === 'object') Object.assign(viteManifest[file], value)
}
return viteManifest
}
export function mockConfig (obj = {}) {
td.replaceEsm('fs/promises', {}, {
readFile () {
return yaml.dump(obj)
}
})
}
export function mockFetch (servers = {}) {
td.replace(global, 'fetch', async function ({ origin, pathname }, ...args) {
const response = servers[origin]?.[pathname]
if (response === undefined) return new Response('', { status: 404 })
if (response instanceof Function) return response.apply(this, arguments)
if (typeof response === 'object') {
return new Response(JSON.stringify(response), {
status: 200,
headers: {
'Content-Type': 'application/json'
}
})
}
return new Response(response, { status: 200 })
})
}
export function mockRedis (data = {}, isEnabled = true) {
const mock = {
isReady () { return Promise.resolve() },
isEnabled () { return isEnabled },
client: new RedisMock(data),
pubClient: new RedisMock(),
subClient: new RedisMock()
}
td.replaceEsm('../src/redis.js', mock)
return mock
}
export async function injectApp () {
register.clear()
const { configMap } = await import('../src/config_map.js')
const { getLatestVersion } = await import('../src/version.js')
await configMap.load()
await getLatestVersion()
const app = fastify({ disableRequestLogging: true })
app.register(sensible)
app.register(urlData)
app.register(formbody)
app.register(autoLoad, { dir: join(__dirname, '../src/routes'), prefix: process.env.APP_ROOT, autoHooks: true })
return app
}
export async function brotliParser (res, cb) {
const brotli = zlib.createBrotliDecompress()
let buffer = Buffer.from('')
res.pipe(brotli)
brotli.on('data', chunk => (buffer = Buffer.concat([buffer, chunk])))
brotli.on('end', () => {
let result = buffer.toString()
if (res.headers['content-type'].startsWith('application/json')) {
result = JSON.parse(result)
}
cb(null, result)
})
}
export async function decompressBrotli (encodedData) {
const compressedData = Buffer.from(encodedData)
return new Promise((resolve, reject) => {
zlib.brotliDecompress(compressedData, (err, data) => {
if (err) reject(err)
else resolve(JSON.parse(data.toString('utf8')))
})
})
}
export async function wait (timeout) {
return new Promise(resolve => setTimeout(resolve, timeout))
}