test(11.2): cover site_url and site_label and gate the framework, app and site stages

- TestCheckSiteURL (21 accepted and rejected values), TestSiteLabel and
  TestSiteURLPrecedence (option over site.yaml, label-without-URL and
  invalid option errors); new TestParseSite rows for blank and two-line labels
- TestSiteLink: escaped label, section page and 404 page, exact unset header
  bytes
- TestDocsSiteFlagsInHelp and the --site-label-without-URL error
- check-phase11.2.sh --framework, --app and --site
This commit is contained in:
Jakub Zych
2026-10-01 16:35:09 +02:00
parent 18fe100113
commit f5f9387ac9
4 changed files with 222 additions and 11 deletions

View File

@@ -77,35 +77,44 @@ func assertCSPSafe(t *testing.T, name, html string) {
}
}
// TestSiteLink checks the optional link back to the main site on a page
// and on the 404 page: absent without a site URL, labelled explicitly, by
// the URL host, or Home.
// TestSiteLink checks the optional link back to the main site on the home
// page, a section page and the 404 page: absent without a site URL (the
// header bytes unchanged), labelled explicitly, by the URL host, or Home,
// and always HTML-escaped.
func TestSiteLink(t *testing.T) {
// unsetHeader is the wordmark's closing tag followed directly by the
// spacer: the header bytes from before site_url existed.
const unsetHeader = `<span class="wordmark-cms">CMS</span></span></a>` + "\n" + `<div class="header-spacer"></div>`
for _, tc := range []struct {
name string
opts Options
want []string
deny []string
}{
{"unset", Options{}, nil},
{"explicit label", Options{SiteURL: "/", SiteLabel: "acme.example"}, []string{`<a class="site-link" href="/"`, `<span class="site-link-label">acme.example</span>`}},
{"host label", Options{SiteURL: "https://acme.example/docs"}, []string{`<a class="site-link" href="https://acme.example/docs"`, `<span class="site-link-label">acme.example</span>`}},
{"home label", Options{SiteURL: "/"}, []string{`<a class="site-link" href="/"`, `<span class="site-link-label">Home</span>`}},
{"unset", Options{}, []string{unsetHeader}, []string{"site-link"}},
{"explicit label", Options{SiteURL: "/", SiteLabel: "acme.example"}, []string{`<a class="site-link" href="/" aria-label="acme.example">`, `<span class="site-link-label">acme.example</span>`}, []string{unsetHeader}},
{"host label", Options{SiteURL: "https://acme.example/docs"}, []string{`<a class="site-link" href="https://acme.example/docs"`, `<span class="site-link-label">acme.example</span>`}, nil},
{"host and port label", Options{SiteURL: "http://acme.example:8080/"}, []string{`<a class="site-link" href="http://acme.example:8080/"`, `<span class="site-link-label">acme.example:8080</span>`}, nil},
{"home label", Options{SiteURL: "/"}, []string{`<a class="site-link" href="/"`, `<span class="site-link-label">Home</span>`}, nil},
{"escaped label", Options{SiteURL: "/", SiteLabel: "<b>&"}, []string{`aria-label="&lt;b&gt;&amp;"`, `<span class="site-link-label">&lt;b&gt;&amp;</span>`}, []string{"<b>&"}},
} {
opts := tc.opts
opts.Root, opts.Commands, opts.Out = themeTree(t), fixtureCommands, filepath.Join(t.TempDir(), "site")
if _, problems, err := Build(opts); err != nil || len(problems) > 0 {
t.Fatalf("%s: Build: %v %q", tc.name, err, problemLines(problems))
}
for _, name := range []string{"index.html", "404.html"} {
for _, name := range []string{"index.html", "setup/start.html", "404.html"} {
html := readOut(t, opts.Out, name)
if tc.want == nil && strings.Contains(html, "site-link") {
t.Errorf("%s: %s has a site link", tc.name, name)
}
for _, w := range tc.want {
if !strings.Contains(html, w) {
t.Errorf("%s: %s lacks %s", tc.name, name, w)
}
}
for _, d := range tc.deny {
if strings.Contains(html, d) {
t.Errorf("%s: %s contains %s", tc.name, name, d)
}
}
}
}
}