|
12 | 12 | // See the License for the specific language governing permissions and |
13 | 13 | // limitations under the License. |
14 | 14 |
|
15 | | -import * as React from 'react'; |
16 | | -import { shallow } from 'enzyme'; |
17 | | -import { Popover } from 'antd'; |
| 15 | +import React from 'react'; |
| 16 | +import { render, screen, fireEvent } from '@testing-library/react'; |
| 17 | +import '@testing-library/jest-dom'; |
18 | 18 |
|
19 | | -import { EDirection } from '../../../../model/ddg/types'; |
| 19 | +import { EDirection, ECheckedStatus } from '../../../../model/ddg/types'; |
20 | 20 | import Selector from './Selector'; |
21 | 21 |
|
| 22 | +// Mock the tracking function as it's called within the component |
| 23 | +jest.mock('../../index.track', () => ({ |
| 24 | + trackHopChange: jest.fn(), |
| 25 | +})); |
| 26 | + |
22 | 27 | describe('Selector', () => { |
23 | 28 | const handleClick = jest.fn(); |
24 | | - const hops = ['full', 'partial', 'full', 'empty', 'empty']; |
25 | | - const makeHops = (fullnessArr, direction = EDirection.Downstream) => |
26 | | - fullnessArr.map((fullness, i) => ({ |
27 | | - distance: i * direction, |
28 | | - fullness, |
29 | | - })); |
30 | | - const props = { |
| 29 | + const hopsData = [ |
| 30 | + { distance: 0, fullness: ECheckedStatus.Full }, |
| 31 | + { distance: 1, fullness: ECheckedStatus.Partial }, |
| 32 | + { distance: 2, fullness: ECheckedStatus.Full }, |
| 33 | + { distance: 3, fullness: ECheckedStatus.Empty }, |
| 34 | + { distance: 4, fullness: ECheckedStatus.Empty }, |
| 35 | + ]; |
| 36 | + |
| 37 | + const defaultProps = { |
31 | 38 | furthestDistance: 2, |
32 | | - furthestFullness: 'full', |
33 | | - hops: makeHops(hops), |
| 39 | + furthestFullness: ECheckedStatus.Full, |
| 40 | + furthestFullDistance: 2, |
| 41 | + hops: hopsData, |
34 | 42 | direction: EDirection.Downstream, |
35 | 43 | handleClick, |
36 | 44 | }; |
37 | | - let wrapper; |
38 | | - function getPopoverButtons() { |
39 | | - const popoverContent = wrapper.find(Popover).prop('content'); |
40 | | - return shallow(<div>{popoverContent}</div>).find('button'); |
41 | | - } |
42 | 45 |
|
43 | 46 | beforeEach(() => { |
44 | | - wrapper = shallow(<Selector {...props} />); |
| 47 | + handleClick.mockClear(); |
| 48 | + // Clean up document body to prevent test interference |
| 49 | + document.body.innerHTML = ''; |
45 | 50 | }); |
46 | 51 |
|
47 | | - it('renders message when there are no options', () => { |
48 | | - const message = shallow(<Selector hops={makeHops(['full'])} />); |
49 | | - expect(message).toMatchSnapshot(); |
| 52 | + it('renders message when there are not enough hops', () => { |
| 53 | + // Render with only one hop |
| 54 | + render(<Selector {...defaultProps} hops={[{ distance: 0, fullness: ECheckedStatus.Full }]} />); |
| 55 | + expect(screen.getByText('No downstream hops')).toBeInTheDocument(); |
50 | 56 | }); |
51 | 57 |
|
52 | | - it('renders buttons with expected text and classNames', () => { |
53 | | - expect(wrapper).toMatchSnapshot(); |
54 | | - }); |
| 58 | + it('renders buttons with expected text and classes for Downstream', () => { |
| 59 | + render(<Selector {...defaultProps} />); |
| 60 | + |
| 61 | + // Check main display buttons (furthest visible and max hops) |
| 62 | + expect(screen.getByTestId('hop-down-2')).toHaveTextContent('2'); |
| 63 | + expect(screen.getByTestId('hop-down-2')).toHaveClass('is-Full'); |
| 64 | + expect(screen.getByTestId('hop-down-4')).toHaveTextContent('4'); |
| 65 | + expect(screen.getByTestId('hop-down-4')).toHaveClass('is-Empty'); |
55 | 66 |
|
56 | | - it('renders upstream hops with negative distance correctly', () => { |
57 | | - const upstreamProps = { |
58 | | - direction: EDirection.Upstream, |
59 | | - furthestDistance: EDirection.Upstream * props.furthestDistance, |
60 | | - furthestFullness: 'full', |
61 | | - hops: makeHops(hops, EDirection.Upstream), |
62 | | - handleClick, |
63 | | - }; |
64 | | - const upstreamWrapper = shallow(<Selector {...upstreamProps} />); |
65 | | - expect(upstreamWrapper).toMatchSnapshot(); |
| 67 | + // Check label |
| 68 | + expect(screen.getByText('Downstream hops')).toBeInTheDocument(); |
66 | 69 | }); |
67 | 70 |
|
68 | | - it('calls handleClick with correct arguments from label buttons', () => { |
69 | | - const buttons = wrapper.find('button'); |
70 | | - expect(buttons.length).toBe(2); |
| 71 | + it('renders buttons with expected text and classes for Upstream', () => { |
| 72 | + const upstreamHops = hopsData.map(h => ({ ...h, distance: -h.distance })); |
| 73 | + render( |
| 74 | + <Selector |
| 75 | + {...defaultProps} |
| 76 | + direction={EDirection.Upstream} |
| 77 | + furthestDistance={-2} |
| 78 | + furthestFullDistance={-2} |
| 79 | + hops={upstreamHops} |
| 80 | + /> |
| 81 | + ); |
71 | 82 |
|
72 | | - buttons.first().simulate('click'); |
73 | | - expect(handleClick).toHaveBeenLastCalledWith(props.furthestDistance, props.direction); |
| 83 | + // Check main display buttons (abs value is used for display) |
| 84 | + expect(screen.getByTestId('hop-up-2')).toHaveTextContent('2'); |
| 85 | + expect(screen.getByTestId('hop-up-2')).toHaveClass('is-Full'); |
| 86 | + expect(screen.getByTestId('hop-up-4')).toHaveTextContent('4'); |
| 87 | + expect(screen.getByTestId('hop-up-4')).toHaveClass('is-Empty'); |
74 | 88 |
|
75 | | - buttons.last().simulate('click'); |
76 | | - expect(handleClick).toHaveBeenLastCalledWith(props.hops.length - 1, props.direction); |
| 89 | + // Check label |
| 90 | + expect(screen.getByText('Upstream hops')).toBeInTheDocument(); |
77 | 91 | }); |
78 | 92 |
|
79 | | - it('calls handleClick with correct arguments from popover buttons', () => { |
80 | | - const expectedDistances = [1, 0, 1, 2, 3, 4, 3]; |
81 | | - const popoverButtons = getPopoverButtons(); |
82 | | - expect(popoverButtons.length).toBe(expectedDistances.length); |
83 | | - |
84 | | - popoverButtons.forEach((btn, i) => { |
85 | | - btn.simulate('click'); |
86 | | - expect(handleClick).toHaveBeenLastCalledWith(expectedDistances[i], props.direction); |
87 | | - }); |
88 | | - }); |
| 93 | + it('calls handleClick with correct arguments from label buttons', () => { |
| 94 | + render(<Selector {...defaultProps} />); |
89 | 95 |
|
90 | | - it('disables increment/decrement buttons', () => { |
91 | | - wrapper.setProps({ furthestDistance: 0 }); |
92 | | - expect(getPopoverButtons().first().prop('disabled')).toBe(true); |
| 96 | + // Furthest visible hop button |
| 97 | + fireEvent.click(screen.getByTestId('hop-down-2')); |
| 98 | + expect(handleClick).toHaveBeenCalledWith(2, EDirection.Downstream); |
93 | 99 |
|
94 | | - wrapper.setProps({ furthestDistance: hops.length - 1 }); |
95 | | - expect(getPopoverButtons().last().prop('disabled')).toBe(true); |
| 100 | + // Max hop button (delimiter) |
| 101 | + fireEvent.click(screen.getByTestId('hop-down-4')); |
| 102 | + expect(handleClick).toHaveBeenCalledWith(4, EDirection.Downstream); |
96 | 103 | }); |
97 | 104 | }); |
0 commit comments