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

refactor(frontend): migrate 6 Enzyme-based tests to RTL, part 2 #30281

Merged
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@
* under the License.
*/

import '@testing-library/jest-dom';
import { ComponentType } from 'react';
import { shallow } from 'enzyme';
import mockConsole, { RestoreConsole } from 'jest-mock-console';
import { render as renderTestComponent, screen } from '@testing-library/react';
import createLoadableRenderer, {
LoadableRenderer as LoadableRendererType,
} from '../../../src/chart/components/createLoadableRenderer';
Expand Down Expand Up @@ -67,7 +68,7 @@ describe('createLoadableRenderer', () => {
it('calls onRenderSuccess when succeeds', async () => {
const onRenderSuccess = jest.fn();
const onRenderFailure = jest.fn();
shallow(
renderTestComponent(
<LoadableRenderer
onRenderSuccess={onRenderSuccess}
onRenderFailure={onRenderFailure}
Expand Down Expand Up @@ -95,7 +96,7 @@ describe('createLoadableRenderer', () => {
});
const onRenderSuccess = jest.fn();
const onRenderFailure = jest.fn();
shallow(
renderTestComponent(
<FailedRenderer
onRenderSuccess={onRenderSuccess}
onRenderFailure={onRenderFailure}
Expand All @@ -122,7 +123,7 @@ describe('createLoadableRenderer', () => {
loading,
render,
});
shallow(<FailedRenderer />);
renderTestComponent(<FailedRenderer />);
expect(loadChartFailure).toHaveBeenCalledTimes(1);
setTimeout(() => {
expect(render).not.toHaveBeenCalled();
Expand All @@ -132,12 +133,12 @@ describe('createLoadableRenderer', () => {

it('renders the lazy-load components', () =>
new Promise(done => {
const wrapper = shallow(<LoadableRenderer />);
renderTestComponent(<LoadableRenderer />);
// lazy-loaded component not rendered immediately
expect(wrapper.find(TestComponent)).toHaveLength(0);
expect(screen.queryByText('test')).not.toBeInTheDocument();
setTimeout(() => {
// but rendered after the component is loaded.
expect(wrapper.find(TestComponent)).toHaveLength(1);
expect(screen.queryByText('test')).toBeInTheDocument();
done(undefined);
}, 10);
}));
Expand All @@ -149,7 +150,7 @@ describe('createLoadableRenderer', () => {
render: () => <div />,
});

expect(() => shallow(<NeverLoadingRenderer />)).not.toThrow();
expect(() => renderTestComponent(<NeverLoadingRenderer />)).not.toThrow();
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
* under the License.
*/

import { mount } from 'enzyme';
import {
styled,
supersetTheme,
Expand All @@ -27,6 +26,7 @@ import {
EmotionCacheProvider,
emotionCache,
} from '@superset-ui/core';
import { render } from '@testing-library/react';

describe('@superset-ui/style package', () => {
it('exports a theme', () => {
Expand All @@ -50,8 +50,8 @@ describe('@superset-ui/style package', () => {
expect(useTheme()).toStrictEqual(supersetTheme);
return <div>test</div>;
}
mount(<ThemeUser />, {
wrappingComponent: ({ children }) => (
render(<ThemeUser />, {
wrapper: ({ children }) => (
<EmotionCacheProvider value={emotionCache}>
<ThemeProvider theme={supersetTheme}>{children}</ThemeProvider>
</EmotionCacheProvider>
Expand All @@ -64,8 +64,8 @@ describe('@superset-ui/style package', () => {
expect(useTheme).toThrow(/could not find a ThemeContext/);
return <div>test</div>;
}
mount(<ThemeUser />, {
wrappingComponent: ({ children }) => <div>{children}</div>,
render(<ThemeUser />, {
wrapper: ({ children }) => <div>{children}</div>,
});
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
* under the License.
*/
import { isValidElement } from 'react';
import { styledMount as mount } from 'spec/helpers/theming';
import { render } from 'spec/helpers/testing-library';
import ColumnElement from 'src/SqlLab/components/ColumnElement';
import { mockedActions, table } from 'src/SqlLab/fixtures';

Expand All @@ -30,19 +30,25 @@ describe('ColumnElement', () => {
expect(isValidElement(<ColumnElement {...mockedProps} />)).toBe(true);
});
it('renders a proper primary key', () => {
const wrapper = mount(<ColumnElement column={table.columns[0]} />);
expect(wrapper.find('i.fa-key')).toExist();
expect(wrapper.find('.col-name').first().text()).toBe('id');
const { container } = render(<ColumnElement column={table.columns[0]} />);
expect(container.querySelector('i.fa-key')).toBeInTheDocument();
expect(container.querySelector('.col-name')?.firstChild).toHaveTextContent(
'id',
);
});
it('renders a multi-key column', () => {
const wrapper = mount(<ColumnElement column={table.columns[1]} />);
expect(wrapper.find('i.fa-link')).toExist();
expect(wrapper.find('i.fa-bookmark')).toExist();
expect(wrapper.find('.col-name').first().text()).toBe('first_name');
const { container } = render(<ColumnElement column={table.columns[1]} />);
expect(container.querySelector('i.fa-link')).toBeInTheDocument();
expect(container.querySelector('i.fa-bookmark')).toBeInTheDocument();
expect(container.querySelector('.col-name')?.firstChild).toHaveTextContent(
'first_name',
);
});
it('renders a column with no keys', () => {
const wrapper = mount(<ColumnElement column={table.columns[2]} />);
expect(wrapper.find('i')).not.toExist();
expect(wrapper.find('.col-name').first().text()).toBe('last_name');
const { container } = render(<ColumnElement column={table.columns[2]} />);
expect(container.querySelector('i')).not.toBeInTheDocument();
expect(container.querySelector('.col-name')?.firstChild).toHaveTextContent(
'last_name',
);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -16,24 +16,18 @@
* specific language governing permissions and limitations
* under the License.
*/
import sinon from 'sinon';
import configureStore from 'redux-mock-store';
import { mount, shallow } from 'enzyme';
import { DatasourceType } from '@superset-ui/core';
import {
supersetTheme,
ThemeProvider,
DatasourceType,
} from '@superset-ui/core';
import { Menu } from 'src/components/Menu';
import {
DatasourceModal,
ChangeDatasourceModal,
} from 'src/components/Datasource';
fireEvent,
waitFor,
screen,
render,
} from 'spec/helpers/testing-library';
import userEvent from '@testing-library/user-event';
import DatasourceControl, {
getDatasourceTitle,
} from 'src/explore/components/controls/DatasourceControl';
import Icons from 'src/components/Icons';
import { Tooltip } from 'src/components/Tooltip';

const defaultProps = {
name: 'datasource',
Expand All @@ -54,9 +48,9 @@ const defaultProps = {
health_check_message: 'Warning message!',
},
actions: {
setDatasource: sinon.spy(),
setDatasource: jest.fn(),
},
onChange: sinon.spy(),
onChange: jest.fn(),
user: {
createdOn: '2021-04-27T18:12:38.952304',
email: 'admin',
Expand All @@ -71,59 +65,74 @@ const defaultProps = {
};

describe('DatasourceControl', () => {
function setup(overrideProps) {
const setup = (overrideProps = {}) => {
const mockStore = configureStore([]);
const store = mockStore({});
const props = {
...defaultProps,
...overrideProps,
};
return mount(<DatasourceControl {...props} />, {
context: { store },
wrappingComponent: ThemeProvider,
wrappingComponentProps: { theme: supersetTheme },
});
}
return {
rendered: render(<DatasourceControl {...props} />, {
useRedux: true,
useRouter: true,
store,
}),
store,
props,
};
};

it('should not render Modal', () => {
const wrapper = setup();
expect(wrapper.find(DatasourceModal)).toHaveLength(0);
setup();
expect(screen.queryByRole('dialog')).not.toBeInTheDocument();
});

it('should not render ChangeDatasourceModal', () => {
const wrapper = setup();
expect(wrapper.find(ChangeDatasourceModal)).toHaveLength(0);
setup();
expect(screen.queryByTestId('Swap dataset-modal')).not.toBeInTheDocument();
});

it('show or hide Edit Datasource option', () => {
let wrapper = setup();
expect(wrapper.find('[data-test="datasource-menu"]')).toExist();
let menuWrapper = shallow(
<div>
{wrapper.find('[data-test="datasource-menu"]').first().prop('overlay')}
</div>,
);
expect(menuWrapper.find(Menu.Item)).toHaveLength(3);
it('show or hide Edit Datasource option', async () => {
const {
rendered: { container, rerender },
store,
props,
} = setup();
expect(
container.querySelector('[data-test="datasource-menu-trigger"]'),
).toBeInTheDocument();
userEvent.click(screen.getByLabelText('more-vert'));
await waitFor(() => {
expect(screen.queryAllByRole('menuitem')).toHaveLength(3);
});

wrapper = setup({
isEditable: false,
rerender(<DatasourceControl {...{ ...props, isEditable: false }} />, {
useRedux: true,
useRouter: true,
store,
});
expect(
container.querySelector('[data-test="datasource-menu-trigger"]'),
).toBeInTheDocument();
userEvent.click(screen.getByLabelText('more-vert'));
await waitFor(() => {
expect(screen.queryAllByRole('menuitem')).toHaveLength(2);
});
expect(wrapper.find('[data-test="datasource-menu"]')).toExist();
menuWrapper = shallow(
<div>
{wrapper.find('[data-test="datasource-menu"]').first().prop('overlay')}
</div>,
);
expect(menuWrapper.find(Menu.Item)).toHaveLength(2);
});

it('should render health check message', () => {
const wrapper = setup();
expect(wrapper.find(Icons.AlertSolid)).toExist();
const tooltip = wrapper.find(Tooltip).at(0);
expect(tooltip.prop('title')).toBe(
defaultProps.datasource.health_check_message,
);
it('should render health check message', async () => {
setup();
const modalTrigger = screen.getByLabelText('alert-solid');
expect(modalTrigger).toBeInTheDocument();

// Hover the modal so healthcheck message can show up
fireEvent.mouseOver(modalTrigger);
await waitFor(() => {
expect(
screen.getByText(defaultProps.datasource.health_check_message),
).toBeInTheDocument();
});
});

it('Gets Datasource Title', () => {
Expand Down
Loading
Loading