Skip to content

Commit

Permalink
test(TreeView): updated treeview test to use rtl (#13025)
Browse files Browse the repository at this point in the history
* test(TreeView): updated test to use rtl

* test(TreeView): updated test

* Update packages/react/src/components/TreeView/TreeView-test.js

Co-authored-by: Taylor Jones <tay1orjones@users.noreply.github.com>

* Apply suggestions from code review

Co-authored-by: Taylor Jones <tay1orjones@users.noreply.github.com>

* test(treeview): updated test

---------

Co-authored-by: TJ Egan <tw15egan@gmail.com>
Co-authored-by: Taylor Jones <tay1orjones@users.noreply.github.com>
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
  • Loading branch information
4 people committed Feb 8, 2023
1 parent b1a6be2 commit d8b5d6d
Show file tree
Hide file tree
Showing 2 changed files with 179 additions and 1,058 deletions.
247 changes: 179 additions & 68 deletions packages/react/src/components/TreeView/TreeView-test.js
Original file line number Diff line number Diff line change
@@ -1,95 +1,206 @@
/**
* Copyright IBM Corp. 2020
* Copyright IBM Corp. 2022
*
* This source code is licensed under the Apache-2.0 license found in the
* LICENSE file in the root directory of this source tree.
*/

import { CaretDown } from '@carbon/icons-react';
import React from 'react';
import { mount } from 'enzyme';
import { Document, Folder } from '@carbon/icons-react';
import TreeView, { TreeNode } from './';
import TreeView from './TreeView';
import TreeNode from './TreeNode';
import userEvent from '@testing-library/user-event';
import { fireEvent, render, screen, within } from '@testing-library/react';

const prefix = 'cds';

describe('TreeView', () => {
let wrapper;
let onTreeSelect;
let onNodeSelect;

beforeEach(() => {
onTreeSelect = jest.fn();
onNodeSelect = jest.fn();
wrapper = mount(
<TreeView label="Tree view" selected={['1']} onSelect={onTreeSelect}>
<TreeNode id="1" value="1" label="1" />
<TreeNode id="2" value="2" label="2" onSelect={onNodeSelect} />
<TreeNode id="5" value="5" label="5" isExpanded>
<TreeNode id="5-1" value="5-1" label="5-1" />
<TreeNode id="5-2" value="5-2" label="5-2" />
<TreeNode id="5-3" value="5-3" label="5-3" isExpanded>
<TreeNode id="5-4" value="5-4" label="5-4" />
describe('renders as expected - Component API', () => {
it('should spread extra props onto outermost element', () => {
render(<TreeView data-testid="test-id" label="Tree" />);

expect(screen.getByRole('tree')).toHaveAttribute(
'data-testid',
'test-id'
);
});

it('should respect active prop', () => {
render(
<TreeView active="Node 1" label="Tree">
<TreeNode data-testid="Node 1" id="Node 1" label="Node 1" />
<TreeNode id="Node 2" label="Node 2" />
</TreeView>
);

const node = screen.getByTestId('Node 1');

expect(node).toHaveClass(`${prefix}--tree-node--active`);
});

it('should render children as expected', () => {
render(
<TreeView label="Tree View">
<TreeNode isExpanded={true} data-testid="Node 1" label="Node 1">
<TreeNode data-testid="Node 2" label="Node 2" />
</TreeNode>
</TreeNode>
</TreeView>
);
});
</TreeView>
);

it('should render', () => {
expect(wrapper).toMatchSnapshot();
});
const nodeParent = screen.getByTestId('Node 1');
const nodeChild = screen.getByTestId('Node 2');

expect(nodeParent).toHaveClass(`${prefix}--tree-parent-node`);
expect(nodeChild).toHaveClass(`${prefix}--tree-leaf-node`);

expect(within(nodeParent).getByText('Node 1')).toBeInTheDocument();
expect(within(nodeChild).getByText('Node 2')).toBeInTheDocument();
});

it('should support a custom `className` prop on the outermost element', () => {
const { container } = render(
<TreeView className="custom-class" label="Tree" />
);

const ul = container?.getElementsByTagName('ul')[0];

expect(ul).toHaveClass('custom-class');
});

it('should respect hideLabel prop', () => {
render(
<TreeView id="Tree" label="Tree View" hideLabel>
<TreeNode id="Node 1" data-testid="Node 1" label="Node 1" />
</TreeView>
);

expect(
screen.queryByText('Tree View', { selector: 'label' })
).not.toBeInTheDocument();
});

it('should respect label prop', () => {
render(
<TreeView label="Tree View" selected={['Node 1']}>
<TreeNode id="Node 1" data-testid="Node 1" label="Node 1" />
</TreeView>
);

expect(screen.getByLabelText('Tree View')).toBeInTheDocument();
});

it('should respect multiselect prop', () => {
render(
<TreeView multiselect label="Tree">
<TreeNode data-testid="Node 1" label="Node 1" />
<TreeNode data-testid="Node 2" label="Node 2" />
</TreeView>
);

const tree = screen.getByRole('tree');
const lists = tree?.getElementsByTagName('li');

it('should render with icons', () => {
wrapper = mount(
<TreeView label="Tree view" selected={['1']}>
<TreeNode renderIcon={Document} id="1" value="1" label="1" />
<TreeNode renderIcon={Document} id="2" value="2" label="2" />
<TreeNode renderIcon={Folder} id="5" value="5" label="5" isExpanded>
<TreeNode renderIcon={Document} id="5-1" value="5-1" label="5-1" />
<TreeNode renderIcon={Document} id="5-2" value="5-2" label="5-2" />
userEvent.click(lists[0], { ctrlKey: true });
userEvent.click(lists[1], { ctrlKey: true });

expect(lists[0]).toHaveAttribute('aria-selected', 'true');
expect(lists[1]).toHaveAttribute('aria-selected', 'true');
});

it('should respect onSelect prop', () => {
const onSelectSpy = jest.fn();

render(
<TreeView label="Tree View">
<TreeNode
renderIcon={Folder}
id="5-3"
value="5-3"
label="5-3"
isExpanded>
<TreeNode renderIcon={Document} id="5-4" value="5-4" label="5-4" />
</TreeNode>
</TreeNode>
</TreeView>
);
expect(wrapper).toMatchSnapshot();
});
onSelect={onSelectSpy}
id="Node 1"
data-testid="Node 1"
label="Node 1"
/>
</TreeView>
);

it('should be able to hide the label', () => {
expect(wrapper.find('TreeLabel').text()).toBe('Tree view');
wrapper.setProps({ hideLabel: true });
expect(wrapper.find('TreeLabel').text()).toBeFalsy();
});
fireEvent.click(screen.getByTestId('Node 1'));

describe('Single node selection', () => {
it('should be able to preselect a node', () => {
expect(wrapper.find(`.${prefix}--tree-node--selected`).text()).toBe('1');
expect(onSelectSpy).toHaveBeenCalled();
});

it('should handle selection at the tree level', () => {
const onTreeSelect = jest.fn();
wrapper.setProps({ onSelect: onTreeSelect });
wrapper.find('TreeNode[value="2"]').simulate('click');
expect(onTreeSelect).toHaveBeenCalledTimes(1);
it('should respect selected prop', () => {
render(
<TreeView label="Tree View" selected={['Node 1']}>
<TreeNode id="Node 1" data-testid="Node 1" label="Node 1" />
</TreeView>
);

expect(screen.getByRole('treeitem', { name: 'Node 1' })).toHaveClass(
`${prefix}--tree-node--selected`
);
});

it('should handle selection at the node level', () => {
wrapper.find('TreeNode[value="2"]').simulate('click');
expect(onTreeSelect).toHaveBeenCalledTimes(1);
expect(onNodeSelect).toHaveBeenCalledTimes(1);
it('should respect size prop', () => {
render(<TreeView size="xs" label="Tree" />);

const tree = screen.getByRole('tree');

expect(tree).toHaveClass(`${prefix}--tree--xs`);
});
});

describe('Tree node expansion', () => {
it('Caret icon should not render in leaf nodes', () => {
expect(wrapper.find(CaretDown).length).toBe(2);
describe('behaves as expected', () => {
it('should render tree with expanded node', () => {
render(
<TreeView label="Tree View">
<TreeNode data-testid="Node 1" label="Node 1" isExpanded={true}>
<TreeNode data-testid="Node 2" label="Node 2" />
</TreeNode>
</TreeView>
);

const nodeParent = screen.getByTestId('Node 1');
const nodeChild = nodeParent?.querySelector('div > span');

expect(nodeChild).toHaveClass(`${prefix}--tree-parent-node__toggle`);
expect(within(nodeParent).getByText('Node 1')).toBeInTheDocument();
expect(within(nodeParent).getByText('Node 2')).toBeInTheDocument();
});

it('should render tree with disabled nodes', () => {
render(
<TreeView label="Tree View">
<TreeNode label="Node 1" data-testid="Node 1" />
<TreeNode
data-testid="Node 2"
label="Node 2"
disabled={true}
isExpanded={true}>
<TreeNode isExpanded={true} data-testid="Node 3" label="Node 3" />
</TreeNode>
</TreeView>
);

const nodeChild = screen.getByTestId('Node 2');

expect(nodeChild.getAttribute('aria-disabled')).toEqual('true');
});

it('should render tree with icons', () => {
const CustomIcon = jest.fn(() => {
return <svg data-testid="test-icon" />;
});

render(
<TreeView label="Tree View">
<TreeNode
renderIcon={CustomIcon}
data-testid="Node 1"
label="Node 1"
/>
</TreeView>
);

expect(screen.getByTestId('Node 1')).toHaveClass(
`${prefix}--tree-node--with-icon`
);
});
});
});
Loading

0 comments on commit d8b5d6d

Please sign in to comment.