Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
import { fireEvent, render, screen } from "@testing-library/react";

import {
ExploitIntelligenceAnalysisCell,
type ExploitIntelligenceCellState,
} from "./exploit-intelligence-analysis-cell";

const CVE_ID = "CVE-2024-0001";

describe("ExploitIntelligenceAnalysisCell", () => {
it("renders 'Request Analysis' button for not_run state", () => {
render(
<ExploitIntelligenceAnalysisCell
vulnerabilityIdentifier={CVE_ID}
state={{ kind: "not_run" }}
onRequestAnalysis={vi.fn()}
requestAnalysisEligible={true}
/>,
);

const button = screen.getByRole("button", {
name: /request.*analysis/i,
});
expect(button).toBeInTheDocument();
expect(button).toBeEnabled();
});

it("renders disabled button when requestAnalysisEligible is false", () => {
render(
<ExploitIntelligenceAnalysisCell
vulnerabilityIdentifier={CVE_ID}
state={{ kind: "not_run" }}
onRequestAnalysis={vi.fn()}
requestAnalysisEligible={false}
/>,
);

const button = screen.getByRole("button", {
name: /request.*analysis/i,
});
expect(button).toBeInTheDocument();
expect(button).toBeDisabled();
});

it.each<{
state: ExploitIntelligenceCellState;
expectedText: string;
}>([
{
state: { kind: "finding", finding: { variant: "vulnerable" } },
expectedText: "Vulnerable",
},
{
state: { kind: "finding", finding: { variant: "not_vulnerable" } },
expectedText: "Not vulnerable",
},
{
state: { kind: "finding", finding: { variant: "uncertain" } },
expectedText: "Uncertain",
},
{
state: { kind: "finding", finding: { variant: "in_progress" } },
expectedText: "In progress",
},
{
state: { kind: "finding", finding: { variant: "failed" } },
expectedText: "Failed",
},
])("renders correct label for $expectedText", ({ state, expectedText }) => {
render(
<ExploitIntelligenceAnalysisCell
vulnerabilityIdentifier={CVE_ID}
state={state}
onRequestAnalysis={vi.fn()}
requestAnalysisEligible={true}
/>,
);

expect(screen.getByText(expectedText)).toBeInTheDocument();
});

it("renders count-prefixed label for multi-component vulnerable finding", () => {
const state: ExploitIntelligenceCellState = {
kind: "finding",
finding: {
variant: "vulnerable",
count: 21,
breakdown: {
vulnerableCount: 21,
uncertainCount: 5,
notVulnerableCount: 24,
failedCount: 3,
},
},
reportUrl: "https://example.com/report",
};

render(
<ExploitIntelligenceAnalysisCell
vulnerabilityIdentifier={CVE_ID}
state={state}
onRequestAnalysis={vi.fn()}
requestAnalysisEligible={true}
/>,
);

expect(screen.getByText("21 Vulnerable")).toBeInTheDocument();
});

it("renders count-prefixed label for multi-component uncertain finding", () => {
const state: ExploitIntelligenceCellState = {
kind: "finding",
finding: {
variant: "uncertain",
count: 4,
breakdown: {
vulnerableCount: 0,
uncertainCount: 4,
notVulnerableCount: 70,
failedCount: 0,
},
},
};

render(
<ExploitIntelligenceAnalysisCell
vulnerabilityIdentifier={CVE_ID}
state={state}
onRequestAnalysis={vi.fn()}
requestAnalysisEligible={true}
/>,
);

expect(screen.getByText("4 Uncertain")).toBeInTheDocument();
});

it("renders 'View report' link when reportUrl is provided", () => {
const state: ExploitIntelligenceCellState = {
kind: "finding",
finding: { variant: "vulnerable" },
reportUrl: "https://example.com/report/CVE-2024-1234",
};

render(
<ExploitIntelligenceAnalysisCell
vulnerabilityIdentifier={CVE_ID}
state={state}
onRequestAnalysis={vi.fn()}
requestAnalysisEligible={true}
/>,
);

const link = screen.getByRole("link", { name: /view report/i });
expect(link).toBeInTheDocument();
expect(link).toHaveAttribute(
"href",
"https://example.com/report/CVE-2024-1234",
);
expect(link).toHaveAttribute("target", "_blank");
});

it("calls onRequestAnalysis with vulnerability identifier when button is clicked", () => {
const onRequestAnalysis = vi.fn();

render(
<ExploitIntelligenceAnalysisCell
vulnerabilityIdentifier={CVE_ID}
state={{ kind: "not_run" }}
onRequestAnalysis={onRequestAnalysis}
requestAnalysisEligible={true}
/>,
);

const button = screen.getByRole("button", {
name: /request.*analysis/i,
});
fireEvent.click(button);

expect(onRequestAnalysis).toHaveBeenCalledTimes(1);
expect(onRequestAnalysis).toHaveBeenCalledWith(CVE_ID);
});

it("renders in_progress label", () => {
const state: ExploitIntelligenceCellState = {
kind: "finding",
finding: { variant: "in_progress" },
};

render(
<ExploitIntelligenceAnalysisCell
vulnerabilityIdentifier={CVE_ID}
state={state}
onRequestAnalysis={vi.fn()}
requestAnalysisEligible={true}
/>,
);

expect(screen.getByText("In progress")).toBeInTheDocument();
});

it("does not show tooltip for single-component finding", async () => {
const state: ExploitIntelligenceCellState = {
kind: "finding",
finding: { variant: "vulnerable" },
};

render(
<ExploitIntelligenceAnalysisCell
vulnerabilityIdentifier={CVE_ID}
state={state}
onRequestAnalysis={vi.fn()}
requestAnalysisEligible={true}
/>,
);

expect(screen.getByText("Vulnerable")).toBeInTheDocument();
expect(screen.queryByText(/Uncertain/)).not.toBeInTheDocument();
expect(screen.queryByText(/Not vulnerable/)).not.toBeInTheDocument();
});
});
Loading