// server/cloudflare-worker/src/push-drain.test.ts import { drainPushDispatches, resolveBatchLimit } from './push-drain.ts' function assert(condition: boolean, message: string): asserts condition { if (!condition) throw new Error(message) } const env = { SUPABASE_URL: 'https://example.supabase.co', SUPABASE_SERVICE_ROLE_KEY: 'x'.repeat(40) } function jsonResponse(status: number, body: unknown): Response { return new Response(JSON.stringify(body), { status, headers: { 'Content-Type': 'application/json' }, }) } Deno.test('batch limit is clamped to the edge function contract', () => { assert(resolveBatchLimit(undefined) === 20, 'default is 20') assert(resolveBatchLimit('5') === 5, 'explicit value is used') assert(resolveBatchLimit('9999') === 100, 'upper bound is 100') assert(resolveBatchLimit('0') === 20, 'zero falls back to the default') assert(resolveBatchLimit('abc') === 20, 'garbage falls back to the default') }) Deno.test('drain fails closed without configuration', async () => { const result = await drainPushDispatches({}, () => { throw new Error('must not be called') }) assert(result.ok === false, 'not ok') assert(result.error === 'push_drain_not_configured', 'clear configuration error') assert(result.status === 503, 'service unavailable') }) Deno.test('drain posts to the drain endpoint with the service role bearer', async () => { const calls: Array<{ url: string; init: RequestInit }> = [] const fetchImpl = ((url: string | URL | Request, init?: RequestInit) => { calls.push({ url: String(url), init: init ?? {} }) return Promise.resolve(jsonResponse(200, { claimed: 3, completed: 2, pending: 1 })) }) as unknown as typeof fetch const result = await drainPushDispatches(env, fetchImpl) assert(result.ok === true, 'ok') assert(result.claimed === 3 && result.completed === 2 && result.pending === 1, 'summary parsed') assert(calls[0].url === 'https://example.supabase.co/functions/v1/send-push?mode=drain&limit=20', 'drain url') const headers = calls[0].init.headers as Record assert(headers.Authorization === `Bearer ${env.SUPABASE_SERVICE_ROLE_KEY}`, 'service role bearer') assert(headers['Content-Type'] === 'application/json', 'json content type') assert(calls[0].init.body === '{}', 'empty json body') assert(calls[0].init.method === 'POST', 'post method') }) Deno.test('drain reports upstream failures without throwing', async () => { const httpFail = ((() => Promise.resolve(new Response('nope', { status: 500 }))) as unknown as typeof fetch) const result = await drainPushDispatches(env, httpFail) assert(result.ok === false, 'not ok') assert(result.error === 'push_drain_http_500', 'http error surfaced') assert(result.status === 500, 'status surfaced') const unreachable = (() => Promise.reject(new Error('network'))) as unknown as typeof fetch const unreachableResult = await drainPushDispatches(env, unreachable) assert(unreachableResult.error === 'push_drain_unreachable', 'network error surfaced') }) Deno.test('drain tolerates a malformed success body', async () => { const fetchImpl = ((() => Promise.resolve(new Response('not-json', { status: 200 }))) as unknown as typeof fetch) const result = await drainPushDispatches(env, fetchImpl) assert(result.ok === true, 'ok') assert(result.claimed === undefined, 'summary left undefined') })