Files
sm-sitemap-plugin/classes/manifest_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

82 lines
2.7 KiB
Go

package classes_test
import (
"os"
"path/filepath"
"strings"
"testing"
"time"
"git.golem15.com/golem15/sm-sitemap-plugin/classes"
)
// TestManifest pins the updates manifest reader: it fails safe (a missing,
// empty-path, directory, oversized, non-object or invalid file is no
// manifest, so lastmod is omitted), normalizes keys, ignores non-string
// values, and parses the ISO dates strtotime reads, a date without a zone
// as UTC.
func TestManifest(t *testing.T) {
dir := t.TempDir()
write := func(name, body string) string {
t.Helper()
path := filepath.Join(dir, name)
if err := os.WriteFile(path, []byte(body), 0o644); err != nil {
t.Fatal(err)
}
return path
}
for name, path := range map[string]string{
"empty path": "",
"spaces": " ",
"missing": filepath.Join(dir, "missing.json"),
"directory": dir,
"list": write("list.json", `["/a"]`),
"string": write("string.json", `"x"`),
"invalid": write("invalid.json", `{"/a": `),
"empty file": write("empty.json", ""),
"oversized": write("big.json", `{"/a":"2026-01-01","pad":"`+strings.Repeat("x", classes.ManifestMaxBytes)+`"}`),
"null": write("null.json", "null"),
"leading space": write("space.json", " \n"),
} {
if m := classes.LoadManifest(path); m != nil {
t.Errorf("%s: manifest = %v, want none", name, m)
}
}
if fifo := filepath.Join(dir, "link.json"); os.Symlink(dir, fifo) == nil {
if m := classes.LoadManifest(fifo); m != nil {
t.Error("a symlink to a directory is not a manifest")
}
}
path := write("updates.json", ` {"blog/a/":"2026-01-02T03:04:05+02:00","/b":"2026-02-03","c":"2026-03-04 05:06:07","/":"2026-04-05T06:07","/num":12,"/bad":"yesterday","/epoch":"1970-01-01T00:00:00Z","/nested":{"x":1}}`)
m := classes.LoadManifest(path)
if m == nil {
t.Fatal("valid manifest not read")
}
if _, ok := m["/num"]; ok {
t.Fatal("a non-string value was kept")
}
for url, want := range map[string]string{
"https://h/blog/a": "2026-01-02T01:04:05Z",
"https://h/blog/a/": "2026-01-02T01:04:05Z",
"https://h/b?x=1": "2026-02-03T00:00:00Z",
"/c": "2026-03-04T05:06:07Z",
"https://h": "2026-04-05T06:07:00Z",
"https://h/": "2026-04-05T06:07:00Z",
} {
got, ok := m.Lastmod(url)
if !ok || got.UTC().Format(time.RFC3339) != want {
t.Errorf("Lastmod(%s) = %v %v, want %s", url, got, ok, want)
}
}
for _, url := range []string{"https://h/bad", "https://h/epoch", "https://h/unlisted", "https://h/num"} {
if got, ok := m.Lastmod(url); ok {
t.Errorf("Lastmod(%s) = %v, want none", url, got)
}
}
var none classes.Manifest
if _, ok := none.Lastmod("https://h/b"); ok {
t.Fatal("a nil manifest answered")
}
}