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", LadderKey: "hosting", Name: "Hosting", TierCount: 1}, }, Topology: PlanTopologyData{ Ladders: []TopologyLadderColumn{ {PlanLadderID: "l-1", LadderKey: "hosting", 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 "No structural issues detected", // clean-health strip (zero-valued Health) `id="createPlanLadderForm"`, // create form still renders "hosting", // ladder-list row still renders } { if !strings.Contains(body, want) { t.Errorf("map-first ladders page missing %q", want) } } topoIdx := strings.Index(body, "Plan topology") formIdx := strings.Index(body, `id="createPlanLadderForm"`) if topoIdx == -1 || formIdx == -1 { t.Fatalf("expected both the topology section and the create form to render") } if topoIdx > formIdx { t.Errorf("expected the topology overview above the create-ladder form; topology at %d, form at %d", topoIdx, formIdx) } } // TestPlanLaddersMapFirstHealthStripStates covers all three // structural-health strip states at the merged page's new home: issues, // healthy, and nothing-to-validate. The underlying template logic is // exercised exhaustively by TestPlanTopologyTemplateRendering; this locks // that the states still surface correctly once included from // operator_plan_ladders.html rather than rendered by a standalone page. func TestPlanLaddersMapFirstHealthStripStates(t *testing.T) { t.Run("issues", func(t *testing.T) { data := PlanLaddersData{Topology: PlanTopologyData{ Health: PlanLadderValidationData{MultiActivePools: []MultiActivePoolViewModel{{PoolID: "p1"}}}, }} body := renderOperatorPartial(t, "operator_plan_ladders.html", data) if !strings.Contains(body, "Structural issues") { t.Errorf("expected the issues state to render at the new home") } }) t.Run("healthy", func(t *testing.T) { body := renderOperatorPartial(t, "operator_plan_ladders.html", PlanLaddersData{}) if !strings.Contains(body, "No structural issues detected") { t.Errorf("expected the healthy state to render at the new home") } }) t.Run("nothing to validate", func(t *testing.T) { data := PlanLaddersData{Topology: PlanTopologyData{ Health: PlanLadderValidationData{MultiActivePools: []MultiActivePoolViewModel{{PoolID: "p1"}}}, NothingToValidate: true, }} body := renderOperatorPartial(t, "operator_plan_ladders.html", data) if !strings.Contains(body, "Nothing to validate yet") { t.Errorf("expected the nothing-to-validate state to render at the new home") } if strings.Contains(body, "Structural issues") { t.Errorf("nothing-to-validate must take precedence over the issues state") } if strings.Contains(body, "No structural issues detected") { t.Errorf("nothing-to-validate must not also claim healthy") } }) }