Files
kandev/apps/web/components/sentry/sentry-issue-watch-table.test.tsx
T

99 lines
3.0 KiB
TypeScript

import { cleanup, render, screen } from "@testing-library/react";
import { afterEach, describe, expect, it, vi } from "vitest";
import { TooltipProvider } from "@kandev/ui/tooltip";
import type { SentryIssueWatch } from "@/lib/types/sentry";
import { SentryIssueWatchTable } from "./sentry-issue-watch-table";
function watch(over: Partial<SentryIssueWatch>): SentryIssueWatch {
return {
id: "w1",
workspaceId: "ws-1",
sentryInstanceId: "inst-1",
workflowId: "wf",
workflowStepId: "step",
repositoryId: "",
baseBranch: "",
filter: { orgSlug: "acme", projectSlugs: ["web"] },
agentProfileId: "ap",
executorProfileId: "",
prompt: "",
enabled: true,
pollIntervalSeconds: 300,
lastPolledAt: null,
lastError: "",
lastErrorAt: null,
createdAt: "",
updatedAt: "",
...over,
} as unknown as SentryIssueWatch;
}
const noop = vi.fn();
function resolveName(id: string): string {
if (id === "inst-1") return "Production";
if (id === "") return "—";
return "(unavailable)";
}
function renderTable(watches: SentryIssueWatch[]) {
return render(
<TooltipProvider>
<SentryIssueWatchTable
watches={watches}
dirtyIds={new Set(watches.slice(0, 1).map(({ id }) => id))}
instanceName={resolveName}
onEdit={noop}
onDelete={noop}
onTrigger={noop}
onReset={noop}
onToggleEnabled={noop}
/>
</TooltipProvider>,
);
}
afterEach(() => {
cleanup();
vi.clearAllMocks();
});
describe("SentryIssueWatchTable", () => {
it("shows an Instance column, not a Workspace column (integration is workspace-scoped)", () => {
renderTable([watch({ id: "w1" })]);
expect(screen.getByText("Instance")).toBeTruthy();
expect(screen.queryByText("Workspace")).toBeNull();
});
it("renders each watch's bound instance name via the resolver", () => {
renderTable([
watch({ id: "w1", sentryInstanceId: "inst-1" }),
watch({ id: "w2", sentryInstanceId: "inst-gone" }),
watch({ id: "w3", sentryInstanceId: "" }),
]);
const cells = screen.getAllByTestId("watch-instance").map((c) => c.textContent);
expect(cells).toEqual(["Production", "(unavailable)", "—"]);
});
it("marks the changed watcher row and enable control dirty", () => {
renderTable([watch({ id: "w1" }), watch({ id: "w2" })]);
expect(screen.getByTestId("sentry-watch-row-w1").getAttribute("data-settings-dirty")).toBe(
"true",
);
expect(screen.getByTestId("sentry-watch-enabled-w1").getAttribute("data-settings-dirty")).toBe(
"true",
);
expect(screen.getByTestId("sentry-watch-row-w2").getAttribute("data-settings-dirty")).toBe(
"false",
);
});
it("renders a comma-joined project list in the filter summary for a multi-project watch", () => {
renderTable([
watch({ id: "w1", filter: { orgSlug: "acme", projectSlugs: ["frontend", "backend"] } }),
]);
expect(screen.getByText("org:acme · project:frontend,backend")).toBeTruthy();
});
});