/* Unit tests for organization jsonld covering RFC-0745: buildOrganizationNode makesOffer priceCurrency; buildOrganizationNode priceRange. Not a contract source of truth — the module under test owns the authoritative behavior; fixtures are minimal scaffolding only. RFC-0745: initial test for priceCurrency in makesOffer Offer nodes. */ import { describe, expect, it } from "vitest"; import { buildOrganizationNode } from "../jsonld/organization.ts"; import { createJsonLdContext } from "../jsonld/context.ts"; import type { SemanticPageModel, SemanticOrganization } from "../models.ts"; function makeOrgWithPrices( prices: Array<{ id: string; label: string; amount: string; currency?: string }>, ): SemanticOrganization { return { name: "Test Org", description: "Test organization", url: "https://example.com", offer: { prices }, }; } function makeModel(org: SemanticOrganization): SemanticPageModel { return { type: "home", lang: "de", url: "https://example.com/de", title: "Test Page", description: "Test description", breadcrumbs: [], blocks: [], organization: org, }; } describe("RFC-0745: buildOrganizationNode makesOffer priceCurrency", () => { it("emits priceCurrency when SemanticPrice has currency", () => { const org = makeOrgWithPrices([ { id: "monthly", label: "Monthly", amount: "70.00", currency: "EUR" }, ]); const context = createJsonLdContext(makeModel(org)); const node = buildOrganizationNode(context); const makesOffer = node.makesOffer as Array>; expect(makesOffer).toHaveLength(1); expect(makesOffer[0].priceCurrency).toBe("EUR"); const priceSpec = makesOffer[0].priceSpecification as Record; expect(priceSpec.price).toBe("70.00"); }); it("omits priceCurrency when SemanticPrice has no currency", () => { const org = makeOrgWithPrices([{ id: "monthly", label: "Monthly", amount: "70.00" }]); const context = createJsonLdContext(makeModel(org)); const node = buildOrganizationNode(context); const makesOffer = node.makesOffer as Array>; expect(makesOffer).toHaveLength(1); expect(makesOffer[0].priceCurrency).toBeUndefined(); }); it("emits priceCurrency for each offer when multiple prices have currency", () => { const org = makeOrgWithPrices([ { id: "monthly", label: "Monthly", amount: "70.00", currency: "EUR" }, { id: "yearly", label: "Yearly", amount: "840.00", currency: "EUR" }, ]); const context = createJsonLdContext(makeModel(org)); const node = buildOrganizationNode(context); const makesOffer = node.makesOffer as Array>; expect(makesOffer).toHaveLength(2); expect(makesOffer[0].priceCurrency).toBe("EUR"); expect(makesOffer[1].priceCurrency).toBe("EUR"); }); }); describe("buildOrganizationNode priceRange", () => { it("emits priceRange as min–max with currency when multiple prices exist", () => { const org = makeOrgWithPrices([ { id: "monthly", label: "Monthly", amount: "70.00", currency: "EUR" }, { id: "yearly", label: "Yearly", amount: "700.00", currency: "EUR" }, { id: "setup", label: "Setup", amount: "200.00", currency: "EUR" }, ]); const context = createJsonLdContext(makeModel(org)); const node = buildOrganizationNode(context); expect(node.priceRange).toBe("70–700 EUR"); }); it("emits single-amount priceRange when all prices are equal", () => { const org = makeOrgWithPrices([ { id: "monthly", label: "Monthly", amount: "70.00", currency: "EUR" }, ]); const context = createJsonLdContext(makeModel(org)); const node = buildOrganizationNode(context); expect(node.priceRange).toBe("70 EUR"); }); it("omits priceRange when no prices exist", () => { const org: SemanticOrganization = { name: "Test Org", description: "Test organization", url: "https://example.com", }; const context = createJsonLdContext(makeModel(org)); const node = buildOrganizationNode(context); expect(node.priceRange).toBeUndefined(); }); it("omits priceRange when price amounts are non-numeric", () => { const org = makeOrgWithPrices([ { id: "custom", label: "Custom", amount: "auf Anfrage", currency: "EUR" }, ]); const context = createJsonLdContext(makeModel(org)); const node = buildOrganizationNode(context); expect(node.priceRange).toBe(""); }); it("emits priceRange without currency when prices lack currency", () => { const org = makeOrgWithPrices([ { id: "monthly", label: "Monthly", amount: "70.00" }, { id: "setup", label: "Setup", amount: "200.00" }, ]); const context = createJsonLdContext(makeModel(org)); const node = buildOrganizationNode(context); expect(node.priceRange).toBe("70–200"); }); });