/**
 * audit3-followup (2026-05-29) — /api/cron route coverage.
 *
 * Focuses on the auth gate, NOT the downstream monitor-engine work.
 * The latter is exercised by the p0-1-cron-auth live smoke when
 * SMOKE_LIVE=1; this jest suite is for the offline path so any
 * regression in the CRON_SECRET check surfaces in CI immediately.
 */
jest.mock('@/lib/monitor-engine', () => ({
    runPendingChecks: jest.fn().mockResolvedValue({ ok: 0 }),
}));

jest.mock('@/lib/prisma', () => ({
    prisma: {
        systemSetting: { findUnique: jest.fn().mockResolvedValue(null) },
        heartbeat: { deleteMany: jest.fn().mockResolvedValue({ count: 0 }) },
    },
}));

import { GET } from '../route';

const SECRET = 'super-secret-cron-token-1234567890';

beforeEach(() => {
    process.env.CRON_SECRET = SECRET;
});

afterEach(() => {
    delete process.env.CRON_SECRET;
});

function makeRequest(opts: { secret?: string; bearer?: string } = {}): Request {
    const url = new URL('http://localhost/api/cron');
    if (opts.secret !== undefined) url.searchParams.set('secret', opts.secret);
    const headers = new Headers();
    if (opts.bearer !== undefined) headers.set('authorization', `Bearer ${opts.bearer}`);
    return new Request(url.toString(), { method: 'GET', headers });
}

describe('GET /api/cron — CRON_SECRET enforcement', () => {
    it('401 when neither query nor Authorization header is supplied', async () => {
        const res = await GET(makeRequest());
        expect(res.status).toBe(401);
    });

    it('401 when the secret is wrong (length differs)', async () => {
        const res = await GET(makeRequest({ secret: 'too-short' }));
        expect(res.status).toBe(401);
    });

    it('401 when the secret is wrong (same length, different bytes)', async () => {
        const wrong = 'X'.repeat(SECRET.length);
        const res = await GET(makeRequest({ secret: wrong }));
        expect(res.status).toBe(401);
    });

    it('200 when the correct secret is supplied via ?secret=', async () => {
        const res = await GET(makeRequest({ secret: SECRET }));
        expect(res.status).toBe(200);
    });

    it('200 when the correct secret is supplied via Authorization: Bearer', async () => {
        const res = await GET(makeRequest({ bearer: SECRET }));
        expect(res.status).toBe(200);
    });

    it('503 when CRON_SECRET is missing from the env', async () => {
        delete process.env.CRON_SECRET;
        const res = await GET(makeRequest({ secret: 'anything' }));
        expect(res.status).toBe(503);
        const body = await res.json();
        expect(body.error).toBe('cron-disabled');
    });

    it('503 when CRON_SECRET is too short (env misconfig)', async () => {
        process.env.CRON_SECRET = 'short';
        const res = await GET(makeRequest({ secret: 'short' }));
        expect(res.status).toBe(503);
    });
});
