diff --git a/frontend/components/packs/PacksList/PacksList.tests.jsx b/frontend/components/packs/PacksList/PacksList.tests.jsx
index 6db57a5b49..d59b6960b0 100644
--- a/frontend/components/packs/PacksList/PacksList.tests.jsx
+++ b/frontend/components/packs/PacksList/PacksList.tests.jsx
@@ -1,6 +1,7 @@
import React from 'react';
import expect, { createSpy, restoreSpies } from 'expect';
import { mount } from 'enzyme';
+import { noop } from 'lodash';
import PacksList from 'components/packs/PacksList';
import { packStub } from 'test/stubs';
@@ -8,13 +9,19 @@ import { packStub } from 'test/stubs';
describe('PacksList - component', () => {
afterEach(restoreSpies);
+ const props = {
+ onCheckAllPacks: noop,
+ onCheckPack: noop,
+ onSelectPack: noop,
+ };
+
it('renders', () => {
- expect(mount().length).toEqual(1);
+ expect(mount().length).toEqual(1);
});
it('calls the onCheckAllPacks prop when select all packs checkbox is checked', () => {
const spy = createSpy();
- const component = mount();
+ const component = mount();
component.find({ name: 'select-all-packs' }).simulate('change');
@@ -23,7 +30,7 @@ describe('PacksList - component', () => {
it('calls the onCheckPack prop when a pack checkbox is checked', () => {
const spy = createSpy();
- const component = mount();
+ const component = mount();
const packCheckbox = component.find({ name: `select-pack-${packStub.id}` });
packCheckbox.simulate('change');
diff --git a/frontend/pages/hosts/ManageHostsPage/ManageHostsPage.jsx b/frontend/pages/hosts/ManageHostsPage/ManageHostsPage.jsx
index ada828861a..b3a37c4776 100644
--- a/frontend/pages/hosts/ManageHostsPage/ManageHostsPage.jsx
+++ b/frontend/pages/hosts/ManageHostsPage/ManageHostsPage.jsx
@@ -2,10 +2,11 @@ import React, { Component, PropTypes } from 'react';
import AceEditor from 'react-ace';
import { connect } from 'react-redux';
import { push } from 'react-router-redux';
-import { filter, orderBy, sortBy } from 'lodash';
+import { orderBy, sortBy } from 'lodash';
import entityGetter from 'redux/utilities/entityGetter';
import { getStatusLabelCounts, setDisplay } from 'redux/nodes/components/ManageHostsPage/actions';
+import helpers from 'pages/hosts/ManageHostsPage/helpers';
import hostActions from 'redux/nodes/entities/hosts/actions';
import labelActions from 'redux/nodes/entities/labels/actions';
import labelInterface from 'interfaces/label';
@@ -137,17 +138,9 @@ export class ManageHostsPage extends Component {
}
filterHosts = () => {
- const { hosts: allHosts, selectedLabel } = this.props;
+ const { hosts, selectedLabel } = this.props;
- // TODO: Filter custom labels by their host_ids attribute
- if (!selectedLabel || selectedLabel.type === 'custom' || selectedLabel.type === 'all') {
- return allHosts;
- }
-
- const { type } = selectedLabel;
- const filterObject = type === 'status' ? { status: selectedLabel.slug } : { [type]: selectedLabel[type] };
-
- return filter(allHosts, filterObject);
+ return helpers.filterHosts(hosts, selectedLabel);
}
sortHosts = (hosts) => {
@@ -196,13 +189,13 @@ export class ManageHostsPage extends Component {
renderHeader = () => {
const { renderIcon, renderQuery } = this;
- const { display, isAddLabel, selectedLabel } = this.props;
+ const { display, isAddLabel, selectedLabel, statusLabels } = this.props;
if (!selectedLabel || isAddLabel) {
return false;
}
- const { count, description, display_text: displayText } = selectedLabel;
+ const { count, description, display_text: displayText, slug, type } = selectedLabel;
const { onToggleDisplay } = this;
const buttonOptions = {
rightIcon: 'grid-select',
@@ -211,6 +204,9 @@ export class ManageHostsPage extends Component {
leftText: 'List',
};
+ const hostCount = type === 'status' ? statusLabels[`${slug}_count`] : count;
+ const hostsTotalDisplay = hostCount === 1 ? '1 Host Total' : `${hostCount} Hosts Total`;
+
return (
@@ -228,7 +224,7 @@ export class ManageHostsPage extends Component {
}
-
{count} Hosts Total
+
{hostsTotalDisplay}
{
hosts: [],
labels: [],
selectedOsqueryTable: stubbedOsqueryTable,
+ statusLabels: {},
};
beforeEach(() => {
@@ -70,6 +71,22 @@ describe('ManageHostsPage - component', () => {
});
});
+ describe('header', () => {
+ it('displays "1 Host Total" when there is 1 host', () => {
+ const oneHostLabel = { ...allHostsLabel, count: 1 };
+ const page = mount();
+
+ expect(page.text()).toInclude('1 Host Total');
+ });
+
+ it('displays "#{count} Hosts Total" when there are more than 1 host', () => {
+ const oneHostLabel = { ...allHostsLabel, count: 2 };
+ const page = mount();
+
+ expect(page.text()).toInclude('2 Hosts Total');
+ });
+ });
+
describe('host rendering', () => {
it('renders hosts as HostDetails by default', () => {
const page = mount();
diff --git a/frontend/pages/hosts/ManageHostsPage/helpers.js b/frontend/pages/hosts/ManageHostsPage/helpers.js
new file mode 100644
index 0000000000..c8c7ba27b4
--- /dev/null
+++ b/frontend/pages/hosts/ManageHostsPage/helpers.js
@@ -0,0 +1,24 @@
+import { filter, includes } from 'lodash';
+
+const filterHosts = (hosts, label) => {
+ if (!label) {
+ return hosts;
+ }
+
+ const { host_ids: hostIDs, platform, slug, type } = label;
+
+ switch (type) {
+ case 'all':
+ return hosts;
+ case 'status':
+ return filter(hosts, { status: slug });
+ case 'platform':
+ return filter(hosts, { platform });
+ case 'custom':
+ return filter(hosts, h => includes(hostIDs, h.id));
+ default:
+ return hosts;
+ }
+};
+
+export default { filterHosts };
diff --git a/frontend/pages/hosts/ManageHostsPage/helpers.tests.js b/frontend/pages/hosts/ManageHostsPage/helpers.tests.js
new file mode 100644
index 0000000000..b218e190d3
--- /dev/null
+++ b/frontend/pages/hosts/ManageHostsPage/helpers.tests.js
@@ -0,0 +1,37 @@
+import expect from 'expect';
+
+import helpers from 'pages/hosts/ManageHostsPage/helpers';
+import { hostStub, labelStub } from 'test/stubs';
+
+const macHost = { ...hostStub, id: 1, platform: 'darwin', status: 'mia' };
+const ubuntuHost = { ...hostStub, id: 2, platform: 'ubuntu', status: 'offline' };
+const windowsHost = { ...hostStub, id: 3, platform: 'windows', status: 'online' };
+const allHosts = [macHost, ubuntuHost, windowsHost];
+
+describe('ManageHostsPage - helpers', () => {
+ describe('#filterHosts', () => {
+ it('filters the all hosts label', () => {
+ const allHostsLabel = { ...labelStub, type: 'all' };
+
+ expect(helpers.filterHosts(allHosts, allHostsLabel)).toEqual(allHosts);
+ });
+
+ it('filters the platform label', () => {
+ const platformLabel = { ...labelStub, type: 'platform', platform: 'ubuntu' };
+
+ expect(helpers.filterHosts(allHosts, platformLabel)).toEqual([ubuntuHost]);
+ });
+
+ it('filters the status label', () => {
+ const statusLabel = { ...labelStub, type: 'status', slug: 'online' };
+
+ expect(helpers.filterHosts(allHosts, statusLabel)).toEqual([windowsHost]);
+ });
+
+ it('filters the custom label', () => {
+ const customLabel = { ...labelStub, type: 'custom', host_ids: [1, 3] };
+
+ expect(helpers.filterHosts(allHosts, customLabel)).toEqual([macHost, windowsHost]);
+ });
+ });
+});
diff --git a/frontend/test/stubs.js b/frontend/test/stubs.js
index 4b4ecae1bc..ccb1f68010 100644
--- a/frontend/test/stubs.js
+++ b/frontend/test/stubs.js
@@ -91,6 +91,26 @@ export const hostStub = {
display_text: '52883a0ba916',
};
+export const labelStub = {
+ created_at: '2017-01-16T23:11:01Z',
+ updated_at: '2017-01-16T23:11:01Z',
+ deleted_at: null,
+ deleted: false,
+ id: 1,
+ name: 'All Hosts',
+ description: '',
+ query: 'select 1;',
+ platform: '',
+ label_type: 1,
+ display_text: 'All Hosts',
+ count: 20,
+ online: 20,
+ offline: 0,
+ missing_in_action: 0,
+ host_ids: [],
+ type: 'all',
+};
+
export const packStub = {
created_at: '0001-01-01T00:00:00Z',
updated_at: '0001-01-01T00:00:00Z',
@@ -146,6 +166,7 @@ export default {
adminUserStub,
configStub,
hostStub,
+ labelStub,
packStub,
queryStub,
scheduledQueryStub,