You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by rt...@apache.org on 2024/06/25 21:58:32 UTC

(superset) branch master updated: refactor(Homepage): Migrate Home.test to RTL (#29353)

This is an automated email from the ASF dual-hosted git repository.

rtmabbz pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/superset.git


The following commit(s) were added to refs/heads/master by this push:
     new b5a72e21f7 refactor(Homepage): Migrate Home.test to RTL (#29353)
b5a72e21f7 is described below

commit b5a72e21f73808bcca94341f5a904753a589e67b
Author: Ross Mabbett <92...@users.noreply.github.com>
AuthorDate: Tue Jun 25 17:58:26 2024 -0400

    refactor(Homepage): Migrate Home.test to RTL (#29353)
---
 superset-frontend/src/pages/Home/Home.test.tsx | 213 ++++++++++---------------
 1 file changed, 85 insertions(+), 128 deletions(-)

diff --git a/superset-frontend/src/pages/Home/Home.test.tsx b/superset-frontend/src/pages/Home/Home.test.tsx
index 6a63483be5..6be4dc186e 100644
--- a/superset-frontend/src/pages/Home/Home.test.tsx
+++ b/superset-frontend/src/pages/Home/Home.test.tsx
@@ -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?*';
@@ -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', () => (
@@ -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();
 });