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