import { describe, it, expect, beforeAll, afterAll, beforeEach, vi } from 'vitest';
import { buildApp } from '../../app.js';
import fs from 'node:fs';
import path from 'node:path';
import os from 'node:os';
let app;
let mockJobRunner;
let tmpSquadsDir;
beforeAll(async () => {
    tmpSquadsDir = fs.mkdtempSync(path.join(os.tmpdir(), 'squads-'));
    // Squad without secret
    const squadDir = path.join(tmpSquadsDir, 'open-squad');
    fs.mkdirSync(path.join(squadDir, 'agents'), { recursive: true });
    fs.writeFileSync(path.join(squadDir, 'squad.yaml'), `squad:
  code: open-squad
  name: Open Squad
  description: Test
  icon: rocket
  agents:
    - id: worker
      name: Worker
      prompt: agents/worker.md
  pipeline:
    steps:
      - id: step-01
        agent: worker
        label: Do work
`);
    fs.writeFileSync(path.join(squadDir, 'agents/worker.md'), '# Worker');
    // Squad with secret
    const secretDir = path.join(tmpSquadsDir, 'secret-squad');
    fs.mkdirSync(path.join(secretDir, 'agents'), { recursive: true });
    fs.writeFileSync(path.join(secretDir, 'squad.yaml'), `squad:
  code: secret-squad
  name: Secret Squad
  description: Test
  icon: lock
  agents:
    - id: worker
      name: Worker
      prompt: agents/worker.md
  pipeline:
    steps:
      - id: step-01
        agent: worker
        label: Do work
  webhooks:
    secret: correct-secret
`);
    fs.writeFileSync(path.join(secretDir, 'agents/worker.md'), '# Worker');
    mockJobRunner = {
        run: vi.fn().mockResolvedValue('completed'),
        isRunning: vi.fn().mockReturnValue(false),
        stopAll: vi.fn(),
    };
    app = await buildApp({
        config: {
            jwtSecret: 'test-webhook-secret',
            squadsDir: tmpSquadsDir,
        },
        jobRunner: mockJobRunner,
    });
    await app.ready();
});
afterAll(async () => {
    await app.close();
    fs.rmSync(tmpSquadsDir, { recursive: true, force: true });
});
beforeEach(() => vi.clearAllMocks());
describe('POST /api/webhooks/:squadName', () => {
    it('returns 404 for non-existent squad', async () => {
        const res = await app.inject({ method: 'POST', url: '/api/webhooks/nonexistent' });
        expect(res.statusCode).toBe(404);
    });
    it('returns 202 and triggers job for squad with no secret configured', async () => {
        const res = await app.inject({
            method: 'POST',
            url: '/api/webhooks/open-squad',
            payload: { prompt: 'Run the daily report' },
        });
        expect(res.statusCode).toBe(202);
        expect(res.json().status).toBe('triggered');
        expect(res.json().squadName).toBe('open-squad');
        await vi.waitFor(() => expect(mockJobRunner.run).toHaveBeenCalledWith(expect.objectContaining({ squadName: 'open-squad', prompt: 'Run the daily report' })));
    });
    it('uses default prompt when none provided', async () => {
        await app.inject({ method: 'POST', url: '/api/webhooks/open-squad' });
        await vi.waitFor(() => expect(mockJobRunner.run).toHaveBeenCalledWith(expect.objectContaining({ prompt: expect.stringContaining('open-squad') })));
    });
    it('returns 401 for squad with secret when no header provided', async () => {
        const res = await app.inject({ method: 'POST', url: '/api/webhooks/secret-squad' });
        expect(res.statusCode).toBe(401);
    });
    it('returns 401 for squad with secret when wrong secret provided', async () => {
        const res = await app.inject({
            method: 'POST',
            url: '/api/webhooks/secret-squad',
            headers: { 'x-webhook-secret': 'wrong' },
        });
        expect(res.statusCode).toBe(401);
    });
    it('returns 202 for squad with secret when correct secret provided', async () => {
        const res = await app.inject({
            method: 'POST',
            url: '/api/webhooks/secret-squad',
            headers: { 'x-webhook-secret': 'correct-secret' },
        });
        expect(res.statusCode).toBe(202);
    });
});
//# sourceMappingURL=webhook-routes.test.js.map