Skip to content

Commit

Permalink
test: add missing tests
Browse files Browse the repository at this point in the history
  • Loading branch information
shervinchen committed Apr 24, 2024
1 parent 3d66762 commit caf5f12
Show file tree
Hide file tree
Showing 11 changed files with 210 additions and 98 deletions.
33 changes: 20 additions & 13 deletions packages/Modal/__tests__/Modal.test.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { useState } from 'react';
import { act, render, screen } from '@testing-library/react';
import { render, waitFor } from '@testing-library/react';
import { Button, Modal, ModalProps } from '../..';
import userEvent from '@testing-library/user-event';

Expand Down Expand Up @@ -89,38 +89,45 @@ describe('Modal', () => {
test('should open modal and close modal when click target', async () => {
jest.useFakeTimers();
const user = userEvent.setup({ advanceTimers: jest.advanceTimersByTime });
const { getByTestId } = render(<Component closeOnOverlayClick={true} />);
const { getByTestId, findByTestId, queryByTestId } = render(
<Component closeOnOverlayClick={true} />
);
await user.click(getByTestId('openModal'));
const modalContainer = screen.getByTestId('modalContainer');
const modalContainer = await findByTestId('modalContainer');
expect(modalContainer).toBeInTheDocument();
await user.click(modalContainer);
act(() => {
jest.runAllTimers();
// act(() => {
// jest.runAllTimers();
// });
await waitFor(() => {
expect(queryByTestId('modalContainer')).not.toBeInTheDocument();
});
expect(modalContainer).not.toBeInTheDocument();
expect(closeHandler).toHaveBeenCalledTimes(1);
jest.useRealTimers();
});

test('should not close modal when disabled overlay clicked', async () => {
jest.useFakeTimers();
const user = userEvent.setup({ advanceTimers: jest.advanceTimersByTime });
const { getByTestId } = render(<Component closeOnOverlayClick={false} />);
const { getByTestId, findByTestId } = render(
<Component closeOnOverlayClick={false} />
);
await user.click(getByTestId('openModal'));
await user.click(getByTestId('modalContainer'));
await user.click(await findByTestId('modalContainer'));
expect(closeHandler).toHaveBeenCalledTimes(0);
jest.useRealTimers();
});

test('should not propagate the click event', async () => {
jest.useFakeTimers();
const user = userEvent.setup({ advanceTimers: jest.advanceTimersByTime });
const { getByTestId } = render(<Component closeOnOverlayClick={true} />);
const { getByTestId, findByTestId } = render(
<Component closeOnOverlayClick={true} />
);
await user.click(getByTestId('openModal'));
const modalWrapper = getByTestId('modalWrapper');
expect(getByTestId('modalContainer')).toBeInTheDocument();
await user.click(modalWrapper);
expect(getByTestId('modalContainer')).toBeInTheDocument();
expect(await findByTestId('modalContainer')).toBeInTheDocument();
await user.click(await findByTestId('modalWrapper'));
expect(await findByTestId('modalContainer')).toBeInTheDocument();
expect(closeHandler).toHaveBeenCalledTimes(0);
jest.useRealTimers();
});
Expand Down
4 changes: 1 addition & 3 deletions packages/Popover/Popover.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,7 @@ const Popover: FC<PropsWithChildren<PopoverProps>> = ({
useClickAway(
ref,
() => {
if (internalValue) {
setInternalValue(false);
}
setInternalValue(false);
},
['click']
);
Expand Down
48 changes: 11 additions & 37 deletions packages/Popover/__tests__/Popover.test.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import React, { useState } from 'react';
import { render, act, screen, waitFor } from '@testing-library/react';
import { render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import Popover from '..';
import { PopoverProps } from '../Popover.types';
import * as useControlled from '../../utils/hooks/useControlled';

describe('Popover', () => {
test('should match the snapshot', () => {
Expand All @@ -24,25 +23,21 @@ describe('Popover', () => {

test('should show popover when click target', async () => {
const user = userEvent.setup();
const { getByTestId } = render(
const { getByTestId, findByTestId } = render(
<Popover content="I am a popover">Click me</Popover>
);
await user.click(getByTestId('popoverTarget'));
await waitFor(() => {
expect(screen.getByTestId('popoverContent')).toBeInTheDocument();
});
expect(await findByTestId('popoverContent')).toBeInTheDocument();
});

test('should switch whether or not popover is visible when click target', async () => {
const user = userEvent.setup();
const { getByTestId } = render(
const { getByTestId, findByTestId } = render(
<Popover content="I am a popover">Click me</Popover>
);
const target = getByTestId('popoverTarget');
await user.click(target);
await waitFor(() => {
expect(screen.getByTestId('popoverContent')).toBeInTheDocument();
});
expect(await findByTestId('popoverContent')).toBeInTheDocument();
await user.click(target);
await waitFor(() => {
expect(screen.queryByTestId('popoverContent')).not.toBeInTheDocument();
Expand All @@ -51,36 +46,17 @@ describe('Popover', () => {

test('should hide popover when click outside', async () => {
const user = userEvent.setup();
const { getByTestId } = render(
const { getByTestId, findByTestId } = render(
<Popover content="I am a popover">Click me</Popover>
);
await user.click(getByTestId('popoverTarget'));
await waitFor(() => {
expect(screen.getByTestId('popoverContent')).toBeInTheDocument();
});
act(() => {
document.dispatchEvent(new MouseEvent('click'));
});
expect(await findByTestId('popoverContent')).toBeInTheDocument();
await user.click(document.body);
await waitFor(() => {
expect(screen.queryByTestId('popoverContent')).not.toBeInTheDocument();
});
});

test('should not trigger click outside logic when popover is invisible', async () => {
const mockSetValueFunc = jest.fn();
jest
.spyOn(useControlled, 'useControlled')
.mockImplementation(() => [false, mockSetValueFunc]);
render(<Popover content="I am a popover">Click me</Popover>);
act(() => {
document.dispatchEvent(new MouseEvent('click'));
});
await waitFor(() => {
expect(mockSetValueFunc).toHaveBeenCalledTimes(0);
});
(useControlled.useControlled as jest.Mock).mockRestore();
});

test('should support disabled popover', async () => {
const user = userEvent.setup();
const { getByTestId } = render(
Expand Down Expand Up @@ -114,13 +90,11 @@ describe('Popover', () => {
</Popover>
);
};
const { getByTestId } = render(
const { getByTestId, findByTestId } = render(
<Component content="I am a controlled popover" onChange={onChange} />
);
await user.click(getByTestId('popoverTarget'));
await waitFor(() => {
expect(screen.getByTestId('popoverContent')).toBeInTheDocument();
expect(onChange).toHaveBeenCalledTimes(1);
});
expect(await findByTestId('popoverContent')).toBeInTheDocument();
expect(onChange).toHaveBeenCalledTimes(1);
});
});
31 changes: 11 additions & 20 deletions packages/Popup/__tests__/Popup.test.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { act, render, screen } from '@testing-library/react';
import { fireEvent, render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import Popup from '..';
import { MutableRefObject, useRef } from 'react';
Expand Down Expand Up @@ -103,13 +103,12 @@ describe('Popup', () => {
/>
);
expect(mockGetPopupPosition).toHaveBeenCalledTimes(1);
act(() => {
window.dispatchEvent(new Event('resize'));
});
fireEvent(window, new Event('resize'));
expect(mockGetPopupPosition).toHaveBeenCalledTimes(2);
});

test('should update popup position when document click', () => {
test('should update popup position when document click', async () => {
const user = userEvent.setup();
render(
<Component
visible
Expand All @@ -118,13 +117,11 @@ describe('Popup', () => {
/>
);
expect(mockGetPopupPosition).toHaveBeenCalledTimes(1);
act(() => {
document.dispatchEvent(new MouseEvent('click'));
});
await user.click(document.body);
expect(mockGetPopupPosition).toHaveBeenCalledTimes(2);
});

test('should update popup position when mouse over', () => {
test('should update popup position when mouse over', async () => {
render(
<Component
visible
Expand All @@ -133,9 +130,7 @@ describe('Popup', () => {
/>
);
expect(mockGetPopupPosition).toHaveBeenCalledTimes(1);
act(() => {
targetRefMock.current.dispatchEvent(new Event('mouseenter'));
});
await userEvent.hover(targetRefMock.current);
expect(mockGetPopupPosition).toHaveBeenCalledTimes(2);
});

Expand Down Expand Up @@ -178,16 +173,14 @@ describe('Popup', () => {
expect(popup).toBeInTheDocument();
});

test('should not trigger mouse over event when target is empty', () => {
test('should not trigger mouse over event when target is empty', async () => {
render(<Component visible getPopupContainer={getPopupContainerMock} />);
expect(mockGetPopupPosition).toHaveBeenCalledTimes(1);
act(() => {
targetRefMock.current.dispatchEvent(new Event('mouseenter'));
});
await userEvent.hover(targetRefMock.current);
expect(mockGetPopupPosition).toHaveBeenCalledTimes(1);
});

test('should not trigger mouse over event when event is removed', () => {
test('should not trigger mouse over event when event is removed', async () => {
const { unmount } = render(
<Component
visible
Expand All @@ -197,9 +190,7 @@ describe('Popup', () => {
);
expect(mockGetPopupPosition).toHaveBeenCalledTimes(1);
unmount();
act(() => {
targetRefMock.current.dispatchEvent(new Event('mouseenter'));
});
await userEvent.hover(targetRefMock.current);
expect(mockGetPopupPosition).toHaveBeenCalledTimes(1);
});
});
14 changes: 6 additions & 8 deletions packages/Select/Select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -155,9 +155,7 @@ const Select = forwardRef<SelectRef, PropsWithChildren<SelectProps>>(
useClickAway(
selectRef,
() => {
if (dropdownVisible) {
setDropdownVisible(false);
}
setDropdownVisible(false);
},
['mousedown']
);
Expand All @@ -167,20 +165,20 @@ const Select = forwardRef<SelectRef, PropsWithChildren<SelectProps>>(
() => ({
focus: () => inputRef.current?.focus(),
blur: () => inputRef.current?.blur(),
scrollTo: (options) => dropdownRef.current?.scrollTo(options),
}),
[inputRef, dropdownRef]
[inputRef]
);

const SelectContent = (): ReactElement => {
if (internalValue === undefined)
if (internalValue === undefined) {
return <span className="raw-select-placeholder">{placeholder}</span>;
}

const selectedOptions = getValidChildren(children).filter((option) => {
if (Array.isArray(internalValue)) {
return multiple ? internalValue.includes(option.props.value) : false;
return internalValue.includes(option.props.value);
} else {
return multiple ? false : internalValue === option.props.value;
return internalValue === option.props.value;
}
});

Expand Down
1 change: 0 additions & 1 deletion packages/Select/Select.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ export type SelectProps = BaseSelectProps & NativeSelectProps;
export type SelectRef = {
focus: () => void;
blur: () => void;
scrollTo?: (options?: ScrollToOptions) => void;
};

export interface SelectConfig {
Expand Down
1 change: 1 addition & 0 deletions packages/Select/SelectDropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ const SelectDropdown = forwardRef<
getPopupContainer={getPopupContainer}
>
<div
data-testid="selectDropdown"
ref={dropdownRef}
className={dropdownClasses}
style={{
Expand Down
9 changes: 7 additions & 2 deletions packages/Select/SelectOption.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const SelectOption: FC<PropsWithChildren<SelectOptionProps>> = ({
const isDisabled = selectDisabled || disabled;
const isSelected = useMemo(() => {
if (Array.isArray(selectValue)) {
return multiple ? selectValue.includes(value) : false;
return selectValue.includes(value);
} else {
return multiple ? false : selectValue === value;
}
Expand All @@ -33,7 +33,12 @@ const SelectOption: FC<PropsWithChildren<SelectOptionProps>> = ({
};

return (
<div className={classes} {...restProps} onClick={clickHandler}>
<div
data-testid="selectOption"
className={classes}
{...restProps}
onClick={clickHandler}
>
<div className="raw-select-option-content">
<span className="raw-select-option-text">{children}</span>
{isSelected && (
Expand Down
6 changes: 5 additions & 1 deletion packages/Select/SelectTag.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,11 @@ const SelectTag: FC<PropsWithChildren<SelectTagProps>> = ({
return (
<div className="raw-select-tag">
<div className="raw-select-tag-text">{children}</div>
<div className="raw-select-tag-icon" onClick={clickHandler}>
<div
data-testid="selectTagIcon"
className="raw-select-tag-icon"
onClick={clickHandler}
>
<X size={14} />
</div>
<style jsx>{`
Expand Down
Loading

0 comments on commit caf5f12

Please sign in to comment.