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 <70410625+michael-s-molina@users.noreply.github.com> * Update superset-frontend/src/dashboard/components/DrillDetailPane/TableControls.test.tsx Co-authored-by: Michael S. Molina <70410625+michael-s-molina@users.noreply.github.com> * Update superset-frontend/src/dashboard/components/DrillDetailPane/TableControls.test.tsx Co-authored-by: Michael S. Molina <70410625+michael-s-molina@users.noreply.github.com> * Update superset-frontend/src/dashboard/components/DrillDetailPane/TableControls.test.tsx Co-authored-by: Michael S. Molina <70410625+michael-s-molina@users.noreply.github.com> * Update superset-frontend/src/dashboard/components/DrillDetailPane/TableControls.test.tsx Co-authored-by: Michael S. Molina <70410625+michael-s-molina@users.noreply.github.com> Co-authored-by: Michael S. Molina <70410625+michael-s-molina@users.noreply.github.com>
This commit is contained in:
parent
77f54585de
commit
1d3a805a61
|
|
@ -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',
|
||||
|
|
|
|||
|
|
@ -35,6 +35,11 @@ export default {
|
|||
sliceEntities: sliceEntitiesForChart,
|
||||
charts: chartQueries,
|
||||
nativeFilters: nativeFiltersInfo,
|
||||
common: {
|
||||
conf: {
|
||||
SAMPLES_ROW_LIMIT: 10,
|
||||
},
|
||||
},
|
||||
dataMask: mockDataMaskInfo,
|
||||
dashboardInfo,
|
||||
dashboardFilters: emptyFilters,
|
||||
|
|
|
|||
|
|
@ -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}`,
|
||||
);
|
||||
});
|
||||
|
|
@ -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();
|
||||
});
|
||||
|
|
@ -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([]);
|
||||
});
|
||||
|
|
@ -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();
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in New Issue