You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by di...@apache.org on 2022/08/29 11:22:25 UTC

[superset] branch master updated: chore: Drill to detail Modal tests (#21148)

This is an automated email from the ASF dual-hosted git repository.

diegopucci pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/superset.git


The following commit(s) were added to refs/heads/master by this push:
     new 1d3a805a61 chore: Drill to detail Modal tests (#21148)
1d3a805a61 is described below

commit 1d3a805a6141c7458f70aca743e3f2a42f2c931b
Author: Geido <60...@users.noreply.github.com>
AuthorDate: Mon Aug 29 14:22:15 2022 +0300

    chore: Drill to detail Modal tests (#21148)
    
    * Add DrillDetailModal test
    
    * Add DrillDetailPane tests
    
    * Add TableControls test
    
    * Lint
    
    * Enhance SliceHeaderControls tests
    
    * Update superset-frontend/src/dashboard/components/DrillDetailPane/TableControls.test.tsx
    
    Co-authored-by: Michael S. Molina <70...@users.noreply.github.com>
    
    * Update superset-frontend/src/dashboard/components/DrillDetailPane/TableControls.test.tsx
    
    Co-authored-by: Michael S. Molina <70...@users.noreply.github.com>
    
    * Update superset-frontend/src/dashboard/components/DrillDetailPane/TableControls.test.tsx
    
    Co-authored-by: Michael S. Molina <70...@users.noreply.github.com>
    
    * Update superset-frontend/src/dashboard/components/DrillDetailPane/TableControls.test.tsx
    
    Co-authored-by: Michael S. Molina <70...@users.noreply.github.com>
    
    * Update superset-frontend/src/dashboard/components/DrillDetailPane/TableControls.test.tsx
    
    Co-authored-by: Michael S. Molina <70...@users.noreply.github.com>
    
    Co-authored-by: Michael S. Molina <70...@users.noreply.github.com>
---
 .../spec/fixtures/mockChartQueries.js              |   1 +
 superset-frontend/spec/fixtures/mockState.js       |   5 +
 .../src/components/Chart/DrillDetailModal.test.tsx | 110 ++++++++++++++++++
 .../DrillDetailPane/DrillDetailPane.test.tsx       | 124 +++++++++++++++++++++
 .../DrillDetailPane/TableControls.test.tsx         | 109 ++++++++++++++++++
 .../SliceHeaderControls.test.tsx                   |  20 ++++
 6 files changed, 369 insertions(+)

diff --git a/superset-frontend/spec/fixtures/mockChartQueries.js b/superset-frontend/spec/fixtures/mockChartQueries.js
index d25267392a..0175df981a 100644
--- a/superset-frontend/spec/fixtures/mockChartQueries.js
+++ b/superset-frontend/spec/fixtures/mockChartQueries.js
@@ -36,6 +36,7 @@ export default {
       datasource: datasourceId,
       viz_type: 'pie',
       slice_id: sliceId,
+      slice_name: 'Genders',
       granularity_sqla: null,
       time_grain_sqla: null,
       since: '100 years ago',
diff --git a/superset-frontend/spec/fixtures/mockState.js b/superset-frontend/spec/fixtures/mockState.js
index e492217e72..629ed775b4 100644
--- a/superset-frontend/spec/fixtures/mockState.js
+++ b/superset-frontend/spec/fixtures/mockState.js
@@ -35,6 +35,11 @@ export default {
   sliceEntities: sliceEntitiesForChart,
   charts: chartQueries,
   nativeFilters: nativeFiltersInfo,
+  common: {
+    conf: {
+      SAMPLES_ROW_LIMIT: 10,
+    },
+  },
   dataMask: mockDataMaskInfo,
   dashboardInfo,
   dashboardFilters: emptyFilters,
diff --git a/superset-frontend/src/components/Chart/DrillDetailModal.test.tsx b/superset-frontend/src/components/Chart/DrillDetailModal.test.tsx
new file mode 100644
index 0000000000..20f319ce4f
--- /dev/null
+++ b/superset-frontend/src/components/Chart/DrillDetailModal.test.tsx
@@ -0,0 +1,110 @@
+/**
+ * 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 { render, screen, waitFor } from 'spec/helpers/testing-library';
+import { getMockStoreWithNativeFilters } from 'spec/fixtures/mockStore';
+import chartQueries, { sliceId } from 'spec/fixtures/mockChartQueries';
+import { QueryFormData } from '@superset-ui/core';
+import fetchMock from 'fetch-mock';
+import userEvent from '@testing-library/user-event';
+import DrillDetailModal from './DrillDetailModal';
+
+const chart = chartQueries[sliceId];
+const setup = (overrides: Record<string, any> = {}) => {
+  const store = getMockStoreWithNativeFilters();
+  const props = {
+    chartId: sliceId,
+    initialFilters: [],
+    formData: chart.form_data as unknown as QueryFormData,
+    ...overrides,
+  };
+  return render(<DrillDetailModal {...props} />, {
+    useRedux: true,
+    useRouter: true,
+    store,
+  });
+};
+const waitForRender = (overrides: Record<string, any> = {}) =>
+  waitFor(() => setup(overrides));
+
+fetchMock.post(
+  'end:/datasource/samples?force=false&datasource_type=table&datasource_id=7&per_page=50&page=1',
+  {
+    result: {
+      data: [],
+      colnames: [],
+      coltypes: [],
+    },
+  },
+);
+
+const mockHistoryPush = jest.fn();
+jest.mock('react-router-dom', () => ({
+  ...jest.requireActual('react-router-dom'),
+  useHistory: () => ({
+    push: mockHistoryPush,
+  }),
+}));
+
+test('should render', async () => {
+  const { container } = await waitForRender();
+  expect(container).toBeInTheDocument();
+});
+
+test('should render the title', async () => {
+  await waitForRender();
+  expect(
+    screen.getByText(`Drill to detail: ${chart.form_data.slice_name}`),
+  ).toBeInTheDocument();
+});
+
+test('should render the modal', async () => {
+  await waitForRender();
+  expect(screen.getByRole('dialog')).toBeInTheDocument();
+});
+
+test('should not render the modal', async () => {
+  await waitForRender({
+    initialFilters: undefined,
+  });
+  expect(screen.queryByRole('dialog')).not.toBeInTheDocument();
+});
+
+test('should render the button', async () => {
+  await waitForRender();
+  expect(
+    screen.getByRole('button', { name: 'Edit chart' }),
+  ).toBeInTheDocument();
+  expect(screen.getAllByRole('button', { name: 'Close' })).toHaveLength(2);
+});
+
+test('should close the modal', async () => {
+  await waitForRender();
+  expect(screen.getByRole('dialog')).toBeInTheDocument();
+  userEvent.click(screen.getAllByRole('button', { name: 'Close' })[1]);
+  expect(screen.queryByRole('dialog')).not.toBeInTheDocument();
+});
+
+test('should forward to Explore', async () => {
+  await waitForRender();
+  userEvent.click(screen.getByRole('button', { name: 'Edit chart' }));
+  expect(mockHistoryPush).toHaveBeenCalledWith(
+    `/explore/?dashboard_page_id=&slice_id=${sliceId}`,
+  );
+});
diff --git a/superset-frontend/src/dashboard/components/DrillDetailPane/DrillDetailPane.test.tsx b/superset-frontend/src/dashboard/components/DrillDetailPane/DrillDetailPane.test.tsx
new file mode 100644
index 0000000000..a65d469fb0
--- /dev/null
+++ b/superset-frontend/src/dashboard/components/DrillDetailPane/DrillDetailPane.test.tsx
@@ -0,0 +1,124 @@
+/**
+ * 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 { render, screen, waitFor } from 'spec/helpers/testing-library';
+import { getMockStoreWithNativeFilters } from 'spec/fixtures/mockStore';
+import chartQueries, { sliceId } from 'spec/fixtures/mockChartQueries';
+import { QueryFormData, SupersetClient } from '@superset-ui/core';
+import fetchMock from 'fetch-mock';
+import DrillDetailPane from './DrillDetailPane';
+
+const chart = chartQueries[sliceId];
+const setup = (overrides: Record<string, any> = {}) => {
+  const store = getMockStoreWithNativeFilters();
+  const props = {
+    initialFilters: [],
+    formData: chart.form_data as unknown as QueryFormData,
+    ...overrides,
+  };
+  return render(<DrillDetailPane {...props} />, {
+    useRedux: true,
+    store,
+  });
+};
+const waitForRender = (overrides: Record<string, any> = {}) =>
+  waitFor(() => setup(overrides));
+const samplesEndpoint =
+  'end:/datasource/samples?force=false&datasource_type=table&datasource_id=7&per_page=50&page=1';
+const fetchWithNoData = () =>
+  fetchMock.post(samplesEndpoint, {
+    result: {
+      total_count: 0,
+      data: [],
+      colnames: [],
+      coltypes: [],
+    },
+  });
+const fetchWithData = () =>
+  fetchMock.post(samplesEndpoint, {
+    result: {
+      total_count: 3,
+      data: [
+        {
+          year: 1996,
+          na_sales: 11.27,
+          eu_sales: 8.89,
+        },
+        {
+          year: 1989,
+          na_sales: 23.2,
+          eu_sales: 2.26,
+        },
+        {
+          year: 1999,
+          na_sales: 9,
+          eu_sales: 6.18,
+        },
+      ],
+      colnames: ['year', 'na_sales', 'eu_sales'],
+      coltypes: [0, 0, 0],
+    },
+  });
+const SupersetClientPost = jest.spyOn(SupersetClient, 'post');
+
+afterEach(fetchMock.restore);
+
+test('should render', async () => {
+  fetchWithNoData();
+  const { container } = await waitForRender();
+  expect(container).toBeInTheDocument();
+});
+
+test('should render the loading component', async () => {
+  fetchWithData();
+  setup();
+  await waitFor(() => {
+    expect(screen.getByRole('status', { name: 'Loading' })).toBeInTheDocument();
+  });
+});
+
+test('should render the table with results', async () => {
+  fetchWithData();
+  await waitForRender();
+  expect(screen.getByRole('table')).toBeInTheDocument();
+  expect(screen.getAllByRole('row')).toHaveLength(4);
+  expect(
+    screen.getByRole('columnheader', { name: 'year' }),
+  ).toBeInTheDocument();
+  expect(
+    screen.getByRole('columnheader', { name: 'na_sales' }),
+  ).toBeInTheDocument();
+  expect(
+    screen.getByRole('columnheader', { name: 'eu_sales' }),
+  ).toBeInTheDocument();
+});
+
+test('should render the "No results" components', async () => {
+  fetchWithNoData();
+  setup();
+  expect(
+    await screen.findByText('No rows were returned for this dataset'),
+  ).toBeInTheDocument();
+});
+
+test('should render the error', async () => {
+  SupersetClientPost.mockRejectedValue(new Error('Something went wrong'));
+  await waitForRender();
+  expect(screen.getByText('Error: Something went wrong')).toBeInTheDocument();
+});
diff --git a/superset-frontend/src/dashboard/components/DrillDetailPane/TableControls.test.tsx b/superset-frontend/src/dashboard/components/DrillDetailPane/TableControls.test.tsx
new file mode 100644
index 0000000000..0768d0ec73
--- /dev/null
+++ b/superset-frontend/src/dashboard/components/DrillDetailPane/TableControls.test.tsx
@@ -0,0 +1,109 @@
+/**
+ * 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 { render, screen } from 'spec/helpers/testing-library';
+import userEvent from '@testing-library/user-event';
+import TableControls from './TableControls';
+
+const setFilters = jest.fn();
+const onReload = jest.fn();
+const setup = (overrides: Record<string, any> = {}) => {
+  const props = {
+    filters: [],
+    setFilters,
+    onReload,
+    loading: false,
+    totalCount: 0,
+    ...overrides,
+  };
+  return render(<TableControls {...props} />);
+};
+test('should render', () => {
+  const { container } = setup();
+  expect(container).toBeInTheDocument();
+});
+
+test('should show 0 rows', () => {
+  setup();
+  expect(screen.getByText('0 rows')).toBeInTheDocument();
+});
+
+test('should show the correct amount of rows', () => {
+  setup({
+    totalCount: 10,
+  });
+  expect(screen.getByText('10 rows')).toBeInTheDocument();
+});
+
+test('should render the reload button', () => {
+  setup();
+  expect(screen.getByRole('button', { name: 'Reload' })).toBeInTheDocument();
+});
+
+test('should show the loading indicator', () => {
+  setup({
+    loading: true,
+  });
+  expect(screen.getByText('Loading...')).toBeInTheDocument();
+});
+
+test('should call onreload', () => {
+  setup();
+  userEvent.click(screen.getByRole('button', { name: 'Reload' }));
+  expect(onReload).toHaveBeenCalledTimes(1);
+});
+
+test('should render with filters', () => {
+  setup({
+    filters: [
+      {
+        col: 'platform',
+        op: '==',
+        val: 'GB',
+      },
+      {
+        col: 'lang',
+        op: '==',
+        val: 'IT',
+      },
+    ],
+  });
+  expect(screen.getByText('platform')).toBeInTheDocument();
+  expect(screen.getByText('GB')).toBeInTheDocument();
+  expect(screen.getByText('lang')).toBeInTheDocument();
+  expect(screen.getByText('IT')).toBeInTheDocument();
+});
+
+test('should remove the filters on close', () => {
+  setup({
+    filters: [
+      {
+        col: 'platform',
+        op: '==',
+        val: 'GB',
+      },
+    ],
+  });
+  expect(screen.getByText('platform')).toBeInTheDocument();
+  expect(screen.getByText('GB')).toBeInTheDocument();
+
+  userEvent.click(screen.getByRole('img', { name: 'close' }));
+
+  expect(setFilters).toHaveBeenCalledWith([]);
+});
diff --git a/superset-frontend/src/dashboard/components/SliceHeaderControls/SliceHeaderControls.test.tsx b/superset-frontend/src/dashboard/components/SliceHeaderControls/SliceHeaderControls.test.tsx
index 514ff4fc2c..455afb6039 100644
--- a/superset-frontend/src/dashboard/components/SliceHeaderControls/SliceHeaderControls.test.tsx
+++ b/superset-frontend/src/dashboard/components/SliceHeaderControls/SliceHeaderControls.test.tsx
@@ -236,3 +236,23 @@ test('Should "Enter fullscreen"', () => {
   userEvent.click(screen.getByText('Enter fullscreen'));
   expect(props.handleToggleFullSize).toBeCalledTimes(1);
 });
+
+test('Drill to detail modal is under featureflag', () => {
+  // @ts-ignore
+  global.featureFlags = {
+    [FeatureFlag.DRILL_TO_DETAIL]: false,
+  };
+  const props = createProps();
+  renderWrapper(props);
+  expect(screen.queryByText('Drill to detail')).not.toBeInTheDocument();
+});
+
+test('Should show the "Drill to detail"', () => {
+  // @ts-ignore
+  global.featureFlags = {
+    [FeatureFlag.DRILL_TO_DETAIL]: true,
+  };
+  const props = createProps();
+  renderWrapper(props);
+  expect(screen.getByText('Drill to detail')).toBeInTheDocument();
+});