Skip to content

Commit

Permalink
Facepile (v8): convert tests to use testing-library (#22282)
Browse files Browse the repository at this point in the history
  • Loading branch information
TristanWatanabe authored Apr 9, 2022
1 parent 69bcdf2 commit c4a33ca
Show file tree
Hide file tree
Showing 2 changed files with 376 additions and 409 deletions.
115 changes: 53 additions & 62 deletions packages/react/src/components/Facepile/Facepile.test.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
import * as React from 'react';
import * as renderer from 'react-test-renderer';
import { mount } from 'enzyme';
import { render } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { TestImages } from '@fluentui/example-data';
import { setRTL } from '../../Utilities';
import { Facepile } from './Facepile';
import { OverflowButtonType } from './Facepile.types';
import { PersonaSize } from '../../Persona';
import { Persona } from '../../Persona';
import { PersonaCoin } from '../../PersonaCoin';
import { findNodes, expectOne, expectMissing } from '../../common/testUtilities';
import { isConformant } from '../../common/isConformant';
import type { IFacepilePersona } from './Facepile.types';

Expand Down Expand Up @@ -37,9 +34,8 @@ describe('Facepile', () => {
});

it('renders Facepile correctly', () => {
const component = renderer.create(<Facepile personas={facepilePersonas} />);
const tree = component.toJSON();
expect(tree).toMatchSnapshot();
const { container } = render(<Facepile personas={facepilePersonas} />);
expect(container).toMatchSnapshot();
});

isConformant({
Expand All @@ -51,60 +47,59 @@ describe('Facepile', () => {
});

it('renders with only add button if no personas found and addButtonProps are not null', () => {
const wrapper = mount(<Facepile personas={[]} addButtonProps={{}} showAddButton={true} />);
const { getAllByRole } = render(<Facepile personas={[]} addButtonProps={{}} showAddButton={true} />);

expectOne(wrapper, '.ms-Facepile-addButton');
expectOne(wrapper, '.ms-Facepile-itemButton');
expect(getAllByRole('button')).toHaveLength(1);
});

it('renders chevron overflow button if overflowButtonProps are not null and OverflowButtonType is downArrow', () => {
const wrapper = mount(
const { getAllByRole } = render(
<Facepile personas={[]} overflowButtonProps={{}} overflowButtonType={OverflowButtonType.downArrow} />,
);

expectOne(wrapper, '.ms-Facepile-overflowButton');
expectOne(wrapper, '.ms-Facepile-itemButton');
expect(getAllByRole('button')).toHaveLength(1);
});

it('renders more overflow button if overflowButtonProps are not null as OverflowButtonType is more', () => {
const wrapper = mount(
const { getAllByRole } = render(
<Facepile personas={[]} overflowButtonProps={{}} overflowButtonType={OverflowButtonType.more} />,
);

expectOne(wrapper, '.ms-Facepile-overflowButton');
expectOne(wrapper, '.ms-Facepile-itemButton');
expect(getAllByRole('button')).toHaveLength(1);
});

// eslint-disable-next-line @fluentui/max-len
it('renders without descriptive overflow button if overflowButtonProps are not null and maximum personas are not exceeded', () => {
const wrapper = mount(
const { queryAllByRole } = render(
<Facepile personas={[]} overflowButtonProps={{}} overflowButtonType={OverflowButtonType.descriptive} />,
);

expectMissing(wrapper, '.ms-Facepile-descriptiveOverflowButton');
expectMissing(wrapper, '.ms-Facepile-itemButton');
expect(queryAllByRole('button')).toHaveLength(0);
});

// eslint-disable-next-line @fluentui/max-len
it('renders with descriptive overflow button if overflowButtonProps are not null and maximum personas are exceeded', () => {
const personas: IFacepilePersona[] = facepilePersonas.concat(...facepilePersonas, ...facepilePersonas);
const wrapper = mount(
const { getAllByRole } = render(
<Facepile
personas={personas}
maxDisplayablePersonas={5}
overflowButtonProps={{}}
overflowButtonType={OverflowButtonType.descriptive}
/>,
);
expectOne(wrapper, '.ms-Facepile-descriptiveOverflowButton');
expect(findNodes(wrapper, '.ms-Facepile-itemButton').length).toEqual(6);
const overflowButton = getAllByRole('button')[1];
const personasDisplayed = getAllByRole('listitem');

expect(overflowButton.className).toContain('ms-Facepile-descriptiveOverflowButton');
expect(personasDisplayed).toHaveLength(5);
});

it('renders descriptive overflow button with comma-delimited persona names as title value by default', () => {
const personas: IFacepilePersona[] = facepilePersonas.concat(...facepilePersonas, ...facepilePersonas);
const maxDisplayablePersonas: number = 5;

const wrapper = mount(
const { getAllByRole } = render(
<Facepile
personas={personas}
maxDisplayablePersonas={maxDisplayablePersonas}
Expand All @@ -118,35 +113,35 @@ describe('Facepile', () => {
.map((p: IFacepilePersona) => p.personaName)
.join(', ');

expect(
findNodes(wrapper, '.ms-Facepile-descriptiveOverflowButton').getDOMNode().attributes.getNamedItem('title'),
).toHaveProperty('value', overflowPersonasTitle);
const overflowButton = getAllByRole('button')[1];

expect(overflowButton.getAttribute('title')).toEqual(overflowPersonasTitle);
});

it('renders a descriptive overflow button with a custom title', () => {
const personas: IFacepilePersona[] = facepilePersonas.concat(...facepilePersonas, ...facepilePersonas);
const title: string = 'custom title';
const wrapper = mount(
const { getAllByRole } = render(
<Facepile
personas={personas}
maxDisplayablePersonas={5}
overflowButtonProps={{ title }}
overflowButtonType={OverflowButtonType.descriptive}
/>,
);
expect(
findNodes(wrapper, '.ms-Facepile-descriptiveOverflowButton').getDOMNode().attributes.getNamedItem('title'),
).toHaveProperty('value', title);
const overflowButton = getAllByRole('button')[1];

expect(overflowButton.getAttribute('title')).toEqual(title);
});

it('renders no more than maximum allowed personas', () => {
const wrapper = mount(
const { getAllByRole } = render(
<Facepile
personas={facepilePersonas.concat(facepilePersonas, facepilePersonas, facepilePersonas)}
maxDisplayablePersonas={2}
/>,
);
expect(findNodes(wrapper, '.ms-Facepile-itemButton').length).toEqual(2);
expect(getAllByRole('listitem')).toHaveLength(2);
});

it('persona is clickable if onClick property is set', () => {
Expand All @@ -161,17 +156,17 @@ describe('Facepile', () => {
},
];

const wrapper = mount(<Facepile personas={personas} />);
const { getAllByRole } = render(<Facepile personas={personas} />);

const buttons = findNodes(wrapper, '.ms-Facepile-itemButton');
const buttons = getAllByRole('button');

expect(buttons.length).toEqual(1);
buttons.simulate('click');
expect(buttons).toHaveLength(1);
userEvent.click(buttons[0]);
expect(clicked).toEqual(1);
});

it('personas and buttons render default size if not specified', () => {
const wrapper = mount(
const { getAllByRole } = render(
<Facepile
personas={facepilePersonas}
addButtonProps={{}}
Expand All @@ -181,49 +176,45 @@ describe('Facepile', () => {
/>,
);

expectOne(wrapper, '.ms-Facepile-addButton .ms-Persona-coin.ms-Persona--size32');
expectOne(wrapper, '.ms-Facepile-overflowButton .ms-Persona--size32');
const [addButton, overflowButton] = getAllByRole('button');

const faces = findNodes(wrapper, '.ms-Facepile-person .ms-Persona-coin');
expect(addButton.querySelectorAll('.ms-Persona--size32')).toHaveLength(1);
expect(overflowButton.querySelectorAll('.ms-Persona--size32')).toHaveLength(1);

expect(faces.length).toEqual(facepilePersonas.length);
const faces = getAllByRole('listitem');

expect(faces).toHaveLength(facepilePersonas.length);
for (let i = 0; i < faces.length; ++i) {
expect(faces.at(i).hasClass('ms-Persona--size32')).toBeTruthy();
expect(faces[i].querySelector('.ms-Persona--size32')).toBeTruthy();
}
});

it('personas and buttons render specified size', () => {
// Test XXS size renders
let wrapper = mount(<Facepile personas={facepilePersonas} personaSize={PersonaSize.size24} />);

expect(wrapper.find(PersonaCoin).length).toEqual(facepilePersonas.length);
wrapper.find(PersonaCoin).forEach(node => {
// Need multiple Dives since PersonaCoin is decorated
expect(node.find('.ms-Persona--size24').length).toEqual(1);
const { getAllByRole, rerender } = render(
<Facepile personas={facepilePersonas} personaSize={PersonaSize.size24} />,
);
expect(getAllByRole('listitem')).toHaveLength(facepilePersonas.length);
getAllByRole('listitem').forEach(node => {
expect(node.querySelectorAll('.ms-Persona--size24')).toHaveLength(1);
});

// Test small size renders
wrapper = mount(<Facepile personas={facepilePersonas} personaSize={PersonaSize.size40} />);

expect(wrapper.find(PersonaCoin).length).toEqual(facepilePersonas.length);
wrapper.find(PersonaCoin).forEach(node => {
// Need multiple Dives since PersonaCoin is decorated
expect(node.find('.ms-Persona--size40').length).toEqual(1);
rerender(<Facepile personas={facepilePersonas} personaSize={PersonaSize.size40} />);
expect(getAllByRole('listitem')).toHaveLength(facepilePersonas.length);
getAllByRole('listitem').forEach(node => {
expect(node.querySelectorAll('.ms-Persona--size40')).toHaveLength(1);
});
});

it('renders Persona control if exactly one persona is sent in props', () => {
const wrapper = mount(<Facepile personas={facepilePersonas.slice(0, 1)} overflowPersonas={[]} />);
const { getAllByRole } = render(<Facepile personas={facepilePersonas.slice(0, 1)} overflowPersonas={[]} />);

expect(wrapper.find(PersonaCoin).length).toEqual(1);
expect(wrapper.find(Persona).length).toEqual(1);
expect(getAllByRole('listitem')).toHaveLength(1);
});

it('renders no Persona or PersonaCoin if 0 is passed in for maxDisplayablePersonas', () => {
const wrapper = mount(<Facepile personas={facepilePersonas} maxDisplayablePersonas={0} />);
const { queryAllByRole } = render(<Facepile personas={facepilePersonas} maxDisplayablePersonas={0} />);

expect(wrapper.find(PersonaCoin).length).toEqual(0);
expect(wrapper.find(Persona).length).toEqual(0);
expect(queryAllByRole('listitem')).toHaveLength(0);
});
});
Loading

0 comments on commit c4a33ca

Please sign in to comment.