Split mim-api into modular routes, refresh nav brand assets, and pin reusable validate workflow to Order-of-Hospitallers/miracles_in_motion@main. Co-authored-by: Cursor <cursoragent@cursor.com>
129 lines
4.7 KiB
JavaScript
129 lines
4.7 KiB
JavaScript
import { describe, it } from 'node:test'
|
|
import assert from 'node:assert/strict'
|
|
import fs from 'node:fs'
|
|
import os from 'node:os'
|
|
import path from 'node:path'
|
|
import { createApp, validateAssistance } from '../src/app.js'
|
|
|
|
describe('assistance validation shape', () => {
|
|
it('requires core fields', () => {
|
|
const errors = validateAssistance({})
|
|
assert.ok(errors.length > 0)
|
|
})
|
|
|
|
it('rejects honeypot', () => {
|
|
const errors = validateAssistance({ website: 'spam' })
|
|
assert.ok(errors.includes('spam detected'))
|
|
})
|
|
})
|
|
|
|
describe('admin auth and settings', () => {
|
|
it('logs in admin and updates stripe settings', async () => {
|
|
const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'mim-api-test-'))
|
|
const { app, AUTH_SECRET } = createApp({ dataDir: tmp, authSecret: 'test-secret', port: 0 })
|
|
const server = app.listen(0)
|
|
const { port } = server.address()
|
|
|
|
const loginRes = await fetch(`http://127.0.0.1:${port}/api/auth/login`, {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ email: 'admin@mim4u.org', password: 'demo123' }),
|
|
})
|
|
assert.equal(loginRes.status, 200)
|
|
const { token } = await loginRes.json()
|
|
assert.ok(token)
|
|
|
|
const settingsRes = await fetch(`http://127.0.0.1:${port}/api/admin/settings`, {
|
|
headers: { Authorization: `Bearer ${token}` },
|
|
})
|
|
assert.equal(settingsRes.status, 200)
|
|
|
|
const patchRes = await fetch(`http://127.0.0.1:${port}/api/admin/settings`, {
|
|
method: 'PATCH',
|
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({
|
|
donationsEnabled: true,
|
|
stripePublishableKey: 'pk_test_abc',
|
|
stripeSecretKey: 'sk_test_abc',
|
|
stripeWebhookSecret: 'whsec_test',
|
|
}),
|
|
})
|
|
assert.equal(patchRes.status, 200)
|
|
const patched = await patchRes.json()
|
|
assert.equal(patched.donationsEnabled, true)
|
|
assert.match(patched.stripeSecretKey, /…/)
|
|
|
|
const publicRes = await fetch(`http://127.0.0.1:${port}/api/public/config`)
|
|
const pub = await publicRes.json()
|
|
assert.equal(pub.stripeConfigured, true)
|
|
assert.equal(pub.stripePublishableKey, 'pk_test_abc')
|
|
|
|
server.close()
|
|
fs.rmSync(tmp, { recursive: true, force: true })
|
|
assert.ok(AUTH_SECRET)
|
|
})
|
|
})
|
|
|
|
describe('qr admin routes', () => {
|
|
it('reports qrcode-monkey as default provider', async () => {
|
|
const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'mim-api-qr-'))
|
|
const { app } = createApp({ dataDir: tmp, authSecret: 'test-secret', port: 0 })
|
|
const server = app.listen(0)
|
|
const { port } = server.address()
|
|
|
|
const loginRes = await fetch(`http://127.0.0.1:${port}/api/auth/login`, {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ email: 'admin@mim4u.org', password: 'demo123' }),
|
|
})
|
|
const { token } = await loginRes.json()
|
|
|
|
const statusRes = await fetch(`http://127.0.0.1:${port}/api/admin/qrcodes/status`, {
|
|
headers: { Authorization: `Bearer ${token}` },
|
|
})
|
|
assert.equal(statusRes.status, 200)
|
|
const status = await statusRes.json()
|
|
assert.equal(status.provider, 'qrcode-monkey')
|
|
assert.equal(status.configured, true)
|
|
assert.equal(status.dynamicTracking, false)
|
|
|
|
server.close()
|
|
fs.rmSync(tmp, { recursive: true, force: true })
|
|
})
|
|
})
|
|
describe('brand manifest', () => {
|
|
it('seeds and serves public brand manifest', async () => {
|
|
const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'mim-api-brand-'))
|
|
const { app } = createApp({ dataDir: tmp, authSecret: 'test-secret', port: 0 })
|
|
const server = app.listen(0)
|
|
const { port } = server.address()
|
|
|
|
const publicRes = await fetch(`http://127.0.0.1:${port}/api/public/brand`)
|
|
assert.equal(publicRes.status, 200)
|
|
const manifest = await publicRes.json()
|
|
assert.ok(manifest.groups?.length > 0)
|
|
assert.ok(manifest.colors?.length > 0)
|
|
|
|
const loginRes = await fetch(`http://127.0.0.1:${port}/api/auth/login`, {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ email: 'admin@mim4u.org', password: 'demo123' }),
|
|
})
|
|
const { token } = await loginRes.json()
|
|
|
|
const patchRes = await fetch(`http://127.0.0.1:${port}/api/admin/brand`, {
|
|
method: 'PATCH',
|
|
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ published: false }),
|
|
})
|
|
assert.equal(patchRes.status, 200)
|
|
|
|
const hidden = await fetch(`http://127.0.0.1:${port}/api/public/brand`)
|
|
const hiddenJson = await hidden.json()
|
|
assert.equal(hiddenJson.published, false)
|
|
|
|
server.close()
|
|
fs.rmSync(tmp, { recursive: true, force: true })
|
|
})
|
|
})
|