test: unit tests for the schema builder, crawler and page helpers

- schema: types per kind, @id links, every node kind, the publisher and
  local business, every validator rule, custom JSON-LD caps and merge
- crawl: HTML parse, each check's positive and negative case, fix routes
  with the fitting tool, the rendered comparison, allowRequest,
  resolverRules and NewRenderer
- pagination, alternates and x-default, primary parents, the filter's
  addresses, registry paths and fields, auto-link addresses
This commit is contained in:
Jakub Zych
2026-11-04 19:43:31 +01:00
parent dfc85bc805
commit 82b0dacff9
14 changed files with 1543 additions and 0 deletions

View File

@@ -0,0 +1,72 @@
package classes
import (
"testing"
"git.golem15.com/golem15/sm-seo-plugin/models"
"git.golem15.com/golem15/summercms/modules/pact"
)
// TestPrimaryParent pins D-86: the stored choice while the record still
// has that parent, else the first parent with gone set for a stale
// choice, and no parent at all (gone only when a choice was stored).
func TestPrimaryParent(t *testing.T) {
a := pact.ContentRef{Type: "cat", ID: "1"}
b := pact.ContentRef{Type: "cat", ID: "2"}
rec := &pact.ContentRecord{Parents: []pact.ContentRef{a, b}}
for _, tc := range []struct {
stored string
want pact.ContentRef
ok, gone bool
}{
{"", a, true, false}, {"cat:2", b, true, false}, {"cat:9", a, true, true}, {"tag:2", a, true, true},
} {
got, ok, gone := PrimaryParent(rec, tc.stored)
if got != tc.want || ok != tc.ok || gone != tc.gone {
t.Errorf("PrimaryParent(%q) = %v %v %v, want %v %v %v", tc.stored, got, ok, gone, tc.want, tc.ok, tc.gone)
}
}
if _, ok, gone := PrimaryParent(&pact.ContentRecord{}, ""); ok || gone {
t.Fatal("no parents, nothing stored")
}
if _, ok, gone := PrimaryParent(nil, "cat:1"); ok || !gone {
t.Fatal("no record with a stored choice is gone")
}
if ParentValue(b) != "cat:2" {
t.Fatal("ParentValue is <type>:<id>")
}
}
// TestHomePath pins the home crumb's address: /<locale> when the page is
// under that prefix (any case), else /.
func TestHomePath(t *testing.T) {
for _, tc := range []struct{ locale, path, want string }{
{"pl", "/blog/a", "/"}, {"en", "/en/blog/a", "/en"}, {"en", "/EN", "/en"}, {"en", "/english", "/"}, {"", "/en/a", "/"},
} {
if got := homePath(tc.locale, tc.path); got != tc.want {
t.Errorf("homePath(%q, %q) = %q, want %q", tc.locale, tc.path, got, tc.want)
}
}
}
// TestLocaleOfAndEntryData pins the exact locale lookup (an empty address
// does not count) and the entry data reader, and the depth cap.
func TestLocaleOfAndEntryData(t *testing.T) {
rec := &pact.ContentRecord{Locales: []pact.ContentLocale{{Locale: "pl", URL: "/a"}, {Locale: "en", URL: " "}}}
if l, ok := localeOf(rec, "pl"); !ok || l.URL != "/a" {
t.Fatal("pl is there")
}
if _, ok := localeOf(rec, "en"); ok {
t.Fatal("en has no address")
}
if _, ok := localeOf(nil, "pl"); ok {
t.Fatal("no record")
}
e := models.Entry{Data: map[string]any{"primary_parent": " cat:1 ", "n": 5}}
if entryData(e, "primary_parent") != "cat:1" || entryData(e, "n") != "" || entryData(models.Entry{}, "x") != "" {
t.Fatal("entryData is wrong")
}
if MaxCrumbDepth != 6 {
t.Fatalf("MaxCrumbDepth = %d", MaxCrumbDepth)
}
}