From dfe030b835bddeeb53346ef056dba28d09e7af49 Mon Sep 17 00:00:00 2001 From: Einat Bertenthal Date: Tue, 25 May 2021 18:41:53 +0300 Subject: [PATCH] feat: chart gallery search improvement (#14484) * feat: chart gallery search improvement * test: adding unit test for VizTypeControl * fix: lint errors Co-authored-by: einatnielsen --- .../{ => VizTypeControl}/VizTypeControl.less | 2 +- .../VizTypeControl/VizTypeControl.test.tsx | 111 ++++++++++++++++++ .../index.jsx} | 20 +++- 3 files changed, 128 insertions(+), 5 deletions(-) rename superset-frontend/src/explore/components/controls/{ => VizTypeControl}/VizTypeControl.less (95%) create mode 100644 superset-frontend/src/explore/components/controls/VizTypeControl/VizTypeControl.test.tsx rename superset-frontend/src/explore/components/controls/{VizTypeControl.jsx => VizTypeControl/index.jsx} (90%) diff --git a/superset-frontend/src/explore/components/controls/VizTypeControl.less b/superset-frontend/src/explore/components/controls/VizTypeControl/VizTypeControl.less similarity index 95% rename from superset-frontend/src/explore/components/controls/VizTypeControl.less rename to superset-frontend/src/explore/components/controls/VizTypeControl/VizTypeControl.less index 3a9e44f3e1..e9faf8bcd3 100644 --- a/superset-frontend/src/explore/components/controls/VizTypeControl.less +++ b/superset-frontend/src/explore/components/controls/VizTypeControl/VizTypeControl.less @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -@import '../../../../stylesheets/less/variables.less'; +@import '../../../../../stylesheets/less/variables.less'; .viztype-label { margin-top: 10px; diff --git a/superset-frontend/src/explore/components/controls/VizTypeControl/VizTypeControl.test.tsx b/superset-frontend/src/explore/components/controls/VizTypeControl/VizTypeControl.test.tsx new file mode 100644 index 0000000000..35dd245bb6 --- /dev/null +++ b/superset-frontend/src/explore/components/controls/VizTypeControl/VizTypeControl.test.tsx @@ -0,0 +1,111 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF 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 { Preset } from '@superset-ui/core'; +import { render, cleanup, screen } from 'spec/helpers/testing-library'; +import { Provider } from 'react-redux'; +import { + getMockStore, + mockStore, + stateWithoutNativeFilters, +} from 'spec/fixtures/mockStore'; +import React from 'react'; +import userEvent from '@testing-library/user-event'; +import { testWithId } from 'src/utils/testUtils'; +import { + EchartsMixedTimeseriesChartPlugin, + EchartsTimeseriesChartPlugin, +} from '@superset-ui/plugin-chart-echarts/lib'; +import { LineChartPlugin } from '@superset-ui/preset-chart-xy/lib'; +import TimeTableChartPlugin from '../../../../visualizations/TimeTable/TimeTableChartPlugin'; +import VizTypeControl, { VIZ_TYPE_CONTROL_TEST_ID } from './index'; + +jest.useFakeTimers(); + +class MainPreset extends Preset { + constructor() { + super({ + name: 'Legacy charts', + plugins: [ + new LineChartPlugin().configure({ key: 'line' }), + new EchartsTimeseriesChartPlugin().configure({ + key: 'echarts_timeseries', + }), + new TimeTableChartPlugin().configure({ key: 'time_table' }), + new EchartsMixedTimeseriesChartPlugin().configure({ + key: 'mixed_timeseries', + }), + ], + }); + } +} + +const getTestId = testWithId(VIZ_TYPE_CONTROL_TEST_ID, true); + +describe('VizTypeControl', () => { + new MainPreset().register(); + const newVizTypeControlProps = { + description: '', + label: '', + name: '', + value: '', + labelType: '', + onChange: jest.fn(), + }; + + const renderWrapper = ( + props = newVizTypeControlProps, + state: object = stateWithoutNativeFilters, + ) => + render( + + + , + ); + + afterEach(() => { + cleanup(); + jest.clearAllMocks(); + }); + + it('Search visualization type', async () => { + renderWrapper(); + + const visualizations = screen.getByTestId(getTestId('viz-row')); + + expect(visualizations).toHaveTextContent(/Time-series Table/); + expect(visualizations).toHaveTextContent(/Time-series Chart/); + expect(visualizations).toHaveTextContent(/Mixed timeseries chart/); + expect(visualizations).toHaveTextContent(/Line Chart/); + + const searchInputText = 'time series'; + + // search + userEvent.type( + screen.getByTestId(getTestId('search-input')), + searchInputText, + ); + + expect(visualizations).toHaveTextContent(/Time-series Table/); + expect(visualizations).toHaveTextContent(/Time-series Chart/); + expect(visualizations).toHaveTextContent(/Mixed timeseries chart/); + expect(visualizations).not.toHaveTextContent(/Line Chart/); + }); +}); diff --git a/superset-frontend/src/explore/components/controls/VizTypeControl.jsx b/superset-frontend/src/explore/components/controls/VizTypeControl/index.jsx similarity index 90% rename from superset-frontend/src/explore/components/controls/VizTypeControl.jsx rename to superset-frontend/src/explore/components/controls/VizTypeControl/index.jsx index f6ea3fff56..e720cbdd4f 100644 --- a/superset-frontend/src/explore/components/controls/VizTypeControl.jsx +++ b/superset-frontend/src/explore/components/controls/VizTypeControl/index.jsx @@ -93,6 +93,8 @@ const DEFAULT_ORDER = [ const typesWithDefaultOrder = new Set(DEFAULT_ORDER); +export const VIZ_TYPE_CONTROL_TEST_ID = 'viz-type-control'; + function VizSupportValidation({ vizType }) { const state = useDynamicPluginContext(); if (state.loading || registry.has(vizType)) { @@ -153,7 +155,10 @@ const VizTypeControl = props => { className={`viztype-selector ${isSelected ? 'selected' : ''}`} src={type.thumbnail} /> -
+
{type.name}
@@ -162,8 +167,10 @@ const VizTypeControl = props => { const { value, labelType } = props; const filterString = filter.toLowerCase(); + const filterStringParts = filterString.split(' '); - const filteredTypes = DEFAULT_ORDER.filter(type => registry.has(type)) + const a = DEFAULT_ORDER.filter(type => registry.has(type)); + const filteredTypes = a .filter(type => { const behaviors = registry.get(type)?.behaviors || []; return nativeFilterGate(behaviors); @@ -181,7 +188,11 @@ const VizTypeControl = props => { }) .filter(({ key }) => !typesWithDefaultOrder.has(key)), ) - .filter(entry => entry.value.name.toLowerCase().includes(filterString)); + .filter(entry => + filterStringParts.every( + part => entry.value.name.toLowerCase().indexOf(part) !== -1, + ), + ); return (
@@ -217,9 +228,10 @@ const VizTypeControl = props => { value={filter} placeholder={t('Search')} onChange={changeSearch} + data-test={`${VIZ_TYPE_CONTROL_TEST_ID}__search-input`} />
- + {filteredTypes.map(entry => ( {renderItem(entry)}