refactor(Homepage): Migrate Home.test to RTL (#29353)

This commit is contained in:
Ross Mabbett 2024-06-25 17:58:26 -04:00 committed by GitHub
parent d74d3a87bb
commit b5a72e21f7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 92 additions and 135 deletions

View File

@ -16,23 +16,14 @@
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*/ */
import { styledMount as mount } from 'spec/helpers/theming';
import { Provider } from 'react-redux';
import thunk from 'redux-thunk';
import fetchMock from 'fetch-mock'; import fetchMock from 'fetch-mock';
import { act } from 'react-dom/test-utils';
import configureStore from 'redux-mock-store';
import * as uiCore from '@superset-ui/core'; import * as uiCore from '@superset-ui/core';
import { render, screen, waitFor } from 'spec/helpers/testing-library';
import userEvent from '@testing-library/user-event';
import Welcome from 'src/pages/Home'; import Welcome from 'src/pages/Home';
import { ReactWrapper } from 'enzyme';
import waitForComponentToPaint from 'spec/helpers/waitForComponentToPaint';
import { render, screen } from 'spec/helpers/testing-library';
import { getExtensionsRegistry } from '@superset-ui/core'; import { getExtensionsRegistry } from '@superset-ui/core';
import setupExtensions from 'src/setup/setupExtensions'; import setupExtensions from 'src/setup/setupExtensions';
const mockStore = configureStore([thunk]);
const store = mockStore({});
const chartsEndpoint = 'glob:*/api/v1/chart/?*'; const chartsEndpoint = 'glob:*/api/v1/chart/?*';
const chartInfoEndpoint = 'glob:*/api/v1/chart/_info?*'; const chartInfoEndpoint = 'glob:*/api/v1/chart/_info?*';
const chartFavoriteStatusEndpoint = 'glob:*/api/v1/chart/favorite_status?*'; const chartFavoriteStatusEndpoint = 'glob:*/api/v1/chart/favorite_status?*';
@ -113,130 +104,104 @@ const mockedProps = {
}, },
}; };
describe('Welcome with sql role', () => { const mockedPropsWithoutSqlRole = {
let wrapper: ReactWrapper; ...{
...mockedProps,
user: {
...mockedProps.user,
roles: {},
},
},
};
beforeAll(async () => { const setupFeatureToggleMock = () =>
await act(async () => { jest.spyOn(uiCore, 'isFeatureEnabled').mockReturnValue(true);
wrapper = mount(
<Provider store={store}> const renderWelcome = (props = mockedProps) =>
<Welcome {...mockedProps} /> waitFor(() => {
</Provider>, render(<Welcome {...props} />, {
); useRedux: true,
useRouter: true,
}); });
}); });
afterAll(() => { afterEach(() => {
fetchMock.resetHistory(); fetchMock.resetHistory();
});
it('renders', () => {
expect(wrapper).toExist();
});
it('renders all panels on the page on page load', () => {
expect(wrapper.find('CollapsePanel')).toHaveLength(8);
});
it('calls api methods in parallel on page load', () => {
const chartCall = fetchMock.calls(/chart\/\?q/);
const savedQueryCall = fetchMock.calls(/saved_query\/\?q/);
const recentCall = fetchMock.calls(/api\/v1\/log\/recent_activity\/*/);
const dashboardCall = fetchMock.calls(/dashboard\/\?q/);
expect(chartCall).toHaveLength(2);
expect(recentCall).toHaveLength(1);
expect(savedQueryCall).toHaveLength(1);
expect(dashboardCall).toHaveLength(2);
});
}); });
describe('Welcome without sql role', () => { test('With sql role - renders', async () => {
let wrapper: ReactWrapper; await renderWelcome();
expect(await screen.findByText('Dashboards')).toBeInTheDocument();
beforeAll(async () => {
await act(async () => {
const props = {
...mockedProps,
user: {
...mockedProps.user,
roles: {},
},
};
wrapper = mount(
<Provider store={store}>
<Welcome {...props} />
</Provider>,
);
});
});
afterAll(() => {
fetchMock.resetHistory();
fetchMock.restore();
});
it('renders', () => {
expect(wrapper).toExist();
});
it('renders all panels on the page on page load', () => {
expect(wrapper.find('CollapsePanel')).toHaveLength(6);
});
it('calls api methods in parallel on page load', () => {
const chartCall = fetchMock.calls(/chart\/\?q/);
const savedQueryCall = fetchMock.calls(/saved_query\/\?q/);
const recentCall = fetchMock.calls(/api\/v1\/log\/recent_activity\/*/);
const dashboardCall = fetchMock.calls(/dashboard\/\?q/);
expect(chartCall).toHaveLength(2);
expect(recentCall).toHaveLength(1);
expect(savedQueryCall).toHaveLength(0);
expect(dashboardCall).toHaveLength(2);
});
}); });
async function mountAndWait(props = mockedProps) { test('With sql role - renders all panels on the page on page load', async () => {
const wrapper = mount( await renderWelcome();
<Provider store={store}> const panels = await screen.findAllByText(
<Welcome {...props} /> /Dashboards|Charts|Recents|Saved queries/,
</Provider>,
); );
await waitForComponentToPaint(wrapper); expect(panels).toHaveLength(4);
return wrapper;
}
describe('Welcome page with toggle switch', () => {
let wrapper: ReactWrapper;
let isFeatureEnabledMock: any;
beforeAll(async () => {
isFeatureEnabledMock = jest
.spyOn(uiCore, 'isFeatureEnabled')
.mockReturnValue(true);
await act(async () => {
wrapper = await mountAndWait();
});
});
afterAll(() => {
isFeatureEnabledMock.mockRestore();
});
it('shows a toggle button when feature flags is turned on', async () => {
await waitForComponentToPaint(wrapper);
expect(wrapper.find('Switch')).toExist();
});
it('does not show thumbnails when switch is off', async () => {
act(() => {
// @ts-ignore
wrapper.find('button[role="switch"]').props().onClick();
});
await waitForComponentToPaint(wrapper);
expect(wrapper.find('ImageLoader')).not.toExist();
});
}); });
test('should render an extension component if one is supplied', () => { test('With sql role - calls api methods in parallel on page load', async () => {
await renderWelcome();
expect(fetchMock.calls(chartsEndpoint)).toHaveLength(2);
expect(fetchMock.calls(recentActivityEndpoint)).toHaveLength(1);
expect(fetchMock.calls(savedQueryEndpoint)).toHaveLength(1);
expect(fetchMock.calls(dashboardsEndpoint)).toHaveLength(2);
});
test('Without sql role - renders', async () => {
/*
We ignore the ts error here because the type does not recognize the absence of a role entry
*/
// @ts-ignore-next-line
await renderWelcome(mockedPropsWithoutSqlRole);
expect(await screen.findByText('Dashboards')).toBeInTheDocument();
});
test('Without sql role - renders all panels on the page on page load', async () => {
// @ts-ignore-next-line
await renderWelcome(mockedPropsWithoutSqlRole);
const panels = await screen.findAllByText(/Dashboards|Charts|Recents/);
expect(panels).toHaveLength(3);
});
test('Without sql role - calls api methods in parallel on page load', async () => {
// @ts-ignore-next-line
await renderWelcome(mockedPropsWithoutSqlRole);
expect(fetchMock.calls(chartsEndpoint)).toHaveLength(2);
expect(fetchMock.calls(recentActivityEndpoint)).toHaveLength(1);
expect(fetchMock.calls(savedQueryEndpoint)).toHaveLength(0);
expect(fetchMock.calls(dashboardsEndpoint)).toHaveLength(2);
});
// Mock specific to the tests related to the toggle switch
fetchMock.get('glob:*/api/v1/dashboard/*', {
result: {
dashboard_title: 'Dashboard 4',
changed_on_utc: '24 Feb 2014 10:13:14',
url: '/fakeUrl/dashboard/4',
id: '4',
},
});
test('With toggle switch - shows a toggle button when feature flag is turned on', async () => {
setupFeatureToggleMock();
await renderWelcome();
expect(screen.getByRole('switch')).toBeInTheDocument();
});
test('With toggle switch - does not show thumbnails when switch is off', async () => {
setupFeatureToggleMock();
await renderWelcome();
const toggle = await screen.findByRole('switch');
userEvent.click(toggle);
expect(screen.queryByAltText('Thumbnails')).not.toBeInTheDocument();
});
test('Should render an extension component if one is supplied', async () => {
const extensionsRegistry = getExtensionsRegistry(); const extensionsRegistry = getExtensionsRegistry();
extensionsRegistry.set('welcome.banner', () => ( extensionsRegistry.set('welcome.banner', () => (
@ -245,29 +210,21 @@ test('should render an extension component if one is supplied', () => {
setupExtensions(); setupExtensions();
render( await renderWelcome();
<Provider store={store}>
<Welcome {...mockedProps} />
</Provider>,
);
expect( expect(
screen.getByText('welcome.banner extension component'), screen.getByText('welcome.banner extension component'),
).toBeInTheDocument(); ).toBeInTheDocument();
}); });
test('should render a submenu extension component if one is supplied', () => { test('Should render a submenu extension component if one is supplied', async () => {
const extensionsRegistry = getExtensionsRegistry(); const extensionsRegistry = getExtensionsRegistry();
extensionsRegistry.set('home.submenu', () => <>submenu extension</>); extensionsRegistry.set('home.submenu', () => <>submenu extension</>);
setupExtensions(); setupExtensions();
render( await renderWelcome();
<Provider store={store}>
<Welcome {...mockedProps} />
</Provider>,
);
expect(screen.getByText('submenu extension')).toBeInTheDocument(); expect(screen.getByText('submenu extension')).toBeInTheDocument();
}); });