mirror of
https://github.com/empayre/fleet.git
synced 2024-11-07 09:18:59 +00:00
87c4aba10d
* added teams to add host modal dropdown * bulk and transfer host on host page * started transferhost API call * hook up client side of api * hook up client side of api call for enrol secrets * added selection number and clear all selections button * remove log and document * fix ManageHostPage tests * fix linting errors * add indeterminate styles to checkbox * added clearable handler for dropdown component * fix up no team for add modal * Add active selection styles and move specific host table styles into ManageHostsPage styles * changed add host team dropdown to include no team option * add no team option to bulk transfer host options * change enroll spelling Co-authored-by: Noah Talerman <noahtal@umich.edu>
345 lines
9.2 KiB
JavaScript
345 lines
9.2 KiB
JavaScript
import React from "react";
|
|
import { mount, shallow } from "enzyme";
|
|
import { noop } from "lodash";
|
|
|
|
import hostActions from "redux/nodes/entities/hosts/actions";
|
|
import labelActions from "redux/nodes/entities/labels/actions";
|
|
import ConnectedManageHostsPage, {
|
|
ManageHostsPage,
|
|
} from "pages/hosts/ManageHostsPage/ManageHostsPage";
|
|
import {
|
|
connectedComponent,
|
|
createAceSpy,
|
|
reduxMockStore,
|
|
stubbedOsqueryTable,
|
|
} from "test/helpers";
|
|
import { hostStub, configStub, userStub, teamStub } from "test/stubs";
|
|
import * as manageHostsPageActions from "redux/nodes/components/ManageHostsPage/actions";
|
|
|
|
const allHostsLabel = {
|
|
id: 1,
|
|
display_text: "All Hosts",
|
|
slug: "all-hosts",
|
|
type: "all",
|
|
count: 22,
|
|
};
|
|
const windowsLabel = {
|
|
id: 2,
|
|
display_text: "Windows",
|
|
slug: "windows",
|
|
type: "platform",
|
|
count: 22,
|
|
};
|
|
const offlineHost = { ...hostStub, id: 111, status: "offline" };
|
|
const offlineHostsLabel = {
|
|
id: 5,
|
|
display_text: "OFFLINE",
|
|
slug: "offline",
|
|
status: "offline",
|
|
type: "status",
|
|
count: 1,
|
|
};
|
|
const customLabel = {
|
|
id: 12,
|
|
display_text: "Custom Label",
|
|
slug: "labels/12",
|
|
type: "custom",
|
|
count: 3,
|
|
};
|
|
const mockStore = reduxMockStore({
|
|
app: { enrollSecret: [], config: {} },
|
|
auth: { user: userStub },
|
|
components: {
|
|
ManageHostsPage: {
|
|
display: "Grid",
|
|
selectedLabel: {
|
|
id: 100,
|
|
display_text: "All Hosts",
|
|
type: "all",
|
|
count: 22,
|
|
},
|
|
status_labels: {},
|
|
},
|
|
QueryPages: {
|
|
selectedOsqueryTable: stubbedOsqueryTable,
|
|
},
|
|
},
|
|
entities: {
|
|
hosts: {
|
|
data: {
|
|
[hostStub.id]: hostStub,
|
|
[offlineHost.id]: offlineHost,
|
|
},
|
|
originalOrder: [hostStub.id, offlineHost.id],
|
|
},
|
|
labels: {
|
|
data: {
|
|
1: allHostsLabel,
|
|
2: windowsLabel,
|
|
3: {
|
|
id: 3,
|
|
display_text: "Ubuntu",
|
|
slug: "ubuntu",
|
|
type: "platform",
|
|
count: 22,
|
|
},
|
|
4: {
|
|
id: 4,
|
|
display_text: "ONLINE",
|
|
slug: "online",
|
|
type: "status",
|
|
count: 22,
|
|
},
|
|
5: offlineHostsLabel,
|
|
6: customLabel,
|
|
},
|
|
},
|
|
teams: {
|
|
data: { [teamStub.id]: teamStub },
|
|
},
|
|
},
|
|
});
|
|
|
|
describe("ManageHostsPage - component", () => {
|
|
const props = {
|
|
config: configStub,
|
|
dispatch: noop,
|
|
hosts: [],
|
|
labels: [],
|
|
loadingHosts: false,
|
|
loadingLabels: false,
|
|
selectedOsqueryTable: stubbedOsqueryTable,
|
|
statusLabels: {},
|
|
enrollSecret: [],
|
|
};
|
|
|
|
beforeEach(() => {
|
|
const spyResponse = () => Promise.resolve([]);
|
|
|
|
jest.spyOn(hostActions, "loadAll").mockImplementation(() => spyResponse);
|
|
jest.spyOn(labelActions, "loadAll").mockImplementation(() => spyResponse);
|
|
jest
|
|
.spyOn(manageHostsPageActions, "getStatusLabelCounts")
|
|
.mockImplementation(() => spyResponse);
|
|
createAceSpy();
|
|
});
|
|
|
|
describe("side panels", () => {
|
|
it("renders a HostSidePanel when not adding a new label", () => {
|
|
const page = shallow(<ManageHostsPage {...props} />);
|
|
|
|
expect(page.find("HostSidePanel").length).toEqual(1);
|
|
});
|
|
|
|
it("renders a QuerySidePanel when adding a new label", () => {
|
|
const ownProps = { location: { hash: "#new_label" }, params: {} };
|
|
const component = connectedComponent(ConnectedManageHostsPage, {
|
|
props: ownProps,
|
|
mockStore,
|
|
});
|
|
const page = mount(component);
|
|
|
|
expect(page.find("QuerySidePanel").length).toEqual(1);
|
|
});
|
|
});
|
|
|
|
describe("host filtering", () => {
|
|
it("shows all hosts by default", () => {
|
|
const ownProps = { location: { hash: "" }, params: {} };
|
|
const component = connectedComponent(ConnectedManageHostsPage, {
|
|
props: ownProps,
|
|
mockStore,
|
|
});
|
|
const page = mount(component);
|
|
expect(page.find("TableContainer").find("tbody tr").length).toEqual(2);
|
|
});
|
|
});
|
|
|
|
describe("Adding a new label", () => {
|
|
beforeEach(() => createAceSpy());
|
|
|
|
const ownProps = { location: { hash: "#new_label" }, params: {} };
|
|
const component = connectedComponent(ConnectedManageHostsPage, {
|
|
props: ownProps,
|
|
mockStore,
|
|
});
|
|
|
|
it("renders a LabelForm component", () => {
|
|
const page = mount(component);
|
|
|
|
expect(page.find("LabelForm").length).toEqual(1);
|
|
});
|
|
|
|
it('displays "New label" as the query form header', () => {
|
|
const page = mount(component);
|
|
|
|
expect(page.find("LabelForm").text()).toContain("New label");
|
|
});
|
|
});
|
|
|
|
describe("Active label", () => {
|
|
beforeEach(() => createAceSpy());
|
|
|
|
it("Displays the all hosts label as the active label by default", () => {
|
|
const ownProps = { location: {}, params: {} };
|
|
const component = connectedComponent(ConnectedManageHostsPage, {
|
|
props: ownProps,
|
|
mockStore,
|
|
});
|
|
const page = mount(component);
|
|
|
|
expect(page.find("HostSidePanel").props()).toMatchObject({
|
|
selectedFilter: "all-hosts",
|
|
});
|
|
});
|
|
|
|
it("Displays the windows label as the active label", () => {
|
|
const ownProps = { location: {}, params: { active_label: "labels/4" } };
|
|
const component = connectedComponent(ConnectedManageHostsPage, {
|
|
props: ownProps,
|
|
mockStore,
|
|
});
|
|
const page = mount(component);
|
|
|
|
expect(page.find("HostSidePanel").props()).toMatchObject({
|
|
selectedFilter: "labels/4",
|
|
});
|
|
});
|
|
|
|
it("Renders the default description if the selected label does not have a description", () => {
|
|
const defaultDescription = "No description available.";
|
|
const noDescriptionLabel = { ...allHostsLabel, description: undefined };
|
|
const pageProps = {
|
|
...props,
|
|
selectedLabel: noDescriptionLabel,
|
|
};
|
|
|
|
const Page = shallow(<ManageHostsPage {...pageProps} />);
|
|
|
|
expect(Page.find(".manage-hosts__header").text()).toContain(
|
|
defaultDescription
|
|
);
|
|
});
|
|
|
|
it("Renders the label description if the selected label has a description", () => {
|
|
const defaultDescription = "No description available.";
|
|
const labelDescription = "This is the label description";
|
|
const noDescriptionLabel = {
|
|
...allHostsLabel,
|
|
description: labelDescription,
|
|
};
|
|
const pageProps = {
|
|
...props,
|
|
selectedLabel: noDescriptionLabel,
|
|
};
|
|
|
|
const Page = shallow(<ManageHostsPage {...pageProps} />);
|
|
|
|
expect(Page.find(".manage-hosts__header").text()).toContain(
|
|
labelDescription
|
|
);
|
|
expect(Page.find(".manage-hosts__header").text()).not.toContain(
|
|
defaultDescription
|
|
);
|
|
});
|
|
});
|
|
|
|
describe("Edit a label", () => {
|
|
const ownProps = {
|
|
location: { hash: "" },
|
|
params: { label_id: "12" },
|
|
};
|
|
const component = connectedComponent(ConnectedManageHostsPage, {
|
|
props: ownProps,
|
|
mockStore,
|
|
});
|
|
|
|
it("renders the Edit button when a custom label is selected", () => {
|
|
const Page = mount(component);
|
|
const EditButton = Page.find(".manage-hosts__label-actions")
|
|
.find("Button")
|
|
.first();
|
|
|
|
expect(EditButton.length).toEqual(1);
|
|
});
|
|
|
|
const ownPropsEditSelected = {
|
|
location: { hash: "#edit_label" },
|
|
params: { label_id: "12" },
|
|
};
|
|
const componentWithEditSelected = connectedComponent(
|
|
ConnectedManageHostsPage,
|
|
{
|
|
props: ownPropsEditSelected,
|
|
mockStore,
|
|
}
|
|
);
|
|
|
|
it("renders a LabelForm component", () => {
|
|
const page = mount(componentWithEditSelected);
|
|
|
|
expect(page.find("LabelForm").length).toEqual(1);
|
|
});
|
|
|
|
it('displays "Edit label" as the query form header', () => {
|
|
const page = mount(componentWithEditSelected);
|
|
|
|
expect(page.find("LabelForm").text()).toContain("Edit label");
|
|
});
|
|
});
|
|
|
|
describe("Delete a label", () => {
|
|
it("Deleted label after confirmation modal", () => {
|
|
const ownProps = {
|
|
location: {},
|
|
params: { label_id: "12" },
|
|
};
|
|
const component = connectedComponent(ConnectedManageHostsPage, {
|
|
props: ownProps,
|
|
mockStore,
|
|
});
|
|
const page = mount(component);
|
|
const deleteBtn = page
|
|
.find(".manage-hosts__label-actions")
|
|
.find("Button")
|
|
.last();
|
|
|
|
jest
|
|
.spyOn(labelActions, "destroy")
|
|
.mockImplementation(() => (dispatch) => {
|
|
dispatch({ type: "labels_LOAD_REQUEST" });
|
|
|
|
return Promise.resolve();
|
|
});
|
|
|
|
expect(page.find("Modal").length).toEqual(0);
|
|
|
|
deleteBtn.simulate("click");
|
|
|
|
const confirmModal = page.find("Modal");
|
|
|
|
expect(confirmModal.length).toEqual(1);
|
|
|
|
const confirmBtn = confirmModal.find(".button--alert");
|
|
confirmBtn.simulate("click");
|
|
|
|
expect(labelActions.destroy).toHaveBeenCalledWith(customLabel);
|
|
});
|
|
});
|
|
|
|
describe("Add Host", () => {
|
|
it("Open the Add Host modal", () => {
|
|
const ownProps = { location: { hash: "" }, params: {} };
|
|
const component = connectedComponent(ConnectedManageHostsPage, {
|
|
props: ownProps,
|
|
mockStore,
|
|
});
|
|
const page = mount(component);
|
|
const addNewHost = page.find(".manage-hosts__add-hosts");
|
|
addNewHost.hostNodes().simulate("click");
|
|
|
|
expect(page.find("AddHostModal").length).toBeGreaterThan(0);
|
|
});
|
|
});
|
|
});
|