- 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
82 lines
2.7 KiB
Go
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")
|
|
}
|
|
}
|