feat(portfolio): add product updates feed
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
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); }
|
||||
});
|
||||
Reference in New Issue
Block a user