Render generic HTMX card shells from integration declarations. Move the FedWiki UI into its partial, add Discourse forum status, and label member entitlements with provider attribution.
108 lines
3.6 KiB
Go
108 lines
3.6 KiB
Go
package server
|
|
|
|
import (
|
|
"html/template"
|
|
"io/fs"
|
|
"net/http/httptest"
|
|
"strings"
|
|
"testing"
|
|
|
|
"git.coopcloud.tech/wiki-cafe/member-console/internal/embeds"
|
|
"log/slog"
|
|
)
|
|
|
|
func renderEntitlements(t *testing.T, data EntitlementsData) string {
|
|
t.Helper()
|
|
sub, err := fs.Sub(embeds.Templates, "templates")
|
|
if err != nil {
|
|
t.Fatalf("sub templates FS: %v", err)
|
|
}
|
|
tmpl, err := template.New("root").ParseFS(sub, "partials/member_entitlements.html")
|
|
if err != nil {
|
|
t.Fatalf("parse member_entitlements.html: %v", err)
|
|
}
|
|
rec := httptest.NewRecorder()
|
|
NewSafeTemplates(tmpl, slog.Default()).Render(rec, "member_entitlements.html", data)
|
|
if rec.Code != 200 {
|
|
t.Fatalf("render = %d, body: %s", rec.Code, rec.Body.String())
|
|
}
|
|
return rec.Body.String()
|
|
}
|
|
|
|
// Resource rows lead with the human label and integration attribution;
|
|
// the raw key is demoted to a title attribute. Two integrations'
|
|
// entitlements stay distinguishable by their attributions.
|
|
func TestEntitlementRowsLabeledAndAttributed(t *testing.T) {
|
|
body := renderEntitlements(t, EntitlementsData{
|
|
HasEntitlements: true,
|
|
Entitlements: []EntitlementViewModel{
|
|
{ResourceKey: "alpha_sites", Label: "Wiki Sites", IntegrationName: "Alpha", ResourceLimit: 2, CurrentUsage: 1},
|
|
{ResourceKey: "beta_widgets", Label: "Widgets", IntegrationName: "Beta", ResourceLimit: 5, CurrentUsage: 0},
|
|
},
|
|
})
|
|
|
|
for _, want := range []string{
|
|
`title="alpha_sites"`, ">Wiki Sites", "Alpha",
|
|
`title="beta_widgets"`, ">Widgets", "Beta",
|
|
} {
|
|
if !strings.Contains(body, want) {
|
|
t.Errorf("rendered entitlements missing %q", want)
|
|
}
|
|
}
|
|
// The raw key appears only as the demoted title attribute, never as
|
|
// headline text content.
|
|
if strings.Contains(body, ">alpha_sites<") {
|
|
t.Errorf("raw resource key rendered as headline text")
|
|
}
|
|
}
|
|
|
|
// A key with no display metadata falls back to the raw key, un-attributed
|
|
// (labelFor's contract) — and the view still renders.
|
|
func TestEntitlementLabelFallback(t *testing.T) {
|
|
got := labelFor(map[string]resourceLabel{}, "mystery_key")
|
|
if got.Label != "mystery_key" || got.IntegrationName != "" {
|
|
t.Errorf("labelFor fallback = %+v, want raw key un-attributed", got)
|
|
}
|
|
|
|
// Present but empty display name also falls back rather than
|
|
// rendering a blank headline.
|
|
got = labelFor(map[string]resourceLabel{"k": {Label: ""}}, "k")
|
|
if got.Label != "k" {
|
|
t.Errorf("empty display name should fall back to raw key, got %+v", got)
|
|
}
|
|
|
|
body := renderEntitlements(t, EntitlementsData{
|
|
HasEntitlements: true,
|
|
Entitlements: []EntitlementViewModel{{ResourceKey: "mystery_key", Label: "mystery_key", ResourceLimit: 1}},
|
|
})
|
|
if !strings.Contains(body, ">mystery_key") {
|
|
t.Errorf("fallback raw key not rendered")
|
|
}
|
|
}
|
|
|
|
// Granted booleans render as labeled "Included" rows without a usage
|
|
// meter; with no granted booleans, no Included badge appears (the handler
|
|
// filters lapsed rows server-side, so the template only ever sees granted
|
|
// ones).
|
|
func TestBooleanEntitlementRows(t *testing.T) {
|
|
body := renderEntitlements(t, EntitlementsData{
|
|
HasEntitlements: true,
|
|
BooleanEntitlements: []BooleanEntitlementViewModel{
|
|
{ResourceKey: "gamma_forum_access", Label: "Forum Access", IntegrationName: "Gamma"},
|
|
},
|
|
})
|
|
for _, want := range []string{">Forum Access", "Gamma", ">Included<", `title="gamma_forum_access"`} {
|
|
if !strings.Contains(body, want) {
|
|
t.Errorf("boolean row missing %q", want)
|
|
}
|
|
}
|
|
if strings.Contains(body, "<meter") {
|
|
t.Errorf("boolean-only view must not render a usage meter")
|
|
}
|
|
|
|
empty := renderEntitlements(t, EntitlementsData{HasEntitlements: true})
|
|
if strings.Contains(empty, ">Included<") {
|
|
t.Errorf("Included badge rendered with no granted booleans")
|
|
}
|
|
}
|