Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(dashboard): migrate enzyme to RTL #26260

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
125 changes: 71 additions & 54 deletions superset-frontend/src/dashboard/components/DashboardGrid.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,77 +17,94 @@
* under the License.
*/
import React from 'react';
import { shallow } from 'enzyme';
import sinon from 'sinon';
import { fireEvent, render } from 'spec/helpers/testing-library';

import DashboardComponent from 'src/dashboard/containers/DashboardComponent';
import DashboardGrid from 'src/dashboard/components/DashboardGrid';
import DragDroppable from 'src/dashboard/components/dnd/DragDroppable';
import newComponentFactory from 'src/dashboard/util/newComponentFactory';

import { DASHBOARD_GRID_TYPE } from 'src/dashboard/util/componentTypes';
import { GRID_COLUMN_COUNT } from 'src/dashboard/util/constants';

describe('DashboardGrid', () => {
const props = {
depth: 1,
editMode: false,
gridComponent: {
...newComponentFactory(DASHBOARD_GRID_TYPE),
children: ['a'],
},
handleComponentDrop() {},
resizeComponent() {},
width: 500,
isComponentVisible: true,
setDirectPathToChild() {},
};
const args = { id: 'id', widthMultiple: 1, heightMultiple: 3 };

function setup(overrideProps) {
const wrapper = shallow(<DashboardGrid {...props} {...overrideProps} />);
return wrapper;
}
jest.mock(
'src/dashboard/containers/DashboardComponent',
() =>
({ onResizeStart, onResizeStop }) =>
(
<button
type="button"
data-test="mock-dashboard-component"
onClick={() => onResizeStart()}
onBlur={() => onResizeStop(args)}
>
Mock
</button>
),
);

it('should render a div with class "dashboard-grid"', () => {
const wrapper = setup();
expect(wrapper.find('.dashboard-grid')).toExist();
});
const props = {
depth: 1,
editMode: false,
gridComponent: {
...newComponentFactory(DASHBOARD_GRID_TYPE),
children: ['a'],
},
handleComponentDrop() {},
resizeComponent() {},
width: 500,
isComponentVisible: true,
setDirectPathToChild() {},
};

it('should render one DashboardComponent for each gridComponent child', () => {
const wrapper = setup({
gridComponent: { ...props.gridComponent, children: ['a', 'b'] },
});
expect(wrapper.find(DashboardComponent)).toHaveLength(2);
function setup(overrideProps) {
return render(<DashboardGrid {...props} {...overrideProps} />, {
useRedux: true,
useDnd: true,
});
}

test('should render a div with class "dashboard-grid"', () => {
const { container } = setup();
expect(container.querySelector('.dashboard-grid')).toBeInTheDocument();
});

it('should render two empty DragDroppables in editMode to increase the drop target zone', () => {
const viewMode = setup({ editMode: false });
const editMode = setup({ editMode: true });
expect(viewMode.find(DragDroppable)).toHaveLength(0);
expect(editMode.find(DragDroppable)).toHaveLength(2);
test('should render one DashboardComponent for each gridComponent child', () => {
const { getAllByTestId } = setup({
gridComponent: { ...props.gridComponent, children: ['a', 'b'] },
});
expect(getAllByTestId('mock-dashboard-component')).toHaveLength(2);
});

it('should render grid column guides when resizing', () => {
const wrapper = setup({ editMode: true });
expect(wrapper.find('.grid-column-guide')).not.toExist();
test('should render two empty DragDroppables in editMode to increase the drop target zone', () => {
const { queryAllByTestId } = setup({ editMode: false });
expect(queryAllByTestId('dragdroppable-object').length).toEqual(0);
const { getAllByTestId } = setup({ editMode: true });
expect(getAllByTestId('dragdroppable-object').length).toEqual(2);
});

wrapper.setState({ isResizing: true });
test('should render grid column guides when resizing', () => {
const { container, getAllByTestId } = setup({ editMode: true });
expect(container.querySelector('.grid-column-guide')).not.toBeInTheDocument();

expect(wrapper.find('.grid-column-guide')).toHaveLength(GRID_COLUMN_COUNT);
});
// map handleResizeStart to the onClick prop of the mock DashboardComponent
fireEvent.click(getAllByTestId('mock-dashboard-component')[0]);

expect(container.querySelectorAll('.grid-column-guide')).toHaveLength(
GRID_COLUMN_COUNT,
);
});

it('should call resizeComponent when a child DashboardComponent calls resizeStop', () => {
const resizeComponent = sinon.spy();
const args = { id: 'id', widthMultiple: 1, heightMultiple: 3 };
const wrapper = setup({ resizeComponent });
const dashboardComponent = wrapper.find(DashboardComponent).first();
dashboardComponent.prop('onResizeStop')(args);
test('should call resizeComponent when a child DashboardComponent calls resizeStop', () => {
const resizeComponent = jest.fn();
const { getAllByTestId } = setup({ resizeComponent });
const dashboardComponent = getAllByTestId('mock-dashboard-component')[0];
fireEvent.blur(dashboardComponent);

expect(resizeComponent.callCount).toBe(1);
expect(resizeComponent.getCall(0).args[0]).toEqual({
id: 'id',
width: 1,
height: 3,
});
expect(resizeComponent).toHaveBeenCalledTimes(1);
expect(resizeComponent).toHaveBeenCalledWith({
id: 'id',
width: 1,
height: 3,
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,8 @@
* under the License.
*/
import React from 'react';
import { shallow } from 'enzyme';
import { Provider } from 'react-redux';
import { Store } from 'redux';
import * as SupersetUI from '@superset-ui/core';
import { styledMount as mount } from 'spec/helpers/theming';
import { render } from 'spec/helpers/testing-library';
import {
CHART_RENDERING_SUCCEEDED,
CHART_UPDATE_SUCCEEDED,
Expand All @@ -36,123 +33,105 @@ import { sliceId } from 'spec/fixtures/mockChartQueries';
import { dashboardFilters } from 'spec/fixtures/mockDashboardFilters';
import { dashboardWithFilter } from 'spec/fixtures/mockDashboardLayout';

jest.mock(
'src/dashboard/components/FiltersBadge/DetailsPanel',
() =>
({ children }: { children: React.ReactNode }) =>
<div data-test="mock-details-panel">{children}</div>,
);

const defaultStore = getMockStoreWithFilters();
function setup(store: Store = defaultStore) {
return mount(
<Provider store={store}>
<FiltersBadge chartId={sliceId} />
</Provider>,
);
return render(<FiltersBadge chartId={sliceId} />, { store });
}

describe('FiltersBadge', () => {
// there's this bizarre "active filters" thing
// that doesn't actually use any kind of state management.
// Have to set variables in there.
buildActiveFilters({
dashboardFilters,
components: dashboardWithFilter,
});

beforeEach(() => {
// shallow rendering in enzyme doesn't propagate contexts correctly,
// so we have to mock the hook.
// See https://medium.com/7shifts-engineering-blog/testing-usecontext-react-hook-with-enzyme-shallow-da062140fc83
jest
.spyOn(SupersetUI, 'useTheme')
.mockImplementation(() => SupersetUI.supersetTheme);
});
// there's this bizarre "active filters" thing
// that doesn't actually use any kind of state management.
// Have to set variables in there.
buildActiveFilters({
dashboardFilters,
components: dashboardWithFilter,
});

describe('for dashboard filters', () => {
it("doesn't show number when there are no active filters", () => {
const store = getMockStoreWithFilters();
// start with basic dashboard state, dispatch an event to simulate query completion
store.dispatch({
type: CHART_UPDATE_SUCCEEDED,
key: sliceId,
queriesResponse: [
{
status: 'success',
applied_filters: [],
rejected_filters: [],
},
],
dashboardFilters,
});
const wrapper = shallow(
<Provider store={store}>
<FiltersBadge chartId={sliceId} />,
</Provider>,
);
expect(wrapper.find('[data-test="applied-filter-count"]')).not.toExist();
describe('for dashboard filters', () => {
test('does not show number when there are no active filters', () => {
const store = getMockStoreWithFilters();
// start with basic dashboard state, dispatch an event to simulate query completion
store.dispatch({
type: CHART_UPDATE_SUCCEEDED,
key: sliceId,
queriesResponse: [
{
status: 'success',
applied_filters: [],
rejected_filters: [],
},
],
dashboardFilters,
});
const { queryByTestId } = setup(store);
expect(queryByTestId('applied-filter-count')).not.toBeInTheDocument();
});

it('shows the indicator when filters have been applied', () => {
const store = getMockStoreWithFilters();
// start with basic dashboard state, dispatch an event to simulate query completion
store.dispatch({
type: CHART_UPDATE_SUCCEEDED,
key: sliceId,
queriesResponse: [
{
status: 'success',
applied_filters: [{ column: 'region' }],
rejected_filters: [],
},
],
dashboardFilters,
});
store.dispatch({ type: CHART_RENDERING_SUCCEEDED, key: sliceId });
const wrapper = setup(store);
expect(wrapper.find('DetailsPanelPopover')).toExist();
expect(
wrapper.find('[data-test="applied-filter-count"] .current'),
).toHaveText('1');
expect(wrapper.find('WarningFilled')).not.toExist();
test('shows the indicator when filters have been applied', () => {
const store = getMockStoreWithFilters();
// start with basic dashboard state, dispatch an event to simulate query completion
store.dispatch({
type: CHART_UPDATE_SUCCEEDED,
key: sliceId,
queriesResponse: [
{
status: 'success',
applied_filters: [{ column: 'region' }],
rejected_filters: [],
},
],
dashboardFilters,
});
store.dispatch({ type: CHART_RENDERING_SUCCEEDED, key: sliceId });
const { getByTestId } = setup(store);
expect(getByTestId('applied-filter-count')).toHaveTextContent('1');
expect(getByTestId('mock-details-panel')).toBeInTheDocument();
});
});

describe('for native filters', () => {
it("doesn't show number when there are no active filters", () => {
const store = getMockStoreWithNativeFilters();
// start with basic dashboard state, dispatch an event to simulate query completion
store.dispatch({
type: CHART_UPDATE_SUCCEEDED,
key: sliceId,
queriesResponse: [
{
status: 'success',
applied_filters: [],
rejected_filters: [],
},
],
});
store.dispatch({ type: CHART_RENDERING_SUCCEEDED, key: sliceId });
const wrapper = setup(store);
expect(wrapper.find('[data-test="applied-filter-count"]')).not.toExist();
describe('for native filters', () => {
test('does not show number when there are no active filters', () => {
const store = getMockStoreWithNativeFilters();
// start with basic dashboard state, dispatch an event to simulate query completion
store.dispatch({
type: CHART_UPDATE_SUCCEEDED,
key: sliceId,
queriesResponse: [
{
status: 'success',
applied_filters: [],
rejected_filters: [],
},
],
});
store.dispatch({ type: CHART_RENDERING_SUCCEEDED, key: sliceId });
const { queryByTestId } = setup(store);
expect(queryByTestId('applied-filter-count')).not.toBeInTheDocument();
});

it('shows the indicator when filters have been applied', () => {
const store = getMockStoreWithNativeFilters();
// start with basic dashboard state, dispatch an event to simulate query completion
store.dispatch({
type: CHART_UPDATE_SUCCEEDED,
key: sliceId,
queriesResponse: [
{
status: 'success',
applied_filters: [{ column: 'region' }],
rejected_filters: [],
},
],
});
store.dispatch({ type: CHART_RENDERING_SUCCEEDED, key: sliceId });
const wrapper = setup(store);
expect(wrapper.find('DetailsPanelPopover')).toExist();
expect(
wrapper.find('[data-test="applied-filter-count"] .current'),
).toHaveText('1');
expect(wrapper.find('WarningFilled')).not.toExist();
test('shows the indicator when filters have been applied', () => {
const store = getMockStoreWithNativeFilters();
// start with basic dashboard state, dispatch an event to simulate query completion
store.dispatch({
type: CHART_UPDATE_SUCCEEDED,
key: sliceId,
queriesResponse: [
{
status: 'success',
applied_filters: [{ column: 'region' }],
rejected_filters: [],
},
],
});
store.dispatch({ type: CHART_RENDERING_SUCCEEDED, key: sliceId });
const { getByTestId } = setup(store);
expect(getByTestId('applied-filter-count')).toHaveTextContent('1');
expect(getByTestId('mock-details-panel')).toBeInTheDocument();
});
});
Loading
Loading