mirror of
https://github.com/fleetdm/fleet
synced 2026-05-24 09:28:54 +00:00
Fleet UI: Return pre-install query output in Install Details modal (#35754)
This commit is contained in:
parent
daae2c1c06
commit
4939979f55
4 changed files with 149 additions and 29 deletions
1
changes/33733-install-details-modal
Normal file
1
changes/33733-install-details-modal
Normal file
|
|
@ -0,0 +1 @@
|
|||
* Fleet UI: Return pre-install query output in Install Details modal
|
||||
|
|
@ -7,6 +7,8 @@ import {
|
|||
getDefaultSoftwareInstallHandler,
|
||||
getSoftwareInstallHandlerNoOutputs,
|
||||
getSoftwareInstallHandlerOnlyInstallOutput,
|
||||
getSoftwareInstallHandlerWithPreInstall,
|
||||
getSoftwareInstallHandlerOnlyPreInstallOutput,
|
||||
} from "test/handlers/software-handlers";
|
||||
import mockServer from "test/mock-server";
|
||||
import { noop } from "lodash";
|
||||
|
|
@ -216,14 +218,78 @@ describe("SoftwareInstallDetailsModal", () => {
|
|||
|
||||
expect(detailsButton).toBeInTheDocument();
|
||||
expect(
|
||||
screen.queryByLabelText("Install script output:")
|
||||
screen.queryByText("Pre-install query output:")
|
||||
).not.toBeInTheDocument();
|
||||
expect(
|
||||
screen.queryByLabelText(/Post-install script output:/i)
|
||||
screen.queryByText("Install script output:")
|
||||
).not.toBeInTheDocument();
|
||||
expect(
|
||||
screen.queryByText(/Post-install script output:/i)
|
||||
).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("shows install and post-install outputs after clicking Details", async () => {
|
||||
it("shows pre-install, install, and post-install outputs after clicking Details", async () => {
|
||||
mockServer.use(getSoftwareInstallHandlerWithPreInstall);
|
||||
const renderWithServer = createCustomRenderer({ withBackendMock: true });
|
||||
const { user } = renderWithServer(
|
||||
<SoftwareInstallDetailsModal
|
||||
details={baseDetails}
|
||||
hostSoftware={baseHostSoftware}
|
||||
onCancel={noop}
|
||||
/>
|
||||
);
|
||||
|
||||
const detailsBtn = await screen.findByRole("button", {
|
||||
name: /Details/i,
|
||||
});
|
||||
await user.click(detailsBtn);
|
||||
|
||||
// Pre-install output
|
||||
expect(
|
||||
await screen.getByText("Pre-install query output:")
|
||||
).toBeInTheDocument();
|
||||
expect(screen.getByText("Pre-install check passed")).toBeInTheDocument();
|
||||
|
||||
// Install output
|
||||
expect(screen.getByText("Install script output:")).toBeInTheDocument();
|
||||
expect(screen.getByText("Install script ran")).toBeInTheDocument();
|
||||
|
||||
// Post-install output
|
||||
expect(
|
||||
screen.getByText("Post-install script output:")
|
||||
).toBeInTheDocument();
|
||||
expect(screen.getByText("Post-install success")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("renders only pre-install output if that's the only script output present", async () => {
|
||||
mockServer.use(getSoftwareInstallHandlerOnlyPreInstallOutput);
|
||||
const renderWithServer = createCustomRenderer({ withBackendMock: true });
|
||||
const { user } = renderWithServer(
|
||||
<SoftwareInstallDetailsModal
|
||||
details={baseDetails}
|
||||
hostSoftware={baseHostSoftware}
|
||||
onCancel={noop}
|
||||
/>
|
||||
);
|
||||
|
||||
const detailsBtn = await screen.findByRole("button", {
|
||||
name: /Details/i,
|
||||
});
|
||||
await user.click(detailsBtn);
|
||||
|
||||
expect(
|
||||
await screen.getByText("Pre-install query output:")
|
||||
).toBeInTheDocument();
|
||||
expect(screen.getByText(/pre-install only/i)).toBeInTheDocument();
|
||||
expect(
|
||||
screen.queryByText("Install script output:")
|
||||
).not.toBeInTheDocument();
|
||||
expect(
|
||||
screen.queryByText(/Post-install script output:/i)
|
||||
).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("shows install and post-install outputs after clicking Details (no pre-install)", async () => {
|
||||
mockServer.use(getDefaultSoftwareInstallHandler);
|
||||
const renderWithServer = createCustomRenderer({ withBackendMock: true });
|
||||
const { user } = renderWithServer(
|
||||
|
|
@ -239,15 +305,48 @@ describe("SoftwareInstallDetailsModal", () => {
|
|||
});
|
||||
await user.click(detailsBtn);
|
||||
|
||||
await screen.findByText("Install script output:");
|
||||
expect(
|
||||
await screen.getByText("Install script output:")
|
||||
).toBeInTheDocument();
|
||||
expect(screen.getByText("Install script ran")).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByText(/Post-install script output:/i)
|
||||
).toBeInTheDocument();
|
||||
expect(screen.getByText("Post-install success")).toBeInTheDocument();
|
||||
expect(
|
||||
screen.queryByText("Pre-install query output:")
|
||||
).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("does not render details button if details (script outputs) are empty", async () => {
|
||||
it("shows only the install output if post-install and pre-install output is empty", async () => {
|
||||
mockServer.use(getSoftwareInstallHandlerOnlyInstallOutput);
|
||||
const renderWithServer = createCustomRenderer({ withBackendMock: true });
|
||||
const { user } = renderWithServer(
|
||||
<SoftwareInstallDetailsModal
|
||||
details={baseDetails}
|
||||
hostSoftware={baseHostSoftware}
|
||||
onCancel={noop}
|
||||
/>
|
||||
);
|
||||
|
||||
const detailsBtn = await screen.findByRole("button", {
|
||||
name: /Details/i,
|
||||
});
|
||||
await user.click(detailsBtn);
|
||||
|
||||
expect(
|
||||
await screen.getByText("Install script output:")
|
||||
).toBeInTheDocument();
|
||||
expect(screen.getByText(/install only/i)).toBeInTheDocument();
|
||||
expect(
|
||||
screen.queryByText("Pre-install query output:")
|
||||
).not.toBeInTheDocument();
|
||||
expect(
|
||||
screen.queryByText(/Post-install script output:/i)
|
||||
).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("does not render details button if all script outputs are empty", async () => {
|
||||
mockServer.use(getSoftwareInstallHandlerNoOutputs);
|
||||
const renderWithServer = createCustomRenderer({ withBackendMock: true });
|
||||
renderWithServer(
|
||||
|
|
@ -264,28 +363,5 @@ describe("SoftwareInstallDetailsModal", () => {
|
|||
})
|
||||
).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("shows only the install output if post-install output is empty", async () => {
|
||||
mockServer.use(getSoftwareInstallHandlerOnlyInstallOutput);
|
||||
const renderWithServer = createCustomRenderer({ withBackendMock: true });
|
||||
const { user } = renderWithServer(
|
||||
<SoftwareInstallDetailsModal
|
||||
details={baseDetails}
|
||||
hostSoftware={baseHostSoftware}
|
||||
onCancel={noop}
|
||||
/>
|
||||
);
|
||||
|
||||
const detailsBtn = await screen.findByRole("button", {
|
||||
name: /Details/i,
|
||||
});
|
||||
await user.click(detailsBtn);
|
||||
|
||||
await screen.findByText("Install script output:");
|
||||
expect(screen.getByText(/install only/i)).toBeInTheDocument();
|
||||
expect(
|
||||
screen.queryByText(/Post-install script output:/i)
|
||||
).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -260,6 +260,10 @@ export const SoftwareInstallDetailsModal = ({
|
|||
|
||||
const renderInstallDetailsSection = () => {
|
||||
const outputs = [
|
||||
{
|
||||
label: "Pre-install query output:",
|
||||
value: swInstallResult?.pre_install_query_output,
|
||||
},
|
||||
{
|
||||
label: "Install script output:",
|
||||
value: swInstallResult?.output,
|
||||
|
|
@ -273,7 +277,8 @@ export const SoftwareInstallDetailsModal = ({
|
|||
// Only show details button if there's details to display
|
||||
const showDetailsButton =
|
||||
(!!swInstallResult?.post_install_script_output ||
|
||||
!!swInstallResult?.output) &&
|
||||
!!swInstallResult?.output ||
|
||||
!!swInstallResult?.pre_install_query_output) &&
|
||||
swInstallResult?.status !== "pending_install";
|
||||
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -64,6 +64,44 @@ export const getSoftwareInstallResultHandler = http.get(
|
|||
}
|
||||
);
|
||||
|
||||
// ---- Pre install query output ----
|
||||
|
||||
// Installed, outputs for pre-install, install, and post-install
|
||||
export const getSoftwareInstallHandlerWithPreInstall = http.get(
|
||||
baseUrl("/software/install/:install_uuid/results"),
|
||||
({ params }) => {
|
||||
return HttpResponse.json({
|
||||
results: {
|
||||
...createMockSoftwareInstallResult({
|
||||
install_uuid: params.install_uuid as string,
|
||||
status: "installed",
|
||||
output: "Install script ran",
|
||||
post_install_script_output: "Post-install success",
|
||||
pre_install_query_output: "Pre-install check passed",
|
||||
}),
|
||||
},
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
// Failed install, only pre-install output
|
||||
export const getSoftwareInstallHandlerOnlyPreInstallOutput = http.get(
|
||||
baseUrl("/software/install/:install_uuid/results"),
|
||||
({ params }) => {
|
||||
return HttpResponse.json({
|
||||
results: {
|
||||
...createMockSoftwareInstallResult({
|
||||
install_uuid: params.install_uuid as string,
|
||||
status: "failed_install",
|
||||
output: "",
|
||||
post_install_script_output: "",
|
||||
pre_install_query_output: "Pre-install only",
|
||||
}),
|
||||
},
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
// ---- MDM Command Handlers ----
|
||||
|
||||
/** This is used for testing command results of IPA custom packages */
|
||||
|
|
|
|||
Loading…
Reference in a new issue