Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions packages/react-core/src/components/Menu/__mocks__/Menu.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import React from 'react';
import { MenuProps } from '../Menu';

export const Menu = ({ className, isPlain, isScrollable, style, onSelect, ...props }: MenuProps) => (
<>
<div className={className} data-testid="menu-mock" {...props}></div>
<div onClick={onSelect}>{'Mock item'}</div>
<p>{`isPlain: ${isPlain}`}</p>
<p>{`isScrollable: ${isScrollable}`}</p>
<p>{`minWidth: ${style?.['--pf-c-menu--MinWidth']}`}</p>
</>
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import React from 'react';

export const MenuContent = ({ children }) => <div>{children}</div>;
12 changes: 12 additions & 0 deletions packages/react-core/src/components/Menu/__mocks__/MenuGroup.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import React from 'react';
import { MenuGroupProps } from '../MenuGroup';

export const MenuGroup = ({ className, children, label, labelHeadingLevel }: MenuGroupProps) => (
<>
<div className={className} data-testid="menu-group-mock">
{children}
</div>
<p>{`label: ${label}`}</p>
<p>{`labelHeadingLevel: ${labelHeadingLevel}`}</p>
</>
);
12 changes: 12 additions & 0 deletions packages/react-core/src/components/Menu/__mocks__/MenuItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import React from 'react';
import { MenuItemProps } from '../MenuItem';

export const MenuItem = ({ className, children, description, itemId }: MenuItemProps) => (
<>
<div className={className} data-testid="menu-item-mock">
{children}
</div>
<p>{`description: ${description}`}</p>
<p>{`itemId: ${itemId}`}</p>
</>
);
10 changes: 10 additions & 0 deletions packages/react-core/src/components/Menu/__mocks__/MenuList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import React from 'react';
import { MenuListProps } from '../MenuList';

export const MenuList = ({ className, children }: MenuListProps) => (
<>
<div className={className} data-testid="menu-list-mock">
{children}
</div>
</>
);
5 changes: 5 additions & 0 deletions packages/react-core/src/components/Menu/__mocks__/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export * from './Menu';
export * from './MenuContent';
export * from './MenuGroup';
export * from './MenuItem';
export * from './MenuList';
11 changes: 11 additions & 0 deletions packages/react-core/src/helpers/Popper/__mocks__/Popper.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import React from 'react';
import { PopperProps } from '../Popper';

export const Popper = ({ popper, zIndex, isVisible, trigger }: PopperProps) => (
<>
<div>{popper}</div>
<p>{`zIndex: ${zIndex}`}</p>
<p>{`isOpen: ${isVisible}`}</p>
<div>{trigger}</div>
</>
);
1 change: 1 addition & 0 deletions packages/react-core/src/helpers/Popper/__mocks__/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './Popper';
Original file line number Diff line number Diff line change
@@ -0,0 +1,236 @@
import React from 'react';
import { Dropdown } from '../../Dropdown';
import { render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';

jest.mock('../../../../components/Menu');

jest.mock('../../../../helpers/Popper/Popper');

const toggle = (ref: React.RefObject<any>) => <button ref={ref}>Dropdown</button>;

const dropdownChildren = <div>Dropdown children</div>;

test('renders dropdown', () => {
render(
<div data-testid="dropdown">
<Dropdown toggle={toggleRef => toggle(toggleRef)}>{dropdownChildren}</Dropdown>
</div>
);

expect(screen.getByTestId('dropdown').children[0]).toBeVisible();
});

test('passes children', () => {
render(<Dropdown toggle={toggleRef => toggle(toggleRef)}>{dropdownChildren}</Dropdown>);

expect(screen.getByText('Dropdown children')).toBeVisible();
});

test('renders passed toggle element', () => {
render(<Dropdown toggle={toggleRef => toggle(toggleRef)}>{dropdownChildren}</Dropdown>);

expect(screen.getByRole('button', { name: 'Dropdown' })).toBeVisible();
});

test('passes no class name by default', () => {
render(
<Dropdown isOpen={true} toggle={toggleRef => toggle(toggleRef)}>
{dropdownChildren}
</Dropdown>
);

expect(screen.getByTestId('menu-mock')).not.toHaveClass();
});

test('passes custom class name', () => {
render(
<Dropdown className="custom-class" isOpen={true} toggle={toggleRef => toggle(toggleRef)}>
{dropdownChildren}
</Dropdown>
);

expect(screen.getByTestId('menu-mock')).toHaveClass('custom-class');
});

test('does not pass isPlain to Menu by default', () => {
render(
<Dropdown isOpen={true} toggle={toggleRef => toggle(toggleRef)}>
{dropdownChildren}
</Dropdown>
);

expect(screen.getByText('isPlain: undefined')).toBeVisible();
});

test('passes isPlain to Menu', () => {
render(
<Dropdown isPlain isOpen={true} toggle={toggleRef => toggle(toggleRef)}>
{dropdownChildren}
</Dropdown>
);

expect(screen.getByText('isPlain: true')).toBeVisible();
});

test('does not pass isScrollable to Menu by default', () => {
render(
<Dropdown isOpen={true} toggle={toggleRef => toggle(toggleRef)}>
{dropdownChildren}
</Dropdown>
);

expect(screen.getByText('isScrollable: undefined')).toBeVisible();
});

test('passes isScrollable to Menu', () => {
render(
<Dropdown isScrollable isOpen={true} toggle={toggleRef => toggle(toggleRef)}>
{dropdownChildren}
</Dropdown>
);

expect(screen.getByText('isScrollable: true')).toBeVisible();
});

test('does not pass minWidth to Menu by default', () => {
render(
<Dropdown isOpen={true} toggle={toggleRef => toggle(toggleRef)}>
{dropdownChildren}
</Dropdown>
);

expect(screen.getByText('minWidth: undefined')).toBeVisible();
});

test('passes minWidth to Menu', () => {
render(
<Dropdown minWidth="100px" isOpen={true} toggle={toggleRef => toggle(toggleRef)}>
{dropdownChildren}
</Dropdown>
);

expect(screen.getByText('minWidth: 100px')).toBeVisible();
});

test('passes default zIndex to popper', () => {
render(<Dropdown toggle={toggleRef => toggle(toggleRef)}>{dropdownChildren}</Dropdown>);

expect(screen.getByText('zIndex: 9999')).toBeVisible();
});

test('passes zIndex to popper', () => {
render(
<Dropdown zIndex={100} toggle={toggleRef => toggle(toggleRef)}>
{dropdownChildren}
</Dropdown>
);

expect(screen.getByText('zIndex: 100')).toBeVisible();
});

test('does not pass isOpen to popper by default', () => {
render(<Dropdown toggle={toggleRef => toggle(toggleRef)}>{dropdownChildren}</Dropdown>);

expect(screen.getByText('isOpen: undefined')).toBeVisible();
});

test('passes isOpen to popper', () => {
render(
<Dropdown isOpen toggle={toggleRef => toggle(toggleRef)}>
{dropdownChildren}
</Dropdown>
);

expect(screen.getByText('isOpen: true')).toBeVisible();
});

/* no default tests for callback props
since there is no way to test that the
function doesn`t get passed */

test('passes onSelect callback', async () => {
const user = userEvent.setup();

const onSelect = jest.fn();
render(
<Dropdown onSelect={onSelect} toggle={toggleRef => toggle(toggleRef)}>
{dropdownChildren}
</Dropdown>
);

const trigger = await screen.findByText('Mock item');
await user.click(trigger);

expect(onSelect).toBeCalledTimes(1);
});

test('onOpenChange is called when passed and user clicks outside of dropdown', async () => {
const user = userEvent.setup();
const onOpenChange = jest.fn();

render(
<Dropdown isOpen={true} onOpenChange={onOpenChange} toggle={toggleRef => toggle(toggleRef)}>
{dropdownChildren}
</Dropdown>
);

const dropdown = screen.getByRole('button', { name: 'Dropdown' });
await user.click(dropdown);
await user.click(document.body);

expect(onOpenChange).toBeCalledTimes(1);
});

test('onOpenChange is called when passed and user presses tab key', async () => {
const user = userEvent.setup();
const onOpenChange = jest.fn();

render(
<Dropdown isOpen={true} onOpenChange={onOpenChange} toggle={toggleRef => toggle(toggleRef)}>
{dropdownChildren}
</Dropdown>
);

//focus dropdown
const dropdown = screen.getByRole('button', { name: 'Dropdown' });
await user.click(dropdown);
await user.keyboard('{Tab}');

expect(onOpenChange).toBeCalledTimes(1);
});

test('onOpenChange is called when passed and user presses esc key', async () => {
const user = userEvent.setup();
const onOpenChange = jest.fn();

render(
<Dropdown isOpen={true} onOpenChange={onOpenChange} toggle={toggleRef => toggle(toggleRef)}>
{dropdownChildren}
</Dropdown>
);

//focus dropdown
const dropdown = screen.getByRole('button', { name: 'Dropdown' });
await user.click(dropdown);
await user.keyboard('{Escape}');

expect(onOpenChange).toBeCalledTimes(1);
});

test('match snapshot', () => {
const { asFragment } = render(
<Dropdown
ouiaId={'dropdown'}
isOpen
isScrollable
isPlain
className={'customClass'}
toggle={toggleRef => toggle(toggleRef)}
>
{dropdownChildren}
</Dropdown>
);

expect(asFragment()).toMatchSnapshot();
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { DropdownGroup } from '../../Dropdown';
import { render, screen } from '@testing-library/react';
import React from 'react';

jest.mock('../../../../components/Menu');

const dropdownGroupChildren = <div>Dropdown Group children</div>;

test('renders dropdown group', () => {
render(
<div data-testid="dropdown-group">
<DropdownGroup>{dropdownGroupChildren}</DropdownGroup>
</div>
);

expect(screen.getByTestId('dropdown-group').children[0]).toBeVisible();
});

test('passes children', () => {
render(<DropdownGroup>{dropdownGroupChildren}</DropdownGroup>);

expect(screen.getByText('Dropdown Group children')).toBeVisible();
});

test('passes no class name by default', () => {
render(<DropdownGroup>{dropdownGroupChildren}</DropdownGroup>);

expect(screen.getByTestId('menu-group-mock')).not.toHaveClass();
});

test('passes custom class name to MenuGroup', () => {
render(<DropdownGroup className="custom-class">{dropdownGroupChildren}</DropdownGroup>);

expect(screen.getByTestId('menu-group-mock')).toHaveClass('custom-class');
});

test('passes no label by default', () => {
render(<DropdownGroup>{dropdownGroupChildren}</DropdownGroup>);

expect(screen.getByText('label: undefined')).toBeVisible();
});

test('passes custom label to MenuGroup', () => {
render(<DropdownGroup label="Test label">{dropdownGroupChildren}</DropdownGroup>);

expect(screen.getByText('label: Test label')).toBeVisible();
});

test('passes h1 as labelHeadingLevel to MenuGroup by default', () => {
render(<DropdownGroup>{dropdownGroupChildren}</DropdownGroup>);

expect(screen.getByText('labelHeadingLevel: h1')).toBeVisible();
});

test('passes custom labelHeadingLevel to MenuGroup', () => {
render(<DropdownGroup labelHeadingLevel="h2">{dropdownGroupChildren}</DropdownGroup>);

expect(screen.getByText('labelHeadingLevel: h2')).toBeVisible();
});

test('matches snapshot', () => {
const { asFragment } = render(
<DropdownGroup className="custom-class" label="Test label" labelHeadingLevel="h2">
{dropdownGroupChildren}
</DropdownGroup>
);

expect(asFragment()).toMatchSnapshot();
});
Loading