import { afterEach, beforeEach, describe, expect, it } from 'vitest';
import { createCMSMiddleware } from '../middleware.js';
/**
 * Regression coverage for the admin/API route matching boundary. The guard used
 * `startsWith('/admin')`, which also captured sibling public routes such as
 * `/administrators` or `/admin-news`. Those must NOT be treated as admin routes.
 */
describe('createCMSMiddleware route boundary', () => {
    const origSecret = process.env.CMS_SECRET;
    beforeEach(() => {
        process.env.CMS_SECRET = 'x'.repeat(32);
    });
    afterEach(() => {
        process.env.CMS_SECRET = origSecret;
    });
    function req(path) {
        return new Request(`https://example.com${path}`);
    }
    it('does not treat /admin-news as an admin route (IP allowlist not enforced)', async () => {
        const mw = createCMSMiddleware({ admin: { path: '/admin', ipAllowlist: ['10.0.0.1'] } });
        // An admin route with a non-allowlisted IP would be 403; a public route
        // passes through (null). /admin-news must pass through.
        const res = await mw(req('/admin-news'));
        expect(res).toBeNull();
    });
    it('does not treat /administrators as an admin route', async () => {
        const mw = createCMSMiddleware({ admin: { path: '/admin', ipAllowlist: ['10.0.0.1'] } });
        expect(await mw(req('/administrators'))).toBeNull();
    });
    it('still enforces the allowlist on the exact admin path', async () => {
        const mw = createCMSMiddleware({ admin: { path: '/admin', ipAllowlist: ['10.0.0.1'] } });
        const res = await mw(req('/admin'));
        expect(res?.status).toBe(403);
    });
    it('still enforces the allowlist on nested admin paths', async () => {
        const mw = createCMSMiddleware({ admin: { path: '/admin', ipAllowlist: ['10.0.0.1'] } });
        const res = await mw(req('/admin/collections/posts'));
        expect(res?.status).toBe(403);
    });
    it('does not treat /api/cmsx as a CMS API route', async () => {
        const mw = createCMSMiddleware({ admin: { path: '/admin', ipAllowlist: ['10.0.0.1'] } });
        expect(await mw(req('/api/cmsx/thing'))).toBeNull();
    });
    it('enforces the allowlist on /api/cms routes', async () => {
        const mw = createCMSMiddleware({ admin: { path: '/admin', ipAllowlist: ['10.0.0.1'] } });
        const res = await mw(req('/api/cms/documents'));
        expect(res?.status).toBe(403);
    });
});
describe('createCMSMiddleware split login (admin.loginPath)', () => {
    const origSecret = process.env.CMS_SECRET;
    beforeEach(() => {
        process.env.CMS_SECRET = 'x'.repeat(32);
    });
    afterEach(() => {
        process.env.CMS_SECRET = origSecret;
    });
    const cfg = {
        admin: { path: '/admin', loginPath: '/securelogin', ipAllowlist: ['10.0.0.1'] },
    };
    function req(path, headers) {
        return new Request(`https://example.com${path}`, { headers });
    }
    it('enforces the IP allowlist on the login mount like the admin mount', async () => {
        const mw = createCMSMiddleware(cfg);
        expect((await mw(req('/securelogin')))?.status).toBe(403);
        expect((await mw(req('/securelogin/reset-password')))?.status).toBe(403);
    });
    it('does not capture sibling public routes of the login mount', async () => {
        const mw = createCMSMiddleware(cfg);
        expect(await mw(req('/securelogin-news'))).toBeNull();
    });
    it('lets the setup wizard route on the login mount through during install', async () => {
        const mw = createCMSMiddleware(cfg);
        expect(await mw(req('/securelogin/setup'))).toBeNull();
    });
    it('redirects an invalid session to the login mount, not the admin mount', async () => {
        const mw = createCMSMiddleware({ admin: { path: '/admin', loginPath: '/securelogin' } });
        const res = await mw(req('/admin/dashboard', { cookie: 'actuate_session=not-a-jwt' }));
        expect(res?.status).toBe(302);
        expect(res?.headers.get('Location')).toBe('/securelogin');
        expect(res?.headers.get('Set-Cookie')).toContain('actuate_session=;');
    });
    it('without loginPath, the invalid-session redirect still targets the admin path', async () => {
        const mw = createCMSMiddleware({ admin: { path: '/admin' } });
        const res = await mw(req('/admin/dashboard', { cookie: 'actuate_session=not-a-jwt' }));
        expect(res?.status).toBe(302);
        expect(res?.headers.get('Location')).toBe('/admin');
    });
    it('shows the CMS_SECRET error page on the login mount too', async () => {
        process.env.CMS_SECRET = '';
        const mw = createCMSMiddleware({ admin: { path: '/admin', loginPath: '/securelogin' } });
        const res = await mw(new Request('https://example.com/securelogin'));
        expect(res?.status).toBe(503);
    });
});
describe('createCMSMiddleware missing CMS_SECRET', () => {
    const origSecret = process.env.CMS_SECRET;
    beforeEach(() => {
        process.env.CMS_SECRET = '';
    });
    afterEach(() => {
        process.env.CMS_SECRET = origSecret;
    });
    function req(path) {
        return new Request(`https://example.com${path}`);
    }
    it('returns an actionable 503 HTML page for the admin UI', async () => {
        const mw = createCMSMiddleware({ admin: { path: '/admin' } });
        const res = await mw(req('/admin'));
        expect(res?.status).toBe(503);
        expect(res?.headers.get('Content-Type')).toContain('text/html');
        const body = await res.text();
        expect(body).toContain('CMS_SECRET');
        // Must not leak any secret value — only the variable name + remediation.
        expect(body).toContain('randomBytes');
    });
    it('still lets the setup API through so the wizard can run before a secret exists', async () => {
        const mw = createCMSMiddleware({ admin: { path: '/admin' } });
        expect(await mw(req('/api/cms/setup/status'))).toBeNull();
    });
    it('does not block public routes when the secret is missing', async () => {
        const mw = createCMSMiddleware({ admin: { path: '/admin' } });
        expect(await mw(req('/about'))).toBeNull();
    });
});
//# sourceMappingURL=middleware.test.js.map