|
1 | 1 | import * as React from 'react'; |
2 | | -import { mount } from 'enzyme'; |
| 2 | +import { render, screen, userEvent } from '../../../test-utils/testing-library'; |
3 | 3 | import { AddTaskButtonComponent as AddTaskButton } from '../AddTaskButton'; |
4 | 4 |
|
5 | | -jest.mock('../../../components/date-picker/DatePicker', () => props => { |
6 | | - // only spread `input` attritutes to the input field |
7 | | - const { name, value = '', className, onChange, placeholder } = props; |
8 | | - const localInputProps = { |
9 | | - name, |
10 | | - value, |
11 | | - className, |
12 | | - onChange, |
13 | | - placeholder, |
14 | | - }; |
15 | | - return ( |
16 | | - <input type="date" {...localInputProps} {...props.inputProps} /> // eslint-disable-line react/prop-types |
17 | | - ); |
18 | | -}); |
| 5 | +jest.mock('../AddTaskMenu', () => ({ onMenuItemClick, isDisabled, setAddTaskButtonRef }) => ( |
| 6 | + <div data-testid="add-task-menu"> |
| 7 | + <button |
| 8 | + type="button" |
| 9 | + onClick={() => onMenuItemClick('GENERAL')} |
| 10 | + disabled={isDisabled} |
| 11 | + ref={setAddTaskButtonRef} |
| 12 | + data-testid="menu-item-general" |
| 13 | + > |
| 14 | + Add General Task |
| 15 | + </button> |
| 16 | + </div> |
| 17 | +)); |
| 18 | + |
| 19 | +jest.mock('../TaskModal', () => ({ isTaskFormOpen, onModalClose, taskType }) => ( |
| 20 | + <div data-testid="task-modal" data-open={isTaskFormOpen} data-task-type={taskType}> |
| 21 | + <button type="button" onClick={onModalClose} data-testid="modal-close"> |
| 22 | + Close Modal |
| 23 | + </button> |
| 24 | + </div> |
| 25 | +)); |
19 | 26 |
|
20 | 27 | describe('elements/content-sidebar/AddTaskButton', () => { |
21 | 28 | /* |
22 | 29 | 1. Pushing the open state into history keeps the sidebar open upon resize and refresh |
23 | 30 | 2. Preventing the sidebar from closing keeps the task modal open upon edit and resize |
24 | 31 | */ |
25 | 32 |
|
26 | | - test('should call history.replace state with force open state when task menu items are clicked', () => { |
| 33 | + const defaultProps = { |
| 34 | + history: { replace: jest.fn() }, |
| 35 | + isDisabled: false, |
| 36 | + onTaskModalClose: jest.fn(), |
| 37 | + taskFormProps: { |
| 38 | + approvers: [], |
| 39 | + approverSelectorContacts: [], |
| 40 | + completionRule: 'ALL', |
| 41 | + createTask: jest.fn(), |
| 42 | + getApproverWithQuery: jest.fn(), |
| 43 | + getAvatarUrl: jest.fn(), |
| 44 | + id: '', |
| 45 | + message: '', |
| 46 | + }, |
| 47 | + }; |
| 48 | + |
| 49 | + const renderComponent = (props = {}) => { |
| 50 | + return render(<AddTaskButton {...defaultProps} {...props} />); |
| 51 | + }; |
| 52 | + |
| 53 | + beforeEach(() => { |
| 54 | + jest.clearAllMocks(); |
| 55 | + }); |
| 56 | + |
| 57 | + test('should call history.replace state with force open state when task menu items are clicked', async () => { |
27 | 58 | const historyMock = { replace: jest.fn() }; |
28 | | - const wrapper = mount(<AddTaskButton history={historyMock} />); |
| 59 | + const user = userEvent(); |
29 | 60 |
|
30 | | - const button = wrapper.find('Button'); |
31 | | - button.simulate('click'); |
| 61 | + renderComponent({ history: historyMock }); |
32 | 62 |
|
33 | | - const menuItem = wrapper.find('MenuItem').first(); |
34 | | - menuItem.simulate('click'); |
| 63 | + const menuItem = screen.getByTestId('menu-item-general'); |
| 64 | + await user.click(menuItem); |
35 | 65 |
|
36 | 66 | expect(historyMock.replace).toHaveBeenCalledWith({ state: { open: true } }); |
37 | 67 | }); |
38 | 68 |
|
39 | | - test('should set state.isTaskFormOpen to false and call onTaskModalClose when task modal is closed', () => { |
| 69 | + test('should set state.isTaskFormOpen to false and call onTaskModalClose when task modal is closed', async () => { |
40 | 70 | const onTaskModalCloseMock = jest.fn(); |
41 | | - const mockButtonRef = { |
42 | | - current: { |
43 | | - focus: jest.fn(), |
44 | | - }, |
45 | | - }; |
46 | | - const wrapper = shallow(<AddTaskButton onTaskModalClose={onTaskModalCloseMock} />); |
47 | | - wrapper.instance().buttonRef = mockButtonRef; |
48 | | - wrapper.setState({ isTaskFormOpen: true }); |
49 | | - |
50 | | - wrapper.instance().handleModalClose(); |
51 | | - |
52 | | - expect(wrapper.state('isTaskFormOpen')).toBe(false); |
53 | | - expect(mockButtonRef.current.focus).toHaveBeenCalledTimes(1); |
| 71 | + const user = userEvent(); |
| 72 | + |
| 73 | + renderComponent({ onTaskModalClose: onTaskModalCloseMock }); |
| 74 | + |
| 75 | + // First click a menu item to open the modal |
| 76 | + const menuItem = screen.getByTestId('menu-item-general'); |
| 77 | + await user.click(menuItem); |
| 78 | + |
| 79 | + // Verify modal is open |
| 80 | + const modal = screen.getByTestId('task-modal'); |
| 81 | + expect(modal).toHaveAttribute('data-open', 'true'); |
| 82 | + |
| 83 | + // Close the modal |
| 84 | + const closeButton = screen.getByTestId('modal-close'); |
| 85 | + await user.click(closeButton); |
| 86 | + |
| 87 | + // Verify modal is closed and callback was called |
| 88 | + expect(modal).toHaveAttribute('data-open', 'false'); |
54 | 89 | expect(onTaskModalCloseMock).toHaveBeenCalledTimes(1); |
55 | 90 | }); |
| 91 | + |
| 92 | + describe('when routerDisabled is true', () => { |
| 93 | + test('should use internalSidebarNavigationHandler when task menu items are clicked', async () => { |
| 94 | + const mockNavigationHandler = jest.fn(); |
| 95 | + const user = userEvent(); |
| 96 | + |
| 97 | + renderComponent({ |
| 98 | + routerDisabled: true, |
| 99 | + internalSidebarNavigationHandler: mockNavigationHandler, |
| 100 | + }); |
| 101 | + |
| 102 | + const menuItem = screen.getByTestId('menu-item-general'); |
| 103 | + await user.click(menuItem); |
| 104 | + |
| 105 | + expect(mockNavigationHandler).toHaveBeenCalledTimes(1); |
| 106 | + expect(mockNavigationHandler).toHaveBeenCalledWith({ open: true }, true); |
| 107 | + }); |
| 108 | + |
| 109 | + test('should preserve internalSidebarNavigation state when using navigation handler', async () => { |
| 110 | + const mockNavigationHandler = jest.fn(); |
| 111 | + const mockInternalSidebarNavigation = { |
| 112 | + sidebar: 'activity', |
| 113 | + activeFeedEntryType: 'comments', |
| 114 | + activeFeedEntryId: '123', |
| 115 | + }; |
| 116 | + const user = userEvent(); |
| 117 | + |
| 118 | + renderComponent({ |
| 119 | + routerDisabled: true, |
| 120 | + internalSidebarNavigationHandler: mockNavigationHandler, |
| 121 | + internalSidebarNavigation: mockInternalSidebarNavigation, |
| 122 | + }); |
| 123 | + |
| 124 | + const menuItem = screen.getByTestId('menu-item-general'); |
| 125 | + await user.click(menuItem); |
| 126 | + |
| 127 | + expect(mockNavigationHandler).toHaveBeenCalledTimes(1); |
| 128 | + expect(mockNavigationHandler).toHaveBeenCalledWith( |
| 129 | + { |
| 130 | + sidebar: 'activity', |
| 131 | + activeFeedEntryType: 'comments', |
| 132 | + activeFeedEntryId: '123', |
| 133 | + open: true, |
| 134 | + }, |
| 135 | + true, |
| 136 | + ); |
| 137 | + }); |
| 138 | + }); |
56 | 139 | }); |
0 commit comments