Files
fleet/frontend/components/AddHostsModal/AddHostsModal.tests.tsx
T
Steven Palmesano 1d1be298a9 Add /enroll URL for macOS in Add hosts modal (#47528)
**Related issue:** Resolves #38874

# Checklist for submitter

- [x] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.


## Testing

- [x] Added/updated automated tests
- [x] QA'd all new/changed functionality manually

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

* **New Features**
* Added macOS enrollment details in the “Add hosts” flow, including a
clearer choice between **Personal (BYOD)** and **Company-owned**
devices.
* Shows a copyable macOS enrollment URL when MDM is configured, updating
the URL based on the selected device type.
* Keeps the macOS setup experience aligned with the enrollment method,
including packaging guidance when MDM isn’t enabled.
* **Tests**
* Added coverage for macOS enrollment URL rendering and device-type
switching in the “Add hosts” modal.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-07 11:18:45 -05:00

315 lines
9.8 KiB
TypeScript

import React from "react";
import { screen } from "@testing-library/react";
import { noop } from "lodash";
import { createCustomRenderer } from "test/test-utils";
import createMockConfig from "__mocks__/configMock";
import AddHostsModal from "./AddHostsModal";
const ENROLL_SECRET = "abcdefg12345678";
describe("AddHostsModal", () => {
it("renders loading state", async () => {
const render = createCustomRenderer({
withBackendMock: true,
context: {
app: {
isPreviewMode: false,
config: createMockConfig(),
},
},
});
render(
<AddHostsModal isAnyTeamSelected={false} isLoading onCancel={noop} />
);
// Spinner has a built-in anti-flash delay, so wait for it to appear.
const loadingSpinner = await screen.findByTestId("spinner");
expect(loadingSpinner).toBeVisible();
});
it("renders platform tabs", async () => {
const render = createCustomRenderer({
withBackendMock: true,
context: {
app: {
isPreviewMode: false,
config: createMockConfig(),
},
},
});
const { user } = render(
<AddHostsModal
isAnyTeamSelected
enrollSecret={ENROLL_SECRET}
isLoading={false}
onCancel={noop}
/>
);
await user.click(screen.getByRole("tab", { name: "macOS" }));
const macOSText = screen.getByText(/--type=pkg/i);
expect(macOSText).toBeInTheDocument();
expect(screen.queryByText(/--enable-scripts/i)).toBeInTheDocument();
await user.click(screen.getByRole("tab", { name: "Windows" }));
const windowsText = screen.getByText(/--type=msi/i);
expect(windowsText).toBeInTheDocument();
expect(screen.queryByText(/--enable-scripts/i)).toBeInTheDocument();
await user.click(screen.getByRole("tab", { name: "Linux" }));
const linuxDebText = screen.getByText(/--type=deb/i);
expect(linuxDebText).toBeInTheDocument();
expect(screen.queryByText(/--enable-scripts/i)).toBeInTheDocument();
expect(screen.queryByText(/--type=rpm/i)).toBeInTheDocument();
await user.click(screen.getByRole("tab", { name: "ChromeOS" }));
const extensionId = screen.getByDisplayValue(
/fleeedmmihkfkeemmipgmhhjemlljidg/i
);
expect(extensionId).toBeInTheDocument();
expect(screen.queryByText(/--enable-scripts/i)).not.toBeInTheDocument();
await user.click(screen.getByRole("tab", { name: "iOS & iPadOS" }));
expect(screen.queryByText(/Turn on Apple MDM/i)).toBeInTheDocument();
await user.click(screen.getByRole("tab", { name: "Android" }));
expect(screen.queryByText(/Turn on Android MDM/i)).toBeInTheDocument();
await user.click(screen.getByRole("tab", { name: "Advanced" }));
const advancedText = screen.getByText(/--type=YOUR_TYPE/i);
expect(advancedText).toBeInTheDocument();
expect(screen.queryByText(/--enable-scripts/i)).not.toBeInTheDocument();
await user.click(screen.getByText(/Plain osquery/i));
const downloadEnrollSecret = screen.getByText(
/Download your enroll secret/i
);
expect(downloadEnrollSecret).toBeInTheDocument();
const osquerydCommand = screen.getByDisplayValue(
/osqueryd --flagfile=flagfile.txt --verbose/i
);
expect(osquerydCommand).toBeInTheDocument();
expect(screen.queryByText(/--enable-scripts/i)).not.toBeInTheDocument();
});
it("renders enroll url input for macOS if mac mdm is enabled", async () => {
const render = createCustomRenderer({
withBackendMock: true,
context: {
app: {
isMacMdmEnabledAndConfigured: true,
isPreviewMode: false,
config: createMockConfig(),
},
},
});
const { user } = render(
<AddHostsModal
isAnyTeamSelected
enrollSecret={ENROLL_SECRET}
isLoading={false}
onCancel={noop}
/>
);
await user.click(screen.getByRole("tab", { name: "macOS" }));
expect(screen.getByLabelText("Personal (BYOD)")).toBeInTheDocument();
expect(screen.getByLabelText("Company-owned")).toBeInTheDocument();
expect(
screen.getByText(/Send this to your end users:/i)
).toBeInTheDocument();
// Company-owned is selected by default — URL has no byod param
const urlInput = screen.getByDisplayValue(
new RegExp(`/enroll\\?enroll_secret=${ENROLL_SECRET}$`)
);
expect(urlInput).toBeInTheDocument();
// Switching to Personal (BYOD) appends byod=true
await user.click(screen.getByLabelText("Personal (BYOD)"));
const byodUrlInput = screen.getByDisplayValue(
new RegExp(`/enroll\\?enroll_secret=${ENROLL_SECRET}&byod=true`)
);
expect(byodUrlInput).toBeInTheDocument();
});
it("renders enroll url input for ios & ipadOS if mac mdm is enabled", async () => {
const render = createCustomRenderer({
withBackendMock: true,
context: {
app: {
isMacMdmEnabledAndConfigured: true,
isPreviewMode: false,
config: createMockConfig(),
},
},
});
const { user } = render(
<AddHostsModal
isAnyTeamSelected
enrollSecret={ENROLL_SECRET}
isLoading={false}
onCancel={noop}
/>
);
await user.click(screen.getByRole("tab", { name: "iOS & iPadOS" }));
expect(screen.queryByText(/Enrollment instructions:/i)).toBeInTheDocument();
expect(screen.getByLabelText("Personal (BYOD)")).toBeInTheDocument();
expect(screen.getByLabelText("Company-owned")).toBeInTheDocument();
});
it("renders enroll url input for android if android mdm is enabled", async () => {
const render = createCustomRenderer({
withBackendMock: true,
context: {
app: {
isAndroidMdmEnabledAndConfigured: true,
isPreviewMode: false,
config: createMockConfig(),
},
},
});
const { user } = render(
<AddHostsModal
isAnyTeamSelected
enrollSecret={ENROLL_SECRET}
isLoading={false}
onCancel={noop}
/>
);
await user.click(screen.getByRole("tab", { name: "Android" }));
expect(screen.queryByText(/Enrollment instructions:/i)).toBeInTheDocument();
});
it("renders installer with secret", async () => {
const render = createCustomRenderer({
withBackendMock: true,
context: {
app: {
isPreviewMode: false,
config: createMockConfig(),
},
},
});
render(
<AddHostsModal
isAnyTeamSelected
enrollSecret={ENROLL_SECRET}
isLoading={false}
onCancel={noop}
/>
);
const regex = new RegExp(`${ENROLL_SECRET}`);
const text = screen.getByDisplayValue(regex);
expect(text).toBeInTheDocument();
});
it("renders no enroll secret cta", async () => {
const onCancel = jest.fn();
const openEnrollSecretModal = jest.fn();
const render = createCustomRenderer({
withBackendMock: true,
context: {
app: {
isPreviewMode: false,
config: createMockConfig(),
},
},
});
const { user } = render(
<AddHostsModal
isAnyTeamSelected={false}
isLoading={false}
onCancel={onCancel}
openEnrollSecretModal={openEnrollSecretModal}
/>
);
expect(screen.getByText("Something's gone wrong.")).toBeInTheDocument();
expect(
screen.getByText(/you have no enroll secrets\./i)
).toBeInTheDocument();
const cta = screen.getByText(/manage enroll secrets/i);
expect(cta).toBeInTheDocument();
await user.click(cta);
expect(onCancel).toHaveBeenCalledTimes(1);
expect(openEnrollSecretModal).toHaveBeenCalledTimes(1);
});
it("excludes `--enable-scripts` flag if `config.server_settings.scripts-disabled` is `true`", async () => {
const mockConfig = createMockConfig();
mockConfig.server_settings.scripts_disabled = true;
const render = createCustomRenderer({
withBackendMock: true,
context: {
app: {
isPreviewMode: false,
config: mockConfig,
},
},
});
const { user } = render(
<AddHostsModal
isAnyTeamSelected
enrollSecret={ENROLL_SECRET}
isLoading={false}
onCancel={noop}
/>
);
await user.click(screen.getByRole("tab", { name: "macOS" }));
const macOSText = screen.getByText(/--type=pkg/i);
expect(macOSText).toBeInTheDocument();
expect(screen.queryByText(/--enable-scripts/i)).not.toBeInTheDocument();
await user.click(screen.getByRole("tab", { name: "Windows" }));
const windowsText = screen.getByText(/--type=msi/i);
expect(windowsText).toBeInTheDocument();
expect(screen.queryByText(/--enable-scripts/i)).not.toBeInTheDocument();
await user.click(screen.getByRole("tab", { name: "Linux" }));
const linuxRPMText = screen.getByText(/--type=rpm/i);
expect(linuxRPMText).toBeInTheDocument();
expect(screen.queryByText(/--enable-scripts/i)).not.toBeInTheDocument();
await user.click(screen.getByRole("tab", { name: "ChromeOS" }));
const extensionId = screen.getByDisplayValue(
/fleeedmmihkfkeemmipgmhhjemlljidg/i
);
expect(extensionId).toBeInTheDocument();
expect(screen.queryByText(/--enable-scripts/i)).not.toBeInTheDocument();
await user.click(screen.getByRole("tab", { name: "Advanced" }));
const advancedText = screen.getByText(/--type=YOUR_TYPE/i);
expect(advancedText).toBeInTheDocument();
expect(screen.queryByText(/--enable-scripts/i)).not.toBeInTheDocument();
await user.click(screen.getByText(/Plain osquery/i));
const downloadEnrollSecret = screen.getByText(
/Download your enroll secret/i
);
expect(downloadEnrollSecret).toBeInTheDocument();
const osquerydCommand = screen.getByDisplayValue(
/osqueryd --flagfile=flagfile.txt --verbose/i
);
expect(osquerydCommand).toBeInTheDocument();
expect(screen.queryByText(/--enable-scripts/i)).not.toBeInTheDocument();
});
});