import { test, expect } from "bun:test"; import { resolveEdit } from "./b32_edit_resolve.ts"; test("resolves an existing sama page", () => { const r = resolveEdit("sama", "sorted"); expect(r).not.toBeNull(); expect(r?.pageUrl).toBe("/sama/discipline/sorted"); expect(r?.filePath).toBe("content/sama/sorted.md"); expect(r?.title).toMatch(/Sorted/); }); test("resolves an existing guide", () => { const r = resolveEdit("guides", "claude-code"); expect(r).not.toBeNull(); expect(r?.filePath).toBe("content/guides/claude-code.md"); }); test("resolves an existing blog post", () => { const r = resolveEdit("blog", "from-rules-to-checks"); expect(r).not.toBeNull(); expect(r?.filePath).toBe("content/blog/from-rules-to-checks.md"); }); test("returns null for unknown section", () => { expect(resolveEdit("admin", "x")).toBeNull(); expect(resolveEdit("etc", "passwd")).toBeNull(); }); test("returns null for unknown slug in a known section", () => { expect(resolveEdit("sama", "nonexistent-discipline")).toBeNull(); }); test("rejects path traversal in slug", () => { expect(resolveEdit("sama", "../sorted")).toBeNull(); expect(resolveEdit("sama", "..")).toBeNull(); expect(resolveEdit("sama", "/etc/passwd")).toBeNull(); }); test("rejects unsafe slug shapes", () => { expect(resolveEdit("sama", "Sorted")).toBeNull(); // uppercase expect(resolveEdit("sama", "")).toBeNull(); expect(resolveEdit("sama", "with space")).toBeNull(); expect(resolveEdit("sama", "-leading-dash")).toBeNull(); }); test("resolves nav-only sama pages (e.g. /sama/skill) via SITE_NAV fallback", () => { const r = resolveEdit("sama", "skill"); expect(r).not.toBeNull(); expect(r?.pageUrl).toBe("/sama/skill"); expect(r?.filePath).toBe("content/sama/skill.md"); expect(r?.title).toMatch(/SKILL/i); }); test("non-editable nav links (editPath:null) stay unresolvable", () => { // /sama/verify is in SITE_NAV but has editPath: null because it's // a verifier form, not a content/<...>.md doc. expect(resolveEdit("sama", "verify")).toBeNull(); });