import { afterEach, beforeEach, describe, expect, it } from 'vitest';
import { handleActuateAPI } from '../../api/index.js';
import { __resetDashboardSeoCache } from '../../api/routes/dashboard.js';
import { createSession } from '../../auth/session.js';
import { initDB } from '../../db.js';
import { generateToken as generateCsrfToken } from '../../security/csrf.js';
/**
 * `/stats` caches its average-SEO-score computation (a read + scan over
 * up to 200 documents) per content-scope for a short TTL. These tests
 * assert the cache is actually consulted: a second request within the
 * window must NOT re-issue the 200-document SEO read, and clearing the
 * cache forces a recompute.
 */
const SECRET = 'test-secret-for-stats-seo-cache-aaaaaaaaaaaaaaaa';
function createMockDB(rows) {
    let seoReadCount = 0;
    const allRows = rows.map((r, i) => ({
        id: `d${i}`,
        title: `Doc ${i}`,
        status: 'PUBLISHED',
        collection: 'posts',
        updatedAt: new Date(),
        createdById: 'u1',
        createdBy: { name: 'Author', email: 'a@example.com' },
        data: r.data,
    }));
    const db = {
        session: { findUnique: async () => ({ revokedAt: null }) },
        user: { count: async () => 0 },
        media: { count: async () => 0 },
        formSubmission: { count: async () => 0 },
        webhookEndpoint: { count: async () => 0 },
        document: {
            count: async () => allRows.length,
            // The SEO read is the only `findMany` with `take: 200` + `select.data`.
            findMany: async ({ take, select }) => {
                if (take === 200 && select?.data)
                    seoReadCount++;
                return allRows;
            },
            groupBy: async () => [],
        },
    };
    return { db, getSeoReadCount: () => seoReadCount };
}
async function sessionCookie() {
    const token = await createSession({ userId: 'user-1', role: 'ADMIN', sessionId: 'session-1' }, { secret: SECRET });
    const csrf = await generateCsrfToken();
    return `actuate_session=${token}; actuate_csrf=${csrf}`;
}
const POSTS_CONFIG = { collections: { posts: { slug: 'posts', fields: {} } } };
describe('GET /api/cms/stats — SEO score cache', () => {
    const originalSecret = process.env.CMS_SECRET;
    beforeEach(() => {
        process.env.CMS_SECRET = SECRET;
        __resetDashboardSeoCache();
    });
    afterEach(() => {
        if (originalSecret === undefined)
            delete process.env.CMS_SECRET;
        else
            process.env.CMS_SECRET = originalSecret;
        delete globalThis.__actuateConfig;
        __resetDashboardSeoCache();
    });
    it('computes the score once and serves repeat requests from cache', async () => {
        const { db, getSeoReadCount } = createMockDB([
            { data: { seoTitle: 'a', metaDescription: 'b' } }, // 50
            { data: { seoTitle: 'a', metaDescription: 'b', canonical: 'c', schemaType: 'Article' } }, // 100
        ]);
        initDB(db);
        const handler = handleActuateAPI({ prismaClient: db, config: POSTS_CONFIG });
        const cookie = await sessionCookie();
        const call = () => handler(new Request('https://example.com/api/cms/stats', { headers: { cookie } }));
        const first = (await (await call()).json());
        expect(first.data.avgSeoScore).toBe(75);
        expect(getSeoReadCount()).toBe(1);
        const second = (await (await call()).json());
        expect(second.data.avgSeoScore).toBe(75);
        // Served from cache — no second 200-document read.
        expect(getSeoReadCount()).toBe(1);
    });
    it('recomputes after the cache is cleared', async () => {
        const { db, getSeoReadCount } = createMockDB([{ data: { seoTitle: 'a' } }]); // 25
        initDB(db);
        const handler = handleActuateAPI({ prismaClient: db, config: POSTS_CONFIG });
        const cookie = await sessionCookie();
        const call = () => handler(new Request('https://example.com/api/cms/stats', { headers: { cookie } }));
        await call();
        expect(getSeoReadCount()).toBe(1);
        __resetDashboardSeoCache();
        await call();
        expect(getSeoReadCount()).toBe(2);
    });
});
//# sourceMappingURL=stats-seo-cache.test.js.map