import { beforeEach, describe, expect, it } from 'vitest';
import { handleActuateAPI } from '../../api/index.js';
import { initDB } from '../../db.js';
function createMockDB(docs) {
    const findFirst = async (args) => {
        const where = args?.where ?? {};
        const matches = docs.filter((d) => {
            if (where.collection && d.collection !== where.collection)
                return false;
            if (where.status && d.status !== where.status)
                return false;
            if (where.deletedAt === null) {
                // mock docs never carry deletedAt
            }
            if (where.OR && Array.isArray(where.OR)) {
                return where.OR.some((clause) => {
                    if (clause.slug !== undefined)
                        return d.slug === clause.slug;
                    if (clause.data?.path && clause.data?.equals) {
                        const path = clause.data.path[0];
                        return d.data?.[path] === clause.data.equals;
                    }
                    return false;
                });
            }
            return true;
        });
        const doc = matches[0];
        if (!doc)
            return null;
        return {
            ...doc,
            publishedAt: doc.publishedAt ?? null,
            updatedAt: doc.updatedAt ?? new Date('2026-03-15T12:00:00Z'),
            createdAt: doc.createdAt ?? new Date('2026-01-01T00:00:00Z'),
            structuredData: doc.structuredData ?? null,
        };
    };
    const findMany = async (args) => {
        const where = args?.where ?? {};
        return docs.filter((d) => {
            if (where.collection && d.collection !== where.collection)
                return false;
            if (where.status && d.status !== where.status)
                return false;
            return true;
        });
    };
    return {
        document: { findFirst, findMany },
        user: {},
        session: {},
        media: {},
    };
}
describe('public SEO routes', () => {
    beforeEach(() => {
        delete globalThis.__actuateConfig;
        // Reset the global guarded DB to a clean, indexable state so SEO module
        // settings (read via getSeoOverrides(db())) don't leak between tests.
        // Tests that need specific overrides call initDB() with their own docs.
        initDB(createMockDB([]));
    });
    it('exposes /sitemap.xml as a sitemap index over configured collections', async () => {
        const handler = handleActuateAPI({
            prismaClient: createMockDB([]),
            config: {
                seo: { siteUrl: 'https://example.com', siteName: 'Example' },
                collections: {
                    pages: {
                        slug: 'pages',
                        labels: { singular: 'Page', plural: 'Pages' },
                        urlPrefix: '',
                        type: 'page',
                        fields: {},
                    },
                    posts: {
                        slug: 'posts',
                        labels: { singular: 'Post', plural: 'Posts' },
                        urlPrefix: 'blog',
                        type: 'post',
                        fields: {},
                    },
                },
            },
        });
        const response = await handler(new Request('https://example.com/api/cms/sitemap.xml'));
        expect(response.status).toBe(200);
        expect(response.headers.get('Content-Type')).toContain('application/xml');
        const text = await response.text();
        expect(text).toContain('<sitemapindex');
        expect(text).toContain('/api/cms/sitemaps/pages.xml');
        expect(text).toContain('/api/cms/sitemaps/posts.xml');
    });
    it('serves an RSS feed of newest posts and excludes noindex docs', async () => {
        const docs = [
            {
                id: 'p1',
                slug: 'hello',
                collection: 'posts',
                status: 'PUBLISHED',
                data: { title: 'Hello', keyTakeaway: 'A short summary.' },
                publishedAt: new Date('2026-03-01T00:00:00Z'),
            },
            {
                id: 'p2',
                slug: 'secret',
                collection: 'posts',
                status: 'PUBLISHED',
                data: { title: 'Secret', noindex: true },
                publishedAt: new Date('2026-02-01T00:00:00Z'),
            },
        ];
        const config = {
            seo: { siteUrl: 'https://example.com', siteName: 'Acme' },
            collections: {
                posts: {
                    slug: 'posts',
                    labels: { singular: 'Post', plural: 'Posts' },
                    urlPrefix: 'blog',
                    type: 'post',
                    fields: {},
                },
            },
        };
        initDB(createMockDB(docs));
        const handler = handleActuateAPI({ prismaClient: createMockDB(docs), config: config });
        const res = await handler(new Request('https://example.com/api/cms/feed.xml'));
        expect(res.status).toBe(200);
        expect(res.headers.get('Content-Type')).toContain('application/rss+xml');
        const text = await res.text();
        expect(text).toContain('<title>Acme</title>');
        expect(text).toContain('https://example.com/blog/hello');
        expect(text).toContain('A short summary.');
        // noindex post must be excluded from the feed.
        expect(text).not.toContain('https://example.com/blog/secret');
    });
    it('serves a JSON Feed 1.1 document', async () => {
        const docs = [
            {
                id: 'p1',
                slug: 'hello',
                collection: 'posts',
                status: 'PUBLISHED',
                data: { title: 'Hello' },
                publishedAt: new Date('2026-03-01T00:00:00Z'),
            },
        ];
        const config = {
            seo: { siteUrl: 'https://example.com', siteName: 'Acme' },
            collections: {
                posts: {
                    slug: 'posts',
                    labels: { singular: 'Post', plural: 'Posts' },
                    urlPrefix: 'blog',
                    type: 'post',
                    fields: {},
                },
            },
        };
        initDB(createMockDB(docs));
        const handler = handleActuateAPI({ prismaClient: createMockDB(docs), config: config });
        const res = await handler(new Request('https://example.com/api/cms/feed.json'));
        expect(res.status).toBe(200);
        expect(res.headers.get('Content-Type')).toContain('application/feed+json');
        const parsed = JSON.parse(await res.text());
        expect(parsed.version).toBe('https://jsonfeed.org/version/1.1');
        expect(parsed.feed_url).toBe('https://example.com/feed.json');
        expect(parsed.items[0].url).toBe('https://example.com/blog/hello');
    });
    it('respects seo.sitemap.excludeCollections', async () => {
        const handler = handleActuateAPI({
            prismaClient: createMockDB([]),
            config: {
                seo: {
                    siteUrl: 'https://example.com',
                    sitemap: { excludeCollections: ['drafts'] },
                },
                collections: {
                    pages: {
                        slug: 'pages',
                        type: 'page',
                        labels: { singular: 'P', plural: 'Pp' },
                        urlPrefix: '',
                        fields: {},
                    },
                    drafts: {
                        slug: 'drafts',
                        type: 'page',
                        labels: { singular: 'D', plural: 'Dd' },
                        urlPrefix: 'd',
                        fields: {},
                    },
                },
            },
        });
        const response = await handler(new Request('https://example.com/api/cms/sitemap.xml'));
        const text = await response.text();
        expect(text).toContain('/sitemaps/pages.xml');
        expect(text).not.toContain('/sitemaps/drafts.xml');
    });
    it('returns 404 when seo.sitemap.disabled is true', async () => {
        const handler = handleActuateAPI({
            prismaClient: createMockDB([]),
            config: {
                seo: { siteUrl: 'https://example.com', sitemap: { disabled: true } },
                collections: {
                    pages: { slug: 'pages', labels: { singular: 'P', plural: 'P' }, fields: {} },
                },
            },
        });
        const response = await handler(new Request('https://example.com/api/cms/sitemap.xml'));
        expect(response.status).toBe(404);
    });
    it('renders per-collection sitemap with absolute URLs and lastmod', async () => {
        const docs = [
            {
                id: '1',
                slug: 'about',
                collection: 'pages',
                status: 'PUBLISHED',
                data: { title: 'About', slug: 'about' },
                updatedAt: new Date('2026-03-10T09:00:00Z'),
            },
            {
                id: '2',
                slug: 'contact',
                collection: 'pages',
                status: 'PUBLISHED',
                data: { title: 'Contact', slug: 'contact' },
                updatedAt: new Date('2026-03-11T09:00:00Z'),
            },
        ];
        initDB(createMockDB(docs));
        const handler = handleActuateAPI({
            prismaClient: createMockDB(docs),
            config: {
                seo: { siteUrl: 'https://example.com' },
                collections: {
                    pages: {
                        slug: 'pages',
                        labels: { singular: 'P', plural: 'Pp' },
                        urlPrefix: '',
                        type: 'page',
                        fields: {},
                    },
                },
            },
        });
        const response = await handler(new Request('https://example.com/api/cms/sitemaps/pages.xml'));
        expect(response.status).toBe(200);
        const text = await response.text();
        expect(text).toContain('<urlset');
        expect(text).toContain('<loc>https://example.com/about</loc>');
        expect(text).toContain('<loc>https://example.com/contact</loc>');
        expect(text).toContain('<priority>0.8</priority>');
        expect(text).toContain('2026-03-10T09:00:00.000Z');
    });
    it('uses data.path for the sitemap loc so the homepage is "/" not "/home"', async () => {
        const docs = [
            {
                id: '1',
                slug: 'home',
                collection: 'pages',
                status: 'PUBLISHED',
                // Editor set an explicit canonical path for the homepage.
                data: { title: 'Home', slug: 'home', path: '/' },
                updatedAt: new Date('2026-03-10T09:00:00Z'),
            },
            {
                id: '2',
                slug: 'about',
                collection: 'pages',
                status: 'PUBLISHED',
                // Explicit path that differs from the bare slug.
                data: { title: 'About', slug: 'about', path: '/about-us' },
                updatedAt: new Date('2026-03-11T09:00:00Z'),
            },
        ];
        initDB(createMockDB(docs));
        const handler = handleActuateAPI({
            prismaClient: createMockDB(docs),
            config: {
                seo: { siteUrl: 'https://example.com' },
                collections: {
                    pages: {
                        slug: 'pages',
                        labels: { singular: 'P', plural: 'Pp' },
                        urlPrefix: '',
                        type: 'page',
                        fields: {},
                    },
                },
            },
        });
        const response = await handler(new Request('https://example.com/api/cms/sitemaps/pages.xml'));
        const text = await response.text();
        // Homepage matches the canonical exactly (no trailing slash), as produced
        // by composePageMeta — sitemap and canonical must never disagree.
        expect(text).toContain('<loc>https://example.com</loc>');
        expect(text).toContain('<loc>https://example.com/about-us</loc>');
        // The non-canonical slug-derived URLs must not appear.
        expect(text).not.toContain('<loc>https://example.com/home</loc>');
        expect(text).not.toContain('<loc>https://example.com/about</loc>');
    });
    it('falls back to the site root for a home/index slug without an explicit path', async () => {
        const docs = [
            {
                id: '1',
                slug: 'home',
                collection: 'pages',
                status: 'PUBLISHED',
                data: { title: 'Home', slug: 'home' },
                updatedAt: new Date('2026-03-10T09:00:00Z'),
            },
        ];
        initDB(createMockDB(docs));
        const handler = handleActuateAPI({
            prismaClient: createMockDB(docs),
            config: {
                seo: { siteUrl: 'https://example.com' },
                collections: {
                    pages: {
                        slug: 'pages',
                        labels: { singular: 'P', plural: 'Pp' },
                        urlPrefix: '',
                        type: 'page',
                        fields: {},
                    },
                },
            },
        });
        const response = await handler(new Request('https://example.com/api/cms/sitemaps/pages.xml'));
        const text = await response.text();
        expect(text).toContain('<loc>https://example.com</loc>');
        expect(text).not.toContain('<loc>https://example.com/home</loc>');
    });
    it('excludes noindexed documents from the sitemap', async () => {
        const docs = [
            {
                id: '1',
                slug: 'visible',
                collection: 'pages',
                status: 'PUBLISHED',
                data: { title: 'Visible', slug: 'visible' },
            },
            {
                id: '2',
                slug: 'hidden-bool',
                collection: 'pages',
                status: 'PUBLISHED',
                data: { title: 'Hidden', slug: 'hidden-bool', noIndex: true },
            },
            {
                id: '3',
                slug: 'hidden-policy',
                collection: 'pages',
                status: 'PUBLISHED',
                data: { title: 'Hidden', slug: 'hidden-policy', robotsPolicy: 'noindex-nofollow' },
            },
            {
                id: '4',
                slug: 'hidden-legacy',
                collection: 'pages',
                status: 'PUBLISHED',
                data: { title: 'Hidden', slug: 'hidden-legacy', noindex: true },
            },
        ];
        initDB(createMockDB(docs));
        const handler = handleActuateAPI({
            prismaClient: createMockDB(docs),
            config: {
                seo: { siteUrl: 'https://example.com' },
                collections: {
                    pages: {
                        slug: 'pages',
                        labels: { singular: 'P', plural: 'Pp' },
                        urlPrefix: '',
                        type: 'page',
                        fields: {},
                    },
                },
            },
        });
        const response = await handler(new Request('https://example.com/api/cms/sitemaps/pages.xml'));
        const text = await response.text();
        expect(text).toContain('<loc>https://example.com/visible</loc>');
        expect(text).not.toContain('hidden-bool');
        expect(text).not.toContain('hidden-policy');
        expect(text).not.toContain('hidden-legacy');
    });
    it('drops post-type collections when includePostsInSitemap is off', async () => {
        // The crawl toggle lives in the SEO overrides document (module settings).
        const overridesDoc = {
            id: 'seo-cfg',
            slug: 'seo-config',
            collection: '__seo_config__',
            data: { module: { includePostsInSitemap: false } },
        };
        initDB(createMockDB([overridesDoc]));
        const handler = handleActuateAPI({
            prismaClient: createMockDB([overridesDoc]),
            config: {
                seo: { siteUrl: 'https://example.com' },
                collections: {
                    pages: {
                        slug: 'pages',
                        labels: { singular: 'P', plural: 'Pp' },
                        urlPrefix: '',
                        type: 'page',
                        fields: {},
                    },
                    posts: {
                        slug: 'posts',
                        labels: { singular: 'Post', plural: 'Posts' },
                        urlPrefix: 'blog',
                        type: 'post',
                        fields: {},
                    },
                },
            },
        });
        const index = await handler(new Request('https://example.com/api/cms/sitemap.xml'));
        const indexText = await index.text();
        expect(indexText).toContain('/api/cms/sitemaps/pages.xml');
        expect(indexText).not.toContain('/api/cms/sitemaps/posts.xml');
        // The post sitemap itself must also 404 so it can't be reached directly.
        const direct = await handler(new Request('https://example.com/api/cms/sitemaps/posts.xml'));
        expect(direct.status).toBe(404);
    });
    it('emits hreflang alternates for translated documents when i18n is configured', async () => {
        const docs = [
            {
                id: 'en',
                slug: 'about',
                collection: 'pages',
                status: 'PUBLISHED',
                locale: 'en',
                localeGroupId: 'grp-1',
                data: { title: 'About', slug: 'about', path: '/about' },
            },
            {
                id: 'es',
                slug: 'sobre-nosotros',
                collection: 'pages',
                status: 'PUBLISHED',
                locale: 'es',
                localeGroupId: 'grp-1',
                data: { title: 'Sobre', slug: 'sobre-nosotros', path: '/es/sobre-nosotros' },
            },
        ];
        initDB(createMockDB(docs));
        const handler = handleActuateAPI({
            prismaClient: createMockDB(docs),
            config: {
                seo: { siteUrl: 'https://example.com' },
                i18n: {
                    defaultLocale: 'en',
                    locales: [
                        { code: 'en', label: 'English' },
                        { code: 'es', label: 'Español' },
                    ],
                },
                collections: {
                    pages: {
                        slug: 'pages',
                        labels: { singular: 'P', plural: 'Pp' },
                        urlPrefix: '',
                        type: 'page',
                        fields: {},
                    },
                },
            },
        });
        const response = await handler(new Request('https://example.com/api/cms/sitemaps/pages.xml'));
        const text = await response.text();
        expect(text).toContain('xmlns:xhtml="http://www.w3.org/1999/xhtml"');
        expect(text).toContain('hreflang="en"');
        expect(text).toContain('hreflang="es"');
        expect(text).toContain('hreflang="x-default"');
        expect(text).toContain('href="https://example.com/about"');
        expect(text).toContain('href="https://example.com/es/sobre-nosotros"');
    });
    it('returns 404 for sitemap of an unknown collection', async () => {
        const handler = handleActuateAPI({
            prismaClient: createMockDB([]),
            config: {
                seo: { siteUrl: 'https://example.com' },
                collections: {
                    pages: { slug: 'pages', labels: { singular: 'P', plural: 'P' }, fields: {} },
                },
            },
        });
        const response = await handler(new Request('https://example.com/api/cms/sitemaps/unknown.xml'));
        expect(response.status).toBe(404);
    });
    it('includes archivePath in a post-type sitemap', async () => {
        const docs = [
            {
                id: '1',
                slug: 'first',
                collection: 'posts',
                status: 'PUBLISHED',
                data: { title: 'First', slug: 'first' },
            },
        ];
        initDB(createMockDB(docs));
        const handler = handleActuateAPI({
            prismaClient: createMockDB(docs),
            config: {
                seo: { siteUrl: 'https://example.com' },
                collections: {
                    posts: {
                        slug: 'posts',
                        labels: { singular: 'Post', plural: 'Posts' },
                        urlPrefix: 'blog',
                        type: 'post',
                        seo: { archivePath: '/blog' },
                        fields: {},
                    },
                },
            },
        });
        const response = await handler(new Request('https://example.com/api/cms/sitemaps/posts.xml'));
        const text = await response.text();
        expect(text).toContain('<loc>https://example.com/blog</loc>');
        expect(text).toContain('<loc>https://example.com/blog/first</loc>');
    });
    it('serves /robots.txt with a Sitemap reference', async () => {
        const handler = handleActuateAPI({
            prismaClient: createMockDB([]),
            config: {
                seo: { siteUrl: 'https://example.com' },
                collections: {},
            },
        });
        const response = await handler(new Request('https://example.com/api/cms/robots.txt'));
        expect(response.status).toBe(200);
        expect(response.headers.get('Content-Type')).toContain('text/plain');
        const text = await response.text();
        expect(text).toMatch(/^User-agent: \*/m);
        expect(text).toContain('Disallow: /admin');
        // robots advertises the canonical public sitemap URL, not the internal mount.
        expect(text).toContain('Sitemap: https://example.com/sitemap.xml');
        expect(text).not.toContain('/api/cms/sitemap.xml');
    });
    it('blocks the whole public site in robots.txt when indexEntireSite is off', async () => {
        const overridesDoc = {
            id: 'seo-cfg',
            slug: 'seo-config',
            collection: '__seo_config__',
            data: { module: { indexEntireSite: false } },
        };
        initDB(createMockDB([overridesDoc]));
        const handler = handleActuateAPI({
            prismaClient: createMockDB([overridesDoc]),
            config: { seo: { siteUrl: 'https://example.com' }, collections: {} },
        });
        const response = await handler(new Request('https://example.com/api/cms/robots.txt'));
        const text = await response.text();
        expect(text).toMatch(/^User-agent: \*/m);
        // Blanket block (which already covers /admin + /api); no per-path Allow.
        expect(text).toMatch(/^Disallow: \/$/m);
        expect(text).not.toMatch(/^Allow: \/$/m);
        // A deindexed site must not advertise a sitemap.
        expect(text).not.toContain('Sitemap:');
    });
    it('serves empty sitemaps when indexEntireSite is off', async () => {
        const overridesDoc = {
            id: 'seo-cfg',
            slug: 'seo-config',
            collection: '__seo_config__',
            data: { module: { indexEntireSite: false } },
        };
        const pageDoc = {
            id: 'p1',
            slug: 'about',
            collection: 'pages',
            status: 'PUBLISHED',
            data: { title: 'About', slug: 'about' },
        };
        initDB(createMockDB([overridesDoc, pageDoc]));
        const handler = handleActuateAPI({
            prismaClient: createMockDB([overridesDoc, pageDoc]),
            config: {
                seo: { siteUrl: 'https://example.com' },
                collections: {
                    pages: {
                        slug: 'pages',
                        labels: { singular: 'P', plural: 'Pp' },
                        urlPrefix: '',
                        type: 'page',
                        fields: {},
                    },
                },
            },
        });
        const index = await handler(new Request('https://example.com/api/cms/sitemap.xml'));
        expect(index.status).toBe(200);
        const indexText = await index.text();
        expect(indexText).toContain('<sitemapindex');
        expect(indexText).not.toContain('<sitemap>');
        const col = await handler(new Request('https://example.com/api/cms/sitemaps/pages.xml'));
        expect(col.status).toBe(200);
        const colText = await col.text();
        expect(colText).toContain('<urlset');
        expect(colText).not.toContain('<url>');
    });
    it('appends AI bot blocks when seo.robots.blockAIBots is true', async () => {
        const handler = handleActuateAPI({
            prismaClient: createMockDB([]),
            config: {
                seo: { siteUrl: 'https://example.com', robots: { blockAIBots: true } },
                collections: {},
            },
        });
        const response = await handler(new Request('https://example.com/api/cms/robots.txt'));
        const text = await response.text();
        expect(text).toContain('User-agent: GPTBot');
        expect(text).toContain('User-agent: ClaudeBot');
        expect(text).toContain('Disallow: /');
    });
    it('honors a nuanced aiPolicy (block training, allow retrieval)', async () => {
        const handler = handleActuateAPI({
            prismaClient: createMockDB([]),
            config: {
                seo: {
                    siteUrl: 'https://example.com',
                    robots: { aiPolicy: { training: 'block', retrieval: 'allow' } },
                },
                collections: {},
            },
        });
        const response = await handler(new Request('https://example.com/api/cms/robots.txt'));
        const text = await response.text();
        // Training crawler blocked…
        expect(text).toContain('User-agent: GPTBot');
        // …retrieval/answer-engine crawler left allowed (not in the file).
        expect(text).not.toContain('User-agent: PerplexityBot');
    });
    it('returns 404 for /robots.txt when seo.robots.disabled is true', async () => {
        const handler = handleActuateAPI({
            prismaClient: createMockDB([]),
            config: {
                seo: { siteUrl: 'https://example.com', robots: { disabled: true } },
                collections: {},
            },
        });
        const response = await handler(new Request('https://example.com/api/cms/robots.txt'));
        expect(response.status).toBe(404);
    });
    it('renders /og.png as an SVG OG card', async () => {
        const handler = handleActuateAPI({
            prismaClient: createMockDB([]),
            config: {
                seo: { siteUrl: 'https://example.com', siteName: 'Example' },
                collections: {},
            },
        });
        const response = await handler(new Request('https://example.com/api/cms/og.png?title=Hello%20World&description=Welcome'));
        expect(response.status).toBe(200);
        expect(response.headers.get('Content-Type')).toContain('image/svg+xml');
        const text = await response.text();
        expect(text).toContain('<svg');
        expect(text).toContain('Hello');
        expect(text).toContain('Example');
    });
    it('returns 404 for /og.png when seo.ogImage.disabled is true', async () => {
        const handler = handleActuateAPI({
            prismaClient: createMockDB([]),
            config: {
                seo: { siteUrl: 'https://example.com', ogImage: { disabled: true } },
                collections: {},
            },
        });
        const response = await handler(new Request('https://example.com/api/cms/og.png?title=X'));
        expect(response.status).toBe(404);
    });
    it('enriches /resolve with composed jsonLd and meta', async () => {
        const docs = [
            {
                id: 'post-1',
                slug: 'hello',
                collection: 'posts',
                status: 'PUBLISHED',
                data: {
                    title: 'Hello World',
                    slug: 'hello',
                    metaDescription: 'A first post',
                    authorName: 'Jane',
                },
                publishedAt: new Date('2026-02-01T00:00:00Z'),
                updatedAt: new Date('2026-02-10T00:00:00Z'),
            },
        ];
        initDB(createMockDB(docs));
        const handler = handleActuateAPI({
            prismaClient: createMockDB(docs),
            config: {
                seo: {
                    siteUrl: 'https://example.com',
                    siteName: 'Example',
                    organization: { name: 'Example Inc' },
                },
                collections: {
                    posts: {
                        slug: 'posts',
                        labels: { singular: 'Post', plural: 'Posts' },
                        urlPrefix: 'blog',
                        type: 'post',
                        fields: {},
                    },
                },
            },
        });
        const response = await handler(new Request('https://example.com/api/cms/resolve?path=/blog/hello'));
        expect(response.status).toBe(200);
        const body = (await response.json());
        expect(body.meta).toBeDefined();
        expect(body.meta.title).toBe('Hello World');
        expect(body.meta.canonical).toBe('https://example.com/blog/hello');
        expect(body.meta.tags['og:title']).toBe('Hello World');
        // /resolve now returns a connected @graph rather than a flat object.
        expect(body.jsonLd['@context']).toBe('https://schema.org');
        const graph = body.jsonLd['@graph'];
        expect(Array.isArray(graph)).toBe(true);
        const article = graph.find((n) => {
            const t = n['@type'];
            return t === 'BlogPosting' || (Array.isArray(t) && t.includes('BlogPosting'));
        });
        expect(article).toBeDefined();
        expect(graph.some((n) => n['@type'] === 'WebSite')).toBe(true);
        const org = graph.find((n) => n['@type'] === 'Organization');
        expect(org).toMatchObject({ name: 'Example Inc' });
        const person = graph.find((n) => n['@type'] === 'Person');
        expect(person).toMatchObject({ name: 'Jane' });
        expect(typeof body.jsonLdHtml).toBe('string');
        expect(body.jsonLdHtml).toContain('<script type="application/ld+json">');
    });
});
//# sourceMappingURL=public-seo.test.js.map