diff --git a/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/__test__/__snapshots__/collapsible_statement.test.js.snap b/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/__test__/__snapshots__/collapsible_statement.test.js.snap
new file mode 100644
index 0000000000000..a6d4a6a4d5b64
--- /dev/null
+++ b/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/__test__/__snapshots__/collapsible_statement.test.js.snap
@@ -0,0 +1,32 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`CollapsibleStatement component renders child components 1`] = `
+
+
+
+
+
+ child element
+
+
+`;
diff --git a/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/__test__/__snapshots__/metric.test.js.snap b/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/__test__/__snapshots__/metric.test.js.snap
new file mode 100644
index 0000000000000..c06d81902cb14
--- /dev/null
+++ b/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/__test__/__snapshots__/metric.test.js.snap
@@ -0,0 +1,36 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Metric component does not render warning badge when no warning present 1`] = `
+
+
+
+ 220
+
+
+
+`;
+
+exports[`Metric component renders warning badge 1`] = `
+
+
+ 220
+
+
+`;
diff --git a/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/__test__/__snapshots__/pipeline_viewer.test.js.snap b/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/__test__/__snapshots__/pipeline_viewer.test.js.snap
new file mode 100644
index 0000000000000..e6c6161f588ee
--- /dev/null
+++ b/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/__test__/__snapshots__/pipeline_viewer.test.js.snap
@@ -0,0 +1,177 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`PipelineViewer component passes expected props 1`] = `
+
+
+
+
+
+
+
+
+
+
+
+`;
+
+exports[`PipelineViewer component renders DetailDrawer when selected vertex is not null 1`] = `
+
+
+
+
+
+
+
+
+
+
+
+
+`;
diff --git a/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/__test__/__snapshots__/plugin_statement.test.js.snap b/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/__test__/__snapshots__/plugin_statement.test.js.snap
new file mode 100644
index 0000000000000..a4ce0c7b20bcc
--- /dev/null
+++ b/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/__test__/__snapshots__/plugin_statement.test.js.snap
@@ -0,0 +1,429 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`PluginStatement component adds warning highlight for cpu time 1`] = `
+
+
+
+
+
+
+ mutate
+
+
+
+
+
+ mutatePlugin
+
+
+
+
+
+
+
+
+
+
+
+
+`;
+
+exports[`PluginStatement component adds warning highlight for event millis 1`] = `
+
+
+
+
+
+
+ mutate
+
+
+
+
+
+ mutatePlugin
+
+
+
+
+
+
+
+
+
+
+
+
+`;
+
+exports[`PluginStatement component does not render explicit id field if no id is specified 1`] = `
+
+
+
+
+
+
+ stdin
+
+
+
+
+
+
+
+
+
+
+
+`;
+
+exports[`PluginStatement component renders input metrics and explicit id fields 1`] = `
+
+
+
+
+
+
+ stdin
+
+
+
+
+
+ standardInput
+
+
+
+
+
+
+
+
+
+
+`;
+
+exports[`PluginStatement component renders processor statement metrics 1`] = `
+
+
+
+
+
+
+ mutate
+
+
+
+
+
+ mutatePlugin
+
+
+
+
+
+
+
+
+
+
+
+
+`;
diff --git a/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/__test__/__snapshots__/queue.test.js.snap b/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/__test__/__snapshots__/queue.test.js.snap
new file mode 100644
index 0000000000000..ab90393a81969
--- /dev/null
+++ b/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/__test__/__snapshots__/queue.test.js.snap
@@ -0,0 +1,19 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Queue component renders default elements 1`] = `
+
+
+
+
+ Queue metrics not available
+
+
+`;
diff --git a/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/__test__/__snapshots__/statement.test.js.snap b/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/__test__/__snapshots__/statement.test.js.snap
new file mode 100644
index 0000000000000..3e6699c31ce6c
--- /dev/null
+++ b/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/__test__/__snapshots__/statement.test.js.snap
@@ -0,0 +1,164 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Statement component renders a CollapsibleStatement with else body for non-IfElement 1`] = `
+
+
+
+
+
+
+ else
+
+
+
+
+
+`;
+
+exports[`Statement component renders a CollapsibleStatement with if body for branch model 1`] = `
+
+
+
+
+
+
+ if
+
+
+
+
+
+
+
+
+`;
+
+exports[`Statement component renders a PluginStatement component for plugin model 1`] = `
+
+
+
+
+`;
+
+exports[`Statement component renders spacers for element with depth > 0 1`] = `
+
+
+
+
+
+
+ else
+
+
+
+
+
+`;
diff --git a/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/__test__/__snapshots__/statement_list.test.js.snap b/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/__test__/__snapshots__/statement_list.test.js.snap
new file mode 100644
index 0000000000000..3314faba55156
--- /dev/null
+++ b/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/__test__/__snapshots__/statement_list.test.js.snap
@@ -0,0 +1,36 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`StatementList renders nested elements as expected 1`] = `
+
+`;
diff --git a/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/__test__/__snapshots__/statement_list_heading.test.js.snap b/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/__test__/__snapshots__/statement_list_heading.test.js.snap
new file mode 100644
index 0000000000000..d553a4c4c173f
--- /dev/null
+++ b/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/__test__/__snapshots__/statement_list_heading.test.js.snap
@@ -0,0 +1,35 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`StatementListHeading component renders title and icon type 1`] = `
+
+
+
+
+
+
+
+ Filters
+
+
+
+
+`;
diff --git a/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/__test__/__snapshots__/statement_section.test.js.snap b/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/__test__/__snapshots__/statement_section.test.js.snap
new file mode 100644
index 0000000000000..59af548f267fd
--- /dev/null
+++ b/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/__test__/__snapshots__/statement_section.test.js.snap
@@ -0,0 +1,28 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`StatementSection component renders heading text, correct icon type, and elements for StatementSection 1`] = `
+
+
+
+
+
+`;
diff --git a/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/__test__/collapsible_statement.test.js b/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/__test__/collapsible_statement.test.js
new file mode 100644
index 0000000000000..f759f879ab790
--- /dev/null
+++ b/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/__test__/collapsible_statement.test.js
@@ -0,0 +1,54 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import React from 'react';
+import { CollapsibleStatement } from '../collapsible_statement';
+import { shallow } from 'enzyme';
+import { EuiButtonIcon } from '@elastic/eui';
+
+describe('CollapsibleStatement component', () => {
+ let props;
+ let collapse;
+ let expand;
+
+ beforeEach(() => {
+ collapse = jest.fn();
+ expand = jest.fn();
+ props = {
+ collapse,
+ expand,
+ id: 'statementId',
+ isCollapsed: false,
+ };
+ });
+
+ it('renders child components', () => {
+ const child = child element
;
+
+ const wrapper = shallow(
+ {child}
+ );
+
+ expect(wrapper).toMatchSnapshot();
+ });
+
+ it('calls collapse if component is expanded', () => {
+ const wrapper = shallow();
+
+ wrapper.find(EuiButtonIcon).simulate('click');
+ expect(collapse).toHaveBeenCalledTimes(1);
+ expect(collapse).toHaveBeenCalledWith('statementId');
+ });
+
+ it('calls expand if component is collapsed', () => {
+ props.isCollapsed = true;
+ const wrapper = shallow();
+
+ wrapper.find(EuiButtonIcon).simulate('click');
+ expect(expand).toHaveBeenCalledTimes(1);
+ expect(expand).toHaveBeenCalledWith('statementId');
+ });
+});
diff --git a/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/__test__/detail_drawer.test.js b/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/__test__/detail_drawer.test.js
index 81e0b9b2e1f32..a20bc9a6c1abe 100644
--- a/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/__test__/detail_drawer.test.js
+++ b/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/__test__/detail_drawer.test.js
@@ -19,15 +19,10 @@ describe('DetailDrawer component', () => {
test('shows vertex title', () => {
const vertex = {
- title: 'grok'
+ title: 'grok',
};
- const component = (
-
- );
+ const component = ;
const renderedComponent = shallow(component);
expect(renderedComponent).toMatchSnapshot();
});
@@ -43,46 +38,34 @@ describe('DetailDrawer component', () => {
id: 'parse_apache_logline',
stats: {
events_in: {
- data: [
- [ 1516131120000, 200 ],
- [ 1516131180000, 203 ]
- ],
+ data: [[1516131120000, 200], [1516131180000, 203]],
timeRange: {
min: 1516131138639,
- max: 1516135440463
- }
+ max: 1516135440463,
+ },
},
events_out: {
- data: [
- [ 1516131120000, 199 ],
- [ 1516131180000, 200 ]
- ],
+ data: [[1516131120000, 199], [1516131180000, 200]],
timeRange: {
min: 1516131138639,
- max: 1516135440463
- }
+ max: 1516135440463,
+ },
},
millis_per_event: {
- data: [
- [ 1516131120000, 0.21 ],
- [ 1516131180000, 0.23 ]
- ],
+ data: [[1516131120000, 0.21], [1516131180000, 0.23]],
timeRange: {
min: 1516131138639,
- max: 1516135440463
- }
- }
+ max: 1516135440463,
+ },
+ },
},
eventsPerSecond: {
- data: [
- [ 1516131120000, 32 ],
- [ 1516131180000, 36 ]
- ],
+ data: [[1516131120000, 32], [1516131180000, 36]],
timeRange: {
min: 1516131138639,
- max: 1516135440463
- }
- }
+ max: 1516135440463,
+ },
+ },
};
const component = (
@@ -107,46 +90,34 @@ describe('DetailDrawer component', () => {
id: 'foobarbazqux',
stats: {
events_in: {
- data: [
- [ 1516131120000, 200 ],
- [ 1516131180000, 203 ]
- ],
+ data: [[1516131120000, 200], [1516131180000, 203]],
timeRange: {
min: 1516131138639,
- max: 1516135440463
- }
+ max: 1516135440463,
+ },
},
events_out: {
- data: [
- [ 1516131120000, 199 ],
- [ 1516131180000, 200 ]
- ],
+ data: [[1516131120000, 199], [1516131180000, 200]],
timeRange: {
min: 1516131138639,
- max: 1516135440463
- }
+ max: 1516135440463,
+ },
},
millis_per_event: {
- data: [
- [ 1516131120000, 0.21 ],
- [ 1516131180000, 0.23 ]
- ],
+ data: [[1516131120000, 0.21], [1516131180000, 0.23]],
timeRange: {
min: 1516131138639,
- max: 1516135440463
- }
- }
+ max: 1516135440463,
+ },
+ },
},
eventsPerSecond: {
- data: [
- [ 1516131120000, 32 ],
- [ 1516131180000, 36 ]
- ],
+ data: [[1516131120000, 32], [1516131180000, 36]],
timeRange: {
min: 1516131138639,
- max: 1516135440463
- }
- }
+ max: 1516135440463,
+ },
+ },
};
const component = (
@@ -167,7 +138,7 @@ describe('DetailDrawer component', () => {
const vertex = {
title: 'if',
typeString: 'if',
- subtitle: '[type] == "apache_log"'
+ subtitle: '[type] == "apache_log"',
};
const component = (
@@ -186,7 +157,7 @@ describe('DetailDrawer component', () => {
test('shows basic info and no stats for queue', () => {
const vertex = {
title: 'queue',
- typeString: 'queue'
+ typeString: 'queue',
};
const component = (
diff --git a/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/__test__/metric.test.js b/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/__test__/metric.test.js
new file mode 100644
index 0000000000000..c623074317c54
--- /dev/null
+++ b/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/__test__/metric.test.js
@@ -0,0 +1,34 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import React from 'react';
+import { Metric } from '../metric';
+import { shallow } from 'enzyme';
+
+describe('Metric component', () => {
+ let metric;
+
+ beforeEach(() => {
+ metric = {
+ className: 'metricClass',
+ warning: true,
+ value: '220',
+ };
+ });
+
+ it('renders warning badge', () => {
+ const wrapper = shallow();
+
+ expect(wrapper).toMatchSnapshot();
+ });
+
+ it('does not render warning badge when no warning present', () => {
+ metric.warning = false;
+ const wrapper = shallow();
+
+ expect(wrapper).toMatchSnapshot();
+ });
+});
diff --git a/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/__test__/pipeline_viewer.test.js b/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/__test__/pipeline_viewer.test.js
new file mode 100644
index 0000000000000..6bc2e4adda271
--- /dev/null
+++ b/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/__test__/pipeline_viewer.test.js
@@ -0,0 +1,85 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import React from 'react';
+import { PipelineViewer } from '../pipeline_viewer';
+import { shallow } from 'enzyme';
+import { get } from 'lodash';
+
+describe('PipelineViewer component', () => {
+ let pipeline;
+ let component;
+
+ beforeEach(() => {
+ pipeline = {
+ inputs: [
+ {
+ depth: 0,
+ id: 'standardInput',
+ parentId: null,
+ },
+ ],
+ filters: [
+ {
+ depth: 0,
+ id: 'mutate',
+ parentId: null,
+ },
+ ],
+ outputs: [
+ {
+ depth: 0,
+ id: 'elasticsearch',
+ parentId: null,
+ },
+ ],
+ queue: {
+ id: '__QUEUE__',
+ hasExplicitId: false,
+ stats: [],
+ meta: null,
+ },
+ };
+
+ component = ;
+ });
+
+ it('passes expected props', () => {
+ const renderedComponent = shallow(component);
+
+ expect(renderedComponent).toMatchSnapshot();
+ });
+
+ it('changes selected vertex', () => {
+ const vertex = { id: 'stdin' };
+
+ const instance = shallow(component).instance();
+ instance.onShowVertexDetails(vertex);
+
+ expect(get(instance, 'state.detailDrawer.vertex')).toBe(vertex);
+ });
+
+ it('toggles selected vertex on second pass', () => {
+ const vertex = { id: 'stdin' };
+
+ const instance = shallow(component).instance();
+ instance.onShowVertexDetails(vertex);
+ instance.onShowVertexDetails(vertex);
+
+ expect(get(instance, 'state.detailDrawer.vertex')).toBeNull();
+ });
+
+ it('renders DetailDrawer when selected vertex is not null', () => {
+ const vertex = { id: 'stdin' };
+
+ const wrapper = shallow(component);
+ const instance = wrapper.instance();
+ instance.onShowVertexDetails(vertex);
+ wrapper.update();
+
+ expect(wrapper).toMatchSnapshot();
+ });
+});
diff --git a/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/__test__/plugin_statement.test.js b/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/__test__/plugin_statement.test.js
new file mode 100644
index 0000000000000..f0e2eecca70f5
--- /dev/null
+++ b/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/__test__/plugin_statement.test.js
@@ -0,0 +1,102 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import React from 'react';
+import { PluginStatement } from '../plugin_statement';
+import { shallow } from 'enzyme';
+
+import { EuiButtonEmpty, EuiBadge } from '@elastic/eui';
+
+describe('PluginStatement component', () => {
+ let props;
+ let onShowVertexDetails;
+ let isSlow;
+ let isTimeConsuming;
+ let processorStatement;
+
+ beforeEach(() => {
+ onShowVertexDetails = jest.fn();
+ props = {
+ statement: {
+ hasExplicitId: true,
+ id: 'standardInput',
+ name: 'stdin',
+ pluginType: 'input',
+ vertex: {
+ latestEventsPerSecond: 125,
+ },
+ },
+ onShowVertexDetails,
+ };
+
+ isSlow = jest.fn().mockImplementation(() => false);
+ isTimeConsuming = jest.fn().mockImplementation(() => false);
+ processorStatement = {
+ hasExplicitId: true,
+ id: 'mutatePlugin',
+ name: 'mutate',
+ pluginType: 'filter',
+ vertex: {
+ latestMillisPerEvent: 100,
+ latestEventsPerSecond: 120,
+ percentOfTotalProcessorTime: 25,
+ isSlow,
+ isTimeConsuming,
+ },
+ };
+ });
+
+ const render = props => shallow();
+
+ it('renders input metrics and explicit id fields', () => {
+ expect(render(props)).toMatchSnapshot();
+ });
+
+ it('does not render explicit id field if no id is specified', () => {
+ props.statement.id = 'dcbb2c37b4fedd3d7b852b5052f03dw3fbe1545a';
+ props.statement.hasExplicitId = false;
+ expect(render(props)).toMatchSnapshot();
+ });
+
+ it('renders processor statement metrics', () => {
+ props.statement = processorStatement;
+ expect(render(props)).toMatchSnapshot();
+ expect(isSlow).toHaveBeenCalledTimes(1);
+ expect(isTimeConsuming).toHaveBeenCalledTimes(1);
+ });
+
+ it('adds warning highlight for cpu time', () => {
+ props.statement = processorStatement;
+ props.statement.vertex.isTimeConsuming = jest
+ .fn()
+ .mockImplementation(() => true);
+ expect(render(props)).toMatchSnapshot();
+ });
+
+ it('adds warning highlight for event millis', () => {
+ props.statement = processorStatement;
+ props.statement.vertex.isSlow = jest.fn().mockImplementation(() => true);
+ expect(render(props)).toMatchSnapshot();
+ });
+
+ it('handles name button click', () => {
+ const { vertex } = props.statement;
+ const wrapper = render(props);
+ wrapper.find(EuiButtonEmpty).simulate('click');
+
+ expect(onShowVertexDetails).toHaveBeenCalledTimes(1);
+ expect(onShowVertexDetails).toHaveBeenCalledWith(vertex);
+ });
+
+ it('handles id badge click', () => {
+ const { vertex } = props.statement;
+ const wrapper = render(props);
+ wrapper.find(EuiBadge).simulate('click');
+
+ expect(onShowVertexDetails).toHaveBeenCalledTimes(1);
+ expect(onShowVertexDetails).toHaveBeenCalledWith(vertex);
+ });
+});
diff --git a/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/__test__/queue.test.js b/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/__test__/queue.test.js
new file mode 100644
index 0000000000000..2d107ed77d664
--- /dev/null
+++ b/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/__test__/queue.test.js
@@ -0,0 +1,15 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import React from 'react';
+import { Queue } from '../queue';
+import { shallow } from 'enzyme';
+
+describe('Queue component', () => {
+ it('renders default elements', () => {
+ expect(shallow()).toMatchSnapshot();
+ });
+});
diff --git a/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/__test__/statement.test.js b/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/__test__/statement.test.js
new file mode 100644
index 0000000000000..88f2ae861da11
--- /dev/null
+++ b/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/__test__/statement.test.js
@@ -0,0 +1,90 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import React from 'react';
+import { Statement } from '../statement';
+import { PluginStatement } from '../../models/pipeline/plugin_statement';
+import { PluginStatement as PluginStatementComponent } from '../plugin_statement';
+import { IfElement } from '../../models/list/if_element';
+import { CollapsibleStatement } from '../collapsible_statement';
+import { shallow } from 'enzyme';
+import { EuiButtonEmpty } from '@elastic/eui';
+
+describe('Statement component', () => {
+ let props;
+ let pluginStatement;
+ let branchElement;
+ let collapse;
+ let expand;
+ let onShowVertexDetails;
+
+ beforeEach(() => {
+ collapse = jest.fn();
+ expand = jest.fn();
+ onShowVertexDetails = jest.fn();
+ props = {
+ collapse,
+ element: {
+ depth: 0,
+ id: 'mutate2',
+ statement: {},
+ },
+ expand,
+ isCollapsed: false,
+ onShowVertexDetails,
+ };
+ pluginStatement = new PluginStatement({
+ hasExplicitId: true,
+ id: 'mutate2',
+ latestEventsPerSecond: 23,
+ meta: null,
+ name: 'mutate',
+ pluginType: 'filter',
+ stats: [],
+ });
+ branchElement = new IfElement(
+ {
+ id: 'ifStatement',
+ name: 'ifStatement',
+ },
+ 0,
+ null
+ );
+ });
+
+ it('renders a PluginStatement component for plugin model', () => {
+ props.element.statement = pluginStatement;
+ const wrapper = shallow();
+
+ expect(wrapper).toMatchSnapshot();
+ expect(wrapper.find(PluginStatementComponent)).toHaveLength(1);
+ });
+
+ it('renders spacers for element with depth > 0', () => {
+ props.element.depth = 2;
+ expect(shallow()).toMatchSnapshot();
+ });
+
+ it('renders a CollapsibleStatement with if body for branch model', () => {
+ props.element = branchElement;
+ const wrapper = shallow();
+
+ expect(wrapper).toMatchSnapshot();
+ expect(wrapper.find(CollapsibleStatement)).toHaveLength(1);
+ });
+
+ it('renders a CollapsibleStatement with else body for non-IfElement', () => {
+ expect(shallow()).toMatchSnapshot();
+ });
+
+ it(`selects the element's vertex when the name is clicked`, () => {
+ props.element = branchElement;
+ const wrapper = shallow();
+
+ wrapper.find(EuiButtonEmpty).simulate('click');
+ expect(onShowVertexDetails).toHaveBeenCalledTimes(1);
+ });
+});
diff --git a/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/__test__/statement_list.test.js b/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/__test__/statement_list.test.js
new file mode 100644
index 0000000000000..e3f3e3cd9a63f
--- /dev/null
+++ b/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/__test__/statement_list.test.js
@@ -0,0 +1,64 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import React from 'react';
+import { StatementList } from '../statement_list';
+import { Statement } from '../statement';
+import { shallow } from 'enzyme';
+
+describe('StatementList', () => {
+ let props;
+ let onShowVertexDetails;
+
+ beforeEach(() => {
+ onShowVertexDetails = jest.fn();
+ props = {
+ elements: [
+ {
+ id: 'mutateIf',
+ parentId: null,
+ depth: 0,
+ },
+ {
+ id: 'mutate',
+ parentId: 'mutateIf',
+ depth: 1,
+ },
+ ],
+ onShowVertexDetails,
+ };
+ });
+
+ const render = props => shallow();
+
+ it('renders nested elements as expected', () => {
+ const wrapper = render(props);
+ expect(wrapper).toMatchSnapshot();
+ expect(wrapper.find(Statement).length).toBe(2);
+ });
+
+ it('renders children elements when parent is collapsed', () => {
+ const wrapper = render(props);
+ const instance = wrapper.instance();
+ instance.collapse('mutateIf');
+ wrapper.update();
+
+ expect(wrapper.find(Statement).length).toBe(1);
+ });
+
+ it('renders children after expanding collapsed elements', () => {
+ const wrapper = render(props);
+ const instance = wrapper.instance();
+
+ instance.collapse('mutateIf');
+ wrapper.update();
+ expect(wrapper.find(Statement).length).toBe(1);
+
+ instance.expand('mutateIf');
+ wrapper.update();
+ expect(wrapper.find(Statement).length).toBe(2);
+ });
+});
diff --git a/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/__test__/statement_list_heading.test.js b/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/__test__/statement_list_heading.test.js
new file mode 100644
index 0000000000000..e4d68901ff544
--- /dev/null
+++ b/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/__test__/statement_list_heading.test.js
@@ -0,0 +1,24 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import React from 'react';
+import { StatementListHeading } from '../statement_list_heading';
+import { shallow } from 'enzyme';
+
+describe('StatementListHeading component', () => {
+ let props;
+
+ beforeEach(() => {
+ props = {
+ iconType: 'logstashInput',
+ title: 'Filters',
+ };
+ });
+
+ it('renders title and icon type', () => {
+ expect(shallow()).toMatchSnapshot();
+ });
+});
diff --git a/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/__test__/statement_section.test.js b/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/__test__/statement_section.test.js
new file mode 100644
index 0000000000000..679c60ee8eaab
--- /dev/null
+++ b/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/__test__/statement_section.test.js
@@ -0,0 +1,43 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import React from 'react';
+import { StatementSection } from '../statement_section';
+import { shallow } from 'enzyme';
+
+describe('StatementSection component', () => {
+ let props;
+ let onShowVertexDetails;
+
+ beforeEach(() => {
+ onShowVertexDetails = jest.fn();
+ props = {
+ elements: [
+ {
+ id: 'standardInput',
+ parentId: null,
+ },
+ {
+ id: 'fileInput',
+ parentId: null,
+ },
+ ],
+ headingText: 'Inputs',
+ iconType: 'logstashInput',
+ onShowVertexDetails,
+ };
+ });
+
+ it('renders heading text, correct icon type, and elements for StatementSection', () => {
+ expect(shallow()).toMatchSnapshot();
+ });
+
+ it('renders nothing if elements array is empty', () => {
+ props.elements = [];
+ const wrapper = shallow();
+ expect(wrapper.instance()).toBe(null);
+ });
+});
diff --git a/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/collapsible_statement.js b/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/collapsible_statement.js
index df6d46f1e45ba..b1fe7aa65a051 100644
--- a/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/collapsible_statement.js
+++ b/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/collapsible_statement.js
@@ -7,23 +7,14 @@
import React from 'react';
import PropTypes from 'prop-types';
-import {
- EuiButtonIcon,
- EuiFlexGroup,
- EuiFlexItem
-} from '@elastic/eui';
+import { EuiButtonIcon, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
function getToggleIconType(isCollapsed) {
return isCollapsed ? 'arrowRight' : 'arrowDown';
}
export function CollapsibleStatement(props) {
- const {
- collapse,
- expand,
- id,
- isCollapsed
- } = props;
+ const { collapse, expand, id, isCollapsed } = props;
const toggleClicked = () => {
if (isCollapsed) {
@@ -40,10 +31,7 @@ export function CollapsibleStatement(props) {
alignItems="center"
className="pipelineViewer__statement"
>
-
+
-
- {value}
-
+ {value}
);
}
return (
-
+
{stylizedValue}
);
@@ -49,4 +36,5 @@ export function Metric({ className, value, warning }) {
Metric.propTypes = {
className: PropTypes.string.isRequired,
value: PropTypes.string.isRequired,
+ warning: PropTypes.bool,
};
diff --git a/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/plugin_statement.js b/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/plugin_statement.js
index 34727ccc7adae..28d4ab89857e1 100644
--- a/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/plugin_statement.js
+++ b/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/plugin_statement.js
@@ -16,13 +16,13 @@ import { formatMetric } from '../../../../lib/format_number';
import { Metric } from './metric';
function getInputStatementMetrics({ latestEventsPerSecond }) {
- return [(
+ return [
- )];
+ />,
+ ];
}
function getProcessorStatementMetrics(processorVertex) {
@@ -33,29 +33,28 @@ function getProcessorStatementMetrics(processorVertex) {
} = processorVertex;
return [
- (
-
- ),
- (
-
- ),
- (
-
- )
+ ,
+ ,
+ ,
];
}
@@ -66,45 +65,36 @@ function renderPluginStatementMetrics(pluginType, vertex) {
}
export function PluginStatement({
- statement: {
- hasExplicitId,
- id,
- name,
- pluginType,
- vertex
- },
- onShowVertexDetails
+ statement: { hasExplicitId, id, name, pluginType, vertex },
+ onShowVertexDetails,
}) {
const statementMetrics = renderPluginStatementMetrics(pluginType, vertex);
- const onNameButtonClick = () => { onShowVertexDetails(vertex); };
+ const onNameButtonClick = () => {
+ onShowVertexDetails(vertex);
+ };
return (
-
+
{name}
- {
- hasExplicitId &&
+ {hasExplicitId && (
- }
+ )}
- {
- statementMetrics &&
+ {statementMetrics && (
-
- {statementMetrics}
-
+ {statementMetrics}
- }
+ )}
);
}
PluginStatement.propTypes = {
+ onShowVertexDetails: PropTypes.func.isRequired,
statement: PropTypes.shape({
hasExplicitId: PropTypes.bool.isRequired,
id: PropTypes.string.isRequired,
name: PropTypes.string.isRequired,
pluginType: PropTypes.string.isRequired,
- vertex: PropTypes.object.isRequired,
+ vertex: PropTypes.shape({
+ latestEventsPerSecond: PropTypes.number.isRequired,
+ latestMillisPerEvent: PropTypes.number,
+ percentOfTotalProcessorTime: PropTypes.number,
+ }).isRequired,
}).isRequired,
- onShowVertexDetails: PropTypes.func.isRequired,
};
diff --git a/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/queue.js b/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/queue.js
index 79a6995670eec..d384b67fc34c4 100644
--- a/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/queue.js
+++ b/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/queue.js
@@ -11,10 +11,7 @@ import { EuiSpacer, EuiText } from '@elastic/eui';
export function Queue() {
return (
-
+
Queue metrics not available
diff --git a/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/statement.js b/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/statement.js
index 0b231b7b00799..dc281bead4cda 100644
--- a/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/statement.js
+++ b/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/statement.js
@@ -6,10 +6,7 @@
import React from 'react';
import PropTypes from 'prop-types';
-import {
- EuiButtonEmpty,
- EuiCodeBlock,
- EuiFlexItem } from '@elastic/eui';
+import { EuiButtonEmpty, EuiCodeBlock, EuiFlexItem } from '@elastic/eui';
import { PluginStatement as PluginStatementModel } from '../models/pipeline/plugin_statement';
import { CollapsibleStatement } from './collapsible_statement';
import { IfElement } from '../models/list/if_element';
@@ -17,10 +14,7 @@ import { PluginStatement } from './plugin_statement';
function renderStatementName(name, onVertexSelected) {
return (
-
+
+
-
- {condition}
-
-
- )
+ {condition}
+
+ ,
];
}
-function getStatementBody(
- isIf,
- statement,
- vertex,
- onShowVertexDetails
-) {
- const showVertexDetailsClicked = () => { onShowVertexDetails(vertex); };
+function getStatementBody(isIf, statement, vertex, onShowVertexDetails) {
+ const showVertexDetailsClicked = () => {
+ onShowVertexDetails(vertex);
+ };
return isIf
? renderIfStatement(statement, showVertexDetailsClicked)
@@ -69,7 +55,9 @@ function getStatementBody(
function renderNestingSpacers(depth) {
const spacers = [];
for (let i = 0; i < depth; i += 1) {
- spacers.push();
+ spacers.push(
+
+ );
}
return spacers;
}
@@ -80,11 +68,11 @@ function renderStatement({
element: {
id,
statement,
- statement: { vertex }
+ statement: { vertex },
},
expand,
isCollapsed,
- onShowVertexDetails
+ onShowVertexDetails,
}) {
if (statement instanceof PluginStatementModel) {
return (
@@ -132,9 +120,9 @@ Statement.propTypes = {
element: PropTypes.shape({
depth: PropTypes.number.isRequired,
id: PropTypes.string.isRequired,
- statement: PropTypes.object.isRequired
+ statement: PropTypes.object.isRequired,
}).isRequired,
expand: PropTypes.func.isRequired,
isCollapsed: PropTypes.bool.isRequired,
- onShowVertexDetails: PropTypes.func.isRequired
+ onShowVertexDetails: PropTypes.func.isRequired,
};
diff --git a/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/statement_list.js b/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/statement_list.js
new file mode 100644
index 0000000000000..6c84ab59dff57
--- /dev/null
+++ b/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/statement_list.js
@@ -0,0 +1,93 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import React from 'react';
+import PropTypes from 'prop-types';
+
+import { Statement } from './statement';
+
+function getCollapsedChildIds(elements, collapsedIds) {
+ const collapsedChildIds = new Set();
+ elements.forEach(({ id, parentId }) => {
+ if (collapsedIds.has(parentId) || collapsedChildIds.has(parentId)) {
+ collapsedChildIds.add(id);
+ }
+ });
+ return collapsedChildIds;
+}
+
+export class StatementList extends React.PureComponent {
+ constructor(props) {
+ super(props);
+
+ this.state = {
+ collapsedIds: new Set(),
+ collapsedChildIds: new Set(),
+ };
+ }
+
+ expand = elementId => {
+ const collapsedIds = new Set(this.state.collapsedIds);
+ collapsedIds.delete(elementId);
+ this.updateCollapsedElement(collapsedIds);
+ };
+
+ collapse = elementId => {
+ const collapsedIds = new Set(this.state.collapsedIds);
+ collapsedIds.add(elementId);
+ this.updateCollapsedElement(collapsedIds);
+ };
+
+ updateCollapsedElement = collapsedIds => {
+ const { elements } = this.props;
+ const collapsedChildIds = getCollapsedChildIds(elements, collapsedIds);
+
+ this.setState({
+ collapsedIds,
+ collapsedChildIds,
+ });
+ };
+
+ elementIsCollapsed = elementId => this.state.collapsedIds.has(elementId);
+
+ renderStatement = element => {
+ const { id, parentId } = element;
+ const { onShowVertexDetails } = this.props;
+
+ return this.state.collapsedIds.has(parentId) ||
+ this.state.collapsedChildIds.has(parentId) ? null : (
+
+ );
+ };
+
+ render() {
+ const { elements } = this.props;
+
+ return (
+
+ {elements.map(this.renderStatement)}
+
+ );
+ }
+}
+
+StatementList.propTypes = {
+ elements: PropTypes.arrayOf(
+ PropTypes.shape({
+ id: PropTypes.string.isRequired,
+ // top-level elements have null parentId
+ parentId: PropTypes.string,
+ })
+ ).isRequired,
+ onShowVertexDetails: PropTypes.func.isRequired,
+};
diff --git a/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/statement_section.js b/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/statement_section.js
index 57cdf164c12be..0bf9a50791d8a 100644
--- a/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/statement_section.js
+++ b/x-pack/plugins/monitoring/public/components/logstash/pipeline_viewer/views/statement_section.js
@@ -7,23 +7,22 @@
import React from 'react';
import PropTypes from 'prop-types';
import { StatementListHeading } from './statement_list_heading';
-import { Statement } from './statement';
import { EuiSpacer } from '@elastic/eui';
+import { StatementList } from './statement_list';
export function StatementSection({
iconType,
headingText,
elements,
- onShowVertexDetails
+ onShowVertexDetails,
}) {
- if (!elements.length) { return null; }
+ if (!elements.length) {
+ return null;
+ }
return (
-
+
{
- if (collapsedIds.has(parentId) || collapsedChildIds.has(parentId)) {
- collapsedChildIds.add(id);
- }
- });
- return collapsedChildIds;
-}
-
-class StatementList extends React.PureComponent {
- constructor(props) {
- super(props);
-
- this.state = {
- collapsedIds: new Set(),
- collapsedChildIds: new Set()
- };
- }
-
- expand = elementId => {
- const collapsedIds = new Set(this.state.collapsedIds);
- collapsedIds.delete(elementId);
- this.updateCollapsedElement(collapsedIds);
- }
-
- collapse = elementId => {
- const collapsedIds = new Set(this.state.collapsedIds);
- collapsedIds.add(elementId);
- this.updateCollapsedElement(collapsedIds);
- }
-
- updateCollapsedElement = collapsedIds => {
- const { elements } = this.props;
- const collapsedChildIds = getCollapsedChildIds(elements, collapsedIds);
-
- this.setState({
- collapsedIds,
- collapsedChildIds
- });
- }
-
- elementIsCollapsed = elementId => this.state.collapsedIds.has(elementId);
-
- renderStatement = element => {
- const { id, parentId } = element;
- const { onShowVertexDetails } = this.props;
-
- return this.state.collapsedIds.has(parentId) || this.state.collapsedChildIds.has(parentId)
- ? null
- : (
-
- );
- }
-
- render() {
- const { elements } = this.props;
-
- return (
-
- {
- elements.map(this.renderStatement)
- }
-
- );
- }
-}
-
-StatementList.propTypes = {
+StatementSection.propTypes = {
elements: PropTypes.arrayOf(
PropTypes.shape({
id: PropTypes.string.isRequired,
// top-level elements have null parentId
- parentId: PropTypes.string
+ parentId: PropTypes.string,
})
).isRequired,
+ headingText: PropTypes.string.isRequired,
+ iconType: PropTypes.string.isRequired,
onShowVertexDetails: PropTypes.func.isRequired,
};