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.
72 lines
2.9 KiB
Go
72 lines
2.9 KiB
Go
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Commercial
|
|
// SPDX-FileCopyrightText: 2025-2026 Christian Galo
|
|
|
|
package server
|
|
|
|
// Render tests for ux-ia-naming 2.2: /operator/plan-ladders opens map-first.
|
|
// operator_plan_ladders.html now includes operator_plan_topology.html as a
|
|
// partial (against PlanLaddersData.Topology) above the existing ladder list
|
|
// and create form. These render against literal view models -- no DB --
|
|
// mirroring the renderPlanLaddersPageBody / renderOperatorPartial pattern
|
|
// used by the sibling *_render_test.go files in this package.
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
// TestPlanLaddersPageOpensMapFirst asserts the merged page renders the
|
|
// topology overview above the existing management surface, and that the
|
|
// management surface (create form + ladder list) still renders in full.
|
|
func TestPlanLaddersPageOpensMapFirst(t *testing.T) {
|
|
data := PlanLaddersData{
|
|
Ladders: []PlanLadderViewModel{
|
|
{PlanLadderID: "l-1", Name: "Hosting", TierCount: 1},
|
|
},
|
|
Topology: PlanTopologyData{
|
|
Ladders: []TopologyLadderColumn{
|
|
{PlanLadderID: "l-1", Name: "Hosting", IsActive: true},
|
|
},
|
|
Rows: []TopologyRow{
|
|
{Rank: 0, Cells: []TopologyCell{
|
|
{Present: true, ProductID: "p-1", ProductName: "Topology Grid Product", LifecycleStatus: "published", LadderID: "l-1"},
|
|
}},
|
|
},
|
|
},
|
|
}
|
|
body := renderOperatorPartial(t, "operator_plan_ladders.html", data)
|
|
|
|
for _, want := range []string{
|
|
"Plan topology", // topology section heading
|
|
"Topology Grid Product", // grid cell renders from Topology
|
|
// design D20 (round 4): the list header's filled link to the create
|
|
// page, in place of the create panel the header used to open.
|
|
`<a href="/operator/plan-ladders/new" class="btn btn-sm btn-primary">New plan ladder</a>`,
|
|
"Hosting", // ladder-list row still renders
|
|
"Open a ladder to reorder its tiers.", // design D8 / operator-topology-overview
|
|
} {
|
|
if !strings.Contains(body, want) {
|
|
t.Errorf("map-first ladders page missing %q", want)
|
|
}
|
|
}
|
|
|
|
// design D8 / operator-topology-overview (acceptance-fixes round 2): the
|
|
// structural-validation health strip this page once carried at its new
|
|
// home was retired outright — the one check it ran is impossible under
|
|
// the database's exclusion constraint.
|
|
for _, banned := range []string{"No structural issues detected", "Structural issues", "Structural validation"} {
|
|
if strings.Contains(body, banned) {
|
|
t.Errorf("map-first ladders page must not render the retired health strip, got %q", banned)
|
|
}
|
|
}
|
|
|
|
topoIdx := strings.Index(body, "Plan topology")
|
|
listIdx := strings.Index(body, `<h2 class="h5 mb-0">Ladders</h2>`)
|
|
if topoIdx == -1 || listIdx == -1 {
|
|
t.Fatalf("expected both the topology section and the ladder list section to render")
|
|
}
|
|
if topoIdx > listIdx {
|
|
t.Errorf("expected the topology overview above the ladder list; topology at %d, list at %d", topoIdx, listIdx)
|
|
}
|
|
}
|