This is an automated email from the ASF dual-hosted git repository. rusackas pushed a commit to branch replace-jest-enzyme in repository https://gitbox.apache.org/repos/asf/superset.git
commit 64b71766685f44eeb8b21b091938b894a6cc0fdd Author: Evan Rusackas <[email protected]> AuthorDate: Sat Feb 8 23:18:58 2025 -0700 HeaderActionsDropdown to RTL --- .../HeaderActionsDropdown.test.tsx | 266 ++++++++++----------- 1 file changed, 133 insertions(+), 133 deletions(-) diff --git a/superset-frontend/src/dashboard/components/Header/HeaderActionsDropdown/HeaderActionsDropdown.test.tsx b/superset-frontend/src/dashboard/components/Header/HeaderActionsDropdown/HeaderActionsDropdown.test.tsx index 090f12a2bd..506c65a4de 100644 --- a/superset-frontend/src/dashboard/components/Header/HeaderActionsDropdown/HeaderActionsDropdown.test.tsx +++ b/superset-frontend/src/dashboard/components/Header/HeaderActionsDropdown/HeaderActionsDropdown.test.tsx @@ -16,14 +16,24 @@ * specific language governing permissions and limitations * under the License. */ -import { shallow } from 'enzyme'; -import sinon from 'sinon'; -import { render, screen } from 'spec/helpers/testing-library'; +import React from 'react'; +import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; +import '@testing-library/jest-dom'; // Changed from '@testing-library/jest-dom/extend-expect' import fetchMock from 'fetch-mock'; import { HeaderDropdownProps } from 'src/dashboard/components/Header/types'; import injectCustomCss from 'src/dashboard/util/injectCustomCss'; import { HeaderActionsDropdown } from '.'; +import { Provider } from 'react-redux'; +import { configureStore } from '@reduxjs/toolkit'; +import { ThemeProvider, supersetTheme } from '@superset-ui/core'; + +const mockStore = configureStore({ + reducer: { + dashboardState: (state = { directPathToChild: [] }) => state, + reports: (state = { dashboards: {} }) => state, // Add reports reducer + }, +}); const createProps = (): HeaderDropdownProps => ({ addSuccessToast: jest.fn(), @@ -102,159 +112,149 @@ const guestUserProps = { function setup(props: HeaderDropdownProps) { return render( - <div className="dashboard-header"> - <HeaderActionsDropdown {...props} /> - </div>, - { useRedux: true }, + <Provider store={mockStore}> + <ThemeProvider theme={supersetTheme}> + <div className="dashboard-header"> + <HeaderActionsDropdown {...props} /> + </div> + </ThemeProvider> + </Provider>, ); } fetchMock.get('glob:*/csstemplateasyncmodelview/api/read', {}); -test('should render', () => { - const mockedProps = createProps(); - const { container } = setup(mockedProps); - expect(container).toBeInTheDocument(); -}); - -test('should render the Download dropdown button when not in edit mode', () => { - const mockedProps = createProps(); - setup(mockedProps); - expect( - screen.getByRole('menuitem', { name: 'Download' }), - ).toBeInTheDocument(); -}); - -test('should render the menu items', async () => { - const mockedProps = createProps(); - setup(mockedProps); - expect(screen.getAllByRole('menuitem')).toHaveLength(4); - expect(screen.getByText('Refresh dashboard')).toBeInTheDocument(); - expect(screen.getByText('Set auto-refresh interval')).toBeInTheDocument(); - expect(screen.getByText('Enter fullscreen')).toBeInTheDocument(); - expect(screen.getByText('Download')).toBeInTheDocument(); -}); - -test('should render the menu items in edit mode', async () => { - setup(editModeOnProps); - expect(screen.getAllByRole('menuitem')).toHaveLength(4); - expect(screen.getByText('Set auto-refresh interval')).toBeInTheDocument(); - expect(screen.getByText('Edit properties')).toBeInTheDocument(); - expect(screen.getByText('Edit CSS')).toBeInTheDocument(); - expect(screen.getByText('Download')).toBeInTheDocument(); -}); +describe('HeaderActionsDropdown', () => { + beforeEach(() => { + fetchMock.resetHistory(); + }); -test('should render the menu items in Embedded mode', async () => { - setup(guestUserProps); - expect(screen.getAllByRole('menuitem')).toHaveLength(3); - expect(screen.getByText('Refresh dashboard')).toBeInTheDocument(); - expect(screen.getByText('Download')).toBeInTheDocument(); - expect(screen.getByText('Set auto-refresh interval')).toBeInTheDocument(); -}); + it('should render', () => { + const mockedProps = createProps(); + const { container } = setup(mockedProps); + expect(container).toBeInTheDocument(); + }); -test('should not render filter mapping in edit mode if explicit filter scopes undefined', async () => { - setup(editModeOnProps); - expect(screen.queryByText('Set filter mapping')).not.toBeInTheDocument(); -}); + it('should render the Download dropdown button when not in edit mode', () => { + const mockedProps = createProps(); + setup(mockedProps); + expect( + screen.getByRole('menuitem', { name: 'Download' }), + ).toBeInTheDocument(); + }); -test('should render filter mapping in edit mode if explicit filter scopes defined', async () => { - setup(editModeOnWithFilterScopesProps); - expect(screen.getByText('Set filter mapping')).toBeInTheDocument(); -}); + it('should render the menu items', () => { + const mockedProps = createProps(); + setup(mockedProps); + expect(screen.getAllByRole('menuitem')).toHaveLength(4); + expect(screen.getByText('Refresh dashboard')).toBeInTheDocument(); + expect(screen.getByText('Set auto-refresh interval')).toBeInTheDocument(); + expect(screen.getByText('Enter fullscreen')).toBeInTheDocument(); + expect(screen.getByText('Download')).toBeInTheDocument(); + }); -test('should show the share actions', async () => { - const mockedProps = createProps(); - const canShareProps = { - ...mockedProps, - userCanShare: true, - }; - setup(canShareProps); + it('should render the menu items in edit mode', () => { + setup(editModeOnProps); + expect(screen.getAllByRole('menuitem')).toHaveLength(4); + expect(screen.getByText('Set auto-refresh interval')).toBeInTheDocument(); + expect(screen.getByText('Edit properties')).toBeInTheDocument(); + expect(screen.getByText('Edit CSS')).toBeInTheDocument(); + expect(screen.getByText('Download')).toBeInTheDocument(); + }); - expect(screen.getByText('Share')).toBeInTheDocument(); -}); + it('should render the menu items in Embedded mode', () => { + setup(guestUserProps); + expect(screen.getAllByRole('menuitem')).toHaveLength(3); + expect(screen.getByText('Refresh dashboard')).toBeInTheDocument(); + expect(screen.getByText('Download')).toBeInTheDocument(); + expect(screen.getByText('Set auto-refresh interval')).toBeInTheDocument(); + }); -test('should render the "Save as" menu item when user can save', async () => { - const mockedProps = createProps(); - const canSaveProps = { - ...mockedProps, - userCanSave: true, - }; - setup(canSaveProps); - expect(screen.getByText('Save as')).toBeInTheDocument(); -}); + it('should not render filter mapping in edit mode if explicit filter scopes undefined', () => { + setup(editModeOnProps); + expect(screen.queryByText('Set filter mapping')).not.toBeInTheDocument(); + }); -test('should NOT render the "Save as" menu item when user cannot save', async () => { - const mockedProps = createProps(); - setup(mockedProps); - expect(screen.queryByText('Save as')).not.toBeInTheDocument(); -}); + it('should render filter mapping in edit mode if explicit filter scopes defined', () => { + setup(editModeOnWithFilterScopesProps); + expect(screen.getByText('Set filter mapping')).toBeInTheDocument(); + }); -test('should render the "Refresh dashboard" menu item as disabled when loading', async () => { - const mockedProps = createProps(); - const loadingProps = { - ...mockedProps, - isLoading: true, - }; - setup(loadingProps); - expect(screen.getByText('Refresh dashboard').parentElement).toHaveClass( - 'ant-menu-item-disabled', - ); -}); + it('should show the share actions when user can share', () => { + const mockedProps = createProps(); + setup({ ...mockedProps, userCanShare: true }); + expect(screen.getByText('Share')).toBeInTheDocument(); + }); -test('should NOT render the "Refresh dashboard" menu item as disabled', async () => { - const mockedProps = createProps(); - setup(mockedProps); - expect(screen.getByText('Refresh dashboard')).not.toHaveClass( - 'ant-menu-item-disabled', - ); -}); + it('should render the "Save as" menu item when user can save', () => { + const mockedProps = createProps(); + setup({ ...mockedProps, userCanSave: true }); + expect(screen.getByText('Save as')).toBeInTheDocument(); + }); -test('should render with custom css', () => { - const mockedProps = createProps(); - const { customCss } = mockedProps; - setup(mockedProps); - injectCustomCss(customCss); - expect(screen.getByTestId('header-actions-menu')).toHaveStyle( - 'margin-left: 100px', - ); -}); + it('should NOT render the "Save as" menu item when user cannot save', () => { + setup(createProps()); + expect(screen.queryByText('Save as')).not.toBeInTheDocument(); + }); -test('should refresh the charts', async () => { - const mockedProps = createProps(); - setup(mockedProps); - userEvent.click(screen.getByText('Refresh dashboard')); - expect(mockedProps.forceRefreshAllCharts).toHaveBeenCalledTimes(1); - expect(mockedProps.addSuccessToast).toHaveBeenCalledTimes(1); -}); + it('should render the "Refresh dashboard" menu item as disabled when loading', () => { + const mockedProps = createProps(); + setup({ ...mockedProps, isLoading: true }); + expect( + screen.getByText('Refresh dashboard').closest('.ant-menu-item'), + ).toHaveClass('ant-menu-item-disabled'); + }); -test('should show the properties modal', async () => { - setup(editModeOnProps); - userEvent.click(screen.getByText('Edit properties')); - expect(editModeOnProps.showPropertiesModal).toHaveBeenCalledTimes(1); -}); + it('should NOT render the "Refresh dashboard" menu item as disabled when not loading', () => { + setup(createProps()); + expect( + screen.getByText('Refresh dashboard').closest('.ant-menu-item'), + ).not.toHaveClass('ant-menu-item-disabled'); + }); -describe('UNSAFE_componentWillReceiveProps', () => { - let wrapper: any; + it('should render with custom css', () => { + const mockedProps = createProps(); + setup(mockedProps); + injectCustomCss(mockedProps.customCss); + expect(screen.getByTestId('header-actions-menu')).toHaveStyle({ + marginLeft: '100px', + }); + }); - const mockedProps = createProps(); - const props = { ...mockedProps, customCss: '' }; - beforeEach(() => { - wrapper = shallow(<HeaderActionsDropdown {...props} />); - wrapper.setState({ css: props.customCss }); - sinon.spy(wrapper.instance(), 'setState'); + it('should refresh the charts when clicking refresh', async () => { + const mockedProps = createProps(); + setup(mockedProps); + await userEvent.click(screen.getByText('Refresh dashboard')); + expect(mockedProps.forceRefreshAllCharts).toHaveBeenCalledTimes(1); + expect(mockedProps.addSuccessToast).toHaveBeenCalledTimes(1); }); - afterEach(() => { - wrapper.instance().setState.restore(); + it('should show the properties modal when clicking edit properties', async () => { + setup(editModeOnProps); + await userEvent.click(screen.getByText('Edit properties')); + expect(editModeOnProps.showPropertiesModal).toHaveBeenCalledTimes(1); }); - it('css should update state and inject custom css', () => { - wrapper.instance().UNSAFE_componentWillReceiveProps({ - ...props, - customCss: mockedProps.customCss, + it('should update css when props change', async () => { + const mockedProps = createProps(); + const { rerender } = setup({ ...mockedProps, customCss: '' }); + + // Update props with new CSS + rerender( + <Provider store={mockStore}> + <ThemeProvider theme={supersetTheme}> + <div className="dashboard-header"> + <HeaderActionsDropdown + {...mockedProps} + customCss={mockedProps.customCss} + /> + </div> + </ThemeProvider> + </Provider>, + ); + + expect(screen.getByTestId('header-actions-menu')).toHaveStyle({ + marginLeft: '100px', }); - expect(wrapper.instance().setState.calledOnce).toBe(true); - const stateKeys = Object.keys(wrapper.instance().setState.lastCall.args[0]); - expect(stateKeys).toContain('css'); }); });
