syntaxai/tdd.md · main · src / b32_edit_resolve.test.ts

b32_edit_resolve.test.ts 59 lines · 2075 bytes raw
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();
});