import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; beforeEach(() => { vi.resetModules(); vi.stubEnv('KOMODO_ADDRESS', 'http://komodo.test'); vi.stubEnv('KOMODO_API_KEY', 'test-key'); vi.stubEnv('KOMODO_API_SECRET', 'test-secret'); }); afterEach(() => { vi.unstubAllGlobals(); vi.unstubAllEnvs(); }); describe('Komodo startup response classification', () => { it.each([403, 502])('preserves HTTP %i so callers can distinguish rejection from uncertain startup', async httpStatus => { vi.stubGlobal('fetch', vi.fn(async () => new Response('Deployment response failed', { status: httpStatus }))); const { komodoDeploy } = await import('../../src/lib/server/integrations/komodo.js'); expect(await komodoDeploy('t5_zombie_theater_1')).toMatchObject({ ok: false, kind: 'http-error', httpStatus }); }); it('identifies an explicit success=false response as a confirmed HTTP 200 failure', async () => { vi.stubGlobal('fetch', vi.fn(async () => Response.json({ success: false, message: 'Image rejected' }))); const { komodoDeploy } = await import('../../src/lib/server/integrations/komodo.js'); expect(await komodoDeploy('t5_zombie_theater_1')).toMatchObject({ ok: false, kind: 'http-error', httpStatus: 200, message: 'Image rejected' }); }); it('returns a structured unreachable result when the startup response times out', async () => { vi.stubGlobal('fetch', vi.fn(async () => { throw new DOMException('Request aborted', 'AbortError'); })); const { komodoDeploy } = await import('../../src/lib/server/integrations/komodo.js'); expect(await komodoDeploy('t5_zombie_theater_1')).toMatchObject({ ok: false, kind: 'unreachable', message: expect.stringContaining('timed out') }); }); });