import { describe, expect, test } from 'bun:test'; import { mkdtemp, readFile, rm } from 'node:fs/promises'; import { tmpdir } from 'node:os'; import { join } from 'node:path'; import { parseSyncEnqueueBody } from '../src/lib/client/sync-queue'; import { workerEnvironment } from '../scripts/run-sync-worker'; import { prepareEnrichmentChunks } from '../workers/sync'; describe('T07 worker runtime boundary', () => { test('bundled worker starts with inert restricted configuration and has no unresolved aliases', async () => { const directory = await mkdtemp(join(tmpdir(), 'eve-sync-worker-')); try { const output = join(directory, 'sync-worker.js'); const built = await Bun.build({ entrypoints: ['workers/sync.ts'], target: 'bun', outdir: directory, naming: 'sync-worker.js', minify: false }); expect(built.success).toBe(true); const source = await readFile(output, 'utf8'); expect(source.includes('$lib/')).toBe(false); const env: Record = { PATH: process.env.PATH, HOME: process.env.HOME, CONVEX_URL: 'http://127.0.0.1:9', CONVEX_SYNC_WORKER_SECRET: 'inert-worker-secret', TOKEN_ENCRYPTION_KEY: Buffer.alloc(32).toString('base64'), EVE_CLIENT_ID: 'inert-client', EVE_CALLBACK_URL: 'http://localhost/unused-worker-callback', ESI_USER_AGENT: 'EVE-Intelligence/test', SYNC_WORKER_STARTUP_CHECK: '1' }; for (const name of ['CONVEX_BRIDGE_SECRET', 'CONVEX_SELF_HOSTED_ADMIN_KEY', 'APP_AUTH_PRIVATE_KEY', 'APP_AUTH_JWKS', 'TYPESAFE_API_KEY']) delete env[name]; const child = Bun.spawn(['bun', output], { env, stdout: 'pipe', stderr: 'pipe' }); const code = await child.exited; const outputText = await new Response(child.stdout).text() + await new Response(child.stderr).text(); expect(code).toBe(0); expect(outputText).toBe(''); } finally { await rm(directory, { recursive: true, force: true }); } }); test('worker preflights oversized enrichment envelopes before any stage mutation', () => { const rows = Array.from({ length: 100 }, (_, index) => ({ itemId: String(index + 1), payload: 'x'.repeat(6_000) })) as any; const chunks = prepareEnrichmentChunks(rows); expect(chunks).not.toBeNull(); expect(chunks!.length).toBeGreaterThan(1); expect(Math.max(...chunks!.map((chunk) => new TextEncoder().encode(JSON.stringify(chunk)).byteLength))).toBeLessThanOrEqual(256 * 1024); expect(prepareEnrichmentChunks([{ payload: 'x'.repeat(300_000) }] as any)).toBeNull(); expect(prepareEnrichmentChunks(Array.from({ length: 2_500 }, () => ({ payload: 'x'.repeat(1_000) })) as any)).toBeNull(); }); test('client preserves structured all-skipped and partial enqueue outcomes on HTTP errors', async () => { expect(parseSyncEnqueueBody({ queued: 0, jobs: [], skipped: [{ characterId: 1, reason: 'queue_full' }], partial: true })).toMatchObject({ queued: 0, skipped: [{ characterId: 1, reason: 'queue_full' }] }); expect(parseSyncEnqueueBody({ queued: 1, jobs: [{ id: 'job', characterId: 2, status: 'queued', attempts: 0, dueAt: 1, createdAt: 1, updatedAt: 1, leaseExpiresAt: null, cancelRequested: false }], skipped: [{ characterId: 3, reason: 'enqueue_failed' }], partial: true })).toMatchObject({ queued: 1, jobs: [{ id: 'job', characterId: 2 }], skipped: [{ characterId: 3, reason: 'enqueue_failed' }] }); const originalFetch = globalThis.fetch; try { globalThis.fetch = (async () => Response.json({ queued: 0, jobs: [], skipped: [{ characterId: 1, reason: 'queue_full' }], partial: true }, { status: 429 })) as unknown as typeof fetch; const allSkipped = await (await import('../src/lib/client/sync-queue')).enqueueSync(); expect(allSkipped.response.status).toBe(429); expect(allSkipped.body).toMatchObject({ jobs: [], skipped: [{ reason: 'queue_full' }] }); globalThis.fetch = (async () => Response.json({ queued: 1, jobs: [{ id: 'job', characterId: 2, status: 'queued', attempts: 0, dueAt: 1, createdAt: 1, updatedAt: 1, leaseExpiresAt: null, cancelRequested: false }], skipped: [{ characterId: 3, reason: 'enqueue_failed' }], partial: true }, { status: 503 })) as unknown as typeof fetch; const partial = await (await import('../src/lib/client/sync-queue')).enqueueSync(); expect(partial.response.status).toBe(503); expect(partial.body).toMatchObject({ jobs: [{ id: 'job' }], skipped: [{ reason: 'enqueue_failed' }] }); } finally { globalThis.fetch = originalFetch; } }); test('missing status is surfaced and status polling forwards cancellation', async () => { const originalFetch = globalThis.fetch; try { globalThis.fetch = (async () => new Response(null, { status: 404 })) as unknown as typeof fetch; expect(await (await import('../src/lib/client/sync-queue')).syncJobStatus('missing')).toBeNull(); globalThis.fetch = (() => new Promise(() => {})) as unknown as typeof fetch; await expect((await import('../src/lib/client/sync-queue')).syncJobStatus('never', undefined, 5)).rejects.toThrow('timed out'); const controller = new AbortController(); globalThis.fetch = ((_input: RequestInfo | URL, init?: RequestInit) => new Promise((_resolve, reject) => { init?.signal?.addEventListener('abort', () => reject(new DOMException('aborted', 'AbortError')), { once: true }); })) as unknown as typeof fetch; const pending = (await import('../src/lib/client/sync-queue')).syncJobStatus('running', controller.signal); controller.abort(); await expect(pending).rejects.toMatchObject({ name: 'AbortError' }); } finally { globalThis.fetch = originalFetch; } }); test('worker child environment drops Infisical bootstrap credentials and ambient web keys', () => { const child = workerEnvironment({ PATH: '/bin', CONVEX_URL: 'http://inert', CONVEX_SYNC_WORKER_SECRET: 'worker-only', TOKEN_ENCRYPTION_KEY: 'inert-key', EVE_CLIENT_ID: 'inert-client', EVE_CLIENT_SECRET: 'inert-eve-secret', REFERENCE_DIR: '/app/data/reference', INFISICAL_TOKEN: 'inert-token', INFISICAL_UNIVERSAL_AUTH_CLIENT_ID: 'inert-client-id', INFISICAL_UNIVERSAL_AUTH_CLIENT_SECRET: 'inert-client-secret', CONVEX_BRIDGE_SECRET: 'inert-bridge', APP_AUTH_PRIVATE_KEY: 'inert-jwt', TYPESAFE_API_KEY: 'inert-jev' }); expect(child).toEqual({ PATH: '/bin', CONVEX_URL: 'http://inert', CONVEX_SYNC_WORKER_SECRET: 'worker-only', TOKEN_ENCRYPTION_KEY: 'inert-key', EVE_CLIENT_ID: 'inert-client', EVE_CLIENT_SECRET: 'inert-eve-secret', REFERENCE_DIR: '/app/data/reference' }); expect(Object.keys(child).some((key) => key.startsWith('INFISICAL_'))).toBe(false); }); test('direct worker launcher refuses general bridge/admin/JWT/JEV credentials', async () => { for (const name of ['CONVEX_BRIDGE_SECRET', 'CONVEX_SELF_HOSTED_ADMIN_KEY', 'APP_AUTH_PRIVATE_KEY', 'APP_AUTH_JWKS', 'TYPESAFE_API_KEY']) { const forbidden = `inert-${name}`; const env = { PATH: process.env.PATH, HOME: process.env.HOME, CONVEX_SYNC_WORKER_SECRET: 'inert-worker-secret', [name]: forbidden }; const child = Bun.spawn(['bun', 'scripts/run-sync-worker.ts'], { env, stdout: 'pipe', stderr: 'pipe' }); const code = await child.exited; const output = await new Response(child.stdout).text() + await new Response(child.stderr).text(); expect(code).not.toBe(0); expect(output).not.toContain(forbidden); } }); });