1
0
Files
record-shop/server/test/helpers.ts

75 lines
2.8 KiB
TypeScript

import { mkdtempSync } from 'node:fs'
import { tmpdir } from 'node:os'
import path from 'node:path'
import { openDatabase, type DB } from '../src/db.js'
import { buildApp } from '../src/app.js'
import type { Config } from '../src/config.js'
import type { FastifyInstance } from 'fastify'
export function testConfig(): Config {
// artworkDir must be a real writable directory (cached images land there)
const artworkDir = mkdtempSync(path.join(tmpdir(), 'rs-art-'))
// backupsDir must be a real writable directory (backup files land there)
const backupsDir = mkdtempSync(path.join(tmpdir(), 'rs-bak-'))
// dataDir must be a real writable directory (release-cache payloads land there)
const dataDir = mkdtempSync(path.join(tmpdir(), 'rs-data-'))
return {
dataDir,
artworkDir,
backupsDir,
dbPath: ':memory:',
port: 0,
sessionSecret: 'test-secret-test-secret-test-secret-1234',
}
}
export async function buildTestApp(fetchImpl?: typeof fetch): Promise<FastifyInstance> {
const db = openDatabase(':memory:')
return buildApp({ db, config: testConfig(), fetchImpl })
}
export async function buildTestAppWithDb(db: DB, fetchImpl?: typeof fetch): Promise<FastifyInstance> {
return buildApp({ db, config: testConfig(), fetchImpl })
}
/** Runs /api/setup to create admin 'admin' / 'adminpass123'. Returns session token value. */
export async function setupAdmin(app: FastifyInstance): Promise<string> {
const res = await app.inject({
method: 'POST',
url: '/api/setup',
payload: { username: 'admin', password: 'adminpass123' },
})
if (res.statusCode !== 200) throw new Error(`setup failed: ${res.body}`)
return getCookie(res)
}
/** Creates and logs in a non-admin user via /api/users + /api/login. Returns session token value. */
export async function loginAs(
app: FastifyInstance,
adminToken: string,
username: string,
password: string
): Promise<string> {
const created = await app.inject({
method: 'POST',
url: '/api/users',
...auth(adminToken),
payload: { username, password },
})
if (created.statusCode !== 200) throw new Error(`user create failed: ${created.body}`)
const login = await app.inject({ method: 'POST', url: '/api/login', payload: { username, password } })
if (login.statusCode !== 200) throw new Error(`login failed: ${login.body}`)
return getCookie(login)
}
export function getCookie(res: { cookies: { name: string; value: string }[] }): string {
const cookie = res.cookies.find((c) => c.name === 'rs_session')
if (!cookie) throw new Error('no rs_session cookie in response')
return cookie.value
}
/** inject option spread for an authenticated request: `app.inject({ ..., ...auth(token) })` */
export function auth(sessionToken: string): { cookies: Record<string, string> } {
return { cookies: { rs_session: sessionToken } }
}