2016-11-17 17:12:41 +00:00
|
|
|
import React from 'react';
|
|
|
|
import { mount } from 'enzyme';
|
|
|
|
import { noop } from 'lodash';
|
|
|
|
|
2017-01-19 23:39:06 +00:00
|
|
|
import hostActions from 'redux/nodes/entities/hosts/actions';
|
2017-01-19 17:57:59 +00:00
|
|
|
import labelActions from 'redux/nodes/entities/labels/actions';
|
2016-11-21 16:26:58 +00:00
|
|
|
import ConnectedManageHostsPage, { ManageHostsPage } from 'pages/hosts/ManageHostsPage/ManageHostsPage';
|
|
|
|
import { connectedComponent, createAceSpy, reduxMockStore, stubbedOsqueryTable } from 'test/helpers';
|
2020-11-05 01:07:58 +00:00
|
|
|
import { hostStub, configStub } from 'test/stubs';
|
2017-02-13 23:19:00 +00:00
|
|
|
import * as manageHostsPageActions from 'redux/nodes/components/ManageHostsPage/actions';
|
2016-11-21 16:26:58 +00:00
|
|
|
|
2016-12-12 16:48:50 +00:00
|
|
|
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 };
|
2017-01-16 22:55:31 +00:00
|
|
|
const offlineHost = { ...hostStub, id: 111, status: 'offline' };
|
|
|
|
const offlineHostsLabel = { id: 5, display_text: 'OFFLINE', slug: 'offline', status: 'offline', type: 'status', count: 1 };
|
2017-01-19 17:57:59 +00:00
|
|
|
const customLabel = { id: 6, display_text: 'Custom Label', slug: 'custom-label', type: 'custom', count: 3 };
|
2016-12-05 15:21:03 +00:00
|
|
|
const mockStore = reduxMockStore({
|
2017-01-21 01:16:00 +00:00
|
|
|
app: { config: {} },
|
2016-12-05 15:21:03 +00:00
|
|
|
components: {
|
|
|
|
ManageHostsPage: {
|
|
|
|
display: 'Grid',
|
|
|
|
selectedLabel: { id: 100, display_text: 'All Hosts', type: 'all', count: 22 },
|
2017-01-16 20:59:01 +00:00
|
|
|
status_labels: {},
|
2016-12-05 15:21:03 +00:00
|
|
|
},
|
|
|
|
QueryPages: {
|
|
|
|
selectedOsqueryTable: stubbedOsqueryTable,
|
|
|
|
},
|
|
|
|
},
|
2016-12-12 16:48:50 +00:00
|
|
|
entities: {
|
2017-01-16 22:55:31 +00:00
|
|
|
hosts: {
|
|
|
|
data: {
|
|
|
|
[hostStub.id]: hostStub,
|
|
|
|
[offlineHost.id]: offlineHost,
|
|
|
|
},
|
|
|
|
},
|
2016-12-12 16:48:50 +00:00
|
|
|
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 },
|
2017-01-16 22:55:31 +00:00
|
|
|
5: offlineHostsLabel,
|
2017-01-19 17:57:59 +00:00
|
|
|
6: customLabel,
|
2016-12-12 16:48:50 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
2016-12-05 15:21:03 +00:00
|
|
|
});
|
2016-11-17 17:12:41 +00:00
|
|
|
|
|
|
|
describe('ManageHostsPage - component', () => {
|
|
|
|
const props = {
|
2020-11-05 01:07:58 +00:00
|
|
|
config: configStub,
|
2016-11-17 17:12:41 +00:00
|
|
|
dispatch: noop,
|
|
|
|
hosts: [],
|
|
|
|
labels: [],
|
2017-01-27 15:05:44 +00:00
|
|
|
loadingHosts: false,
|
|
|
|
loadingLabels: false,
|
2016-11-17 17:12:41 +00:00
|
|
|
selectedOsqueryTable: stubbedOsqueryTable,
|
2017-01-17 21:44:00 +00:00
|
|
|
statusLabels: {},
|
2020-05-29 16:12:39 +00:00
|
|
|
enrollSecret: [],
|
2016-11-17 17:12:41 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
beforeEach(() => {
|
2017-02-13 23:19:00 +00:00
|
|
|
const spyResponse = () => Promise.resolve([]);
|
|
|
|
|
2020-12-01 18:15:12 +00:00
|
|
|
jest.spyOn(hostActions, 'loadAll')
|
|
|
|
.mockImplementation(() => spyResponse);
|
|
|
|
jest.spyOn(labelActions, 'loadAll')
|
|
|
|
.mockImplementation(() => spyResponse);
|
|
|
|
jest.spyOn(manageHostsPageActions, 'getStatusLabelCounts')
|
|
|
|
.mockImplementation(() => spyResponse);
|
2016-11-17 17:12:41 +00:00
|
|
|
createAceSpy();
|
|
|
|
});
|
2017-02-13 23:19:00 +00:00
|
|
|
|
2016-11-21 16:26:58 +00:00
|
|
|
describe('side panels', () => {
|
|
|
|
it('renders a HostSidePanel when not adding a new label', () => {
|
|
|
|
const page = mount(<ManageHostsPage {...props} />);
|
|
|
|
|
|
|
|
expect(page.find('HostSidePanel').length).toEqual(1);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('renders a QuerySidePanel when adding a new label', () => {
|
2016-12-12 16:48:50 +00:00
|
|
|
const ownProps = { location: { hash: '#new_label' }, params: {} };
|
2016-12-05 15:21:03 +00:00
|
|
|
const component = connectedComponent(ConnectedManageHostsPage, { props: ownProps, mockStore });
|
|
|
|
const page = mount(component);
|
2016-11-17 17:12:41 +00:00
|
|
|
|
2016-11-21 16:26:58 +00:00
|
|
|
expect(page.find('QuerySidePanel').length).toEqual(1);
|
|
|
|
});
|
2016-11-17 17:12:41 +00:00
|
|
|
});
|
|
|
|
|
2017-01-17 21:44:00 +00:00
|
|
|
describe('header', () => {
|
2020-12-01 18:15:12 +00:00
|
|
|
it('displays "1 host" when there is 1 host', () => {
|
2017-01-17 21:44:00 +00:00
|
|
|
const oneHostLabel = { ...allHostsLabel, count: 1 };
|
|
|
|
const page = mount(<ManageHostsPage {...props} selectedLabel={oneHostLabel} />);
|
|
|
|
|
2020-12-01 18:15:12 +00:00
|
|
|
expect(page.text()).toContain('1 host');
|
2017-01-17 21:44:00 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
it('displays "#{count} Hosts Total" when there are more than 1 host', () => {
|
|
|
|
const oneHostLabel = { ...allHostsLabel, count: 2 };
|
|
|
|
const page = mount(<ManageHostsPage {...props} selectedLabel={oneHostLabel} />);
|
|
|
|
|
2020-12-01 18:15:12 +00:00
|
|
|
expect(page.text()).toContain('2 hosts');
|
2017-01-17 21:44:00 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2017-11-07 17:54:56 +00:00
|
|
|
describe('host filtering', () => {
|
2017-01-16 22:55:31 +00:00
|
|
|
it('filters hosts', () => {
|
|
|
|
const allHostsLabelPageNode = mount(
|
|
|
|
<ManageHostsPage
|
|
|
|
{...props}
|
|
|
|
hosts={[hostStub, offlineHost]}
|
|
|
|
selectedLabel={allHostsLabel}
|
2020-07-07 02:31:48 +00:00
|
|
|
/>,
|
2019-01-14 21:45:28 +00:00
|
|
|
).instance();
|
2017-01-16 22:55:31 +00:00
|
|
|
const offlineHostsLabelPageNode = mount(
|
|
|
|
<ManageHostsPage
|
|
|
|
{...props}
|
|
|
|
hosts={[hostStub, offlineHost]}
|
|
|
|
selectedLabel={offlineHostsLabel}
|
2020-07-07 02:31:48 +00:00
|
|
|
/>,
|
2019-01-14 21:45:28 +00:00
|
|
|
).instance();
|
2017-01-16 22:55:31 +00:00
|
|
|
|
2017-11-07 17:54:56 +00:00
|
|
|
expect(allHostsLabelPageNode.filterAllHosts([hostStub, offlineHost], allHostsLabel)).toEqual([hostStub, offlineHost]);
|
|
|
|
expect(offlineHostsLabelPageNode.filterAllHosts([hostStub, offlineHost], offlineHostsLabel)).toEqual([offlineHost]);
|
2017-01-16 22:55:31 +00:00
|
|
|
});
|
2016-11-17 17:12:41 +00:00
|
|
|
});
|
2016-12-05 15:21:03 +00:00
|
|
|
|
|
|
|
describe('Adding a new label', () => {
|
|
|
|
beforeEach(() => createAceSpy());
|
|
|
|
|
2016-12-12 16:48:50 +00:00
|
|
|
const ownProps = { location: { hash: '#new_label' }, params: {} };
|
2016-12-05 15:21:03 +00:00
|
|
|
const component = connectedComponent(ConnectedManageHostsPage, { props: ownProps, mockStore });
|
|
|
|
|
2017-02-15 14:51:19 +00:00
|
|
|
it('renders a LabelForm component', () => {
|
2016-12-05 15:21:03 +00:00
|
|
|
const page = mount(component);
|
|
|
|
|
2017-02-15 14:51:19 +00:00
|
|
|
expect(page.find('LabelForm').length).toEqual(1);
|
2016-12-05 15:21:03 +00:00
|
|
|
});
|
|
|
|
|
2020-12-07 23:08:59 +00:00
|
|
|
it('displays "New label" as the query form header', () => {
|
2016-12-05 15:21:03 +00:00
|
|
|
const page = mount(component);
|
|
|
|
|
2020-12-07 23:08:59 +00:00
|
|
|
expect(page.find('LabelForm').text()).toContain('New label');
|
2016-12-05 15:21:03 +00:00
|
|
|
});
|
|
|
|
});
|
2016-12-12 16:48:50 +00:00
|
|
|
|
|
|
|
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);
|
|
|
|
|
2020-12-01 18:15:12 +00:00
|
|
|
expect(page.find('HostSidePanel').props()).toMatchObject({
|
2020-03-30 02:19:54 +00:00
|
|
|
selectedFilter: 'all-hosts',
|
2016-12-12 16:48:50 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('Displays the windows label as the active label', () => {
|
2020-03-30 02:19:54 +00:00
|
|
|
const ownProps = { location: {}, params: { active_label: 'labels/4' } };
|
2016-12-12 16:48:50 +00:00
|
|
|
const component = connectedComponent(ConnectedManageHostsPage, { props: ownProps, mockStore });
|
|
|
|
const page = mount(component);
|
|
|
|
|
2020-12-01 18:15:12 +00:00
|
|
|
expect(page.find('HostSidePanel').props()).toMatchObject({
|
2020-03-30 02:19:54 +00:00
|
|
|
selectedFilter: 'labels/4',
|
2016-12-12 16:48:50 +00:00
|
|
|
});
|
|
|
|
});
|
2017-02-21 22:40:59 +00:00
|
|
|
|
2020-12-01 18:15:12 +00:00
|
|
|
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,
|
|
|
|
};
|
2017-02-21 22:40:59 +00:00
|
|
|
|
2020-12-01 18:15:12 +00:00
|
|
|
const Page = mount(<ManageHostsPage {...pageProps} />);
|
2017-02-21 22:40:59 +00:00
|
|
|
|
2020-12-01 18:15:12 +00:00
|
|
|
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 = mount(<ManageHostsPage {...pageProps} />);
|
|
|
|
|
|
|
|
expect(Page.find('.manage-hosts__header').text())
|
|
|
|
.toContain(labelDescription);
|
|
|
|
expect(Page.find('.manage-hosts__header').text())
|
|
|
|
.not.toContain(defaultDescription);
|
|
|
|
},
|
|
|
|
);
|
2016-12-12 16:48:50 +00:00
|
|
|
});
|
2017-01-19 17:57:59 +00:00
|
|
|
|
2017-02-15 14:51:19 +00:00
|
|
|
describe('Edit a label', () => {
|
|
|
|
const ownProps = { location: {}, params: { active_label: 'custom-label' } };
|
|
|
|
const Component = connectedComponent(ConnectedManageHostsPage, { props: ownProps, mockStore });
|
|
|
|
|
|
|
|
it('renders the LabelForm when Edit is clicked', () => {
|
|
|
|
const Page = mount(Component);
|
|
|
|
const EditButton = Page
|
2020-12-07 23:08:59 +00:00
|
|
|
.find('.manage-hosts__label-actions')
|
2017-02-15 14:51:19 +00:00
|
|
|
.find('Button')
|
|
|
|
.first();
|
|
|
|
|
|
|
|
expect(Page.find('LabelForm').length).toEqual(0, 'Expected the LabelForm to not be on the page');
|
|
|
|
|
|
|
|
EditButton.simulate('click');
|
|
|
|
|
|
|
|
const LabelForm = Page.find('LabelForm');
|
|
|
|
|
|
|
|
expect(LabelForm.length).toEqual(1, 'Expected the LabelForm to be on the page');
|
|
|
|
|
|
|
|
expect(LabelForm.prop('formData')).toEqual(customLabel);
|
|
|
|
expect(LabelForm.prop('isEdit')).toEqual(true);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2017-01-19 17:57:59 +00:00
|
|
|
describe('Delete a label', () => {
|
|
|
|
it('Deleted label after confirmation modal', () => {
|
|
|
|
const ownProps = { location: {}, params: { active_label: 'custom-label' } };
|
2017-02-13 23:19:00 +00:00
|
|
|
const component = connectedComponent(ConnectedManageHostsPage, {
|
|
|
|
props: ownProps,
|
|
|
|
mockStore,
|
|
|
|
});
|
2017-01-19 17:57:59 +00:00
|
|
|
const page = mount(component);
|
2017-02-15 14:51:19 +00:00
|
|
|
const deleteBtn = page
|
2020-12-07 23:08:59 +00:00
|
|
|
.find('.manage-hosts__label-actions')
|
2017-02-15 14:51:19 +00:00
|
|
|
.find('Button')
|
|
|
|
.last();
|
2017-01-19 17:57:59 +00:00
|
|
|
|
2020-12-01 18:15:12 +00:00
|
|
|
jest.spyOn(labelActions, 'destroy').mockImplementation(() => (dispatch) => {
|
2017-02-13 23:19:00 +00:00
|
|
|
dispatch({ type: 'labels_LOAD_REQUEST' });
|
|
|
|
|
|
|
|
return Promise.resolve();
|
|
|
|
});
|
2017-01-19 17:57:59 +00:00
|
|
|
|
|
|
|
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);
|
|
|
|
});
|
|
|
|
});
|
2017-01-19 23:39:06 +00:00
|
|
|
|
|
|
|
describe('Delete a host', () => {
|
|
|
|
it('Deleted host after confirmation modal', () => {
|
|
|
|
const ownProps = { location: {}, params: { active_label: 'all-hosts' } };
|
|
|
|
const component = connectedComponent(ConnectedManageHostsPage, { props: ownProps, mockStore });
|
|
|
|
const page = mount(component);
|
2020-11-30 18:23:58 +00:00
|
|
|
const deleteBtn = page.find('ActionButton').last().find('Button');
|
2017-01-19 23:39:06 +00:00
|
|
|
|
2020-12-01 18:15:12 +00:00
|
|
|
jest.spyOn(hostActions, 'destroy').mockImplementation(() => (dispatch) => {
|
2017-02-13 23:19:00 +00:00
|
|
|
dispatch({ type: 'hosts_LOAD_REQUEST' });
|
|
|
|
|
|
|
|
return Promise.resolve();
|
|
|
|
});
|
2017-01-19 23:39:06 +00:00
|
|
|
|
|
|
|
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');
|
|
|
|
|
2017-01-20 23:07:54 +00:00
|
|
|
expect(hostActions.destroy).toHaveBeenCalledWith(offlineHost);
|
2017-01-19 23:39:06 +00:00
|
|
|
});
|
|
|
|
});
|
2017-01-21 00:10:58 +00:00
|
|
|
|
|
|
|
describe('Add Host', () => {
|
2020-12-04 20:19:08 +00:00
|
|
|
it('Open the Add Host modal', () => {
|
2017-01-21 00:10:58 +00:00
|
|
|
const page = mount(<ManageHostsPage {...props} hosts={[]} selectedLabel={allHostsLabel} />);
|
2020-12-04 20:19:08 +00:00
|
|
|
const addNewHost = page.find('.manage-hosts__add-hosts');
|
2019-01-14 21:45:28 +00:00
|
|
|
addNewHost.hostNodes().simulate('click');
|
2017-01-21 00:10:58 +00:00
|
|
|
|
2019-01-14 21:45:28 +00:00
|
|
|
expect(page.find('AddHostModal').length).toBeGreaterThan(0);
|
2017-01-21 00:10:58 +00:00
|
|
|
});
|
|
|
|
});
|
2016-11-17 17:12:41 +00:00
|
|
|
});
|