import { describe, it, expect, beforeAll } from 'vitest'; import request from 'supertest'; import { resetDb } from '../helpers/db.js'; import { migrateUp } from '../../lib/db/migrate.js'; import { createApp } from '../../server.js'; let app; beforeAll(async () => { await resetDb(); await migrateUp(); process.env.OWNER_TOKEN = 'test-token'; process.env.ACTIONS_CONFIG = new URL('../fixtures/actions.test.json', import.meta.url).pathname; app = createApp(); }); const auth = (r) => r.set('Authorization', 'Bearer test-token'); describe('actions API', () => { it('GET / lists the whitelist (owner)', async () => { const res = await auth(request(app).get('/api/actions')); expect(res.status).toBe(200); expect(res.body.actions.map(a => a.id)).toContain('stop-ct107'); }); it('no auth is rejected', async () => { const res = await request(app).get('/api/actions'); expect(res.status).toBe(401); }); it('risky run queues; appears in /pending; reject resolves it (owner)', async () => { const run = await auth(request(app).post('/api/actions/stop-ct107/run')); expect(run.status).toBe(200); expect(run.body.queued).toBe(true); const pend = await auth(request(app).get('/api/actions/pending')); expect(pend.body.pending.some(p => p.id === run.body.action_row_id)).toBe(true); const rej = await auth(request(app).post(`/api/actions/pending/${run.body.action_row_id}/reject`)); expect(rej.body.status).toBe('rejected'); }); });