chore(fe): migrate 4 Enzyme-based tests to RTL (#31634)

Signed-off-by: hainenber <dotronghai96@gmail.com>
This commit is contained in:
Đỗ Trọng Hải 2025-02-11 23:01:59 +07:00 committed by GitHub
parent 3160607aaf
commit db70c7912c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 72 additions and 82 deletions

View File

@ -17,9 +17,9 @@
* under the License.
*/
import { mount, shallow } from 'enzyme';
import { triggerResizeObserver } from 'resize-observer-polyfill';
import { promiseTimeout, WithLegend } from '@superset-ui/core';
import { render } from '@testing-library/react';
let renderChart = jest.fn();
let renderLegend = jest.fn();
@ -32,18 +32,18 @@ describe.skip('WithLegend', () => {
});
it('sets className', () => {
const wrapper = shallow(
const { container } = render(
<WithLegend
className="test-class"
renderChart={renderChart}
renderLegend={renderLegend}
/>,
);
expect(wrapper.hasClass('test-class')).toEqual(true);
expect(container.querySelectorAll('.test-class')).toHaveLength(1);
});
it('renders when renderLegend is not set', () => {
const wrapper = mount(
const { container } = render(
<WithLegend
debounceTime={1}
width={500}
@ -56,13 +56,13 @@ describe.skip('WithLegend', () => {
// Have to delay more than debounceTime (1ms)
return promiseTimeout(() => {
expect(renderChart).toHaveBeenCalledTimes(1);
expect(wrapper.render().find('div.chart')).toHaveLength(1);
expect(wrapper.render().find('div.legend')).toHaveLength(0);
expect(container.querySelectorAll('div.chart')).toHaveLength(1);
expect(container.querySelectorAll('div.legend')).toHaveLength(0);
}, 100);
});
it('renders', () => {
const wrapper = mount(
const { container } = render(
<WithLegend
debounceTime={1}
width={500}
@ -77,13 +77,13 @@ describe.skip('WithLegend', () => {
return promiseTimeout(() => {
expect(renderChart).toHaveBeenCalledTimes(1);
expect(renderLegend).toHaveBeenCalledTimes(1);
expect(wrapper.render().find('div.chart')).toHaveLength(1);
expect(wrapper.render().find('div.legend')).toHaveLength(1);
expect(container.querySelectorAll('div.chart')).toHaveLength(1);
expect(container.querySelectorAll('div.legend')).toHaveLength(1);
}, 100);
});
it('renders without width or height', () => {
const wrapper = mount(
const { container } = render(
<WithLegend
debounceTime={1}
renderChart={renderChart}
@ -96,13 +96,13 @@ describe.skip('WithLegend', () => {
return promiseTimeout(() => {
expect(renderChart).toHaveBeenCalledTimes(1);
expect(renderLegend).toHaveBeenCalledTimes(1);
expect(wrapper.render().find('div.chart')).toHaveLength(1);
expect(wrapper.render().find('div.legend')).toHaveLength(1);
expect(container.querySelectorAll('div.chart')).toHaveLength(1);
expect(container.querySelectorAll('div.legend')).toHaveLength(1);
}, 100);
});
it('renders legend on the left', () => {
const wrapper = mount(
const { container } = render(
<WithLegend
debounceTime={1}
position="left"
@ -116,13 +116,13 @@ describe.skip('WithLegend', () => {
return promiseTimeout(() => {
expect(renderChart).toHaveBeenCalledTimes(1);
expect(renderLegend).toHaveBeenCalledTimes(1);
expect(wrapper.render().find('div.chart')).toHaveLength(1);
expect(wrapper.render().find('div.legend')).toHaveLength(1);
expect(container.querySelectorAll('div.chart')).toHaveLength(1);
expect(container.querySelectorAll('div.legend')).toHaveLength(1);
}, 100);
});
it('renders legend on the right', () => {
const wrapper = mount(
const { container } = render(
<WithLegend
debounceTime={1}
position="right"
@ -136,13 +136,13 @@ describe.skip('WithLegend', () => {
return promiseTimeout(() => {
expect(renderChart).toHaveBeenCalledTimes(1);
expect(renderLegend).toHaveBeenCalledTimes(1);
expect(wrapper.render().find('div.chart')).toHaveLength(1);
expect(wrapper.render().find('div.legend')).toHaveLength(1);
expect(container.querySelectorAll('div.chart')).toHaveLength(1);
expect(container.querySelectorAll('div.legend')).toHaveLength(1);
}, 100);
});
it('renders legend on the top', () => {
const wrapper = mount(
const { container } = render(
<WithLegend
debounceTime={1}
position="top"
@ -156,13 +156,13 @@ describe.skip('WithLegend', () => {
return promiseTimeout(() => {
expect(renderChart).toHaveBeenCalledTimes(1);
expect(renderLegend).toHaveBeenCalledTimes(1);
expect(wrapper.render().find('div.chart')).toHaveLength(1);
expect(wrapper.render().find('div.legend')).toHaveLength(1);
expect(container.querySelectorAll('div.chart')).toHaveLength(1);
expect(container.querySelectorAll('div.legend')).toHaveLength(1);
}, 100);
});
it('renders legend on the bottom', () => {
const wrapper = mount(
const { container } = render(
<WithLegend
debounceTime={1}
position="bottom"
@ -176,13 +176,13 @@ describe.skip('WithLegend', () => {
return promiseTimeout(() => {
expect(renderChart).toHaveBeenCalledTimes(1);
expect(renderLegend).toHaveBeenCalledTimes(1);
expect(wrapper.render().find('div.chart')).toHaveLength(1);
expect(wrapper.render().find('div.legend')).toHaveLength(1);
expect(container.querySelectorAll('div.chart')).toHaveLength(1);
expect(container.querySelectorAll('div.legend')).toHaveLength(1);
}, 100);
});
it('renders legend with justifyContent set', () => {
const wrapper = mount(
const { container } = render(
<WithLegend
debounceTime={1}
position="right"
@ -197,8 +197,8 @@ describe.skip('WithLegend', () => {
return promiseTimeout(() => {
expect(renderChart).toHaveBeenCalledTimes(1);
expect(renderLegend).toHaveBeenCalledTimes(1);
expect(wrapper.render().find('div.chart')).toHaveLength(1);
expect(wrapper.render().find('div.legend')).toHaveLength(1);
expect(container.querySelectorAll('div.chart')).toHaveLength(1);
expect(container.querySelectorAll('div.legend')).toHaveLength(1);
}, 100);
});
});

View File

@ -17,10 +17,11 @@
* under the License.
*/
import '@testing-library/jest-dom';
import PropTypes from 'prop-types';
import { PureComponent } from 'react';
import { mount } from 'enzyme';
import { reactify } from '@superset-ui/core';
import { render, screen } from '@testing-library/react';
import { RenderFuncType } from '../../../src/chart/components/reactify';
describe('reactify(renderFn)', () => {
@ -78,14 +79,18 @@ describe('reactify(renderFn)', () => {
it('returns a React component class', () =>
new Promise(done => {
const wrapper = mount(<TestComponent />);
render(<TestComponent />);
expect(renderFn).toHaveBeenCalledTimes(1);
expect(wrapper.html()).toEqual('<div id="test"><b>abc</b></div>');
expect(screen.getByText('abc')).toBeInTheDocument();
expect(screen.getByText('abc').parentNode).toHaveAttribute('id', 'test');
setTimeout(() => {
expect(renderFn).toHaveBeenCalledTimes(2);
expect(wrapper.html()).toEqual('<div id="test"><b>def</b></div>');
wrapper.unmount();
expect(screen.getByText('def')).toBeInTheDocument();
expect(screen.getByText('def').parentNode).toHaveAttribute(
'id',
'test',
);
done(undefined);
}, 20);
}));
@ -119,8 +124,9 @@ describe('reactify(renderFn)', () => {
describe('defaultProps', () => {
it('has defaultProps if renderFn.defaultProps is defined', () => {
expect(TheChart.defaultProps).toBe(renderFn.defaultProps);
const wrapper = mount(<TheChart id="test" />);
expect(wrapper.html()).toEqual('<div id="test"><b>ghi</b></div>');
render(<TheChart id="test" />);
expect(screen.getByText('ghi')).toBeInTheDocument();
expect(screen.getByText('ghi').parentNode).toHaveAttribute('id', 'test');
});
it('does not have defaultProps if renderFn.defaultProps is not defined', () => {
const AnotherChart = reactify(() => {});
@ -136,9 +142,9 @@ describe('reactify(renderFn)', () => {
});
it('calls willUnmount hook when it is provided', () =>
new Promise(done => {
const wrapper = mount(<AnotherTestComponent />);
const { unmount } = render(<AnotherTestComponent />);
setTimeout(() => {
wrapper.unmount();
unmount();
expect(willUnmountCb).toHaveBeenCalledTimes(1);
done(undefined);
}, 20);

View File

@ -16,8 +16,8 @@
* specific language governing permissions and limitations
* under the License.
*/
import { styledMount as mount } from 'spec/helpers/theming';
import { TableTab } from 'src/views/CRUD/types';
import { render, screen } from 'spec/helpers/testing-library';
import EmptyState, { EmptyStateProps } from './EmptyState';
import { WelcomeTable } from './types';
@ -65,29 +65,30 @@ describe('EmptyState', () => {
variants.forEach(variant => {
it(`renders an ${variant.tab} ${variant.tableName} empty state`, () => {
const wrapper = mount(<EmptyState {...variant} />);
expect(wrapper).toExist();
const { container } = render(<EmptyState {...variant} />);
// Select the first description node
const textContainer = wrapper.find('.ant-empty-description').at(0);
expect(textContainer.text()).toEqual('Nothing here yet');
expect(wrapper.find('button')).toHaveLength(1);
expect(
container.querySelector('.ant-empty-description'),
).toHaveTextContent('Nothing here yet');
expect(screen.getAllByRole('button')).toHaveLength(1);
});
});
recents.forEach(recent => {
it(`renders a ${recent.tab} ${recent.tableName} empty state`, () => {
const wrapper = mount(<EmptyState {...recent} />);
expect(wrapper).toExist();
const { container } = render(<EmptyState {...recent} />);
// Select the first description node
const textContainer = wrapper.find('.ant-empty-description').at(0);
// Check the correct text is displayed
expect(
container.querySelector('.ant-empty-description'),
).toHaveTextContent('Nothing here yet');
// Validate the image
expect(wrapper.find('.ant-empty-image').children()).toHaveLength(1);
// Check the correct text is displayed
expect(textContainer.text()).toContain(`Nothing here yet`);
expect(
container.querySelector('.ant-empty-image')?.children,
).toHaveLength(1);
});
});
});

View File

@ -17,24 +17,15 @@
* under the License.
*/
import fetchMock from 'fetch-mock';
import { Provider } from 'react-redux';
import configureStore from 'redux-mock-store';
import thunk from 'redux-thunk';
import { styledMount as mount } from 'spec/helpers/theming';
import waitForComponentToPaint from 'spec/helpers/waitForComponentToPaint';
import ListView from 'src/components/ListView';
import ExecutionLog from 'src/pages/ExecutionLogList';
// store needed for withToasts(ExecutionLog)
const mockStore = configureStore([thunk]);
const store = mockStore({});
import { render, screen } from 'spec/helpers/testing-library';
const executionLogsEndpoint = 'glob:*/api/v1/report/*/log*';
const reportEndpoint = 'glob:*/api/v1/report/*';
fetchMock.delete(executionLogsEndpoint, {});
const mockannotations = [...new Array(3)].map((_, i) => ({
const mockAnnotations = [...new Array(3)].map((_, i) => ({
end_dttm: new Date().toISOString,
error_message: `report ${i} error message`,
id: i,
@ -47,7 +38,7 @@ const mockannotations = [...new Array(3)].map((_, i) => ({
fetchMock.get(executionLogsEndpoint, {
ids: [2, 0, 1],
result: mockannotations,
result: mockAnnotations,
count: 3,
});
@ -61,30 +52,22 @@ jest.mock('react-router-dom', () => ({
useParams: () => ({ alertId: '1' }),
}));
async function mountAndWait(props) {
const mounted = mount(
<Provider store={store}>
<ExecutionLog {...props} />
</Provider>,
);
await waitForComponentToPaint(mounted);
return mounted;
}
const renderAndWait = (props = {}) =>
render(<ExecutionLog {...props} />, {
useRedux: true,
useQueryParams: true,
useRouter: true,
});
describe('ExecutionLog', () => {
let wrapper;
beforeAll(() => renderAndWait());
beforeAll(async () => {
wrapper = await mountAndWait();
});
it('renders', () => {
expect(wrapper.find(ExecutionLog)).toExist();
});
it('renders a ListView', () => {
expect(wrapper.find(ListView)).toExist();
it('renders with a ListView', () => {
expect(screen.getByText('Back to all')).toHaveAttribute(
'href',
'/alert/list/',
);
expect(screen.getByTestId('execution-log-list-view')).toBeVisible();
});
it('fetches report/alert', () => {