mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-07-24 04:51:51 +00:00
179 lines
6.1 KiB
TypeScript
179 lines
6.1 KiB
TypeScript
import type { ColumnDef } from "@tanstack/react-table";
|
|
import { render, screen } from "@testing-library/react";
|
|
import { describe, expect, it, vi } from "vitest";
|
|
|
|
import type { MetaDataProps } from "@/types";
|
|
|
|
import { DataTable } from "./data-table";
|
|
|
|
vi.mock("next/navigation", () => ({
|
|
usePathname: () => "/findings",
|
|
useRouter: () => ({
|
|
push: vi.fn(),
|
|
}),
|
|
useSearchParams: () => new URLSearchParams(),
|
|
}));
|
|
|
|
vi.mock("@/contexts", () => ({
|
|
useFilterTransitionOptional: () => null,
|
|
}));
|
|
|
|
vi.mock("@/lib", () => ({
|
|
cn: (...classes: Array<string | false | null | undefined>) =>
|
|
classes.filter(Boolean).join(" "),
|
|
getPaginationInfo: (metadata: MetaDataProps) => ({
|
|
currentPage: metadata.pagination.page,
|
|
totalPages: metadata.pagination.pages,
|
|
totalEntries: metadata.pagination.count,
|
|
itemsPerPageOptions: metadata.pagination.itemsPerPage ?? [10, 20, 50],
|
|
}),
|
|
}));
|
|
|
|
interface TestRow {
|
|
name: string;
|
|
}
|
|
|
|
const columns: ColumnDef<TestRow>[] = [
|
|
{
|
|
accessorKey: "name",
|
|
header: "Name",
|
|
},
|
|
];
|
|
|
|
const columnsWithActions: ColumnDef<TestRow>[] = [
|
|
{
|
|
accessorKey: "name",
|
|
header: "Name",
|
|
},
|
|
{
|
|
id: "actions",
|
|
header: "",
|
|
cell: () => <button type="button">Actions</button>,
|
|
enableSorting: false,
|
|
},
|
|
];
|
|
|
|
const metadata: MetaDataProps = {
|
|
pagination: {
|
|
page: 1,
|
|
pages: 1,
|
|
count: 7,
|
|
},
|
|
version: "v1",
|
|
};
|
|
|
|
describe("DataTable", () => {
|
|
describe("when toolbar right content is provided", () => {
|
|
it("should render it before the total entries count", () => {
|
|
// Given
|
|
render(
|
|
<DataTable
|
|
columns={columns}
|
|
data={[{ name: "Finding A" }]}
|
|
metadata={metadata}
|
|
toolbarRightContent={<span>Include muted findings</span>}
|
|
/>,
|
|
);
|
|
|
|
// When
|
|
const toolbarContent = screen.getByText("Include muted findings");
|
|
const totalEntries = screen.getByText("7 Total Entries");
|
|
const tableContainerText =
|
|
toolbarContent.parentElement?.textContent ?? "";
|
|
|
|
// Then
|
|
expect(toolbarContent).toBeInTheDocument();
|
|
expect(totalEntries).toBeInTheDocument();
|
|
expect(tableContainerText.indexOf("Include muted findings")).toBeLessThan(
|
|
tableContainerText.indexOf("7 Total Entries"),
|
|
);
|
|
});
|
|
|
|
it("should stack the right content below search when the container is narrow", () => {
|
|
// Given
|
|
render(
|
|
<DataTable
|
|
columns={columns}
|
|
data={[{ name: "Finding A" }]}
|
|
metadata={metadata}
|
|
showSearch
|
|
toolbarRightContent={<span>Include muted findings</span>}
|
|
/>,
|
|
);
|
|
|
|
// When
|
|
const toolbar = screen.getByTestId("data-table-toolbar");
|
|
const rightContent = screen.getByTestId("data-table-toolbar-right");
|
|
|
|
// Then: md is a container query app-wide, so this also reacts when the
|
|
// side panel shrinks the page; the right group stays on one row.
|
|
expect(toolbar).toHaveClass("flex-col");
|
|
expect(toolbar).toHaveClass("md:flex-row");
|
|
expect(rightContent).toHaveClass("w-full");
|
|
expect(rightContent).toHaveClass("md:w-auto");
|
|
expect(rightContent).toHaveClass("flex-wrap", "items-center");
|
|
});
|
|
});
|
|
|
|
describe("when an actions column is present", () => {
|
|
it("should keep the actions header and cells sticky on the right edge", () => {
|
|
// Given
|
|
render(
|
|
<DataTable
|
|
columns={columnsWithActions}
|
|
data={[{ name: "Finding A" }]}
|
|
/>,
|
|
);
|
|
|
|
// When
|
|
const columnHeaders = screen.getAllByRole("columnheader");
|
|
const nameHeader = columnHeaders[0];
|
|
const actionsHeader = columnHeaders.at(-1);
|
|
expect(actionsHeader).toBeDefined();
|
|
const actionsHeaderElement = actionsHeader as HTMLElement;
|
|
const nameCell = screen.getByText("Finding A").closest("td");
|
|
const actionsCell = screen
|
|
.getByRole("button", {
|
|
name: "Actions",
|
|
})
|
|
.closest("td");
|
|
|
|
// Then
|
|
expect(nameHeader).not.toHaveClass("sticky");
|
|
expect(nameCell).not.toHaveClass("sticky");
|
|
expect(nameHeader).toHaveClass("pr-6");
|
|
expect(nameCell).toHaveClass("pr-6");
|
|
expect(actionsHeaderElement).not.toHaveClass("sticky");
|
|
expect(actionsHeaderElement).not.toHaveClass("pr-6");
|
|
expect(actionsHeaderElement).not.toHaveClass("right-0");
|
|
expect(actionsHeaderElement).not.toHaveClass("z-20");
|
|
expect(actionsHeaderElement).toHaveClass("bg-bg-neutral-tertiary");
|
|
expect(actionsHeaderElement).toHaveClass("border-y");
|
|
expect(actionsHeaderElement).toHaveClass("last:border-r");
|
|
expect(actionsHeaderElement).toHaveClass("last:rounded-r-full");
|
|
expect(actionsHeaderElement).not.toHaveClass("bg-transparent");
|
|
expect(actionsHeaderElement).not.toHaveClass("border-y-0");
|
|
expect(actionsHeaderElement).not.toHaveClass("border-l-0");
|
|
expect(actionsHeaderElement).not.toHaveClass("border-r-0");
|
|
expect(actionsHeaderElement).not.toHaveClass("last:border-r-0");
|
|
expect(actionsHeaderElement).not.toHaveClass("backdrop-blur-none");
|
|
expect(actionsHeaderElement).not.toHaveClass("last:rounded-r-none");
|
|
expect(actionsHeaderElement).not.toHaveClass("before:bg-gradient-to-r");
|
|
expect(actionsHeaderElement).not.toHaveClass("before:content-['']");
|
|
expect(actionsHeaderElement).not.toHaveClass("after:content-['']");
|
|
expect(actionsHeaderElement).not.toHaveClass("after:rounded-r-full");
|
|
expect(actionsHeaderElement.querySelector("div")).not.toBeInTheDocument();
|
|
expect(actionsCell).toHaveClass("sticky");
|
|
expect(actionsCell).not.toHaveClass("pr-6");
|
|
expect(actionsCell).toHaveClass("right-0");
|
|
expect(actionsCell).toHaveClass("z-20");
|
|
expect(actionsCell).toHaveClass("bg-bg-neutral-secondary");
|
|
expect(actionsCell).toHaveClass("last:rounded-r-none!");
|
|
expect(actionsCell).not.toHaveClass("border-l");
|
|
expect(actionsCell).toHaveClass("before:bg-gradient-to-r");
|
|
expect(actionsCell).toHaveClass("before:from-transparent");
|
|
expect(actionsCell).toHaveClass("before:to-bg-neutral-secondary");
|
|
});
|
|
});
|
|
});
|