Files
fleet/frontend/components/TargetLabelSelector/DropdownTargetLabelSelector.tests.tsx
T
Nico 8ba889f701 Extract reusable Include/Exclude TargetLabelSelector component (#47212)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #46583

Before implementing changes in the Save policy / Edit policy modal (see
[Figma](https://www.figma.com/design/0F1sw63SuYaKVWlcL7mnc6/-33441-Policies--Custom-targets-with-%22Include-any%22-and-%22Exclude-any%22?node-id=5303-5687&t=Fszpf83KhcZ7ViWh-0)),
I though of making the label selection a reusable component that we
could reuse both in Configuration Profiles and in Policies, so that we
don't repeat ourselves.

## Testing

- [x] Added/updated automated tests

- [x] QA'd all new/changed functionality manually

I don't have MDM fully wired up but I checked the payloads were sent as
expected.



https://github.com/user-attachments/assets/b2c4898f-c69c-4c05-b76c-e89728842661



<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added a dropdown-based target selector and a tabbed Include/Exclude
label selector with Any/All mode.

* **Improvements**
* Unified target/label selection across packages, policies, queries, and
profiles.
* Better empty/loading/error states, selectable badges, help/subtitle
support, and cross-tab disabling of selected labels.

* **Tests**
* Added and updated test coverage for both dropdown and tabbed selector
behaviors.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-10 11:14:47 -03:00

211 lines
6.8 KiB
TypeScript

import React from "react";
import { render, screen } from "@testing-library/react";
import { noop } from "lodash";
import DropdownTargetLabelSelector from "./DropdownTargetLabelSelector";
describe("DropdownTargetLabelSelector component", () => {
describe("renders the custom target selector when the target type is 'Custom'", () => {
it("with a dropdown when there are custom options to choose from", () => {
render(
<DropdownTargetLabelSelector
selectedTargetType="Custom"
selectedCustomTarget="labelIncludeAny"
customTargetOptions={[
{ value: "labelIncludeAny", label: "Include any" },
]}
selectedLabels={{}}
labels={[
{ id: 1, name: "label 1", label_type: "regular" },
{ id: 2, name: "label 2", label_type: "regular" },
]}
onSelectCustomTarget={noop}
onSelectLabel={noop}
onSelectTargetType={noop}
/>
);
// custom target selector is rendering
expect(screen.getByRole("option", { name: "Include any" })).toBeVisible();
// lables are rendering
expect(screen.getByRole("checkbox", { name: "label 1" })).toBeVisible();
expect(screen.getByRole("checkbox", { name: "label 2" })).toBeVisible();
});
it("with an optional message and no dropdown when there are no custom options to choose from", () => {
const HELP_TEXT = "go boldly where no target has gone before";
render(
<DropdownTargetLabelSelector
selectedTargetType="Custom"
selectedCustomTarget="labelIncludeAny"
customHelpText={<span>{HELP_TEXT}</span>}
selectedLabels={{}}
labels={[
{ id: 1, name: "label 1", label_type: "regular" },
{ id: 2, name: "label 2", label_type: "regular" },
]}
onSelectCustomTarget={noop}
onSelectLabel={noop}
onSelectTargetType={noop}
/>
);
// custom target help text is visible
expect(screen.getByText(HELP_TEXT)).toBeVisible();
expect(screen.queryByRole("option")).not.toBeInTheDocument();
// lables are rendering
expect(screen.getByRole("checkbox", { name: "label 1" })).toBeVisible();
expect(screen.getByRole("checkbox", { name: "label 2" })).toBeVisible();
});
});
it("does not render the custom target selector when the target type is 'All hosts'", () => {
render(
<DropdownTargetLabelSelector
selectedTargetType="All hosts"
selectedCustomTarget="labelIncludeAny"
customTargetOptions={[
{ value: "labelIncludeAny", label: "Include any" },
]}
selectedLabels={{}}
labels={[
{ id: 1, name: "label 1", label_type: "regular" },
{ id: 2, name: "label 2", label_type: "regular" },
]}
onSelectCustomTarget={noop}
onSelectLabel={noop}
onSelectTargetType={noop}
/>
);
// custom target selector is not rendering
expect(screen.queryByRole("option", { name: "Include any" })).toBeNull();
// lables are not rendering
expect(screen.queryByRole("checkbox", { name: "label 1" })).toBeNull();
expect(screen.queryByRole("checkbox", { name: "label 2" })).toBeNull();
});
it("renders selected labels as checked", () => {
render(
<DropdownTargetLabelSelector
selectedTargetType="Custom"
selectedCustomTarget="labelIncludeAny"
customTargetOptions={[
{ value: "labelIncludeAny", label: "Include any" },
]}
selectedLabels={{ "label 1": true, "label 2": false }}
labels={[
{ id: 1, name: "label 1", label_type: "regular" },
{ id: 2, name: "label 2", label_type: "regular" },
]}
onSelectCustomTarget={noop}
onSelectLabel={noop}
onSelectTargetType={noop}
/>
);
// lables are rendering
expect(screen.getByRole("checkbox", { name: "label 1" })).toBeChecked();
expect(screen.getByRole("checkbox", { name: "label 2" })).not.toBeChecked();
});
it("sets the title to Target by default", () => {
const TITLE = "Target";
render(
<DropdownTargetLabelSelector
selectedTargetType="Custom"
selectedCustomTarget="labelIncludeAny"
customTargetOptions={[
{ value: "labelIncludeAny", label: "Include any" },
]}
selectedLabels={{}}
labels={[
{ id: 1, name: "label 1", label_type: "regular" },
{ id: 2, name: "label 2", label_type: "regular" },
]}
onSelectCustomTarget={noop}
onSelectLabel={noop}
onSelectTargetType={noop}
title={TITLE}
/>
);
expect(screen.getByText(TITLE)).toBeVisible();
});
it("allows a custom title to be passed in", () => {
const TITLE = "Choose a target";
render(
<DropdownTargetLabelSelector
selectedTargetType="Custom"
selectedCustomTarget="labelIncludeAny"
customTargetOptions={[
{ value: "labelIncludeAny", label: "Include any" },
]}
selectedLabels={{}}
labels={[
{ id: 1, name: "label 1", label_type: "regular" },
{ id: 2, name: "label 2", label_type: "regular" },
]}
onSelectCustomTarget={noop}
onSelectLabel={noop}
onSelectTargetType={noop}
title={TITLE}
/>
);
expect(screen.getByText(TITLE)).toBeVisible();
});
it("suppresses the title when suppressTitle is true", () => {
render(
<DropdownTargetLabelSelector
selectedTargetType="Custom"
selectedCustomTarget="labelIncludeAny"
customTargetOptions={[
{ value: "labelIncludeAny", label: "Include any" },
]}
selectedLabels={{}}
labels={[
{ id: 1, name: "label 1", label_type: "regular" },
{ id: 2, name: "label 2", label_type: "regular" },
]}
onSelectCustomTarget={noop}
onSelectLabel={noop}
onSelectTargetType={noop}
suppressTitle
/>
);
expect(screen.queryByText("Target")).not.toBeInTheDocument();
});
it("allows a subtitle to be passed in", () => {
const SUBTITLE = "Select one of the following options";
render(
<DropdownTargetLabelSelector
selectedTargetType="Custom"
selectedCustomTarget="labelIncludeAny"
customTargetOptions={[
{ value: "labelIncludeAny", label: "Include any" },
]}
selectedLabels={{}}
labels={[
{ id: 1, name: "label 1", label_type: "regular" },
{ id: 2, name: "label 2", label_type: "regular" },
]}
onSelectCustomTarget={noop}
onSelectLabel={noop}
onSelectTargetType={noop}
subTitle={SUBTITLE}
/>
);
expect(screen.getByText(SUBTITLE)).toBeVisible();
});
});