Skip to content

Commit

Permalink
refactor(Homepage): Migrate Home.test to RTL (apache#29353)
Browse files Browse the repository at this point in the history
  • Loading branch information
rtexelm authored Jun 25, 2024
1 parent d74d3a8 commit b5a72e2
Showing 1 changed file with 85 additions and 128 deletions.
213 changes: 85 additions & 128 deletions superset-frontend/src/pages/Home/Home.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,14 @@
* specific language governing permissions and limitations
* 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 { act } from 'react-dom/test-utils';
import configureStore from 'redux-mock-store';
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 { ReactWrapper } from 'enzyme';
import waitForComponentToPaint from 'spec/helpers/waitForComponentToPaint';
import { render, screen } from 'spec/helpers/testing-library';
import { getExtensionsRegistry } from '@superset-ui/core';
import setupExtensions from 'src/setup/setupExtensions';

const mockStore = configureStore([thunk]);
const store = mockStore({});

const chartsEndpoint = 'glob:*/api/v1/chart/?*';
const chartInfoEndpoint = 'glob:*/api/v1/chart/_info?*';
const chartFavoriteStatusEndpoint = 'glob:*/api/v1/chart/favorite_status?*';
Expand Down Expand Up @@ -113,130 +104,104 @@ const mockedProps = {
},
};

describe('Welcome with sql role', () => {
let wrapper: ReactWrapper;
const mockedPropsWithoutSqlRole = {
...{
...mockedProps,
user: {
...mockedProps.user,
roles: {},
},
},
};

beforeAll(async () => {
await act(async () => {
wrapper = mount(
<Provider store={store}>
<Welcome {...mockedProps} />
</Provider>,
);
});
});
const setupFeatureToggleMock = () =>
jest.spyOn(uiCore, 'isFeatureEnabled').mockReturnValue(true);

afterAll(() => {
fetchMock.resetHistory();
const renderWelcome = (props = mockedProps) =>
waitFor(() => {
render(<Welcome {...props} />, {
useRedux: true,
useRouter: true,
});
});

it('renders', () => {
expect(wrapper).toExist();
});
afterEach(() => {
fetchMock.resetHistory();
});

it('renders all panels on the page on page load', () => {
expect(wrapper.find('CollapsePanel')).toHaveLength(8);
});
test('With sql role - renders', async () => {
await renderWelcome();
expect(await screen.findByText('Dashboards')).toBeInTheDocument();
});

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);
});
test('With sql role - renders all panels on the page on page load', async () => {
await renderWelcome();
const panels = await screen.findAllByText(
/Dashboards|Charts|Recents|Saved queries/,
);
expect(panels).toHaveLength(4);
});

describe('Welcome without sql role', () => {
let wrapper: ReactWrapper;

beforeAll(async () => {
await act(async () => {
const props = {
...mockedProps,
user: {
...mockedProps.user,
roles: {},
},
};
wrapper = mount(
<Provider store={store}>
<Welcome {...props} />
</Provider>,
);
});
});
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);
});

afterAll(() => {
fetchMock.resetHistory();
fetchMock.restore();
});
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();
});

it('renders', () => {
expect(wrapper).toExist();
});
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);
});

it('renders all panels on the page on page load', () => {
expect(wrapper.find('CollapsePanel')).toHaveLength(6);
});
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);
});

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);
});
// 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',
},
});

async function mountAndWait(props = mockedProps) {
const wrapper = mount(
<Provider store={store}>
<Welcome {...props} />
</Provider>,
);
await waitForComponentToPaint(wrapper);
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();
});
});
test('With toggle switch - shows a toggle button when feature flag is turned on', async () => {
setupFeatureToggleMock();

afterAll(() => {
isFeatureEnabledMock.mockRestore();
});
await renderWelcome();
expect(screen.getByRole('switch')).toBeInTheDocument();
});

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('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', () => {
test('Should render an extension component if one is supplied', async () => {
const extensionsRegistry = getExtensionsRegistry();

extensionsRegistry.set('welcome.banner', () => (
Expand All @@ -245,29 +210,21 @@ test('should render an extension component if one is supplied', () => {

setupExtensions();

render(
<Provider store={store}>
<Welcome {...mockedProps} />
</Provider>,
);
await renderWelcome();

expect(
screen.getByText('welcome.banner extension component'),
).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();

extensionsRegistry.set('home.submenu', () => <>submenu extension</>);

setupExtensions();

render(
<Provider store={store}>
<Welcome {...mockedProps} />
</Provider>,
);
await renderWelcome();

expect(screen.getByText('submenu extension')).toBeInTheDocument();
});

0 comments on commit b5a72e2

Please sign in to comment.