Files
sm-sitemap-plugin/routes_test.go
Jakub Zych 3359f1a196 feat: sitemap index and per-type files from a slot table (tracer)
- contract package: Filter, Listing and their types (D-95)
- golem15_sitemap_urls slot table and the new settings columns
- Rebuild over signpost Records, stable slot assignment, rebuild job
- GET /sitemap.xml index and GET /_sitemap/files/{file} from the table
2026-11-04 10:58:05 +01:00

82 lines
2.9 KiB
Go

package sitemap
import (
"os"
"path/filepath"
"testing"
"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"
)
// TestSiteURLPrecedence pins the site address every <loc> starts with
// (CONTEXT 2026-10-28): the setting, else golem15.sitemap.site_url, else
// app.url, each only when it is an absolute http(s) URL, trailing slashes
// trimmed; nothing configured is "" (the request's Host is never used).
func TestSiteURLPrecedence(t *testing.T) {
app := func(t *testing.T, files map[string]string) *backpack.App {
t.Helper()
dir := t.TempDir()
for name, body := range files {
if err := os.WriteFile(filepath.Join(dir, name), []byte(body), 0o644); err != nil {
t.Fatal(err)
}
}
cfg, err := compass.Open(compass.Options{Dir: dir, Environ: []string{}})
if err != nil {
t.Fatal(err)
}
return backpack.New(cfg)
}
text := func(s string) *string { return &s }
both := app(t, map[string]string{"app.yaml": "url: https://api.example.test/\n", "golem15.yaml": "sitemap:\n site_url: https://config.example.test/\n"})
appOnly := app(t, map[string]string{"app.yaml": "url: https://api.example.test/\n"})
for _, tc := range []struct {
name string
app *backpack.App
settings models.Settings
want string
}{
{"setting wins", both, models.Settings{SiteURL: text("https://www.example.test/")}, "https://www.example.test"},
{"config key", both, models.Settings{}, "https://config.example.test"},
{"app.url", appOnly, models.Settings{}, "https://api.example.test"},
{"unsafe setting skipped", appOnly, models.Settings{SiteURL: text("javascript:alert(1)")}, "https://api.example.test"},
{"nothing configured", app(t, nil), models.Settings{}, ""},
{"nil app", nil, models.Settings{}, ""},
} {
t.Run(tc.name, func(t *testing.T) {
if got := classes.SiteURL(tc.app, tc.settings); got != tc.want {
t.Fatalf("SiteURL = %q, want %q", got, tc.want)
}
})
}
}
// TestFileNames pins the per-group file names the index lists and the file
// route accepts.
func TestFileNames(t *testing.T) {
if got := classes.FileName("posts", 3); got != "sitemap-posts-3.xml" {
t.Fatalf("FileName = %q", got)
}
for name, want := range map[string]struct {
grp string
n int
ok bool
}{
"sitemap-posts-1.xml": {"posts", 1, true},
"sitemap-landing-pages-12.xml": {"landing-pages", 12, true},
"sitemap-posts-2-1.xml": {"posts-2", 1, true},
"sitemap-posts-0.xml": {"", 0, false},
"sitemap-Posts-1.xml": {"", 0, false},
"sitemap-posts.xml": {"", 0, false},
"sitemap-../x-1.xml": {"", 0, false},
} {
grp, n, ok := classes.ParseFileName(name)
if grp != want.grp || n != want.n || ok != want.ok {
t.Errorf("ParseFileName(%q) = %q %d %v, want %+v", name, grp, n, ok, want)
}
}
}