import * as TestAdmin from '../../../test/Admin.js' import * as TestApp from '../../../test/App.js' import * as EarlyAccessApp from './early-access.js' /** Lists the table's entries. */ async function listAdded(client: ReturnType['client']) { const response = await client['early-access'].$get() const body = await TestApp.json(response, EarlyAccessApp.schema.listEarlyAccessEntries.Response) return body.data } describe('authentication', () => { test('denied identity → 401 on every route', async () => { const { app } = TestAdmin.setup({ identify: () => null }) const routes = [ new Request('http://admin/early-access'), new Request('http://admin/early-access', { body: JSON.stringify({ entry: 'example.org' }), headers: { 'content-type': 'application/json' }, method: 'POST', }), new Request('http://admin/early-access', { body: JSON.stringify({ entry: 'example.org' }), headers: { 'content-type': 'application/json' }, method: 'DELETE', }), ] for (const request of routes) { const response = await app.request(request) expect(response.status).toBe(401) } }) }) describe('GET /early-access', () => { test('starts empty; entries are seeded through the dash, never migrations', async () => { const { client } = TestAdmin.setup() const response = await client['early-access'].$get() const body = await TestApp.json(response, EarlyAccessApp.schema.listEarlyAccessEntries.Response) expect(response.status).toBe(200) expect(body.data).toEqual([]) }) }) describe('POST /early-access', () => { test('add → list → remove round-trip', async () => { const { client } = TestAdmin.setup() const created = await client['early-access'].$post({ json: { entry: 'a/b@example.org' } }) expect(created.status).toBe(200) const body = await TestApp.json(created, EarlyAccessApp.schema.createEarlyAccessEntry.Response) expect(body.data.entry).toBe('a/b@example.org') // createdBy is the verified admin email, never client-supplied. expect(body.data.createdBy).toBe(TestAdmin.identity.email) expect((await listAdded(client)).map((record) => record.entry)).toEqual(['a/b@example.org']) // Reserved URL characters stay in the JSON body. const removed = await client['early-access'].$delete({ json: { entry: 'a/b@example.org' } }) expect(removed.status).toBe(200) expect(await listAdded(client)).toEqual([]) }) test('normalizes the entry lowercase and trimmed', async () => { const { client } = TestAdmin.setup() const response = await client['early-access'].$post({ json: { entry: ' User@Example.ORG ' } }) const body = await TestApp.json(response, EarlyAccessApp.schema.createEarlyAccessEntry.Response) expect(response.status).toBe(200) expect(body.data.entry).toBe('user@example.org') }) test('rejects an invalid entry with 400', async () => { const { client } = TestAdmin.setup() for (const entry of ['', ' ', 'no spaces.org x', 'not-a-domain', '@example.org', 'user@']) { const response = await client['early-access'].$post({ json: { entry } }) const body = (await response.json()) as { error?: { code?: string } } expect(response.status).toBe(400) expect(body.error?.code).toBe('body_invalid') } }) test('rejects a duplicate entry with 409', async () => { const { client } = TestAdmin.setup() await client['early-access'].$post({ json: { entry: 'example.org' } }) const duplicate = await client['early-access'].$post({ json: { entry: 'Example.org' } }) const body = (await duplicate.json()) as { error?: { code?: string } } expect(duplicate.status).toBe(409) expect(body.error?.code).toBe('entry_exists') }) }) describe('DELETE /early-access', () => { test('removing an unknown entry → 404', async () => { const { client } = TestAdmin.setup() const response = await client['early-access'].$delete({ json: { entry: 'missing.example.org' }, }) const body = (await response.json()) as { error?: { code?: string } } expect(response.status).toBe(404) expect(body.error?.code).toBe('entry_not_found') }) }) describe('audit logging', () => { test('writes an audit row for allowlist mutations', async () => { const { client, db } = TestAdmin.setup() await client['early-access'].$post({ json: { entry: 'example.org' } }) const records = await db.kysely .selectFrom('admin_audit_logs') .selectAll() .orderBy('createdAt', 'desc') .execute() expect(records[0]).toMatchObject({ actor: TestAdmin.identity.email, method: 'POST', path: '/early-access', status: 200, }) }) })