mirror of
https://github.com/fleetdm/fleet
synced 2026-05-24 09:28:54 +00:00
147 lines
4.3 KiB
TypeScript
147 lines
4.3 KiB
TypeScript
// TransferHostModal.test.tsx
|
|
import React from "react";
|
|
import { render, screen } from "@testing-library/react";
|
|
import userEvent from "@testing-library/user-event";
|
|
|
|
import { ITeam } from "interfaces/team";
|
|
|
|
import TransferHostModal from "./TransferHostModal";
|
|
|
|
const teams: ITeam[] = [
|
|
{ id: 1, name: "Team Alpha" },
|
|
{ id: 2, name: "Team Beta" },
|
|
];
|
|
|
|
const setup = (
|
|
props: Partial<React.ComponentProps<typeof TransferHostModal>> = {}
|
|
) => {
|
|
const onSubmit = jest.fn();
|
|
const onCancel = jest.fn();
|
|
|
|
const user = userEvent.setup();
|
|
|
|
render(
|
|
<TransferHostModal
|
|
isGlobalAdmin={false}
|
|
teams={teams}
|
|
onSubmit={onSubmit}
|
|
onCancel={onCancel}
|
|
isUpdating={false}
|
|
multipleHosts={false}
|
|
hostsTeamId={1}
|
|
{...props}
|
|
/>
|
|
);
|
|
|
|
return { user, onSubmit, onCancel };
|
|
};
|
|
|
|
describe("TransferHostModal", () => {
|
|
it("renders title for single host and label", () => {
|
|
setup();
|
|
|
|
expect(
|
|
screen.getByText("Transfer host to:", { selector: "label" })
|
|
).toBeInTheDocument();
|
|
});
|
|
|
|
it("pluralizes title and label when multipleHosts is true", () => {
|
|
setup({ multipleHosts: true });
|
|
|
|
expect(
|
|
screen.getByText("Transfer selected hosts to:", { selector: "label" })
|
|
).toBeInTheDocument();
|
|
});
|
|
|
|
it("shows Create a fleet link when user is global admin", () => {
|
|
setup({ isGlobalAdmin: true });
|
|
|
|
expect(screen.getByText(/Create a fleet/i)).toBeInTheDocument();
|
|
});
|
|
|
|
it("does not show Create a fleet link when not global admin", () => {
|
|
setup({ isGlobalAdmin: false });
|
|
|
|
expect(screen.queryByText(/Create a fleet/i)).not.toBeInTheDocument();
|
|
});
|
|
|
|
it("disables Transfer button until a team is selected", () => {
|
|
setup();
|
|
|
|
const transferButton = screen.getByRole("button", { name: "Transfer" });
|
|
expect(transferButton).toBeDisabled();
|
|
});
|
|
|
|
it("filters out current host team from dropdown options and includes No fleet when allowed", async () => {
|
|
const { user } = setup({ hostsTeamId: 1 });
|
|
|
|
const dropdown = screen.getByText(/Select a fleet/i);
|
|
|
|
await user.click(dropdown);
|
|
|
|
expect(screen.getByText("Unassigned")).toBeInTheDocument();
|
|
expect(screen.getByText("Team Beta")).toBeInTheDocument();
|
|
expect(screen.queryByText("Team Alpha")).not.toBeInTheDocument();
|
|
});
|
|
|
|
it("does not allow transferring to No fleet again when host is already on no team", async () => {
|
|
const { user } = setup({ hostsTeamId: 0 });
|
|
|
|
const dropdown = screen.getByText(/Select a fleet/i);
|
|
await user.click(dropdown);
|
|
|
|
expect(screen.queryByText("Unassigned")).not.toBeInTheDocument();
|
|
expect(screen.getByText("Team Alpha")).toBeInTheDocument();
|
|
expect(screen.getByText("Team Beta")).toBeInTheDocument();
|
|
});
|
|
|
|
it("enables Transfer after selecting a team and calls onSubmit with selected team", async () => {
|
|
const { user, onSubmit } = setup({ hostsTeamId: 1 });
|
|
|
|
const dropdown = screen.getByText(/Select a fleet/i);
|
|
|
|
// Custom dropdown path: open then click an option
|
|
await user.click(dropdown);
|
|
await user.click(await screen.findByText("Team Beta"));
|
|
|
|
const transferButton = screen.getByRole("button", { name: "Transfer" });
|
|
expect(transferButton).not.toBeDisabled();
|
|
|
|
await user.click(transferButton);
|
|
|
|
expect(onSubmit).toHaveBeenCalledTimes(1);
|
|
});
|
|
|
|
it("supports selecting No fleet and passes through the no-team object shape", async () => {
|
|
const { user, onSubmit } = setup({ hostsTeamId: 1 });
|
|
|
|
const dropdown = screen.getByText(/Select a fleet/i);
|
|
await user.click(dropdown);
|
|
const options = await screen.findAllByTestId("dropdown-option");
|
|
const noTeamOption = options.find((el) =>
|
|
/Unassigned/i.test(el.textContent || "")
|
|
);
|
|
|
|
if (!noTeamOption) {
|
|
throw new Error("Unassigned option not found in dropdown");
|
|
}
|
|
|
|
await user.click(noTeamOption);
|
|
|
|
const transferButton = screen.getByRole("button", { name: "Transfer" });
|
|
expect(transferButton).not.toBeDisabled();
|
|
|
|
await user.click(transferButton);
|
|
|
|
expect(onSubmit).toHaveBeenCalledTimes(1);
|
|
});
|
|
|
|
it("calls onCancel when Cancel button is clicked", async () => {
|
|
const { user, onCancel } = setup();
|
|
|
|
const cancelButton = screen.getByRole("button", { name: "Cancel" });
|
|
await user.click(cancelButton);
|
|
|
|
expect(onCancel).toHaveBeenCalledTimes(1);
|
|
});
|
|
});
|