Files
member-console/internal/server/member_domains_dissolve_render_test.go
T
cgalo5758 408fa6f5a6 Add page anatomy parts and UI quality gate
- Add shared ui_*.html parts (pageHeader, sectionHeader, statusBadge,
  emptyState) parsed into every template set
- Add anatomy lint rules with a shrinking allowlist and screen-coverage
  check
- Add make screens capture harness with contact sheets and baseline diff
- Compose member and FedWiki regions server-side so pages arrive
  complete
- Rebuild Domains and Integrations on the parts as pilots
2026-08-30 04:05:31 -05:00

89 lines
3.1 KiB
Go

// Render coverage for the member-side domains dissolution
// (dissolve-member-domains): the member shells carry no Domains navigation,
// and the dashboard carries the pending-claim notice — the durable re-entry
// point for an in-flight DNS verification now that the standalone page is
// gone. DB-free: templates render with literal data.
package server_test
import (
"net/http/httptest"
"strings"
"testing"
"git.coopcloud.tech/wiki-cafe/member-console/internal/server"
)
// TestMemberShellsHaveNoDomainsNav pins the de-centering: no member shell
// offers Domains as a destination.
func TestMemberShellsHaveNoDomainsNav(t *testing.T) {
st := rootTemplates(t)
render := func(name string, data any) string {
t.Helper()
rec := httptest.NewRecorder()
st.Render(rec, name, data)
if rec.Code != 200 {
t.Fatalf("%s: expected 200, got %d: %s", name, rec.Code, rec.Body.String())
}
return rec.Body.String()
}
for name, body := range map[string]string{
"index.html": render("index.html", dashboardData{}),
"products.html": render("products.html", server.ProductsPageData{}),
"billing.html": render("billing.html", server.BillingPageData{}),
} {
if strings.Contains(body, `href="/domains"`) {
t.Errorf("%s still links /domains", name)
}
if strings.Contains(body, ">Domains<") {
t.Errorf("%s still renders a Domains nav label", name)
}
}
}
// TestDashboardPendingDomainNotice covers the notice's contract: present and
// claim-naming while a claim is pending, absent without one (no empty
// chrome), opening a claim is a pure GET into the notice's own
// .domains-surface wrapper, and the notice is core content — not one of the
// registry-declared integration cards.
func TestDashboardPendingDomainNotice(t *testing.T) {
st := rootTemplates(t)
rec := httptest.NewRecorder()
st.Render(rec, "index.html", dashboardData{
PendingDomainClaims: []server.PendingDomainClaim{
{ClaimID: "claim-1", Root: "wiki.example.org"},
{ClaimID: "claim-2", Root: "docs.example.net"},
},
})
body := rec.Body.String()
for _, want := range []string{
"Domain verification in progress",
"wiki.example.org", "docs.example.net",
`hx-get="/partials/domains/claims/claim-1"`,
`hx-target="closest .domains-surface"`,
"View DNS records",
} {
if !strings.Contains(body, want) {
t.Errorf("pending notice missing %q", want)
}
}
// Opening instructions is a pure read: the notice must not POST anything.
if strings.Contains(body, `hx-post="/partials/domains/claims/claim-1`) {
t.Error("the notice must open instructions via GET, never a mutating request")
}
// Core content, not a card: this render declares zero DashboardCards, and
// the notice still appears — so it cannot be riding the card registry.
// (The presence assertions above are that proof; nothing more to check.)
empty := httptest.NewRecorder()
st.Render(empty, "index.html", dashboardData{})
if strings.Contains(empty.Body.String(), "Domain verification") {
t.Error("no pending claims must mean no notice and no empty chrome")
}
if strings.Contains(empty.Body.String(), "domains-surface") {
t.Error("no pending claims must leave no dangling domains-surface wrapper")
}
}