import { afterEach, describe, expect, it, vi } from 'vitest'; import { getAgentWriteToken, provisionAgentSite } from '../src/agent-deployment.js'; vi.mock('node:timers/promises', () => ({ setTimeout: vi.fn().mockResolvedValue(undefined) })); const ready = { status: 'ready', deploymentId: 'deployment', subdomain: 'actual-name', remote: 'https://git.example.com/repo.git', branch: 'main', expiresAt: '2026-12-01T00:00:00.000Z', }; const existing = { ...ready, code: 'deployment_already_exists' }; const provision = () => provisionAgentSite('https://api.example.com', 'access', { subdomain: 'requested', orgName: 'Docs', }); function response(body: unknown, status: number) { return new Response(JSON.stringify(body), { status }); } afterEach(() => vi.unstubAllGlobals()); describe('agent deployment API', () => { it('sends root content layout and uses the allocated subdomain', async () => { const request = vi.fn().mockResolvedValue(response(ready, 201)); vi.stubGlobal('fetch', request); expect(await provision()).toEqual({ ...ready, created: true }); expect(JSON.parse(request.mock.calls[0]?.[1].body)).toEqual({ subdomain: 'requested', orgName: 'Docs', docsPath: '', }); }); it('returns an existing site as an update, not a new creation', async () => { vi.stubGlobal('fetch', vi.fn().mockResolvedValue(response(existing, 409))); expect(await provision()).toEqual({ ...existing, created: false }); }); it('retries provisioning even when no deployment ID exists yet', async () => { const request = vi .fn() .mockResolvedValueOnce(response({ status: 'provisioning', code: existing.code }, 409)) .mockResolvedValueOnce(response(existing, 409)); vi.stubGlobal('fetch', request); expect((await provision()).status).toBe('ready'); expect(request).toHaveBeenCalledTimes(2); }); it('bounds provisioning retries', async () => { const request = vi .fn() .mockImplementation(async () => response({ status: 'provisioning', code: existing.code }, 409) ); vi.stubGlobal('fetch', request); await expect(provision()).rejects.toThrow('still provisioning'); expect(request).toHaveBeenCalledTimes(4); }); it('distinguishes confirmed expiry from upstream failure', async () => { const request = vi .fn() .mockResolvedValueOnce(response({ ...existing, status: 'expired' }, 409)) .mockResolvedValueOnce(response({ error: 'unavailable' }, 503)); vi.stubGlobal('fetch', request); expect((await provision()).status).toBe('expired'); await expect(provision()).rejects.toThrow('503'); }); it('requests a write token without a caller-selected deployment', async () => { const credential = { remote: ready.remote, branch: 'main', token: 'write-secret', tokenExpiresAt: ready.expiresAt, }; const request = vi.fn().mockResolvedValue(response(credential, 200)); vi.stubGlobal('fetch', request); expect(await getAgentWriteToken('https://api.example.com', 'access')).toEqual(credential); expect(request.mock.calls[0]?.[1].body).toBeUndefined(); }); });