Files
sm-sitemap-plugin/console/import_winter_test.go
Jakub Zych 84cb27a810 feat!: remove the PHP-parity sitemap, tiers, definitions screen and XSL
BREAKING CHANGE: /sitemap.xsl is gone (404), the definitions screen and
the Phase 17 settings tile are replaced by the settings singleton, and
priority, change frequency, priority tiers and the update manifest are
no longer written or read. The config keys golem15.sitemap.cache_seconds
and golem15.sitemap.priority_tiers are removed; site_url, lastmod_ignore
and rebuild_delay_seconds are new.

- sitemap:import and sitemap:import-winter write the additional addresses
  (and site_url, default_locale) instead of the definition
- the golem15_sitemap_definitions table stays in the database, unread
2026-11-04 11:12:51 +01:00

92 lines
3.2 KiB
Go

package console
import (
"bytes"
"context"
"encoding/json"
"os"
"path/filepath"
"strings"
"testing"
"git.golem15.com/golem15/summercms/modules/bonfire"
)
// TestWinterSettingsFrontendURL pins the import check of T-17-15: a settings
// export whose frontend_url models.AllowedFrontendURL refuses stops
// sitemap:import-winter with an error naming the setting, with and without
// --dry-run and before the database is used (the test passes none). An
// accepted, empty, null or missing frontend_url is read as before.
func TestWinterSettingsFrontendURL(t *testing.T) {
dir := t.TempDir()
n := 0
settingsFile := func(fields map[string]any) string {
t.Helper()
// json.Marshal encodes the quotes of the attack value.
raw, err := json.Marshal(fields)
if err != nil {
t.Fatal(err)
}
n++
path := filepath.Join(dir, "settings-"+string(rune('a'+n))+".json")
if err := os.WriteFile(path, raw, 0o644); err != nil {
t.Fatal(err)
}
return path
}
for _, value := range []string{
"javascript:alert(document.domain)//",
`https://x"/><y a="`,
"0",
" https://www.example.test",
} {
file := settingsFile(map[string]any{"frontend_url": value, "enable_priority_tiers": "1"})
var report WinterReport
if _, err := readWinterSettings(file, &report); err == nil || !strings.Contains(err.Error(), "setting frontend_url") {
t.Errorf("readWinterSettings(%q) = %v, want an error naming setting frontend_url", value, err)
}
for _, dry := range []bool{false, true} {
var buf bytes.Buffer
out := bonfire.NewOutput(strings.NewReader(""), &buf, &buf)
report, err := ImportWinterFiles(context.Background(), nil, WinterOptions{SettingsFile: file, DryRun: dry}, out)
if err == nil || !strings.Contains(err.Error(), "setting frontend_url") {
t.Errorf("ImportWinterFiles(%q, dry run %v) = %v, want an error naming setting frontend_url", value, dry, err)
}
if report.Settings {
t.Errorf("ImportWinterFiles(%q, dry run %v) reports the settings as copied", value, dry)
}
if strings.Contains(buf.String(), "would be copied") || strings.Contains(buf.String(), "Settings copied") {
t.Errorf("ImportWinterFiles(%q, dry run %v) printed a copy line:\n%s", value, dry, buf.String())
}
}
}
// The error quotes the value, so a control character is not printed raw.
var report WinterReport
_, err := readWinterSettings(settingsFile(map[string]any{"frontend_url": "https://www.example.test\x1b[2J"}), &report)
if err == nil || strings.Contains(err.Error(), "\x1b") || !strings.Contains(err.Error(), `\x1b`) {
t.Errorf("a control character in frontend_url: %q", err)
}
for name, tc := range map[string]struct {
fields map[string]any
want string
}{
"valid": {map[string]any{"frontend_url": "https://www.example.test/"}, "https://www.example.test/"},
"empty": {map[string]any{"frontend_url": ""}, ""},
"null": {map[string]any{"frontend_url": nil}, ""},
"missing": {map[string]any{"enable_priority_tiers": "1"}, ""},
} {
var report WinterReport
s, err := readWinterSettings(settingsFile(tc.fields), &report)
if err != nil {
t.Errorf("%s: readWinterSettings = %v", name, err)
continue
}
if got := s.SiteURL; got != tc.want {
t.Errorf("%s: frontend_url = %q, want %q", name, got, tc.want)
}
}
}