import { describe, it, expect } from "vitest";
import { readFileSync } from "node:fs";
import { qualityScore } from "@/lib/quality";
import { toolRecordSchema, WORD } from "@/lib/content/schema";
import { renderMarkdown, slugify } from "@/lib/text";
const duck = JSON.parse(readFileSync("content/tools/duckdb.json", "utf8"));
describe("content schema", () => {
it("accepts the reference record", () => { expect(toolRecordSchema.safeParse(duck).success).toBe(true); });
it("rejects bad slugs, schemes, enums and short summaries", () => {
expect(toolRecordSchema.safeParse({ ...duck, slug: "Duck DB" }).success).toBe(false);
expect(toolRecordSchema.safeParse({ ...duck, homepage_url: "ftp://x.org" }).success).toBe(false);
expect(toolRecordSchema.safeParse({ ...duck, source_model: "freeware" }).success).toBe(false);
expect(toolRecordSchema.safeParse({ ...duck, summary: "too short" }).success).toBe(false);
expect(toolRecordSchema.safeParse({ ...duck, sources: [] }).success).toBe(false);
});
it("defaults visibility public and status reviewed", () => { const r = toolRecordSchema.parse({ ...duck, visibility: undefined, editorial_status: undefined }); expect(r.visibility).toBe("public"); expect(r.editorial_status).toBe("reviewed"); });
});
describe("quality score", () => {
const p = toolRecordSchema.parse(duck);
it("is deterministic, bounded and rewards evidence/link state", () => {
const a = qualityScore(p, "unchecked"), b = qualityScore(p, "ok"), c = qualityScore(p, "broken");
expect(a).toBe(qualityScore(p, "unchecked")); expect(b).toBeGreaterThan(a); expect(c).toBeLessThan(a); expect(b).toBeLessThanOrEqual(100); expect(c).toBeGreaterThanOrEqual(0);
});
it("penalizes thin records", () => { const thin = { ...p, description: "x ".repeat(60), capabilities: ["a", "b"], limitations: [], workflows: [], advantages: [], alternatives: [], tags: [], use_cases: [], docs_url: undefined, repo_url: undefined, license_spdx: undefined, sources: p.sources.slice(0, 1), confidence: "low" as const, comparison_notes: undefined }; expect(qualityScore(thin)).toBeLessThan(40); });
it("WORD counts words", () => { expect(WORD(" a b\nc ")).toBe(3); });
});
describe("text", () => {
it("renderMarkdown strips scripts and adds rel noopener", () => { const h = renderMarkdown("Hi [x](https://a.com)
"); expect(h).not.toContain("