import { describe, it, expect } from "vitest"; import { mount } from "@vue/test-utils"; import RcaPanel from "../RcaPanel.vue"; import { groupIncidents } from "@/lib/rca"; import type { TelemetryRecord } from "@/lib/telemetry"; const env = (m: string, c: string, corr: string) => ({ messageId: m, causationId: c, correlationId: corr, }); const RECORDS: TelemetryRecord[] = [ { kind: "action.dispatched", action: "orders.charge", appName: "billing", ts: "2026-01-01T00:00:00.000Z", envelope: env("m1", "m1", "c1"), }, { kind: "action.failed", action: "orders.charge", appName: "billing", attempt: 1, maxAttempts: 3, willRetry: true, ts: "2026-01-01T00:00:00.050Z", error: { name: "TimeoutError", message: "timed out", stack: "at chargeCard (billing.ts:42)" }, envelope: env("m2", "m1", "c1"), }, { kind: "dlq.recorded", action: "orders.charge", appName: "billing", attempts: 3, ts: "2026-01-01T00:00:00.300Z", error: { name: "TimeoutError", message: "timed out" }, envelope: env("m3", "m1", "c1"), }, ]; const incident = groupIncidents(RECORDS)[0]!; describe("RcaPanel", () => { it("opens on the 'What happened' tab with the suggested fix", () => { const w = mount(RcaPanel, { props: { incident } }); expect(w.get('[data-testid="rca-what"]').exists()).toBe(true); expect(w.get('[data-testid="rca-suggestion"]').text().length).toBeGreaterThan(0); }); it("switches to the timeline and lists the whole chain with failures flagged", async () => { const w = mount(RcaPanel, { props: { incident } }); await w.get('[data-testid="rca-tab-timeline"]').trigger("click"); const rows = w.findAll('[data-testid="rca-timeline-row"]'); expect(rows).toHaveLength(3); expect(rows.filter((r) => r.attributes("data-failure") === "true")).toHaveLength(2); }); it("shows the blast radius on the impact tab", async () => { const w = mount(RcaPanel, { props: { incident } }); await w.get('[data-testid="rca-tab-impact"]').trigger("click"); const impact = w.get('[data-testid="rca-impact"]'); expect(impact.text()).toContain("billing"); expect(impact.text()).toContain("Yes"); // dead-lettered }); it("shows the root error + stack on the evidence tab", async () => { const w = mount(RcaPanel, { props: { incident } }); await w.get('[data-testid="rca-tab-evidence"]').trigger("click"); expect(w.get('[data-testid="rca-evidence"]').text()).toContain("TimeoutError"); expect(w.get('[data-testid="rca-stack"]').text()).toContain("chargeCard"); }); it("emits open-source when the source pill is clicked", async () => { const source = { file: "apps/billing/orders.charge.ts", line: 42 }; const w = mount(RcaPanel, { props: { incident, source } }); await w.get('[data-testid="source-pill"]').trigger("click"); expect(w.emitted("open-source")?.[0]?.[0]).toEqual(source); }); });