Files
cgalo5758 8e3c68c6be Make UI surfaces honestly reflect system state
- Add deployment-name branding to titles, mastheads, and OG tags
- Share one grant delivery-state query with lineage across grants
  surfaces
- Show pool status/usage, org owners, and config readiness
- Make billing views projection-aware with recency and sync vocabulary
- Guard FedWiki creation without domains and render route-aware 404s
2026-08-23 01:45:52 -05:00

130 lines
4.2 KiB
Go

package server
import (
"html/template"
"io/fs"
"net/http/httptest"
"strings"
"testing"
"git.coopcloud.tech/wiki-cafe/member-console/internal/config"
"git.coopcloud.tech/wiki-cafe/member-console/internal/embeds"
"git.coopcloud.tech/wiki-cafe/member-console/internal/web"
"log/slog"
)
// indexPageData mirrors the anonymous struct the "/" handler feeds
// index.html (server.go); keep the field sets in sync.
type indexPageData struct {
Name string
Username string
Email string
KeycloakAccountURL string
CSRFToken string
IsOperator bool
HasMultipleWorkspaces bool
CheckoutStatus string
DashboardCards []DashboardCard
PendingDomainClaims []PendingDomainClaim
}
func renderIndex(t *testing.T, data indexPageData) string {
t.Helper()
sub, err := fs.Sub(embeds.Templates, "templates")
if err != nil {
t.Fatalf("sub templates FS: %v", err)
}
// index.html references no other templates, so it parses standalone; the
// pending-domain notice uses routeURL, registered for real.
tmpl, err := template.New("root").Funcs(template.FuncMap{
"routeURL": web.RouteURL,
"deploymentName": config.DeploymentName,
}).ParseFS(sub, "index.html")
if err != nil {
t.Fatalf("parse index.html: %v", err)
}
rec := httptest.NewRecorder()
NewSafeTemplates(tmpl, slog.Default()).Render(rec, "index.html", data)
if rec.Code != 200 {
t.Fatalf("render = %d, body: %s", rec.Code, rec.Body.String())
}
return rec.Body.String()
}
// The raw template bytes must be integration-free too — a rendered-output
// check could miss a reference hidden behind an untaken template branch.
func TestIndexTemplateNamesNoIntegration(t *testing.T) {
raw, err := fs.ReadFile(embeds.Templates, "templates/index.html")
if err != nil {
t.Fatalf("read embedded index.html: %v", err)
}
for _, banned := range []string{"fedwiki", "discourse", "stripe"} {
if strings.Contains(strings.ToLower(string(raw)), banned) {
t.Errorf("core index.html template references integration %q", banned)
}
}
}
// The dashboard is registry-driven: core's index.html must not name any
// integration, and with no declared cards it must render no card section
// chrome and no integration script tags.
func TestIndexNoDashboardCards(t *testing.T) {
body := renderIndex(t, indexPageData{CSRFToken: "tok"})
if strings.Contains(strings.ToLower(body), "fedwiki") {
t.Errorf("index.html without cards still references fedwiki")
}
if strings.Contains(strings.ToLower(body), "discourse") {
t.Errorf("index.html without cards references discourse")
}
if strings.Contains(body, "hx-trigger=\"load, ") {
t.Errorf("card shell rendered despite zero declared cards")
}
}
// Declared cards render as generic shells in declaration (registry) order,
// with the declared partial path, trigger spec, and page-level deferred
// script tags.
func TestIndexRendersDeclaredCards(t *testing.T) {
body := renderIndex(t, indexPageData{
CSRFToken: "tok",
DashboardCards: []DashboardCard{
{
Title: "Stub Sites",
PartialPath: "/partials/stub/sites",
RefreshEvent: "refreshStub",
Scripts: []string{"/static/stub/stub-form.js"},
},
{
Title: "Other Service",
PartialPath: "/partials/other/status",
},
},
})
first := strings.Index(body, "Stub Sites")
second := strings.Index(body, "Other Service")
if first == -1 || second == -1 {
t.Fatalf("declared card titles missing (first=%d second=%d)", first, second)
}
if first > second {
t.Errorf("cards rendered out of declaration order")
}
if !strings.Contains(body, `hx-get="/partials/stub/sites"`) ||
!strings.Contains(body, `hx-get="/partials/other/status"`) {
t.Errorf("card body hx-get partial paths missing")
}
if !strings.Contains(body, `hx-trigger="load, refreshStub from:body"`) {
t.Errorf("refresh-event trigger spec missing")
}
if !strings.Contains(body, `hx-trigger="load"`) {
t.Errorf("plain load trigger missing for card without refresh event")
}
if !strings.Contains(body, `<script defer src="/static/stub/stub-form.js"></script>`) {
t.Errorf("declared card script not rendered as page-level deferred tag")
}
if strings.Contains(strings.ToLower(body), "fedwiki") {
t.Errorf("generic shell leaked an integration name")
}
}