import test from 'node:test'; import assert from 'node:assert/strict'; import { mkdtempSync } from 'node:fs'; import { tmpdir } from 'node:os'; import { join } from 'node:path'; import { createApp } from '../src/server.js'; async function setup() { const app = createApp({ dbPath: join(mkdtempSync(join(tmpdir(), 'updates-')), 'updates.sqlite'), adminToken: 'test-token' }); await new Promise(resolve => app.server.listen(0, resolve)); const port = app.server.address().port; const request = (path, options = {}) => fetch(`http://127.0.0.1:${port}${path}`, options); return { app, request }; } async function teardown(app) { await new Promise(resolve => app.server.close(resolve)); app.close(); } const headers = { 'content-type': 'application/json', authorization: 'Bearer test-token' }; const draft = { product: 'standalone', title: 'Standalone 1', summary: 'First update', body_markdown: 'Details' }; test('public feed hides drafts until authenticated publish', async () => { const { app, request } = await setup(); try { const created = await request('/v1/admin/updates', { method: 'POST', headers, body: JSON.stringify(draft) }); assert.equal(created.status, 201); const hidden = await request('/v1/updates?product=standalone'); assert.deepEqual((await hidden.json()).data, []); const id = (await (await request('/v1/admin/updates?product=standalone')).json()).data; // route must remain private assert.equal(id, undefined); const unauthorized = await request('/v1/admin/updates/1/publish', { method: 'POST' }); assert.equal(unauthorized.status, 401); const published = await request('/v1/admin/updates/1/publish', { method: 'POST', headers }); assert.equal(published.status, 200); const visible = await request('/v1/updates?product=standalone'); assert.equal((await visible.json()).data.length, 1); } finally { await teardown(app); } }); test('validates product and keeps health response minimal', async () => { const { app, request } = await setup(); try { assert.deepEqual(await (await request('/healthz')).json(), { status: 'ok' }); const response = await request('/v1/admin/updates', { method: 'POST', headers, body: JSON.stringify({ ...draft, product: 'other' }) }); assert.equal(response.status, 400); assert.equal((await response.json()).error.code, 'INVALID_PRODUCT'); } finally { await teardown(app); } }); test('rejects oversized request bodies', async () => { const { app, request } = await setup(); try { const response = await request('/v1/admin/updates', { method: 'POST', headers, body: JSON.stringify({ ...draft, body_markdown: 'x'.repeat(70_000) }) }); assert.equal(response.status, 413); } finally { await teardown(app); } });