Unverified Commit 4d39d5fd authored by Manoj Pandian Sakthivel's avatar Manoj Pandian Sakthivel Committed by GitHub
Browse files

Update accordion component tests (#479)

parent 16c42b78
Pipeline #138260 passed with stages
in 4 minutes and 53 seconds
......@@ -15,8 +15,9 @@
*/
import React from 'react';
import { render } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { mount } from 'enzyme';
import Accordion from './Accordion';
import AccordionItem from './AccordionItem';
import AccordionItemHeading from './AccordionItemHeading';
......@@ -30,40 +31,42 @@ enum UUIDS {
describe('Accordion', () => {
it('renders without erroring', () => {
expect(() => {
mount(<Accordion />);
render(<Accordion />);
}).not.toThrow();
});
describe('className', () => {
it('is “accordionDefault” by default', () => {
const wrapper = mount(<Accordion />);
expect(wrapper.find('div').hasClass('accordionDefault')).toBe(true);
const { container } = render(<Accordion />);
expect(container.querySelector('.accordionDefault')).toBeTruthy();
});
it('can be extended', () => {
const wrapper = mount(<Accordion className="foo" />);
const { container } = render(<Accordion className="foo" />);
expect(wrapper.find('div').props().className).toEqual(
'accordionDefault foo'
);
expect(
container.querySelector('.accordionDefault')?.classList.contains('foo')
).toBe(true);
});
it('can also be overridden by using extendDefaultStyles === false', () => {
const wrapper = mount(
const { container } = render(
<Accordion className="foo" extendDefaultStyles={false} />
);
expect(wrapper.find('div').props().className).toEqual('foo');
expect(
container.querySelector('.foo')?.classList.contains('accordionDefault')
).toBe(false);
});
});
describe('expanding and collapsing: ', () => {
it('permits multiple items to be expanded when allowMultipleExpanded is true', () => {
const [FooHeader, BarHeader] = [
(): JSX.Element => <AccordionItemButton />,
(): JSX.Element => <AccordionItemButton />
(): JSX.Element => <AccordionItemButton className="foo" />,
(): JSX.Element => <AccordionItemButton className="bar" />
];
const wrapper = mount(
const { container } = render(
<Accordion allowMultipleExpanded={true}>
<AccordionItem>
<AccordionItemHeading>
......@@ -78,24 +81,31 @@ describe('Accordion', () => {
</Accordion>
);
wrapper.find(FooHeader).simulate('click');
wrapper.find(BarHeader).simulate('click');
expect(wrapper.find(FooHeader).find('div').props()['aria-expanded']).toBe(
true
);
expect(wrapper.find(BarHeader).find('div').props()['aria-expanded']).toBe(
true
);
userEvent.click(container.querySelector('.foo') as HTMLButtonElement);
userEvent.click(container.querySelector('.bar') as HTMLButtonElement);
expect(
container
.querySelector('.foo')
?.closest('div')
?.getAttribute('aria-expanded')
).toBe('true');
expect(
container
.querySelector('.bar')
?.closest('div')
?.getAttribute('aria-expanded')
).toBe('true');
});
it('does not permit multiple items to be expanded when allowMultipleExpanded is false', () => {
const [FooHeader, BarHeader] = [
(): JSX.Element => <AccordionItemButton />,
(): JSX.Element => <AccordionItemButton />
(): JSX.Element => <AccordionItemButton className="foo" />,
(): JSX.Element => <AccordionItemButton className="bar" />
];
const wrapper = mount(
const { container } = render(
<Accordion>
<AccordionItem>
<AccordionItemHeading>
......@@ -110,20 +120,27 @@ describe('Accordion', () => {
</Accordion>
);
wrapper.find(FooHeader).simulate('click');
wrapper.find(BarHeader).simulate('click');
expect(wrapper.find(FooHeader).find('div').props()['aria-expanded']).toBe(
false
);
expect(wrapper.find(BarHeader).find('div').props()['aria-expanded']).toBe(
true
);
userEvent.click(container.querySelector('.foo') as HTMLButtonElement);
userEvent.click(container.querySelector('.bar') as HTMLButtonElement);
expect(
container
.querySelector('.foo')
?.closest('div')
?.getAttribute('aria-expanded')
).toBe('false');
expect(
container
.querySelector('.bar')
?.closest('div')
?.getAttribute('aria-expanded')
).toBe('true');
});
describe('allowZeroExpanded prop', () => {
it('permits the last-expanded item to be collapsed when explicitly true', () => {
const wrapper = mount(
const { container } = render(
<Accordion allowZeroExpanded={true}>
<AccordionItem>
<AccordionItemHeading>
......@@ -133,16 +150,27 @@ describe('Accordion', () => {
</Accordion>
);
wrapper.find(AccordionItemButton).simulate('click');
wrapper.find(AccordionItemButton).simulate('click');
userEvent.click(
container.querySelector(
'.accordionButtonDefault'
) as HTMLButtonElement
);
userEvent.click(
container.querySelector(
'.accordionButtonDefault'
) as HTMLButtonElement
);
expect(
wrapper.find(AccordionItemButton).find('div').props()['aria-expanded']
).toEqual(false);
container
.querySelector('.accordionButtonDefault')
?.closest('div')
?.getAttribute('aria-expanded')
).toBe('false');
});
it('prevents the last-expanded item being collapsed by default', () => {
const wrapper = mount(
const { container } = render(
<Accordion allowZeroExpanded={false}>
<AccordionItem>
<AccordionItemHeading>
......@@ -152,18 +180,25 @@ describe('Accordion', () => {
</Accordion>
);
wrapper.find(AccordionItemButton).simulate('click');
wrapper.find(AccordionItemButton).simulate('click');
const accordionButtonDefault = container.querySelector(
'.accordionButtonDefault'
) as HTMLButtonElement;
userEvent.click(accordionButtonDefault);
userEvent.click(accordionButtonDefault);
expect(
wrapper.find(AccordionItemButton).find('div').props()['aria-expanded']
).toEqual(true);
container
.querySelector('.accordionButtonDefault')
?.closest('div')
?.getAttribute('aria-expanded')
).toBe('true');
});
});
describe('preExpanded prop', () => {
it('expands items whose uuid props match those passed', () => {
const wrapper = mount(
const { container } = render(
<Accordion preExpanded={[UUIDS.FOO]}>
<AccordionItem uuid={UUIDS.FOO}>
<AccordionItemHeading>
......@@ -174,12 +209,15 @@ describe('Accordion', () => {
);
expect(
wrapper.find(AccordionItemButton).find('div').props()['aria-expanded']
).toEqual(true);
container
.querySelector('.accordionButtonDefault')
?.closest('div')
?.getAttribute('aria-expanded')
).toEqual('true');
});
it('collapses items by default', () => {
const wrapper = mount(
const { container } = render(
<Accordion>
<AccordionItem>
<AccordionItemHeading>
......@@ -190,15 +228,18 @@ describe('Accordion', () => {
);
expect(
wrapper.find(AccordionItemButton).find('div').props()['aria-expanded']
).toEqual(false);
container
.querySelector('.accordionButtonDefault')
?.closest('div')
?.getAttribute('aria-expanded')
).toEqual('false');
});
});
describe('onChange prop', () => {
it('is invoked with an array of expanded items’ uuids, if there are any', async () => {
it('is invoked with an array of expanded items’ uuids, if there are any', () => {
const onChange = jest.fn();
const wrapper = mount(
const { container } = render(
<Accordion onChange={onChange}>
<AccordionItem uuid={UUIDS.FOO}>
<AccordionItemHeading>
......@@ -208,17 +249,18 @@ describe('Accordion', () => {
</Accordion>
);
wrapper.find(AccordionItemButton).simulate('click');
// ugly hack: fall back to the end of event queue, giving priority to useEffect and useState
await new Promise((resolve) => setTimeout(resolve, 0));
userEvent.click(
container.querySelector(
'.accordionButtonDefault'
) as HTMLButtonElement
);
expect(onChange).toHaveBeenCalledWith([UUIDS.FOO]);
});
it('is invoked with an empty array, if no items are expanded', async () => {
it('is invoked with an empty array, if no items are expanded', () => {
const onChange = jest.fn();
const wrapper = mount(
const { container } = render(
<Accordion
onChange={onChange}
preExpanded={[UUIDS.FOO]}
......@@ -232,10 +274,11 @@ describe('Accordion', () => {
</Accordion>
);
wrapper.find(AccordionItemButton).simulate('click');
// ugly hack: fall back to the end of event queue, giving priority to useEffect and useState
await new Promise((resolve) => setTimeout(resolve, 0));
userEvent.click(
container.querySelector(
'.accordionButtonDefault'
) as HTMLButtonElement
);
expect(onChange).toHaveBeenCalledWith([]);
});
......
......@@ -15,17 +15,17 @@
*/
import React from 'react';
import { mount } from 'enzyme';
import { render } from '@testing-library/react';
import { Consumer, Provider } from './AccordionContext';
describe('ItemContext', () => {
it('renders children props', () => {
const wrapper = mount(
const { container } = render(
<Provider>
<Consumer>{(): string => 'Hello World'}</Consumer>
</Provider>
);
expect(wrapper.text()).toBe('Hello World');
expect(container.textContent).toBe('Hello World');
});
});
......@@ -15,53 +15,54 @@
*/
import React from 'react';
import { mount } from 'enzyme';
import { render } from '@testing-library/react';
import Accordion from './Accordion';
import AccordionItem from './AccordionItem';
describe('AccordionItem', () => {
it('renders without erroring', () => {
expect(() => {
mount(<Accordion />);
render(<Accordion />);
}).not.toThrow();
});
describe('className prop', () => {
it('is "accordionItemDefault" by default', () => {
const wrapper = mount(
const { container } = render(
<Accordion>
<AccordionItem uuid={'FOO'} />
</Accordion>
);
expect(
wrapper.find(AccordionItem).find('div').hasClass('accordionItemDefault')
).toBe(true);
expect(container.querySelector('.accordionItemDefault')).toBeTruthy();
});
it('can be extended', () => {
const wrapper = mount(
const { container } = render(
<Accordion>
<AccordionItem uuid={'FOO'} className="foo" />
</Accordion>
);
expect(container.querySelector('.accordionItemDefault')).toBeTruthy();
expect(
wrapper.find(AccordionItem).find('div').hasClass('accordionItemDefault')
container
.querySelector('.accordionItemDefault')
?.classList.contains('foo')
).toBe(true);
expect(wrapper.find(AccordionItem).find('div').hasClass('foo')).toBe(
true
);
});
});
describe('children prop', () => {
it('is respected', () => {
const wrapper = mount(
const { container } = render(
<Accordion>
<AccordionItem>Hello World</AccordionItem>
</Accordion>
);
expect(wrapper.find(AccordionItem).text()).toBe('Hello World');
expect(
container.querySelector('.accordionItemDefault')?.textContent
).toBe('Hello World');
});
});
});
......@@ -15,7 +15,7 @@
*/
import React from 'react';
import { mount } from 'enzyme';
import { render } from '@testing-library/react';
import Accordion from './Accordion';
import AccordionItem from './AccordionItem';
import AccordionItemButton from './AccordionItemButton';
......@@ -24,13 +24,13 @@ import AccordionItemHeading from './AccordionItemHeading';
describe('AccordionItemButton', () => {
it('renders without erroring', () => {
expect(() => {
mount(<AccordionItemButton />);
render(<AccordionItemButton />);
}).not.toThrow();
});
describe('className prop', () => {
it('is accordionButton by default', () => {
const wrapper = mount(
const { container } = render(
<Accordion>
<AccordionItem uuid={'FOO'}>
<AccordionItemHeading>
......@@ -40,16 +40,11 @@ describe('AccordionItemButton', () => {
</Accordion>
);
expect(
wrapper
.find(AccordionItemButton)
.find('div')
.hasClass('accordionButtonDefault')
).toBe(true);
expect(container.querySelector('.accordionButtonDefault')).toBeTruthy();
});
it('can be extended', () => {
const wrapper = mount(
const { container } = render(
<Accordion>
<AccordionItem uuid={'FOO'}>
<AccordionItemHeading>
......@@ -60,21 +55,16 @@ describe('AccordionItemButton', () => {
);
expect(
wrapper
.find(AccordionItemButton)
.find('div')
.hasClass('accordionButtonDefault')
).toBe(true);
expect(
wrapper.find(AccordionItemButton).find('div').hasClass('foo')
container
.querySelector('.accordionButtonDefault')
?.classList.contains('foo')
).toBe(true);
});
});
describe('children prop', () => {
it('is respected', () => {
const wrapper = mount(
const { container } = render(
<Accordion>
<AccordionItem>
<AccordionItemHeading>
......@@ -84,13 +74,15 @@ describe('AccordionItemButton', () => {
</Accordion>
);
expect(wrapper.find(AccordionItemButton).text()).toBe('Hello World');
expect(
container.querySelector('.accordionButtonDefault')?.textContent
).toBe('Hello World');
});
});
describe('disabled prop', () => {
it('applies the accordionButtonDisabled className', () => {
const wrapper = mount(
const { container } = render(
<Accordion>
<AccordionItem>
<AccordionItemHeading>
......@@ -102,7 +94,9 @@ describe('AccordionItemButton', () => {
</Accordion>
);
expect(wrapper.find('.accordionButtonDisabled')).toHaveLength(1);
expect(
container.querySelectorAll('.accordionButtonDisabled')
).toHaveLength(1);
});
});
});
......@@ -15,7 +15,7 @@
*/
import React from 'react';
import { mount } from 'enzyme';
import { render } from '@testing-library/react';
import Accordion from './Accordion';
import AccordionItem from './AccordionItem';
import AccordionItemButton from './AccordionItemButton';
......@@ -24,13 +24,13 @@ import AccordionItemHeading, { SPEC_ERROR } from './AccordionItemHeading';
describe('AccordionItemHeading', () => {
it('renders without erroring', () => {
expect(() => {
mount(<AccordionItemHeading />);
render(<AccordionItemHeading />);
}).not.toThrow();
});
describe('children prop', () => {
it('is respected', () => {
const wrapper = mount(
const { container } = render(
<Accordion>
<AccordionItem>
<AccordionItemHeading>
......@@ -39,7 +39,9 @@ describe('AccordionItemHeading', () => {
</AccordionItem>
</Accordion>
);
expect(wrapper.find(AccordionItemButton).text()).toEqual('Hello World');
expect(
container.querySelector('.accordionButtonDefault')?.textContent
).toEqual('Hello World');
});
});
......@@ -59,7 +61,7 @@ describe('AccordionItemHeading', () => {
it('permits a single AccordionItemButton as a child', () => {
expect(() =>
mount(
render(
<Accordion>
<AccordionItem>
<AccordionItemHeading>
......@@ -73,7 +75,7 @@ describe('AccordionItemHeading', () => {
it('permits a single AccordionItemButton as a child within an array', () => {
expect(() =>
mount(
render(
<Accordion>
<AccordionItem>
<AccordionItemHeading>
......@@ -89,7 +91,7 @@ describe('AccordionItemHeading', () => {
it('does not permit multiple AccordionItemButton as children within an array', () => {
expect(() =>
mount(
render(
<Accordion>
<AccordionItem>
<AccordionItemHeading>
......@@ -106,7 +108,7 @@ describe('AccordionItemHeading', () => {
it('throws an error if you don’t nest an AccordionItemButton', () => {
expect(() =>
mount(
render(
<Accordion>
<AccordionItem>
<AccordionItemHeading />
......@@ -118,7 +120,7 @@ describe('AccordionItemHeading', () => {
it('throws an error if you nest any non-AccordionItemButton element', () => {
expect(() =>
mount(
render(
<Accordion>
<AccordionItem>
<AccordionItemHeading>Foo</AccordionItemHeading>
......
......@@ -15,7 +15,7 @@
*/
import React from 'react';
import { mount } from 'enzyme';
import { render } from '@testing-library/react';
import Accordion from './Accordion';
import AccordionItem from './AccordionItem';
import AccordionItemPanel from './AccordionItemPanel';
......@@ -28,13 +28,13 @@ enum UUIDS {
describe('AccordionItemPanel', () => {
it('renders without erroring', () => {
expect(() => {