Files
sm-sitemap-plugin/classes/lastmod_test.go
Jakub Zych 1048c01fd9 test: unit tests for the writer, News, IndexNow, HTML groups, slugs, lastmod and slots
- XML escaping and namespaces, no priority, the image cap and file names
- News window and cap, sources and languages, the publication name
- IndexNow batches of 10 000, answer outcomes, keys and the host filter
- HTML sitemap group order, tree order and paging
- default slugs, the effective type setting, lastmod config, slot edges
2026-11-04 19:36:10 +01:00

103 lines
3.2 KiB
Go

package classes
import (
"slices"
"strings"
"testing"
"time"
"git.golem15.com/golem15/summercms/modules/compass"
"git.golem15.com/golem15/summercms/modules/pact"
)
// TestRealChanges pins which saves move lastmod (D-30, RESEARCH Pitfall
// 4): nothing for an empty or ignored-only change list; every locale for a
// change on the record's own row; only the named locales for translated
// changes.
func TestRealChanges(t *testing.T) {
ignore := map[string]bool{"updated_at": true, "views": true}
for name, c := range map[string]struct {
changes []pact.RecordChange
any bool
all bool
locales []string
}{
"no-op save": {nil, false, false, nil},
"ignored only": {[]pact.RecordChange{{Attribute: "updated_at"}, {Attribute: "views"}}, false, false, nil},
"own row": {[]pact.RecordChange{{Attribute: "updated_at"}, {Attribute: "title"}}, true, true, nil},
"translated": {[]pact.RecordChange{{Attribute: "title", Locale: "pl"}, {Attribute: "slug", Locale: "de"}}, true, false, []string{"de", "pl"}},
"both": {[]pact.RecordChange{{Attribute: "title", Locale: "pl"}, {Attribute: "content"}}, true, true, nil},
} {
got := RealChanges(c.changes, ignore)
if got.Any != c.any || got.All != c.all || len(got.Locales) != len(c.locales) {
t.Errorf("%s: %+v", name, got)
continue
}
for _, l := range c.locales {
if !got.Locales[l] {
t.Errorf("%s: locale %s missing in %+v", name, l, got)
}
}
}
}
// TestLastmodIgnore pins golem15.sitemap.lastmod_ignore: the default list
// when unset, a YAML list or a comma-separated string replacing it (names
// trimmed, blanks dropped), and an empty list ignoring nothing.
func TestLastmodIgnore(t *testing.T) {
keys := func(m map[string]bool) string {
out := make([]string, 0, len(m))
for k := range m {
out = append(out, k)
}
slices.Sort(out)
return strings.Join(out, ",")
}
if got := keys(LastmodIgnore(nil)); got != "created_at,sort_order,updated_at,views" {
t.Fatalf("default = %s", got)
}
for _, tc := range []struct {
value any
want string
}{
{[]any{"updated_at", " hits ", ""}, "hits,updated_at"},
{[]string{"a", "b"}, "a,b"},
{" views , rank,,", "rank,views"},
{[]any{}, ""},
} {
cfg := testConfig(t)
if err := cfg.Set(LastmodIgnoreConfigKey, tc.value); err != nil {
t.Fatal(err)
}
if got := keys(LastmodIgnore(cfg)); got != tc.want {
t.Errorf("LastmodIgnore(%#v) = %s, want %s", tc.value, got, tc.want)
}
}
}
// TestRebuildDelay pins golem15.sitemap.rebuild_delay_seconds: 60 s when
// unset, the value in seconds, and 0 for 0 or a negative value.
func TestRebuildDelay(t *testing.T) {
if RebuildDelay(nil) != time.Minute || RebuildDelay(testConfig(t)) != time.Minute {
t.Fatal("default delay is not 60 s")
}
for value, want := range map[int]time.Duration{5: 5 * time.Second, 0: 0, -3: 0} {
cfg := testConfig(t)
if err := cfg.Set(RebuildDelayConfigKey, value); err != nil {
t.Fatal(err)
}
if got := RebuildDelay(cfg); got != want {
t.Errorf("RebuildDelay(%d) = %s, want %s", value, got, want)
}
}
}
func testConfig(t *testing.T) *compass.Config {
t.Helper()
cfg, err := compass.Open(compass.Options{Dir: t.TempDir()})
if err != nil {
t.Fatal(err)
}
return cfg
}