Files
sm-sitemap-plugin/classes/tiers_test.go
Jakub Zych 4e55939a1f test(17-06): sitemap parity unit tests
- TestURLTo (every Url::to golden case, BackendURL, URLPath),
  TestXMLEscaping (PHP XmlEscapingTest as behaviour), TestTiers (each
  default rule, first match, off, bad pattern fails Boot), TestRewrite,
  TestHooks, TestURLCap, TestManifest (fail-safe reads, key
  normalization, dates), TestFillable (PHP MassAssignmentTest),
  TestDefinitionItemJSON, TestBackendURL (trusted forwarded proto)
- TestImportWinter on Postgres: maps and drops with report, --theme,
  --dry-run, --force, settings upsert, refusals
2026-10-12 19:38:04 +02:00

116 lines
4.5 KiB
Go

package classes_test
import (
"os"
"path/filepath"
"strings"
"testing"
sitemap "git.golem15.com/golem15/sm-sitemap-plugin"
"git.golem15.com/golem15/sm-sitemap-plugin/classes"
"git.golem15.com/golem15/sm-sitemap-plugin/models"
"git.golem15.com/golem15/summercms/modules/backpack"
"git.golem15.com/golem15/summercms/modules/compass"
)
// TestTiers pins the priority tiers (D-13): each default rule of the PHP
// getPriorityForUrl with paths from its list, trailing slashes, the first
// match winning, the settings' values, tiers turned off, a host list that
// replaces the defaults, and a bad rule failing the plugin's Boot.
func TestTiers(t *testing.T) {
tiers := pluginTiers(t)
if len(tiers) != 5 {
t.Fatalf("default rules = %d", len(tiers))
}
s := models.DefaultSettings()
for url, want := range map[string]string{
"https://h": "1.0",
"https://h/": "1.0",
"https://h/en": "1.0",
"https://h/en/": "1.0",
"https://h/uslugi/strony-www": "0.8",
"https://h/en/services/web": "0.8",
"https://h/realizacje/projekt/": "0.8",
"https://h/en/work/x": "0.8",
"https://h/blog/kategoria/wpis": "0.6",
"https://h/en/blog/category/post/": "0.6",
"https://h/blog": "0.4",
"https://h/blog/kategoria": "0.4",
"https://h/uslugi": "0.4",
"https://h/en/work": "0.4",
"https://h/polityka-prywatnosci": "0.2",
"https://h/en/terms/": "0.2",
"https://h/laboratorium-ai/zabawa-animacja": "0.2",
"https://h/en/ai-lab/blob-playground": "0.2",
"https://h/kontakt?x=1": "0.2",
} {
if got, ok := tiers.Priority(url, s); !ok || got != want {
t.Errorf("Priority(%s) = %q %v, want %s", url, got, ok, want)
}
}
for _, url := range []string{"https://h/other", "https://h/blog/a/b/c", "https://h/uslugi/a/b", "https://h/en/blogs/x", "https://h/kontakt/more"} {
if got, ok := tiers.Priority(url, s); ok {
t.Errorf("Priority(%s) = %q, want no rule", url, got)
}
}
custom := s
custom.PriorityBlog = text("0.65")
if got, _ := tiers.Priority("https://h/blog/a/b", custom); got != "0.65" {
t.Fatalf("custom blog priority = %q", got)
}
off := s
off.EnablePriorityTiers = false
if _, ok := tiers.Priority("https://h/", off); ok {
t.Fatal("tiers apply while turned off")
}
// First match wins: an exact rule listed before a pattern that also matches.
ordered, err := classes.CompileTiers([]classes.TierConfig{
{Setting: models.PriorityLegal, Exact: []string{"/blog"}},
{Setting: models.PriorityCategories, Pattern: "^/blog$"},
})
if err != nil {
t.Fatal(err)
}
if got, _ := ordered.Priority("https://h/blog/", s); got != "0.2" {
t.Fatalf("first match = %q", got)
}
if empty, err := classes.CompileTiers(nil); err != nil || len(empty) != 0 {
t.Fatalf("no rules = %v %v", empty, err)
}
if none, err := classes.LoadTiers(nil); err != nil || len(none) != 0 {
t.Fatalf("LoadTiers(nil) = %v %v", none, err)
}
// Every refused rule names its index; a bad RE2 pattern too.
for name, rule := range map[string]classes.TierConfig{
"unknown setting": {Setting: "priority_other", Exact: []string{""}},
"neither": {Setting: models.PriorityHomepage},
"both": {Setting: models.PriorityHomepage, Exact: []string{""}, Pattern: "^/$"},
"lookahead": {Setting: models.PriorityBlog, Pattern: "^/(?=blog)"},
"unbalanced": {Setting: models.PriorityBlog, Pattern: "^/(blog"},
} {
_, err := classes.CompileTiers([]classes.TierConfig{{Setting: models.PriorityHomepage, Exact: []string{""}}, rule})
if err == nil || !strings.Contains(err.Error(), classes.TiersConfigKey+"[1]") {
t.Errorf("%s: err = %v", name, err)
}
}
// A bad host rule fails the plugin's Boot.
dir := t.TempDir()
if err := os.WriteFile(filepath.Join(dir, "golem15.yaml"), []byte("sitemap:\n priority_tiers:\n - setting: priority_blog\n pattern: '^/(blog'\n"), 0o644); err != nil {
t.Fatal(err)
}
cfg, err := compass.Open(compass.Options{Dir: dir, Environ: []string{}})
if err != nil {
t.Fatal(err)
}
p := &sitemap.Plugin{}
if err := cfg.MergePlugin("golem15.sitemap", p.ConfigFS()); err != nil {
t.Fatal(err)
}
if err := p.Boot(backpack.New(cfg)); err == nil || !strings.Contains(err.Error(), "priority_tiers[0]") {
t.Fatalf("Boot with a bad pattern = %v", err)
}
}