import { describe, it, expect } from "vitest";
import { buildJsonLd, renderJsonLdScript, resolveSchemaType, MissingPropertyError, } from "../lib/schema-mapping.js";
describe("resolveSchemaType", () => {
    it("maps known graph labels to schema.org types", () => {
        expect(resolveSchemaType("LocalBusiness")).toBe("LocalBusiness");
        expect(resolveSchemaType("Organization")).toBe("Organization");
        expect(resolveSchemaType("Person")).toBe("Person");
        expect(resolveSchemaType("Service")).toBe("Service");
        expect(resolveSchemaType("Product")).toBe("Product");
        expect(resolveSchemaType("CreativeWork")).toBe("Article");
        expect(resolveSchemaType("Article")).toBe("Article");
        expect(resolveSchemaType("FAQPage")).toBe("FAQPage");
        expect(resolveSchemaType("Listing")).toBe("RealEstateListing");
        expect(resolveSchemaType("RealEstateListing")).toBe("RealEstateListing");
        expect(resolveSchemaType("Event")).toBe("Event");
    });
    it("falls back to Thing for unknown labels", () => {
        expect(resolveSchemaType("UnknownLabel")).toBe("Thing");
    });
});
describe("buildJsonLd", () => {
    it("renders an Organization with required name", () => {
        const obj = buildJsonLd({
            label: "Organization",
            properties: { name: "Acme", website: "https://acme.test" },
        });
        expect(obj["@context"]).toBe("https://schema.org");
        expect(obj["@type"]).toBe("Organization");
        expect(obj.name).toBe("Acme");
        expect(obj.url).toBe("https://acme.test");
    });
    it("renders a LocalBusiness with nested PostalAddress", () => {
        const obj = buildJsonLd({
            label: "LocalBusiness",
            elementId: "4:abc:1",
            properties: {
                name: "Acme Plumbing",
                streetAddress: "1 High St",
                addressLocality: "Brighton",
                postalCode: "BN1 1AA",
            },
        });
        expect(obj["@id"]).toBe("4:abc:1");
        expect(obj.address).toEqual({
            "@type": "PostalAddress",
            streetAddress: "1 High St",
            addressLocality: "Brighton",
            postalCode: "BN1 1AA",
        });
    });
    it("renders a Person and synthesises name from givenName + familyName", () => {
        const obj = buildJsonLd({
            label: "Person",
            properties: {
                givenName: "Joel",
                familyName: "Smalley",
                email: "j@example.com",
            },
        });
        expect(obj["@type"]).toBe("Person");
        expect(obj.name).toBe("Joel Smalley");
        expect(obj.email).toBe("j@example.com");
    });
    it("renders a Service with an Offer when price is set", () => {
        const obj = buildJsonLd({
            label: "Service",
            properties: { name: "Boiler service", price: 120, priceCurrency: "GBP" },
        });
        expect(obj.offers).toEqual({
            "@type": "Offer",
            price: 120,
            priceCurrency: "GBP",
        });
    });
    it("renders an Article remapping title→headline and abstract→description", () => {
        const obj = buildJsonLd({
            label: "Article",
            properties: { title: "How boilers work", abstract: "Short summary" },
        });
        expect(obj.headline).toBe("How boilers work");
        expect(obj.description).toBe("Short summary");
    });
    it("renders an FAQPage with mainEntity Question/Answer pairs", () => {
        const obj = buildJsonLd({
            label: "FAQPage",
            properties: {
                name: "Boiler FAQ",
                questions: [
                    { name: "How long does it take?", acceptedAnswer: "About an hour." },
                    { name: "Do you charge call-out?", acceptedAnswer: "No." },
                ],
            },
        });
        expect(Array.isArray(obj.mainEntity)).toBe(true);
        const main = obj.mainEntity;
        expect(main).toHaveLength(2);
    });
    it("renders an Event with required name + startDate", () => {
        const obj = buildJsonLd({
            label: "Event",
            properties: { name: "Open day", startDate: "2026-06-01T10:00:00Z" },
        });
        expect(obj.startDate).toBe("2026-06-01T10:00:00Z");
    });
    it("throws MissingPropertyError when required property is absent", () => {
        expect(() => buildJsonLd({ label: "Event", properties: { name: "Open day" } })).toThrow(MissingPropertyError);
    });
    it("renders unknown labels as schema:Thing without throwing", () => {
        const obj = buildJsonLd({
            label: "Mystery",
            properties: { name: "Anonymous", description: "Unknown" },
        });
        expect(obj["@type"]).toBe("Thing");
        expect(obj.name).toBe("Anonymous");
    });
});
describe("renderJsonLdScript", () => {
    it("wraps the JSON in a script block", () => {
        const obj = buildJsonLd({
            label: "Organization",
            properties: { name: "Acme" },
        });
        const block = renderJsonLdScript(obj);
        expect(block).toMatch(/^<script type="application\/ld\+json">/);
        expect(block).toMatch(/<\/script>$/);
        expect(block).toContain('"Acme"');
    });
});
//# sourceMappingURL=schema-mapping.test.js.map