From 235670244e71301fc8c58f48b95e4b0d6b5d8382 Mon Sep 17 00:00:00 2001 From: Ross Mabbett <92495987+rtexelm@users.noreply.github.com> Date: Fri, 22 Mar 2024 17:21:55 -0400 Subject: [PATCH] test(Migration to RTL): Refactor ActivityTable.test.tsx from Enzyme to RTL (#27422) --- .../src/features/home/ActivityTable.test.tsx | 137 +++++++++--------- .../src/features/home/ChartTable.test.tsx | 12 +- 2 files changed, 76 insertions(+), 73 deletions(-) diff --git a/superset-frontend/src/features/home/ActivityTable.test.tsx b/superset-frontend/src/features/home/ActivityTable.test.tsx index 65ef15ee2ae61..6400dc37e1fe1 100644 --- a/superset-frontend/src/features/home/ActivityTable.test.tsx +++ b/superset-frontend/src/features/home/ActivityTable.test.tsx @@ -17,19 +17,12 @@ * under the License. */ import React from 'react'; -import { styledMount as mount } from 'spec/helpers/theming'; -import { act } from 'react-dom/test-utils'; -import { ReactWrapper } from 'enzyme'; -import { Provider } from 'react-redux'; +import { render, screen, waitFor } from 'spec/helpers/testing-library'; import fetchMock from 'fetch-mock'; -import thunk from 'redux-thunk'; -import configureStore from 'redux-mock-store'; import { TableTab } from 'src/views/CRUD/types'; +import userEvent from '@testing-library/user-event'; import ActivityTable from './ActivityTable'; -const mockStore = configureStore([thunk]); -const store = mockStore({}); - const chartsEndpoint = 'glob:*/api/v1/chart/?*'; const dashboardsEndpoint = 'glob:*/api/v1/dashboard/?*'; @@ -76,64 +69,78 @@ fetchMock.get(dashboardsEndpoint, { ], }); -describe('ActivityTable', () => { - const activityProps = { - activeChild: TableTab.Created, - activityData: mockData, - setActiveChild: jest.fn(), - user: { userId: '1' }, - isFetchingActivityData: false, - }; +const mockSetActiveChild = jest.fn(); - let wrapper: ReactWrapper; +const activityProps = { + activeChild: TableTab.Created, + activityData: mockData, + setActiveChild: mockSetActiveChild, + user: { userId: '1' }, + isFetchingActivityData: false, +}; - beforeAll(async () => { - await act(async () => { - wrapper = mount( - - - , - ); - }); - }); +const activityEditedTabProps = { + activeChild: TableTab.Edited, + activityData: mockData, + setActiveChild: mockSetActiveChild, + user: { userId: '1' }, + isFetchingActivityData: false, +}; - it('the component renders', () => { - expect(wrapper.find(ActivityTable)).toExist(); - }); - it('renders tabs with three buttons', () => { - expect(wrapper.find('[role="tab"]')).toHaveLength(3); - }); - it('renders ActivityCards', async () => { - expect(wrapper.find('ListViewCard')).toExist(); - }); - it('calls the getEdited batch call when edited tab is clicked', async () => { - act(() => { - const handler = wrapper.find('[role="tab"] a').at(1).prop('onClick'); - if (handler) { - handler({} as any); - } - }); - const dashboardCall = fetchMock.calls(/dashboard\/\?q/); - const chartCall = fetchMock.calls(/chart\/\?q/); - // waitforcomponenttopaint does not work here in this instance... - setTimeout(() => { - expect(chartCall).toHaveLength(1); - expect(dashboardCall).toHaveLength(1); - }); - }); - it('show empty state if there is no data', () => { - const activityProps = { - activeChild: TableTab.Created, - activityData: {}, - setActiveChild: jest.fn(), - user: { userId: '1' }, - isFetchingActivityData: false, - }; - const wrapper = mount( - - - , - ); - expect(wrapper.find('EmptyState')).toExist(); +const activityViewedTabProps = { + activeChild: TableTab.Viewed, + activityData: mockData, + setActiveChild: mockSetActiveChild, + user: { userId: '1' }, + isFetchingActivityData: false, +}; + +const emptyActivityProps = { + activeChild: TableTab.Created, + activityData: {}, + setActiveChild: mockSetActiveChild, + user: { userId: '1' }, + isFetchingActivityData: false, +}; + +const renderOptions = { + useRedux: true, + useRouter: true, +}; + +const renderActivityTable = (props: any) => + render(, renderOptions); + +test('the component renders with ActivityCards', async () => { + renderActivityTable(activityProps); + expect(screen.getByText(/dashboard_test/i)).toBeInTheDocument(); +}); +test('renders tabs with three buttons', async () => { + renderActivityTable(activityProps); + expect(screen.getAllByRole('tab')).toHaveLength(3); +}); +test('renders Viewed tab with ActivityCards', async () => { + renderActivityTable(activityViewedTabProps); + expect(screen.getByText(/chartychart/i)).toBeInTheDocument(); +}); +test('calls the getEdited batch call when edited tab is clicked', async () => { + const { rerender } = renderActivityTable(activityProps); + const editedButton = screen.getByText(/edited/i); + expect(editedButton).toBeInTheDocument(); + userEvent.click(editedButton); + expect(mockSetActiveChild).toHaveBeenCalledWith(TableTab.Edited); + rerender(); + // simulate the render after getEditedObjects has been called + await waitFor(() => { + expect(screen.getByText(/chartychart/i)).toBeInTheDocument(); + expect(screen.getByText(/dashboard_test/i)).toBeInTheDocument(); }); }); +test('show empty state if there is no data', () => { + renderActivityTable(emptyActivityProps); + expect( + screen.getByText( + /recently created charts, dashboards, and saved queries will appear here/i, + ), + ).toBeInTheDocument(); +}); diff --git a/superset-frontend/src/features/home/ChartTable.test.tsx b/superset-frontend/src/features/home/ChartTable.test.tsx index 68a534ed3a373..018e3693b128e 100644 --- a/superset-frontend/src/features/home/ChartTable.test.tsx +++ b/superset-frontend/src/features/home/ChartTable.test.tsx @@ -17,14 +17,10 @@ * under the License. */ import React from 'react'; -import { - render, - screen, - waitFor, - fireEvent, -} from 'spec/helpers/testing-library'; +import { render, screen, waitFor } from 'spec/helpers/testing-library'; import fetchMock from 'fetch-mock'; import { act } from 'react-dom/test-utils'; +import userEvent from '@testing-library/user-event'; import ChartTable from './ChartTable'; const chartsEndpoint = 'glob:*/api/v1/chart/?*'; @@ -98,7 +94,7 @@ test('renders with EmptyState if no data present', async () => { test('fetches chart favorites and renders chart cards', async () => { await renderChartTable(mockedProps); - fireEvent.click(screen.getByText(/favorite/i)); + userEvent.click(screen.getByText(/favorite/i)); await waitFor(() => { expect(fetchMock.calls(chartFavoriteStatusEndpoint)).toHaveLength(1); expect(screen.getAllByText(/cool chart/i)).toHaveLength(3); @@ -112,7 +108,7 @@ test('renders other tab by default', async () => { test('renders mine tab on click', async () => { await renderChartTable(mineTabProps); - fireEvent.click(screen.getByText(/mine/i)); + userEvent.click(screen.getByText(/mine/i)); await waitFor(() => { expect(screen.getAllByText(/cool chart/i)).toHaveLength(3); });