From 5e46eeb7c0d66486ba818c5472ba9fa980466269 Mon Sep 17 00:00:00 2001 From: Roman Mitasov Date: Wed, 15 Jul 2026 14:02:19 +0300 Subject: [PATCH] test(team-view): cover column-header sorting in the members heatmap MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The diff-coverage gate on #200 flagged the column-sort branch of sortedRows (COLUMNS.findIndex lookup) — the revert re-introduced those lines and no test clicked a column header. Add a test that sorts by a higher-is-better column, checks the row order flips, and exercises the lower-is-better path with missing values. Co-Authored-By: Claude Fable 5 Signed-off-by: Roman Mitasov --- .../widgets/v2/members-heatmap/index.test.tsx | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/src/components/widgets/v2/members-heatmap/index.test.tsx b/src/components/widgets/v2/members-heatmap/index.test.tsx index a0686ef..fe3d985 100644 --- a/src/components/widgets/v2/members-heatmap/index.test.tsx +++ b/src/components/widgets/v2/members-heatmap/index.test.tsx @@ -300,6 +300,50 @@ describe("", () => { expect(screen.queryByText(/^\d+ issues?$/)).not.toBeInTheDocument(); }); + it("clicking a column header sorts rows by that column's value", async () => { + const user = userEvent.setup(); + fetchCatalog.mockResolvedValue(buildCatalogResponse([])); + renderWithCatalogClient( + , + ); + const memberNameOrder = () => + screen + .getAllByRole("button") + .map((b) => b.textContent?.trim()) + .filter((t) => t === "Alice" || t === "Bob"); + + // Default sort is "issues"; with none, ties break by name → Alice first. + expect(memberNameOrder()[0]).toBe("Alice"); + + // tasks_closed is higher-is-better → Bob (15) sorts above Alice (8). + await user.click( + screen.getByRole("button", { name: "Tasks closed — sort by this column" }), + ); + expect(memberNameOrder()[0]).toBe("Bob"); + + // MTTR is lower-is-better; neither member has the bullet, so order + // falls back to stable null handling (no crash, list intact). + await user.click( + screen.getByRole("button", { + name: "Mean time to resolution — sort by this column", + }), + ); + expect(memberNameOrder().length).toBeGreaterThan(0); + }); + it("details sheet shows the full metric set: grid columns + remaining bullets + unified entries, deduped", async () => { const user = userEvent.setup(); fetchCatalog.mockResolvedValue(