/* RFC-0211: round-trip + edge-case tests for the claim subject address codec. Not a contract source of truth — the module under test owns the authoritative behavior; fixtures are minimal scaffolding only. RFC-0211: initial codec tests. */ import { test, expect } from "vitest"; import { parseClaimSubject, formatClaimSubject, claimSubjectsEqual, ClaimSubjectParseError, } from "../claim.ts"; test("parse: lang-scoped subject with simple field", () => { const s = parseClaimSubject("business/de/location#residents"); expect(s.collection).toBe("business"); expect(s.lang).toBe("de"); expect(s.file).toBe("location"); expect(s.fieldPath).toEqual(["residents"]); }); test("parse: lang-scoped subject with nested field path", () => { const s = parseClaimSubject("business/uk/offer#price.monthly"); expect(s.lang).toBe("uk"); expect(s.file).toBe("offer"); expect(s.fieldPath).toEqual(["price", "monthly"]); }); test("parse: collection without lang", () => { const s = parseClaimSubject("surface/landing#headline"); expect(s.collection).toBe("surface"); expect(s.lang).toBe(undefined); expect(s.file).toBe("landing"); expect(s.fieldPath).toEqual(["headline"]); }); test("parse: nested file path under a lang", () => { const s = parseClaimSubject("business/de/faq/df-start#answer"); expect(s.lang).toBe("de"); expect(s.file).toBe("faq/df-start"); expect(s.fieldPath).toEqual(["answer"]); }); test("format is the inverse of parse", () => { for (const raw of [ "business/de/location#residents", "business/uk/offer#price.monthly", "surface/landing#headline", "business/de/faq/df-start#answer", ]) { expect(formatClaimSubject(parseClaimSubject(raw))).toBe(raw); } }); test("claimSubjectsEqual compares canonical forms", () => { const a = parseClaimSubject("business/de/location#residents"); const b = parseClaimSubject("business/de/location#residents"); const c = parseClaimSubject("business/uk/location#residents"); expect(claimSubjectsEqual(a, b)).toBeTruthy(); expect(!claimSubjectsEqual(a, c)).toBeTruthy(); }); test("parse: a two-letter file stem is not mistaken for a lang when alone", () => { // Only treated as lang when a file segment still remains after it. const s = parseClaimSubject("glossary/de#term"); expect(s.collection).toBe("glossary"); expect(s.lang).toBe(undefined); expect(s.file).toBe("de"); expect(s.fieldPath).toEqual(["term"]); }); test("parse: missing # throws", () => { expect(() => parseClaimSubject("business/de/location")).toThrow(ClaimSubjectParseError); }); test("parse: empty field path throws", () => { expect(() => parseClaimSubject("business/de/location#")).toThrow(ClaimSubjectParseError); }); test("parse: too-short path throws", () => { expect(() => parseClaimSubject("business#x")).toThrow(ClaimSubjectParseError); });