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 @@ ...@@ -15,8 +15,9 @@
*/ */
import React from 'react'; 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 Accordion from './Accordion';
import AccordionItem from './AccordionItem'; import AccordionItem from './AccordionItem';
import AccordionItemHeading from './AccordionItemHeading'; import AccordionItemHeading from './AccordionItemHeading';
...@@ -30,40 +31,42 @@ enum UUIDS { ...@@ -30,40 +31,42 @@ enum UUIDS {
describe('Accordion', () => { describe('Accordion', () => {
it('renders without erroring', () => { it('renders without erroring', () => {
expect(() => { expect(() => {
mount(<Accordion />); render(<Accordion />);
}).not.toThrow(); }).not.toThrow();
}); });
describe('className', () => { describe('className', () => {
it('is “accordionDefault” by default', () => { it('is “accordionDefault” by default', () => {
const wrapper = mount(<Accordion />); const { container } = render(<Accordion />);
expect(wrapper.find('div').hasClass('accordionDefault')).toBe(true); expect(container.querySelector('.accordionDefault')).toBeTruthy();
}); });
it('can be extended', () => { it('can be extended', () => {
const wrapper = mount(<Accordion className="foo" />); const { container } = render(<Accordion className="foo" />);
expect(wrapper.find('div').props().className).toEqual( expect(
'accordionDefault foo' container.querySelector('.accordionDefault')?.classList.contains('foo')
); ).toBe(true);
}); });
it('can also be overridden by using extendDefaultStyles === false', () => { it('can also be overridden by using extendDefaultStyles === false', () => {
const wrapper = mount( const { container } = render(
<Accordion className="foo" extendDefaultStyles={false} /> <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: ', () => { describe('expanding and collapsing: ', () => {
it('permits multiple items to be expanded when allowMultipleExpanded is true', () => { it('permits multiple items to be expanded when allowMultipleExpanded is true', () => {
const [FooHeader, BarHeader] = [ const [FooHeader, BarHeader] = [
(): JSX.Element => <AccordionItemButton />, (): JSX.Element => <AccordionItemButton className="foo" />,
(): JSX.Element => <AccordionItemButton /> (): JSX.Element => <AccordionItemButton className="bar" />
]; ];
const wrapper = mount( const { container } = render(
<Accordion allowMultipleExpanded={true}> <Accordion allowMultipleExpanded={true}>
<AccordionItem> <AccordionItem>
<AccordionItemHeading> <AccordionItemHeading>
...@@ -78,24 +81,31 @@ describe('Accordion', () => { ...@@ -78,24 +81,31 @@ describe('Accordion', () => {
</Accordion> </Accordion>
); );
wrapper.find(FooHeader).simulate('click'); userEvent.click(container.querySelector('.foo') as HTMLButtonElement);
wrapper.find(BarHeader).simulate('click'); userEvent.click(container.querySelector('.bar') as HTMLButtonElement);
expect(wrapper.find(FooHeader).find('div').props()['aria-expanded']).toBe( expect(
true container
); .querySelector('.foo')
expect(wrapper.find(BarHeader).find('div').props()['aria-expanded']).toBe( ?.closest('div')
true ?.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', () => { it('does not permit multiple items to be expanded when allowMultipleExpanded is false', () => {
const [FooHeader, BarHeader] = [ const [FooHeader, BarHeader] = [
(): JSX.Element => <AccordionItemButton />, (): JSX.Element => <AccordionItemButton className="foo" />,
(): JSX.Element => <AccordionItemButton /> (): JSX.Element => <AccordionItemButton className="bar" />
]; ];
const wrapper = mount( const { container } = render(
<Accordion> <Accordion>
<AccordionItem> <AccordionItem>
<AccordionItemHeading> <AccordionItemHeading>
...@@ -110,20 +120,27 @@ describe('Accordion', () => { ...@@ -110,20 +120,27 @@ describe('Accordion', () => {
</Accordion> </Accordion>
); );
wrapper.find(FooHeader).simulate('click'); userEvent.click(container.querySelector('.foo') as HTMLButtonElement);
wrapper.find(BarHeader).simulate('click'); userEvent.click(container.querySelector('.bar') as HTMLButtonElement);
expect(wrapper.find(FooHeader).find('div').props()['aria-expanded']).toBe( expect(
false container
); .querySelector('.foo')
expect(wrapper.find(BarHeader).find('div').props()['aria-expanded']).toBe( ?.closest('div')
true ?.getAttribute('aria-expanded')
); ).toBe('false');
expect(
container
.querySelector('.bar')
?.closest('div')
?.getAttribute('aria-expanded')
).toBe('true');
}); });
describe('allowZeroExpanded prop', () => { describe('allowZeroExpanded prop', () => {
it('permits the last-expanded item to be collapsed when explicitly true', () => { it('permits the last-expanded item to be collapsed when explicitly true', () => {
const wrapper = mount( const { container } = render(
<Accordion allowZeroExpanded={true}> <Accordion allowZeroExpanded={true}>
<AccordionItem> <AccordionItem>
<AccordionItemHeading> <AccordionItemHeading>
...@@ -133,16 +150,27 @@ describe('Accordion', () => { ...@@ -133,16 +150,27 @@ describe('Accordion', () => {
</Accordion> </Accordion>
); );
wrapper.find(AccordionItemButton).simulate('click'); userEvent.click(
wrapper.find(AccordionItemButton).simulate('click'); container.querySelector(
'.accordionButtonDefault'
) as HTMLButtonElement
);
userEvent.click(
container.querySelector(
'.accordionButtonDefault'
) as HTMLButtonElement
);
expect( expect(
wrapper.find(AccordionItemButton).find('div').props()['aria-expanded'] container
).toEqual(false); .querySelector('.accordionButtonDefault')
?.closest('div')
?.getAttribute('aria-expanded')
).toBe('false');
}); });
it('prevents the last-expanded item being collapsed by default', () => { it('prevents the last-expanded item being collapsed by default', () => {
const wrapper = mount( const { container } = render(
<Accordion allowZeroExpanded={false}> <Accordion allowZeroExpanded={false}>
<AccordionItem> <AccordionItem>
<AccordionItemHeading> <AccordionItemHeading>
...@@ -152,18 +180,25 @@ describe('Accordion', () => { ...@@ -152,18 +180,25 @@ describe('Accordion', () => {
</Accordion> </Accordion>
); );
wrapper.find(AccordionItemButton).simulate('click'); const accordionButtonDefault = container.querySelector(
wrapper.find(AccordionItemButton).simulate('click'); '.accordionButtonDefault'
) as HTMLButtonElement;
userEvent.click(accordionButtonDefault);
userEvent.click(accordionButtonDefault);
expect( expect(
wrapper.find(AccordionItemButton).find('div').props()['aria-expanded'] container
).toEqual(true); .querySelector('.accordionButtonDefault')
?.closest('div')
?.getAttribute('aria-expanded')
).toBe('true');
}); });
}); });
describe('preExpanded prop', () => { describe('preExpanded prop', () => {
it('expands items whose uuid props match those passed', () => { it('expands items whose uuid props match those passed', () => {
const wrapper = mount( const { container } = render(
<Accordion preExpanded={[UUIDS.FOO]}> <Accordion preExpanded={[UUIDS.FOO]}>
<AccordionItem uuid={UUIDS.FOO}> <AccordionItem uuid={UUIDS.FOO}>
<AccordionItemHeading> <AccordionItemHeading>
...@@ -174,12 +209,15 @@ describe('Accordion', () => { ...@@ -174,12 +209,15 @@ describe('Accordion', () => {
); );
expect( expect(
wrapper.find(AccordionItemButton).find('div').props()['aria-expanded'] container
).toEqual(true); .querySelector('.accordionButtonDefault')
?.closest('div')
?.getAttribute('aria-expanded')
).toEqual('true');
}); });
it('collapses items by default', () => { it('collapses items by default', () => {
const wrapper = mount( const { container } = render(
<Accordion> <Accordion>
<AccordionItem> <AccordionItem>
<AccordionItemHeading> <AccordionItemHeading>
...@@ -190,15 +228,18 @@ describe('Accordion', () => { ...@@ -190,15 +228,18 @@ describe('Accordion', () => {
); );
expect( expect(
wrapper.find(AccordionItemButton).find('div').props()['aria-expanded'] container
).toEqual(false); .querySelector('.accordionButtonDefault')
?.closest('div')
?.getAttribute('aria-expanded')
).toEqual('false');
}); });
}); });
describe('onChange prop', () => { 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 onChange = jest.fn();
const wrapper = mount( const { container } = render(
<Accordion onChange={onChange}> <Accordion onChange={onChange}>
<AccordionItem uuid={UUIDS.FOO}> <AccordionItem uuid={UUIDS.FOO}>
<AccordionItemHeading> <AccordionItemHeading>
...@@ -208,17 +249,18 @@ describe('Accordion', () => { ...@@ -208,17 +249,18 @@ describe('Accordion', () => {
</Accordion> </Accordion>
); );
wrapper.find(AccordionItemButton).simulate('click'); userEvent.click(
container.querySelector(
// ugly hack: fall back to the end of event queue, giving priority to useEffect and useState '.accordionButtonDefault'
await new Promise((resolve) => setTimeout(resolve, 0)); ) as HTMLButtonElement
);
expect(onChange).toHaveBeenCalledWith([UUIDS.FOO]); 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 onChange = jest.fn();
const wrapper = mount( const { container } = render(
<Accordion <Accordion
onChange={onChange} onChange={onChange}
preExpanded={[UUIDS.FOO]} preExpanded={[UUIDS.FOO]}
...@@ -232,10 +274,11 @@ describe('Accordion', () => { ...@@ -232,10 +274,11 @@ describe('Accordion', () => {
</Accordion> </Accordion>
); );
wrapper.find(AccordionItemButton).simulate('click'); userEvent.click(
container.querySelector(
// ugly hack: fall back to the end of event queue, giving priority to useEffect and useState '.accordionButtonDefault'
await new Promise((resolve) => setTimeout(resolve, 0)); ) as HTMLButtonElement
);
expect(onChange).toHaveBeenCalledWith([]); expect(onChange).toHaveBeenCalledWith([]);
}); });
......
...@@ -15,17 +15,17 @@ ...@@ -15,17 +15,17 @@
*/ */
import React from 'react'; import React from 'react';
import { mount } from 'enzyme'; import { render } from '@testing-library/react';
import { Consumer, Provider } from './AccordionContext'; import { Consumer, Provider } from './AccordionContext';
describe('ItemContext', () => { describe('ItemContext', () => {
it('renders children props', () => { it('renders children props', () => {
const wrapper = mount( const { container } = render(
<Provider> <Provider>
<Consumer>{(): string => 'Hello World'}</Consumer> <Consumer>{(): string => 'Hello World'}</Consumer>
</Provider> </Provider>
); );
expect(wrapper.text()).toBe('Hello World'); expect(container.textContent).toBe('Hello World');
}); });
}); });
...@@ -15,53 +15,54 @@ ...@@ -15,53 +15,54 @@
*/ */
import React from 'react'; import React from 'react';
import { mount } from 'enzyme'; import { render } from '@testing-library/react';
import Accordion from './Accordion'; import Accordion from './Accordion';
import AccordionItem from './AccordionItem'; import AccordionItem from './AccordionItem';
describe('AccordionItem', () => { describe('AccordionItem', () => {
it('renders without erroring', () => { it('renders without erroring', () => {
expect(() => { expect(() => {
mount(<Accordion />); render(<Accordion />);
}).not.toThrow(); }).not.toThrow();
}); });
describe('className prop', () => { describe('className prop', () => {
it('is "accordionItemDefault" by default', () => { it('is "accordionItemDefault" by default', () => {
const wrapper = mount( const { container } = render(
<Accordion> <Accordion>
<AccordionItem uuid={'FOO'} /> <AccordionItem uuid={'FOO'} />
</Accordion> </Accordion>
); );
expect( expect(container.querySelector('.accordionItemDefault')).toBeTruthy();
wrapper.find(AccordionItem).find('div').hasClass('accordionItemDefault')
).toBe(true);
}); });
it('can be extended', () => { it('can be extended', () => {
const wrapper = mount( const { container } = render(
<Accordion> <Accordion>
<AccordionItem uuid={'FOO'} className="foo" /> <AccordionItem uuid={'FOO'} className="foo" />
</Accordion> </Accordion>
); );
expect(container.querySelector('.accordionItemDefault')).toBeTruthy();
expect( expect(
wrapper.find(AccordionItem).find('div').hasClass('accordionItemDefault') container
.querySelector('.accordionItemDefault')
?.classList.contains('foo')
).toBe(true); ).toBe(true);
expect(wrapper.find(AccordionItem).find('div').hasClass('foo')).toBe(
true
);
}); });
}); });
describe('children prop', () => { describe('children prop', () => {
it('is respected', () => { it('is respected', () => {
const wrapper = mount( const { container } = render(
<Accordion> <Accordion>
<AccordionItem>Hello World</AccordionItem> <AccordionItem>Hello World</AccordionItem>
</Accordion> </Accordion>
); );
expect(wrapper.find(AccordionItem).text()).toBe('Hello World'); expect(
container.querySelector('.accordionItemDefault')?.textContent
).toBe('Hello World');
}); });
}); });
}); });
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
*/ */
import React from 'react'; import React from 'react';
import { mount } from 'enzyme'; import { render } from '@testing-library/react';
import Accordion from './Accordion'; import Accordion from './Accordion';
import AccordionItem from './AccordionItem'; import AccordionItem from './AccordionItem';
import AccordionItemButton from './AccordionItemButton'; import AccordionItemButton from './AccordionItemButton';
...@@ -24,13 +24,13 @@ import AccordionItemHeading from './AccordionItemHeading'; ...@@ -24,13 +24,13 @@ import AccordionItemHeading from './AccordionItemHeading';
describe('AccordionItemButton', () => { describe('AccordionItemButton', () => {
it('renders without erroring', () => { it('renders without erroring', () => {
expect(() => { expect(() => {
mount(<AccordionItemButton />); render(<AccordionItemButton />);
}).not.toThrow(); }).not.toThrow();
}); });
describe('className prop', () => { describe('className prop', () => {
it('is accordionButton by default', () => { it('is accordionButton by default', () => {
const wrapper = mount( const { container } = render(
<Accordion> <Accordion>
<AccordionItem uuid={'FOO'}> <AccordionItem uuid={'FOO'}>
<AccordionItemHeading> <AccordionItemHeading>
...@@ -40,16 +40,11 @@ describe('AccordionItemButton', () => { ...@@ -40,16 +40,11 @@ describe('AccordionItemButton', () => {
</Accordion> </Accordion>
); );
expect( expect(container.querySelector('.accordionButtonDefault')).toBeTruthy();
wrapper
.find(AccordionItemButton)
.find('div')
.hasClass('accordionButtonDefault')
).toBe(true);
}); });