import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' import type { H3Event } from 'h3' import { kickWorker } from '../../server/utils/kick-worker' const ORIGINAL_SECRET = process.env.CRON_SECRET const ORIGINAL_URL = process.env.NUXT_PUBLIC_URL function fakeEvent() { const waitUntil = vi.fn<(p: Promise) => void>() // eslint-disable-next-line ts/no-unsafe-type-assertion -- only waitUntil is exercised return { event: { waitUntil } as unknown as H3Event, waitUntil } } describe('kickWorker', () => { beforeEach(() => { process.env.CRON_SECRET = 'test-secret' process.env.NUXT_PUBLIC_URL = 'https://synchub.to' // kick-worker reads `useRuntimeConfig().public.url`; the Nuxt auto-import // isn't available in plain unit tests, so stub it to read from env. vi.stubGlobal('useRuntimeConfig', () => ({ public: { url: process.env.NUXT_PUBLIC_URL ?? '' } })) }) afterEach(() => { if (ORIGINAL_SECRET === undefined) delete process.env.CRON_SECRET else process.env.CRON_SECRET = ORIGINAL_SECRET if (ORIGINAL_URL === undefined) delete process.env.NUXT_PUBLIC_URL else process.env.NUXT_PUBLIC_URL = ORIGINAL_URL vi.unstubAllGlobals() }) it('fires a GET to the worker with the cron bearer and registers it via waitUntil', async () => { const fetchMock = vi.fn<(url: string, init?: RequestInit) => Promise>(async () => new Response('{}')) vi.stubGlobal('fetch', fetchMock) const { event, waitUntil } = fakeEvent() kickWorker(event) expect(waitUntil).toHaveBeenCalledTimes(1) expect(fetchMock).toHaveBeenCalledTimes(1) const [url, init] = fetchMock.mock.calls[0]! expect(url).toBe('https://synchub.to/api/jobs/run') expect(init).toMatchObject({ method: 'GET', headers: { authorization: 'Bearer test-secret' } }) }) it('strips a trailing slash from the public URL', () => { process.env.NUXT_PUBLIC_URL = 'https://synchub.to/' const fetchMock = vi.fn<(url: string, init?: RequestInit) => Promise>(async () => new Response('{}')) vi.stubGlobal('fetch', fetchMock) const { event } = fakeEvent() kickWorker(event) expect(fetchMock.mock.calls[0]![0]).toBe('https://synchub.to/api/jobs/run') }) it('no-ops when CRON_SECRET is unset', () => { delete process.env.CRON_SECRET const fetchMock = vi.fn<(url: string, init?: RequestInit) => Promise>() vi.stubGlobal('fetch', fetchMock) const { event, waitUntil } = fakeEvent() kickWorker(event) expect(fetchMock).not.toHaveBeenCalled() expect(waitUntil).not.toHaveBeenCalled() }) it('swallows a fetch rejection (cron is the safety net)', async () => { const rejecting = vi.fn<(url: string, init?: RequestInit) => Promise>(async () => { throw new Error('network down') }) vi.stubGlobal('fetch', rejecting) const captured: Promise[] = [] // eslint-disable-next-line ts/no-unsafe-type-assertion -- minimal event stub const event = { waitUntil: (p: Promise) => { captured.push(p) } } as unknown as H3Event kickWorker(event) await expect(captured[0]).resolves.toBeUndefined() }) })