From 0f3f38d7d387bb1a3b10a65a595273f517e9379d Mon Sep 17 00:00:00 2001 From: sulemanof Date: Tue, 23 Jul 2019 12:03:55 +0300 Subject: [PATCH 1/3] Add vis_options_react_wrapper --- .../public/components/editor/controls_tab.js | 49 +++++++-------- .../public/components/editor/options_tab.js | 23 +++---- .../public/vis/editors/default/sidebar.html | 1 + .../ui/public/vis/editors/default/sidebar.js | 6 ++ .../vis/editors/default/vis_options.html | 4 -- .../public/vis/editors/default/vis_options.js | 63 +++++++------------ .../vis/editors/default/vis_options_props.tsx | 26 ++++++++ .../default/vis_options_react_wrapper.tsx | 31 +++++++++ 8 files changed, 114 insertions(+), 89 deletions(-) delete mode 100644 src/legacy/ui/public/vis/editors/default/vis_options.html create mode 100644 src/legacy/ui/public/vis/editors/default/vis_options_props.tsx create mode 100644 src/legacy/ui/public/vis/editors/default/vis_options_react_wrapper.tsx diff --git a/src/legacy/core_plugins/input_control_vis/public/components/editor/controls_tab.js b/src/legacy/core_plugins/input_control_vis/public/components/editor/controls_tab.js index 7188bcdf424f9..86ddd34745825 100644 --- a/src/legacy/core_plugins/input_control_vis/public/components/editor/controls_tab.js +++ b/src/legacy/core_plugins/input_control_vis/public/components/editor/controls_tab.js @@ -17,7 +17,6 @@ * under the License. */ -import _ from 'lodash'; import PropTypes from 'prop-types'; import React, { Component } from 'react'; import { ControlEditor } from './control_editor'; @@ -41,69 +40,63 @@ class ControlsTabUi extends Component { } getIndexPattern = async (indexPatternId) => { - return await this.props.scope.vis.API.indexPatterns.get(indexPatternId); - } - - setVisParam(paramName, paramValue) { - const params = _.cloneDeep(this.props.editorState.params); - params[paramName] = paramValue; - this.props.stageEditorParams(params); + return await this.props.vis.API.indexPatterns.get(indexPatternId); } handleLabelChange = (controlIndex, evt) => { - const updatedControl = this.props.editorState.params.controls[controlIndex]; + const updatedControl = this.props.stateParams.controls[controlIndex]; updatedControl.label = evt.target.value; - this.setVisParam('controls', setControl(this.props.editorState.params.controls, controlIndex, updatedControl)); + this.props.setValue('controls', setControl(this.props.stateParams.controls, controlIndex, updatedControl)); } handleIndexPatternChange = (controlIndex, indexPatternId) => { - const updatedControl = this.props.editorState.params.controls[controlIndex]; + const updatedControl = this.props.stateParams.controls[controlIndex]; updatedControl.indexPattern = indexPatternId; updatedControl.fieldName = ''; - this.setVisParam('controls', setControl(this.props.editorState.params.controls, controlIndex, updatedControl)); + this.props.setValue('controls', setControl(this.props.stateParams.controls, controlIndex, updatedControl)); } handleFieldNameChange = (controlIndex, fieldName) => { - const updatedControl = this.props.editorState.params.controls[controlIndex]; + const updatedControl = this.props.stateParams.controls[controlIndex]; updatedControl.fieldName = fieldName; - this.setVisParam('controls', setControl(this.props.editorState.params.controls, controlIndex, updatedControl)); + this.props.setValue('controls', setControl(this.props.stateParams.controls, controlIndex, updatedControl)); } handleCheckboxOptionChange = (controlIndex, optionName, evt) => { - const updatedControl = this.props.editorState.params.controls[controlIndex]; + const updatedControl = this.props.stateParams.controls[controlIndex]; updatedControl.options[optionName] = evt.target.checked; - this.setVisParam('controls', setControl(this.props.editorState.params.controls, controlIndex, updatedControl)); + this.props.setValue('controls', setControl(this.props.stateParams.controls, controlIndex, updatedControl)); } handleNumberOptionChange = (controlIndex, optionName, evt) => { - const updatedControl = this.props.editorState.params.controls[controlIndex]; + const updatedControl = this.props.stateParams.controls[controlIndex]; updatedControl.options[optionName] = parseFloat(evt.target.value); - this.setVisParam('controls', setControl(this.props.editorState.params.controls, controlIndex, updatedControl)); + this.props.setValue('controls', setControl(this.props.stateParams.controls, controlIndex, updatedControl)); } handleRemoveControl = (controlIndex) => { - this.setVisParam('controls', removeControl(this.props.editorState.params.controls, controlIndex)); + this.props.setValue('controls', removeControl(this.props.stateParams.controls, controlIndex)); } moveControl = (controlIndex, direction) => { - this.setVisParam('controls', moveControl(this.props.editorState.params.controls, controlIndex, direction)); + this.props.setValue('controls', moveControl(this.props.stateParams.controls, controlIndex, direction)); } handleAddControl = () => { - this.setVisParam('controls', addControl(this.props.editorState.params.controls, newControl(this.state.type))); + this.props.setValue('controls', addControl(this.props.stateParams.controls, newControl(this.state.type))); } handleParentChange = (controlIndex, evt) => { - const updatedControl = this.props.editorState.params.controls[controlIndex]; + const updatedControl = this.props.stateParams.controls[controlIndex]; updatedControl.parent = evt.target.value; - this.setVisParam('controls', setControl(this.props.editorState.params.controls, controlIndex, updatedControl)); + this.props.setValue('controls', setControl(this.props.stateParams.controls, controlIndex, updatedControl)); } renderControls() { - const lineageMap = getLineageMap(this.props.editorState.params.controls); - return this.props.editorState.params.controls.map((controlParams, controlIndex) => { + const lineageMap = getLineageMap(this.props.stateParams.controls); + return this.props.stateParams.controls.map((controlParams, controlIndex) => { const parentCandidates = getParentCandidates( - this.props.editorState.params.controls, + this.props.stateParams.controls, controlParams.id, lineageMap); return ( @@ -187,8 +180,8 @@ class ControlsTabUi extends Component { } ControlsTabUi.propTypes = { - scope: PropTypes.object.isRequired, - stageEditorParams: PropTypes.func.isRequired + vis: PropTypes.object.isRequired, + setValue: PropTypes.func.isRequired }; export const ControlsTab = injectI18n(ControlsTabUi); diff --git a/src/legacy/core_plugins/input_control_vis/public/components/editor/options_tab.js b/src/legacy/core_plugins/input_control_vis/public/components/editor/options_tab.js index d63ef66117854..0045ec2508b95 100644 --- a/src/legacy/core_plugins/input_control_vis/public/components/editor/options_tab.js +++ b/src/legacy/core_plugins/input_control_vis/public/components/editor/options_tab.js @@ -17,7 +17,6 @@ * under the License. */ -import _ from 'lodash'; import PropTypes from 'prop-types'; import React, { Component } from 'react'; @@ -31,22 +30,16 @@ import { FormattedMessage } from '@kbn/i18n/react'; export class OptionsTab extends Component { - setVisParam = (paramName, paramValue) => { - const params = _.cloneDeep(this.props.editorState.params); - params[paramName] = paramValue; - this.props.stageEditorParams(params); - } - handleUpdateFiltersChange = (evt) => { - this.setVisParam('updateFiltersOnChange', evt.target.checked); + this.props.setValue('updateFiltersOnChange', evt.target.checked); } handleUseTimeFilter = (evt) => { - this.setVisParam('useTimeFilter', evt.target.checked); + this.props.setValue('useTimeFilter', evt.target.checked); } handlePinFilters = (evt) => { - this.setVisParam('pinFilters', evt.target.checked); + this.props.setValue('pinFilters', evt.target.checked); } render() { @@ -60,7 +53,7 @@ export class OptionsTab extends Component { id="inputControl.editor.optionsTab.updateFilterLabel" defaultMessage="Update Kibana filters on each change" />} - checked={this.props.editorState.params.updateFiltersOnChange} + checked={this.props.stateParams.updateFiltersOnChange} onChange={this.handleUpdateFiltersChange} data-test-subj="inputControlEditorUpdateFiltersOnChangeCheckbox" /> @@ -74,7 +67,7 @@ export class OptionsTab extends Component { id="inputControl.editor.optionsTab.useTimeFilterLabel" defaultMessage="Use time filter" />} - checked={this.props.editorState.params.useTimeFilter} + checked={this.props.stateParams.useTimeFilter} onChange={this.handleUseTimeFilter} data-test-subj="inputControlEditorUseTimeFilterCheckbox" /> @@ -88,7 +81,7 @@ export class OptionsTab extends Component { id="inputControl.editor.optionsTab.pinFiltersLabel" defaultMessage="Pin filters for all applications" />} - checked={this.props.editorState.params.pinFilters} + checked={this.props.stateParams.pinFilters} onChange={this.handlePinFilters} data-test-subj="inputControlEditorPinFiltersCheckbox" /> @@ -99,6 +92,6 @@ export class OptionsTab extends Component { } OptionsTab.propTypes = { - scope: PropTypes.object.isRequired, - stageEditorParams: PropTypes.func.isRequired + vis: PropTypes.object.isRequired, + setValue: PropTypes.func.isRequired }; diff --git a/src/legacy/ui/public/vis/editors/default/sidebar.html b/src/legacy/ui/public/vis/editors/default/sidebar.html index 77a930c94a462..5b54352e21b4d 100644 --- a/src/legacy/ui/public/vis/editors/default/sidebar.html +++ b/src/legacy/ui/public/vis/editors/default/sidebar.html @@ -166,6 +166,7 @@ ui-state="uiState" visualize-editor="visualizeEditor" editor="tab.editor" + on-agg-params-change="onAggParamsChange" > diff --git a/src/legacy/ui/public/vis/editors/default/sidebar.js b/src/legacy/ui/public/vis/editors/default/sidebar.js index a335880bcf917..e21987b3dd4fc 100644 --- a/src/legacy/ui/public/vis/editors/default/sidebar.js +++ b/src/legacy/ui/public/vis/editors/default/sidebar.js @@ -47,6 +47,12 @@ uiModules this.section = this.section || (this.showData ? 'data' : _.get(visType, 'editorConfig.optionTabs[0].name')); } }); + + $scope.onAggParamsChange = (params, paramName, value) => { + if (params[paramName] !== value) { + params[paramName] = value; + } + }; } }; }); diff --git a/src/legacy/ui/public/vis/editors/default/vis_options.html b/src/legacy/ui/public/vis/editors/default/vis_options.html deleted file mode 100644 index 51a4c296b5b79..0000000000000 --- a/src/legacy/ui/public/vis/editors/default/vis_options.html +++ /dev/null @@ -1,4 +0,0 @@ - -
diff --git a/src/legacy/ui/public/vis/editors/default/vis_options.js b/src/legacy/ui/public/vis/editors/default/vis_options.js index fe1bc3a0f61ea..0f4548e115565 100644 --- a/src/legacy/ui/public/vis/editors/default/vis_options.js +++ b/src/legacy/ui/public/vis/editors/default/vis_options.js @@ -17,12 +17,9 @@ * under the License. */ -import _ from 'lodash'; -import React from 'react'; -import { render, unmountComponentAtNode } from 'react-dom'; +import { wrapInI18nContext } from 'ui/i18n'; import { uiModules } from '../../../modules'; -import visOptionsTemplate from './vis_options.html'; -import { I18nContext } from 'ui/i18n'; +import { VisOptionsReactWrapper } from './vis_options_react_wrapper'; /** * This directive sort of "transcludes" in whatever template you pass in via the `editor` attribute. @@ -32,10 +29,15 @@ import { I18nContext } from 'ui/i18n'; uiModules .get('app/visualize') + .directive('visOptionsReactWrapper', reactDirective => reactDirective(wrapInI18nContext(VisOptionsReactWrapper), [ + ['component', { wrapApply: false }], + ['stateParams', { watchDepth: 'collection' }], + ['vis', { watchDepth: 'collection' }], + ['setValue', { watchDepth: 'reference' }], + ])) .directive('visEditorVisOptions', function ($compile) { return { restrict: 'E', - template: visOptionsTemplate, scope: { vis: '=', visData: '=', @@ -43,45 +45,22 @@ uiModules editor: '=', visualizeEditor: '=', editorState: '=', + onAggParamsChange: '=', }, link: function ($scope, $el) { - const $optionContainer = $el.find('[data-visualization-options]'); + $scope.setValue = (paramName, value) => + $scope.onAggParamsChange($scope.editorState.params, paramName, value); - const reactOptionsComponent = typeof $scope.editor !== 'string'; - const stageEditorParams = (params) => { - $scope.editorState.params = _.cloneDeep(params); - $scope.$apply(); - }; - const renderReactComponent = () => { - const Component = $scope.editor; - render( - - - , $el[0]); - }; - // Bind the `editor` template with the scope. - if (reactOptionsComponent) { - renderReactComponent(); - } else { - const $editor = $compile($scope.editor)($scope); - $optionContainer.append($editor); - } - - $scope.$watchGroup(['visData', 'visualizeEditor', 'editorState.params'], () => { - if (reactOptionsComponent) { - renderReactComponent(); - } - }); - - $scope.$watch('vis.type.schemas.all.length', function (len) { - $scope.alwaysShowOptions = len === 0; - }); - - $el.on('$destroy', () => { - if (reactOptionsComponent) { - unmountComponentAtNode($el[0]); - } - }); + const comp = typeof $scope.editor === 'string' ? + $scope.editor : + ` + `; + const $editor = $compile(comp)($scope); + $el.append($editor); } }; }); diff --git a/src/legacy/ui/public/vis/editors/default/vis_options_props.tsx b/src/legacy/ui/public/vis/editors/default/vis_options_props.tsx new file mode 100644 index 0000000000000..66346ccab6007 --- /dev/null +++ b/src/legacy/ui/public/vis/editors/default/vis_options_props.tsx @@ -0,0 +1,26 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { Vis, VisParams } from 'ui/vis'; + +export interface VisOptionsProps { + stateParams: VisParams; + vis: Vis; + setValue(paramName: string, value: unknown): void; +} diff --git a/src/legacy/ui/public/vis/editors/default/vis_options_react_wrapper.tsx b/src/legacy/ui/public/vis/editors/default/vis_options_react_wrapper.tsx new file mode 100644 index 0000000000000..d214abecb9c0c --- /dev/null +++ b/src/legacy/ui/public/vis/editors/default/vis_options_react_wrapper.tsx @@ -0,0 +1,31 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React from 'react'; +import { VisOptionsProps } from './vis_options_props'; + +interface VisOptionsReactWrapperProps extends VisOptionsProps { + component: React.ComponentType; +} + +function VisOptionsReactWrapper({ component: Component, ...rest }: VisOptionsReactWrapperProps) { + return ; +} + +export { VisOptionsReactWrapper }; From 1d0bd0a992171d1a4aed20f738c9405a29d9bdfe Mon Sep 17 00:00:00 2001 From: sulemanof Date: Tue, 23 Jul 2019 14:34:03 +0300 Subject: [PATCH 2/3] Update jest tests --- .../__snapshots__/options_tab.test.js.snap | 2 +- .../public/components/editor/controls_tab.js | 20 +- .../components/editor/controls_tab.test.js | 210 ++++++++---------- .../components/editor/options_tab.test.js | 104 ++++----- 4 files changed, 146 insertions(+), 190 deletions(-) diff --git a/src/legacy/core_plugins/input_control_vis/public/components/editor/__snapshots__/options_tab.test.js.snap b/src/legacy/core_plugins/input_control_vis/public/components/editor/__snapshots__/options_tab.test.js.snap index bc333351b307d..f78607e9cfa0a 100644 --- a/src/legacy/core_plugins/input_control_vis/public/components/editor/__snapshots__/options_tab.test.js.snap +++ b/src/legacy/core_plugins/input_control_vis/public/components/editor/__snapshots__/options_tab.test.js.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`renders OptionsTab 1`] = ` +exports[`OptionsTab should renders OptionsTab 1`] = ` this.props.setValue('controls', value) + handleLabelChange = (controlIndex, evt) => { const updatedControl = this.props.stateParams.controls[controlIndex]; updatedControl.label = evt.target.value; - this.props.setValue('controls', setControl(this.props.stateParams.controls, controlIndex, updatedControl)); + this.onChange(setControl(this.props.stateParams.controls, controlIndex, updatedControl)); } handleIndexPatternChange = (controlIndex, indexPatternId) => { const updatedControl = this.props.stateParams.controls[controlIndex]; updatedControl.indexPattern = indexPatternId; updatedControl.fieldName = ''; - this.props.setValue('controls', setControl(this.props.stateParams.controls, controlIndex, updatedControl)); + this.onChange(setControl(this.props.stateParams.controls, controlIndex, updatedControl)); } handleFieldNameChange = (controlIndex, fieldName) => { const updatedControl = this.props.stateParams.controls[controlIndex]; updatedControl.fieldName = fieldName; - this.props.setValue('controls', setControl(this.props.stateParams.controls, controlIndex, updatedControl)); + this.onChange(setControl(this.props.stateParams.controls, controlIndex, updatedControl)); } handleCheckboxOptionChange = (controlIndex, optionName, evt) => { const updatedControl = this.props.stateParams.controls[controlIndex]; updatedControl.options[optionName] = evt.target.checked; - this.props.setValue('controls', setControl(this.props.stateParams.controls, controlIndex, updatedControl)); + this.onChange(setControl(this.props.stateParams.controls, controlIndex, updatedControl)); } handleNumberOptionChange = (controlIndex, optionName, evt) => { const updatedControl = this.props.stateParams.controls[controlIndex]; updatedControl.options[optionName] = parseFloat(evt.target.value); - this.props.setValue('controls', setControl(this.props.stateParams.controls, controlIndex, updatedControl)); + this.onChange(setControl(this.props.stateParams.controls, controlIndex, updatedControl)); } handleRemoveControl = (controlIndex) => { - this.props.setValue('controls', removeControl(this.props.stateParams.controls, controlIndex)); + this.onChange(removeControl(this.props.stateParams.controls, controlIndex)); } moveControl = (controlIndex, direction) => { - this.props.setValue('controls', moveControl(this.props.stateParams.controls, controlIndex, direction)); + this.onChange(moveControl(this.props.stateParams.controls, controlIndex, direction)); } handleAddControl = () => { - this.props.setValue('controls', addControl(this.props.stateParams.controls, newControl(this.state.type))); + this.onChange(addControl(this.props.stateParams.controls, newControl(this.state.type))); } handleParentChange = (controlIndex, evt) => { const updatedControl = this.props.stateParams.controls[controlIndex]; updatedControl.parent = evt.target.value; - this.props.setValue('controls', setControl(this.props.stateParams.controls, controlIndex, updatedControl)); + this.onChange(setControl(this.props.stateParams.controls, controlIndex, updatedControl)); } renderControls() { diff --git a/src/legacy/core_plugins/input_control_vis/public/components/editor/controls_tab.test.js b/src/legacy/core_plugins/input_control_vis/public/components/editor/controls_tab.test.js index add17262860a2..4a9433d4cd698 100644 --- a/src/legacy/core_plugins/input_control_vis/public/components/editor/controls_tab.test.js +++ b/src/legacy/core_plugins/input_control_vis/public/components/editor/controls_tab.test.js @@ -18,7 +18,6 @@ */ import React from 'react'; -import sinon from 'sinon'; import { shallowWithIntl, mountWithIntl } from 'test_utils/enzyme_helpers'; import { findTestSubject } from '@elastic/eui/lib/test'; import { getIndexPatternMock } from './__tests__/get_index_pattern_mock'; @@ -29,15 +28,17 @@ import { const indexPatternsMock = { get: getIndexPatternMock }; -const scopeMock = { - vis: { - API: { - indexPatterns: indexPatternsMock +let props; + +beforeEach(() => { + props = { + vis: { + API: { + indexPatterns: indexPatternsMock + }, }, - }, - editorState: { - params: { - 'controls': [ + stateParams: { + controls: [ { 'id': '1', 'indexPattern': 'indexPattern1', @@ -62,138 +63,111 @@ const scopeMock = { } } ] - } - } -}; -let stageEditorParams; - -beforeEach(() => { - stageEditorParams = sinon.spy(); + }, + setValue: jest.fn(), + }; }); test('renders ControlsTab', () => { - const component = shallowWithIntl(); - expect(component).toMatchSnapshot(); // eslint-disable-line + const component = shallowWithIntl(); + + expect(component).toMatchSnapshot(); }); describe('behavior', () => { test('add control button', () => { - const component = mountWithIntl(); + const component = mountWithIntl(); + findTestSubject(component, 'inputControlEditorAddBtn').simulate('click'); - // Use custom match function since control.id is dynamically generated and never the same. - sinon.assert.calledWith(stageEditorParams, sinon.match((newParams) => { - if (newParams.controls.length !== 3) { - return false; - } - return true; - }, 'control not added to editorState.params')); + + // // Use custom match function since control.id is dynamically generated and never the same. + expect(props.setValue).toHaveBeenCalledWith( + 'controls', + expect.arrayContaining(props.stateParams.controls) + ); + expect(props.setValue.mock.calls[0][1].length).toEqual(3); }); test('remove control button', () => { - const component = mountWithIntl(); + const component = mountWithIntl(); findTestSubject(component, 'inputControlEditorRemoveControl0').simulate('click'); - const expectedParams = { - 'controls': [ - { - 'id': '2', - 'indexPattern': 'indexPattern1', - 'fieldName': 'numberField', - 'label': '', - 'type': 'range', - 'options': { - 'step': 1 - } - } - ] - }; - sinon.assert.calledWith(stageEditorParams, sinon.match(expectedParams)); + const expectedParams = ['controls', [{ + 'id': '2', + 'indexPattern': 'indexPattern1', + 'fieldName': 'numberField', + 'label': '', + 'type': 'range', + 'options': { + 'step': 1 + } + }]]; + + expect(props.setValue).toHaveBeenCalledWith(...expectedParams); }); test('move down control button', () => { - const component = mountWithIntl(); + const component = mountWithIntl(); findTestSubject(component, 'inputControlEditorMoveDownControl0').simulate('click'); - const expectedParams = { - 'controls': [ - { - 'id': '2', - 'indexPattern': 'indexPattern1', - 'fieldName': 'numberField', - 'label': '', - 'type': 'range', - 'options': { - 'step': 1 - } - }, - { - 'id': '1', - 'indexPattern': 'indexPattern1', - 'fieldName': 'keywordField', - 'label': 'custom label', - 'type': 'list', - 'options': { - 'type': 'terms', - 'multiselect': true, - 'size': 5, - 'order': 'desc' - } + const expectedParams = ['controls', [ + { + 'id': '2', + 'indexPattern': 'indexPattern1', + 'fieldName': 'numberField', + 'label': '', + 'type': 'range', + 'options': { + 'step': 1 } - ] - }; - sinon.assert.calledWith(stageEditorParams, sinon.match(expectedParams)); + }, + { + 'id': '1', + 'indexPattern': 'indexPattern1', + 'fieldName': 'keywordField', + 'label': 'custom label', + 'type': 'list', + 'options': { + 'type': 'terms', + 'multiselect': true, + 'size': 5, + 'order': 'desc' + } + } + ]]; + + expect(props.setValue).toHaveBeenCalledWith(...expectedParams); }); test('move up control button', () => { - const component = mountWithIntl(); + const component = mountWithIntl(); findTestSubject(component, 'inputControlEditorMoveUpControl1').simulate('click'); - const expectedParams = { - 'controls': [ - { - 'id': '2', - 'indexPattern': 'indexPattern1', - 'fieldName': 'numberField', - 'label': '', - 'type': 'range', - 'options': { - 'step': 1 - } - }, - { - 'id': '1', - 'indexPattern': 'indexPattern1', - 'fieldName': 'keywordField', - 'label': 'custom label', - 'type': 'list', - 'options': { - 'type': 'terms', - 'multiselect': true, - 'size': 5, - 'order': 'desc' - } + const expectedParams = ['controls', [ + { + 'id': '2', + 'indexPattern': 'indexPattern1', + 'fieldName': 'numberField', + 'label': '', + 'type': 'range', + 'options': { + 'step': 1 } - ] - }; - sinon.assert.calledWith(stageEditorParams, sinon.match(expectedParams)); + }, + { + 'id': '1', + 'indexPattern': 'indexPattern1', + 'fieldName': 'keywordField', + 'label': 'custom label', + 'type': 'list', + 'options': { + 'type': 'terms', + 'multiselect': true, + 'size': 5, + 'order': 'desc' + } + } + ]]; + + expect(props.setValue).toHaveBeenCalledWith(...expectedParams); }); }); diff --git a/src/legacy/core_plugins/input_control_vis/public/components/editor/options_tab.test.js b/src/legacy/core_plugins/input_control_vis/public/components/editor/options_tab.test.js index ba4d43bea133f..6203f7d6a29cb 100644 --- a/src/legacy/core_plugins/input_control_vis/public/components/editor/options_tab.test.js +++ b/src/legacy/core_plugins/input_control_vis/public/components/editor/options_tab.test.js @@ -18,7 +18,6 @@ */ import React from 'react'; -import sinon from 'sinon'; import { shallow } from 'enzyme'; import { mountWithIntl } from 'test_utils/enzyme_helpers'; @@ -26,70 +25,51 @@ import { OptionsTab, } from './options_tab'; -const scopeMock = { - editorState: { - params: { - updateFiltersOnChange: false, - useTimeFilter: false - } - } -}; -let stageEditorParams; +describe('OptionsTab', () => { + let props; -beforeEach(() => { - stageEditorParams = sinon.spy(); -}); + beforeEach(() => { + props = { + vis: {}, + stateParams: { + updateFiltersOnChange: false, + useTimeFilter: false + }, + setValue: jest.fn() + }; + }); -test('renders OptionsTab', () => { - const component = shallow(); - expect(component).toMatchSnapshot(); // eslint-disable-line -}); + it('should renders OptionsTab', () => { + const component = shallow(); -test('updateFiltersOnChange', () => { - const component = mountWithIntl(); - const checkbox = component.find('[data-test-subj="inputControlEditorUpdateFiltersOnChangeCheckbox"] input[type="checkbox"]'); - checkbox.simulate('change', { target: { checked: true } }); - const expectedParams = { - updateFiltersOnChange: true - }; - sinon.assert.calledOnce(stageEditorParams); - sinon.assert.calledWith(stageEditorParams, sinon.match(expectedParams)); -}); + expect(component).toMatchSnapshot(); // eslint-disable-line + }); -test('useTimeFilter', () => { - const component = mountWithIntl(); - const checkbox = component.find('[data-test-subj="inputControlEditorUseTimeFilterCheckbox"] input[type="checkbox"]'); - checkbox.simulate('change', { target: { checked: true } }); - const expectedParams = { - useTimeFilter: true - }; - sinon.assert.calledOnce(stageEditorParams); - sinon.assert.calledWith(stageEditorParams, sinon.match(expectedParams)); -}); + it('should update updateFiltersOnChange', () => { + const component = mountWithIntl(); + const checkbox = component.find('[data-test-subj="inputControlEditorUpdateFiltersOnChangeCheckbox"] input[type="checkbox"]'); + checkbox.simulate('change', { target: { checked: true } }); + + expect(props.setValue).toHaveBeenCalledTimes(1); + expect(props.setValue).toHaveBeenCalledWith('updateFiltersOnChange', true); + }); + + it('should update useTimeFilter', () => { + const component = mountWithIntl(); + const checkbox = component.find('[data-test-subj="inputControlEditorUseTimeFilterCheckbox"] input[type="checkbox"]'); + checkbox.simulate('change', { target: { checked: true } }); + + expect(props.setValue).toHaveBeenCalledTimes(1); + expect(props.setValue).toHaveBeenCalledWith('useTimeFilter', true); + }); + + it('should update pinFilters', () => { + const component = mountWithIntl(); + const checkbox = component.find('[data-test-subj="inputControlEditorPinFiltersCheckbox"] input[type="checkbox"]'); + checkbox.simulate('change', { target: { checked: true } }); + + expect(props.setValue).toHaveBeenCalledTimes(1); + expect(props.setValue).toHaveBeenCalledWith('pinFilters', true); + }); -test('pinFilters', () => { - const component = mountWithIntl(); - const checkbox = component.find('[data-test-subj="inputControlEditorPinFiltersCheckbox"] input[type="checkbox"]'); - checkbox.simulate('change', { target: { checked: true } }); - const expectedParams = { - pinFilters: true - }; - sinon.assert.calledOnce(stageEditorParams); - sinon.assert.calledWith(stageEditorParams, sinon.match(expectedParams)); }); From 1092ca0aa662db6a5052731d6b403cacbc6af9bc Mon Sep 17 00:00:00 2001 From: sulemanof Date: Tue, 23 Jul 2019 17:19:30 +0300 Subject: [PATCH 3/3] Fix plugin functional test --- .../public/self_changing_vis/self_changing_editor.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/test/plugin_functional/plugins/kbn_tp_custom_visualizations/public/self_changing_vis/self_changing_editor.js b/test/plugin_functional/plugins/kbn_tp_custom_visualizations/public/self_changing_vis/self_changing_editor.js index d9f70096aa6e8..7b14ecf692ffa 100644 --- a/test/plugin_functional/plugins/kbn_tp_custom_visualizations/public/self_changing_vis/self_changing_editor.js +++ b/test/plugin_functional/plugins/kbn_tp_custom_visualizations/public/self_changing_vis/self_changing_editor.js @@ -27,16 +27,14 @@ import { export class SelfChangingEditor extends React.Component { onCounterChange = (ev) => { - this.props.stageEditorParams({ - counter: parseInt(ev.target.value), - }); + this.props.setValue('counter', parseInt(ev.target.value)); } render() { return (