Files
member-console/internal/server/operator_org_detail_title_test.go
T
cgalo5758 88db730fcc Add dual licensing and SPDX headers
Introduce a commercial license option alongside AGPL-3.0-only, require a
CLA for contributors, and document the terms in COMMERCIAL.md and
NOTICE. Add a script to stamp SPDX headers on Go files and apply it
across the tree.
2026-09-06 02:29:42 -05:00

91 lines
3.9 KiB
Go

// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Commercial
// SPDX-FileCopyrightText: 2025-2026 Christian Galo
package server
import (
"strings"
"testing"
)
// TestOrgDetailTitledByOrganizationName covers plan-enrollment-administration
// ("The page is titled by the organization, not 'Enrollment'"): the h1 is the
// organization's own display name, the trail reads Organizations /
// {name}, and the word "Enrollment" appears nowhere in the title, breadcrumb,
// or (per docs/operator-ia.md's owning template) the sidebar.
func TestOrgDetailTitledByOrganizationName(t *testing.T) {
out := renderOrgEnrollment(t, onePoolFixture())
if !strings.Contains(out, `<h1 class="h2 mb-0">Test Org</h1>`) {
t.Errorf("expected the h1 to be the organization's own display name, got:\n%s", out)
}
if !strings.Contains(out, `<li class="breadcrumb-item"><a href="/operator/organizations">Organizations</a></li>`) || !strings.Contains(out, `aria-current="page">Test Org</li>`) {
t.Errorf("expected the breadcrumb Organizations → Test Org, got:\n%s", out)
}
if strings.Contains(out, "Enrollment") {
t.Errorf("the word Enrollment must not appear on the org detail page, got:\n%s", out)
}
}
// TestOrgDetailSectionHeadingsUseCanonicalVocabulary covers the same delta's
// canonical-heading requirement: billing, pools, plan and grants, members,
// with the audit list heading "Tier changes" (maintainer design round
// 2026-08-24 retired "Position history"; operators cannot decode
// "position"). Every heading renders OUTSIDE its box (h2, never a card
// title) per the same round's one-rule heading doctrine.
func TestOrgDetailSectionHeadingsUseCanonicalVocabulary(t *testing.T) {
data := onePoolFixture()
// The "Plan and grants" card only renders once a grant exists.
data.Grants = []GrantViewModel{
{GrantID: "g-1", ProductName: "Standard Plan", GrantReason: "manual", Status: "active", DeliveryState: "live"},
}
out := renderOrgEnrollment(t, data)
for _, want := range []string{
">Billing<",
`<h2 class="h5 mb-0">Pools `,
">Plan and grants<",
">Members<",
`<h2 class="h5 mb-0">Tier changes`,
} {
if !strings.Contains(out, want) {
t.Errorf("expected canonical section heading %q, got:\n%s", want, out)
}
}
for _, banned := range []string{"Resource Pools", "Transition History", "Position history"} {
if strings.Contains(out, banned) {
t.Errorf("retired heading %q must not render, got:\n%s", banned, out)
}
}
// Card titles may only name instances (the pool's own name); the two
// sections that used to title themselves inside their cards must not.
for _, banned := range []string{`card-title mb-0 h6">Billing`, `card-title h6 mb-0">Plan and grants`} {
if strings.Contains(out, banned) {
t.Errorf("section title rendered inside its card (%q); headings live outside the box, got:\n%s", banned, out)
}
}
}
// TestOrganizationsListManageLinkNotEnrollment covers the same delta's nav
// reference: the organizations list's row action into the detail page must
// not carry the retired "Enrollment" label.
func TestOrganizationsListManageLinkNotEnrollment(t *testing.T) {
body := renderOrganizationsPageBody(t, OrganizationsData{
Organizations: []OrganizationViewModel{
{OrgID: "org-1", Name: "Acme Co-op", OrgType: "team", Status: "active", OwnerName: "Jamie Rivera"},
},
})
if strings.Contains(body, "Enrollment") {
t.Errorf("organizations list must not offer an Enrollment-labeled action, got:\n%s", body)
}
if !strings.Contains(body, `href="/operator/organizations/org-1"`) {
t.Errorf("expected the row's action link to the org detail page, got:\n%s", body)
}
if strings.Contains(body, ">Manage<") {
t.Errorf("the Manage button is retired; rows navigate through the name link, got:\n%s", body)
}
if !strings.Contains(body, `<a href="/operator/organizations/org-1">Acme Co-op</a>`) {
t.Errorf("expected the organization's name to be the row's link, got:\n%s", body)
}
}