package contentdata import ( "os" "path/filepath" "regexp" "testing" ) func writeContent(t *testing.T, name, body string) string { t.Helper() dir := t.TempDir() if err := os.WriteFile(filepath.Join(dir, name), []byte(body), 0o644); err != nil { t.Fatal(err) } return dir } func TestLoadGlossaryOrderAndLookup(t *testing.T) { dir := writeContent(t, "glossary.yaml", ` terms: - slug: b-term term: B short: short b body: |- Body b with {base} link. - slug: a-term term: A short: short a body: body a `) g, err := LoadGlossary(dir) if err != nil { t.Fatalf("LoadGlossary: %v", err) } // File order, not alphabetical — the index page renders in this order. if len(g.Terms) != 2 || g.Terms[0].Slug != "b-term" || g.Terms[1].Slug != "a-term" { t.Errorf("order wrong: %+v", g.Terms) } e, ok := g.Get("b-term") if !ok || e.Term != "B" || e.Body != "Body b with {base} link." { t.Errorf("Get(b-term) = %+v, %v", e, ok) } if _, ok := g.Get("missing"); ok { t.Error("Get(missing) should report not-found") } } func TestLoadGlossaryFailsLoud(t *testing.T) { cases := map[string]string{ "empty terms": "terms: []\n", "missing field": "terms:\n- slug: x\n term: X\n short: s\n", // no body "missing slug": "terms:\n- term: X\n short: s\n body: b\n", "duplicate slug": "terms:\n- {slug: x, term: X, short: s, body: b}\n- {slug: x, term: Y, short: s, body: b}\n", "empty required": "terms:\n- {slug: x, term: X, short: '', body: b}\n", // falsy value fails, like the Python's `not entry.get(f)` } for name, body := range cases { if _, err := LoadGlossary(writeContent(t, "glossary.yaml", body)); err == nil { t.Errorf("%s: expected an error", name) } } } func TestLoadPages(t *testing.T) { dir := writeContent(t, "pages.yaml", ` pages: about: title: "About | X" description: >- Folded description. `) p, err := LoadPages(dir) if err != nil { t.Fatalf("LoadPages: %v", err) } if p["about"].Title != "About | X" || p["about"].Description != "Folded description." { t.Errorf("pages = %+v", p) } if _, err := LoadPages(writeContent(t, "pages.yaml", "pages: {}\n")); err == nil { t.Error("empty pages mapping should fail loud") } if _, err := LoadPages(writeContent(t, "pages.yaml", "pages:\n about: {title: T}\n")); err == nil { t.Error("missing description should fail loud") } } // Smoke-check against the real committed content files (frontend/content/), // when present — the same files the Python loader validated at import. func TestLoadRealContentFiles(t *testing.T) { dir := filepath.Join("..", "..", "..", "content") if _, err := os.Stat(filepath.Join(dir, "glossary.yaml")); err != nil { t.Skipf("real content dir not available: %v", err) } g, err := LoadGlossary(dir) if err != nil { t.Fatalf("LoadGlossary(real): %v", err) } if len(g.Terms) == 0 { t.Error("real glossary should have terms") } p, err := LoadPages(dir) if err != nil { t.Fatalf("LoadPages(real): %v", err) } for _, key := range []string{"about", "privacy", "hub", "glossary_index"} { if _, ok := p[key]; !ok { t.Errorf("real pages.yaml missing key %q (content.py reads it)", key) } } } // pages.yaml's title/description are interpolated as plain strings into //