From 9156f089ffb96fe765d67766cc015cf3d7df2faa Mon Sep 17 00:00:00 2001
From: Geido <60598000+geido@users.noreply.github.com>
Date: Thu, 1 Apr 2021 09:14:51 +0300
Subject: [PATCH] test: Refactor and enhance tests for the Explore
DatasourcePanel Component (#13799)
* Refactor and enhance tests
* Fix linting issues
---
.../components/DatasourcePanel_spec.jsx | 127 --------------
.../DatasourcePanel/DatasourcePanel.test.tsx | 164 ++++++++++++++++++
.../components/DatasourcePanel/index.ts | 19 --
.../{DatasourcePanel.tsx => index.tsx} | 2 +-
4 files changed, 165 insertions(+), 147 deletions(-)
delete mode 100644 superset-frontend/spec/javascripts/explore/components/DatasourcePanel_spec.jsx
create mode 100644 superset-frontend/src/explore/components/DatasourcePanel/DatasourcePanel.test.tsx
delete mode 100644 superset-frontend/src/explore/components/DatasourcePanel/index.ts
rename superset-frontend/src/explore/components/DatasourcePanel/{DatasourcePanel.tsx => index.tsx} (99%)
diff --git a/superset-frontend/spec/javascripts/explore/components/DatasourcePanel_spec.jsx b/superset-frontend/spec/javascripts/explore/components/DatasourcePanel_spec.jsx
deleted file mode 100644
index c0ddb5b3db848..0000000000000
--- a/superset-frontend/spec/javascripts/explore/components/DatasourcePanel_spec.jsx
+++ /dev/null
@@ -1,127 +0,0 @@
-/**
- * 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 React from 'react';
-import { HTML5Backend } from 'react-dnd-html5-backend';
-import { DndProvider } from 'react-dnd';
-import { render, screen } from 'spec/helpers/testing-library';
-import userEvent from '@testing-library/user-event';
-import DatasourcePanel from 'src/explore/components/DatasourcePanel';
-import { columns, metrics } from 'spec/javascripts/datasource/fixtures';
-
-describe('datasourcepanel', () => {
- const datasource = {
- name: 'birth_names',
- type: 'table',
- uid: '1__table',
- id: 1,
- columns,
- metrics,
- database: {
- backend: 'mysql',
- name: 'main',
- },
- };
- const props = {
- datasource,
- controls: {
- datasource: {
- validationErrors: null,
- mapStateToProps: () => null,
- type: 'DatasourceControl',
- label: 'hello',
- datasource,
- },
- },
- actions: {},
- };
-
- const setup = props => (
-
-
-
- );
-
- function search(value, input) {
- userEvent.clear(input);
- userEvent.type(input, value);
- }
-
- it('should render', () => {
- const { container } = render(setup(props));
- expect(container).toBeVisible();
- });
-
- it('should display items in controls', () => {
- render(setup(props));
- expect(screen.getByText('birth_names')).toBeTruthy();
- expect(screen.getByText('Columns')).toBeTruthy();
- expect(screen.getByText('Metrics')).toBeTruthy();
- expect(screen.queryByTestId('warning')).not.toBeInTheDocument();
- });
-
- it('should render search results', () => {
- const { container } = render(setup(props));
- const c = container.getElementsByClassName('option-label');
-
- expect(c).toHaveLength(5);
- });
-
- it('should render 0 search results', () => {
- const { container } = render(setup(props));
- 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(setup(props));
- 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);
- });
-
- it('should render a warning', () => {
- const deprecatedDatasource = {
- ...datasource,
- extra: JSON.stringify({ warning_markdown: 'This is a warning.' }),
- };
- render(
- setup({
- ...props,
- datasource: deprecatedDatasource,
- controls: {
- datasource: {
- ...props.controls.datasource,
- datasource: deprecatedDatasource,
- },
- },
- }),
- );
- expect(screen.getByTestId('alert-solid')).toBeTruthy();
- });
-});
diff --git a/superset-frontend/src/explore/components/DatasourcePanel/DatasourcePanel.test.tsx b/superset-frontend/src/explore/components/DatasourcePanel/DatasourcePanel.test.tsx
new file mode 100644
index 0000000000000..c8f61ad3eb2bd
--- /dev/null
+++ b/superset-frontend/src/explore/components/DatasourcePanel/DatasourcePanel.test.tsx
@@ -0,0 +1,164 @@
+/**
+ * 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 React from 'react';
+import { HTML5Backend } from 'react-dnd-html5-backend';
+import { DndProvider } from 'react-dnd';
+import { render, screen, waitFor } from 'spec/helpers/testing-library';
+import userEvent from '@testing-library/user-event';
+import DatasourcePanel, {
+ Props as DatasourcePanelProps,
+} from 'src/explore/components/DatasourcePanel';
+import { columns, metrics } from 'spec/javascripts/datasource/fixtures';
+import { DatasourceType } from '@superset-ui/core/lib/query/types/Datasource';
+import DatasourceControl from 'src/explore/components/controls/DatasourceControl';
+
+const datasource = {
+ id: 1,
+ type: DatasourceType.Table,
+ name: 'birth_names',
+ columns,
+ metrics,
+ uid: '1__table',
+ database: {
+ backend: 'mysql',
+ name: 'main',
+ },
+ column_format: { ratio: '.2%' },
+ verbose_map: { __timestamp: 'Time' },
+ main_dttm_col: 'None',
+ datasource_name: 'table1',
+ description: 'desc',
+};
+const props = {
+ datasource,
+ controls: {
+ datasource: {
+ validationErrors: null,
+ mapStateToProps: () => ({ value: undefined }),
+ type: DatasourceControl,
+ label: 'hello',
+ datasource,
+ },
+ },
+ actions: {
+ setControlValue: () => ({
+ type: 'type',
+ controlName: 'control',
+ value: 'val',
+ validationErrors: [],
+ }),
+ },
+};
+
+const setup = (props: DatasourcePanelProps) => (
+
+
+
+);
+
+function search(value: string, input: HTMLElement) {
+ userEvent.clear(input);
+ userEvent.type(input, value);
+}
+
+test('should render', () => {
+ const { container } = render(setup(props));
+ expect(container).toBeVisible();
+});
+
+test('should display items in controls', () => {
+ render(setup(props));
+ expect(screen.getByText('birth_names')).toBeInTheDocument();
+ expect(screen.getByText('Metrics')).toBeInTheDocument();
+ expect(screen.getByText('Columns')).toBeInTheDocument();
+});
+
+test('should render the metrics', () => {
+ render(setup(props));
+ const metricsNum = metrics.length;
+ metrics.forEach(metric =>
+ expect(screen.getByText(metric.metric_name)).toBeInTheDocument(),
+ );
+ expect(
+ screen.getByText(`Showing ${metricsNum} of ${metricsNum}`),
+ ).toBeInTheDocument();
+});
+
+test('should render the columns', () => {
+ render(setup(props));
+ const columnsNum = columns.length;
+ columns.forEach(col =>
+ expect(screen.getByText(col.column_name)).toBeInTheDocument(),
+ );
+ expect(
+ screen.getByText(`Showing ${columnsNum} of ${columnsNum}`),
+ ).toBeInTheDocument();
+});
+
+test('should render 0 search results', async () => {
+ render(setup(props));
+ const searchInput = screen.getByPlaceholderText('Search Metrics & Columns');
+
+ search('nothing', searchInput);
+ expect(await screen.findByText('Showing 0 of 0')).toBeInTheDocument();
+});
+
+test('should search and render matching columns', async () => {
+ render(setup(props));
+ const searchInput = screen.getByPlaceholderText('Search Metrics & Columns');
+
+ search(columns[0].column_name, searchInput);
+
+ await waitFor(() => {
+ expect(screen.getByText(columns[0].column_name)).toBeInTheDocument();
+ expect(screen.queryByText(columns[1].column_name)).not.toBeInTheDocument();
+ });
+});
+
+test('should search and render matching metrics', async () => {
+ render(setup(props));
+ const searchInput = screen.getByPlaceholderText('Search Metrics & Columns');
+
+ search(metrics[0].metric_name, searchInput);
+
+ await waitFor(() => {
+ expect(screen.getByText(metrics[0].metric_name)).toBeInTheDocument();
+ expect(screen.queryByText(metrics[1].metric_name)).not.toBeInTheDocument();
+ });
+});
+
+test('should render a warning', () => {
+ const deprecatedDatasource = {
+ ...datasource,
+ extra: JSON.stringify({ warning_markdown: 'This is a warning.' }),
+ };
+ render(
+ setup({
+ ...props,
+ datasource: deprecatedDatasource,
+ controls: {
+ datasource: {
+ ...props.controls.datasource,
+ datasource: deprecatedDatasource,
+ },
+ },
+ }),
+ );
+ expect(screen.getByTestId('alert-solid')).toBeInTheDocument();
+});
diff --git a/superset-frontend/src/explore/components/DatasourcePanel/index.ts b/superset-frontend/src/explore/components/DatasourcePanel/index.ts
deleted file mode 100644
index 82a2573159641..0000000000000
--- a/superset-frontend/src/explore/components/DatasourcePanel/index.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
- * 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 { default } from './DatasourcePanel';
diff --git a/superset-frontend/src/explore/components/DatasourcePanel/DatasourcePanel.tsx b/superset-frontend/src/explore/components/DatasourcePanel/index.tsx
similarity index 99%
rename from superset-frontend/src/explore/components/DatasourcePanel/DatasourcePanel.tsx
rename to superset-frontend/src/explore/components/DatasourcePanel/index.tsx
index cd195d63d3f98..475601ac49d7d 100644
--- a/superset-frontend/src/explore/components/DatasourcePanel/DatasourcePanel.tsx
+++ b/superset-frontend/src/explore/components/DatasourcePanel/index.tsx
@@ -38,7 +38,7 @@ interface DatasourceControl extends ControlConfig {
datasource?: DatasourceMeta;
}
-interface Props {
+export interface Props {
datasource: DatasourceMeta;
controls: {
datasource: DatasourceControl;