Test RunScriptBatchPaginatedList (#28839)

## For #28159

### Follow-up to #28563 

- Add tests
- Misc cleanup

- [x] Added/updated automated tests

Co-authored-by: Jacob Shandling <jacob@fleetdm.com>
This commit is contained in:
jacobshandling 2025-05-06 11:42:04 -07:00 committed by GitHub
parent b2c1ddaafa
commit 07869b8ad4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 111 additions and 15 deletions

View file

@ -0,0 +1,109 @@
import React from "react";
import { http, HttpResponse } from "msw";
import { screen, waitFor, within } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { baseUrl, createCustomRenderer } from "test/test-utils";
import mockServer from "test/mock-server";
import { createMockScript } from "__mocks__/scriptMock";
import RunScriptBatchPaginatedList from "./RunScriptBatchPaginatedList";
const waitForLoadingToFinish = async (container: HTMLElement) => {
await waitFor(() => {
expect(container.querySelector(".loading-overlay")).not.toBeInTheDocument();
});
};
const team1Scripts = [
createMockScript({ team_id: 1, name: "Team script 1" }),
createMockScript({ id: 2, team_id: 1, name: "Team script 2" }),
];
const teamScriptsHandler = http.get(baseUrl(`/scripts?team_id=1`), () => {
// The case where a team has no scripts is handled by the parent
return HttpResponse.json({
scripts: team1Scripts,
});
});
describe("RunScriptBatchPaginatedList - component", () => {
const render = createCustomRenderer({
withBackendMock: true,
});
it("Lists a team's scripts", async () => {
mockServer.use(teamScriptsHandler);
const { container } = render(
<RunScriptBatchPaginatedList
onRunScript={jest.fn()}
isUpdating={false}
teamId={1}
scriptCount={2}
setScriptForDetails={jest.fn()}
/>
);
await waitForLoadingToFinish(container);
const listedScripts = screen.getAllByRole("listitem");
expect(listedScripts).toHaveLength(team1Scripts.length);
team1Scripts.forEach((item, index) => {
expect(listedScripts[index]).toHaveTextContent(item.name);
});
});
// });
it("Calls `onRunScript` with the appropriate script when `Run script`/`Run again` is clicked", async () => {
mockServer.use(teamScriptsHandler);
const onRunScript = jest.fn();
const { container } = render(
<RunScriptBatchPaginatedList
onRunScript={onRunScript}
isUpdating={false}
teamId={1}
scriptCount={2}
setScriptForDetails={jest.fn()}
/>
);
await waitForLoadingToFinish(container);
const listedScripts = screen.getAllByRole("listitem");
await userEvent.click(within(listedScripts[0]).getByRole("button"));
await waitFor(() => {
expect(onRunScript.mock.calls.length).toEqual(1); //
});
// checking ids rather than full equality allows extending the components `fetchPage` to
// modifying the incoming scripst without breaking this test
// const changedItems = onSubmit.mock.calls[0][0];
const ranScript = onRunScript.mock.calls[0][0]; // the second arg is a callback
expect(ranScript.id).toEqual(team1Scripts[0].id);
});
it("Sets the right script for details when clicking on the script's name", async () => {
mockServer.use(teamScriptsHandler);
const onSetScriptForDetails = jest.fn();
const { container } = render(
<RunScriptBatchPaginatedList
onRunScript={jest.fn()}
isUpdating={false}
teamId={1}
scriptCount={2}
setScriptForDetails={onSetScriptForDetails}
/>
);
await waitForLoadingToFinish(container);
const listedScripts = screen.getAllByRole("listitem");
// click on the script's name
await userEvent.click(
within(listedScripts[0]).getByText(team1Scripts[0].name)
);
await waitFor(() => {
expect(onSetScriptForDetails.mock.calls.length).toEqual(1); //
});
// checking ids rather than full equality allows extending the components `fetchPage` to
// modifying the incoming scripst without breaking this test
const detailsScript = onSetScriptForDetails.mock.calls[0][0]; // the second arg is a callback
expect(detailsScript.id).toEqual(team1Scripts[0].id);
});
});

View file

@ -52,7 +52,7 @@ const RunScriptBatchPaginatedList = ({
}
);
return fetchPromise.then(({ scripts, meta }: IScriptsResponse) => {
return fetchPromise.then(({ scripts }: IScriptsResponse) => {
return scripts || [];
});
},

View file

@ -5,8 +5,6 @@ import {
LEARN_MORE_ABOUT_BASE_LINK,
} from "utilities/constants";
import { IPolicyStats } from "interfaces/policy";
import CustomLink from "components/CustomLink";
import Modal from "components/Modal";
import Button from "components/buttons/Button";

View file

@ -41,17 +41,6 @@ const teamPolicies = [
createMockPolicy({ id: 5, team_id: 2, name: "Team policy 2" }),
];
const globalPoliciesNoMac = [
createMockPolicy({ team_id: null, name: "Inherited policy 1" }),
createMockPolicy({ id: 2, team_id: null, name: "Inherited policy 2" }),
createMockPolicy({ id: 3, team_id: null, name: "Inherited policy 3" }),
];
const teamPoliciesNoMac = [
createMockPolicy({ id: 4, team_id: 2, name: "Team policy 1" }),
createMockPolicy({ id: 5, team_id: 2, name: "Team policy 2" }),
];
const globalPoliciesHandler = http.get(baseUrl("/policies"), () => {
return HttpResponse.json({
policies: globalPolicies,

View file

@ -11,7 +11,7 @@ import { ReactElement } from "react-markdown/lib/react-markdown";
import { AppContext } from "context/app";
import PaginatedList, { IPaginatedListHandle } from "components/PaginatedList";
import { useQueryClient } from "react-query";
import { IPolicy, IPolicyStats } from "interfaces/policy";
import { IPolicy } from "interfaces/policy";
import teamPoliciesAPI from "services/entities/team_policies";
import globalPoliciesAPI from "services/entities/global_policies";