diff --git a/superset-frontend/spec/javascripts/datasource/fixtures.tsx b/superset-frontend/spec/javascripts/datasource/fixtures.tsx new file mode 100644 index 0000000000..115b5716b0 --- /dev/null +++ b/superset-frontend/spec/javascripts/datasource/fixtures.tsx @@ -0,0 +1,93 @@ +/** + * 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. + */ +export const columns = [ + { + column_name: 'bootcamp_attend', + description: null, + expression: null, + filterable: true, + groupby: true, + id: 516, + is_dttm: false, + python_date_format: null, + type: 'DOUBLE PRECISION', + verbose_name: null, + }, + { + column_name: 'calc_first_time_dev', + description: null, + expression: + 'CASE WHEN is_first_dev_job = 0 THEN "No" WHEN is_first_dev_job = 1 THEN "Yes" END', + filterable: true, + groupby: true, + id: 477, + is_dttm: false, + python_date_format: null, + type: 'STRING', + verbose_name: null, + }, + { + column_name: 'aaaaaaaaaaa', + description: null, + expression: null, + filterable: true, + groupby: true, + id: 516, + is_dttm: false, + python_date_format: null, + type: 'DOUBLE PRECISION', + verbose_name: null, + }, +]; + +const metricsFiltered = { + certified: [ + { + certification_details: null, + certified_by: 'user', + d3format: null, + description: null, + expression: '', + id: 56, + is_certified: true, + metric_name: 'metric_end_certified', + verbose_name: '', + warning_text: null, + }, + ], + uncertified: [ + { + certification_details: null, + certified_by: null, + d3format: null, + description: null, + expression: '', + id: 57, + is_certified: false, + metric_name: 'metric_end', + verbose_name: '', + warning_text: null, + }, + ], +}; + +export const metrics = [ + ...metricsFiltered.certified, + ...metricsFiltered.uncertified, +]; diff --git a/superset-frontend/spec/javascripts/explore/components/DatasourcePanel_spec.jsx b/superset-frontend/spec/javascripts/explore/components/DatasourcePanel_spec.jsx index 784e105814..f9c09603dc 100644 --- a/superset-frontend/spec/javascripts/explore/components/DatasourcePanel_spec.jsx +++ b/superset-frontend/spec/javascripts/explore/components/DatasourcePanel_spec.jsx @@ -17,9 +17,11 @@ * under the License. */ import React from 'react'; -import { render, screen } from '@testing-library/react'; +import { Simulate } from 'react-dom/test-utils'; +import { render, screen, fireEvent } from '@testing-library/react'; import { supersetTheme, ThemeProvider } from '@superset-ui/core'; import DatasourcePanel from 'src/explore/components/DatasourcePanel'; +import { columns, metrics } from 'spec/javascripts/datasource/fixtures'; describe('datasourcepanel', () => { const datasource = { @@ -27,8 +29,8 @@ describe('datasourcepanel', () => { type: 'table', uid: '1__table', id: 1, - columns: [], - metrics: [], + columns, + metrics, database: { backend: 'mysql', name: 'main', @@ -47,6 +49,14 @@ describe('datasourcepanel', () => { }, actions: {}, }; + + function search(value, input) { + fireEvent.change(input, { + target: { value }, + }); + Simulate.change(input); + } + it('should render', () => { const { container } = render( @@ -66,4 +76,46 @@ describe('datasourcepanel', () => { expect(screen.getByText('Columns')).toBeTruthy(); expect(screen.getByText('Metrics')).toBeTruthy(); }); + + it('should render search results', () => { + const { container } = render( + + + , + ); + const c = container.getElementsByClassName('option-label'); + + expect(c).toHaveLength(5); + }); + + it('should render 0 search results', () => { + const { container } = render( + + + , + ); + const c = container.getElementsByClassName('option-label'); + const searchInput = screen.getByPlaceholderText('Search Metrics & Columns'); + + search('sssssssss', searchInput); + setTimeout(() => { + expect(c).toHaveLength(0); + }, 201); + }); + + it('should render and sort search results', () => { + const { container } = render( + + + , + ); + const c = container.getElementsByClassName('option-label'); + const searchInput = screen.getByPlaceholderText('Search Metrics & Columns'); + + search('end', searchInput); + setTimeout(() => { + expect(c).toHaveLength(4); + expect(c[0].value).toBe('metric_end_certified'); + }, 201); + }); }); diff --git a/superset-frontend/src/explore/components/DatasourcePanel.tsx b/superset-frontend/src/explore/components/DatasourcePanel.tsx index 7beebd2d7c..143550c276 100644 --- a/superset-frontend/src/explore/components/DatasourcePanel.tsx +++ b/superset-frontend/src/explore/components/DatasourcePanel.tsx @@ -117,31 +117,43 @@ export default function DataSourcePanel({ setList({ columns: matchSorter(columns, value, { keys: [ - 'verbose_name', - 'column_name', { - key: 'description', + key: 'verbose_name', threshold: rankings.CONTAINS, }, { - key: 'expression', + key: 'column_name', threshold: rankings.CONTAINS, }, + { + key: item => + [item.description, item.expression].map( + x => x?.replace(/[_\n\s]+/g, ' ') || '', + ), + threshold: rankings.CONTAINS, + maxRanking: rankings.CONTAINS, + }, ], keepDiacritics: true, }), metrics: matchSorter(metrics, value, { keys: [ - 'verbose_name', - 'metric_name', { - key: 'description', + key: 'verbose_name', threshold: rankings.CONTAINS, }, { - key: 'expression', + key: 'metric_name', threshold: rankings.CONTAINS, }, + { + key: item => + [item.description, item.expression].map( + x => x?.replace(/[_\n\s]+/g, ' ') || '', + ), + threshold: rankings.CONTAINS, + maxRanking: rankings.CONTAINS, + }, ], keepDiacritics: true, baseSort: (a, b) =>