// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Commercial // SPDX-FileCopyrightText: 2025-2026 Christian Galo package server_test import ( "net/http/httptest" "strings" "testing" "github.com/spf13/viper" "git.coopcloud.tech/wiki-cafe/member-console/internal/server" ) // renderMemberShell renders a member page through the root template set // with the given shell, the way the /, /products, and /billing handlers do. func renderMemberShell(t *testing.T, page string, shell server.Shell) string { t.Helper() st := rootTemplates(t) rec := httptest.NewRecorder() switch page { case "index.html": st.Render(rec, page, dashboardData{Shell: shell}) case "products.html": st.Render(rec, page, server.ProductsPageData{Shell: shell}) default: st.Render(rec, page, server.BillingPageData{Shell: shell}) } if rec.Code != 200 { t.Fatalf("expected 200, got %d: %s", rec.Code, rec.Body.String()) } return rec.Body.String() } func memberShell(active string, operator bool) server.Shell { return server.Shell{ Surface: server.ShellMember, Name: "Alice Admin", Username: "alice", Email: "alice@example.test", KeycloakAccountURL: "https://idp.example.test/account", IsOperator: operator, Active: active, } } // topBarRegion slices a rendered member page down to the shell's top bar, // and railRegion down to the rail element. The account menu has two homes // now, one per width (chrome-conventions "Only one account menu renders"), // so an assertion about either must name the region it means: a body-wide // match would be satisfied by the wrong one. func topBarRegion(t *testing.T, body string) string { t.Helper() return regionBetween(t, body, `