Skip to content

Commit

Permalink
refactor(react): update PaginationNav tests to rtl (#12072)
Browse files Browse the repository at this point in the history
* refactor(react): add RTL tests for PaginationNav and remove enzyme tests

* chore(react): add comment and update tests builder

* chore(react): remove comment

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
  • Loading branch information
abbeyhrt and kodiakhq[bot] authored Sep 13, 2022
1 parent 3719443 commit c66e77f
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 221 deletions.
310 changes: 93 additions & 217 deletions packages/react/src/components/PaginationNav/PaginationNav-test.js
Original file line number Diff line number Diff line change
@@ -1,237 +1,113 @@
/**
* 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 React from 'react';
import PaginationNav from '../PaginationNav';
import { mount } from 'enzyme';
import { expect } from 'window-or-global';

const prefix = 'cds';
import PaginationNav from './PaginationNav';
import userEvent from '@testing-library/user-event';
import { render, screen } from '@testing-library/react';

describe('PaginationNav', () => {
const props = {
className: 'extra-class',
totalItems: 24,
itemsShown: 8,
page: 1,
};

const renderPaginationNav = (additionalProps = {}) =>
mount(<PaginationNav {...props} {...additionalProps} />);

describe('renders as expected', () => {
const pagination = renderPaginationNav();

describe('container', () => {
it('should render the expected classes', () => {
const container = pagination.childAt(0);
expect(container.hasClass(`${prefix}--pagination-nav`)).toBe(true);
expect(container.hasClass(`extra-class`)).toBe(true);
});
describe('renders as expected - Component API', () => {
it('should spread extra props onto outermost element', () => {
const { container } = render(
<PaginationNav totalItems={10} data-testid="test-id" />
);

expect(container.firstChild).toHaveAttribute('data-testid', 'test-id');
});

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

expect(container.firstChild).toHaveClass('custom-class');
});

it('should respect itemsShown prop', () => {
render(<PaginationNav totalItems={10} itemsShown={4} />);

expect(
document.querySelectorAll('.cds--pagination-nav__page').length
).toBe(4);
});

it('should respect loop prop', () => {
render(<PaginationNav totalItems={4} loop />);

userEvent.click(screen.getByText('4'));

userEvent.click(screen.getByLabelText('Next'));
expect(screen.getByText('1')).toHaveAttribute('aria-current', 'page');

userEvent.click(screen.getByText('1'));
userEvent.click(screen.getByLabelText('Previous'));

expect(screen.getByText('4')).toHaveAttribute('aria-current', 'page');
});

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

render(<PaginationNav totalItems={10} onChange={onChange} />);
userEvent.click(screen.getByText('4'));
expect(onChange).toHaveBeenCalled();
});

describe('items', () => {
it('should render n page items, where n = props.itemsShown', () => {
const pages = pagination.find(`.${prefix}--pagination-nav__page`);
expect(pages.length).toBe(props.itemsShown);
});

it('should render the expected classes for the active page', () => {
const activePage = pagination
.find(`.${prefix}--pagination-nav__page`)
.at(props.page);
expect(
activePage.hasClass(`${prefix}--pagination-nav__page--active`)
).toBe(true);
});

it('should disable "Previous" button when on first page and props.loop = false', () => {
let i = 0;

const pNav = renderPaginationNav({
page: 0,
loop: false,
onChange: () => {
i++;
},
});

const button = pNav
.find(`.${prefix}--pagination-nav__list-item`)
.first()
.childAt(0);

expect(button.props().disabled).toBe(true);
expect(i).toBe(0);
button.simulate('click');
expect(i).toBe(0);
});
it('should respect page prop', () => {
render(<PaginationNav totalItems={10} page={3} />);

expect(screen.getByText('4')).toHaveAttribute('aria-current', 'page');
});

it('should disable "Next" button when on last page and props.loop = false', () => {
let i = 0;

const pNav = renderPaginationNav({
page: 23,
loop: false,
onChange: () => {
i++;
},
});

const button = pNav
.find(`.${prefix}--pagination-nav__list-item`)
.last()
.childAt(0);

expect(button.props().disabled).toBe(true);
expect(i).toBe(0);
button.simulate('click');
expect(i).toBe(0);
it('should respect totalItems prop', () => {
render(<PaginationNav totalItems={5} />);

expect(
document.querySelectorAll('.cds--pagination-nav__page').length
).toBe(5);
});

it('should disable "Previous" button when on first page and loop is false', () => {
render(<PaginationNav totalItems={4} />);

expect(screen.getByLabelText('Previous')).toHaveProperty('disabled');
});

it('should disable "Next" button when on last page and loop is false', () => {
render(<PaginationNav totalItems={4} page={3} />);

expect(screen.getByLabelText('Next')).toHaveProperty('disabled');
});
});

describe('behaves as expected', () => {
describe('direction buttons', () => {
it('should move to next page when "Next" button is pressed', () => {
const pagination = renderPaginationNav();

let pages = pagination.find(`.${prefix}--pagination-nav__page`);
let activePage = pagination.find(
`.${prefix}--pagination-nav__page--active`
);
expect(activePage.matchesElement(pages.get(props.page))).toBe(true);

pagination.find(`.${prefix}--btn`).last().simulate('click');

pages = pagination.find(`.${prefix}--pagination-nav__page`);
activePage = pagination.find(
`.${prefix}--pagination-nav__page--active`
);
expect(activePage.matchesElement(pages.get(props.page + 1))).toBe(true);
});

it('should move to previous page when "Previous" button is pressed', () => {
const pagination = renderPaginationNav();

let pages = pagination.find(`.${prefix}--pagination-nav__page`);
let activePage = pagination.find(
`.${prefix}--pagination-nav__page--active`
);
expect(activePage.matchesElement(pages.get(props.page))).toBe(true);

pagination
.find(`.${prefix}--popover-container`)
.first()
.childAt(0)
.simulate('click');

pages = pagination.find(`.${prefix}--pagination-nav__page`);
activePage = pagination.find(
`.${prefix}--pagination-nav__page--active`
);
expect(activePage.matchesElement(pages.get(props.page - 1))).toBe(true);
});

it('should move to page when user clicks on one', () => {
const pagination = renderPaginationNav();

let pages = pagination.find(`.${prefix}--pagination-nav__page`);
let activePage = pagination.find(
`.${prefix}--pagination-nav__page--active`
);
expect(activePage.matchesElement(pages.get(props.page))).toBe(true);

pagination
.find(`.${prefix}--pagination-nav__page`)
.at(4)
.simulate('click');

pages = pagination.find(`.${prefix}--pagination-nav__page`);
activePage = pagination.find(
`.${prefix}--pagination-nav__page--active`
);
expect(activePage.matchesElement(pages.get(4))).toBe(true);
});

it('should emit onChange when moved to new page', () => {
let i = 0;

const pagination = renderPaginationNav({
onChange: () => {
i++;
},
});

expect(i).toBe(0);
pagination
.find(`.${prefix}--popover-container`)
.first()
.childAt(0)
.simulate('click');
expect(i).toBe(1);
pagination.find(`.${prefix}--btn`).last().simulate('click');
expect(i).toBe(2);
pagination
.find(`.${prefix}--pagination-nav__list-item`)
.at(2)
.childAt(0)
.simulate('click');
expect(i).toBe(3);
});

it('should move to last page when "Previous" button is pressed on first page and props.loop = true', () => {
const pagination = renderPaginationNav({
page: 0,
loop: true,
});

let pages = pagination.find(`.${prefix}--pagination-nav__page`);
let activePage = pagination.find(
`.${prefix}--pagination-nav__page--active`
);
expect(activePage.matchesElement(pages.get(0))).toBe(true);

pagination
.find(`.${prefix}--popover-container`)
.first()
.childAt(0)
.simulate('click');

pages = pagination.find(`.${prefix}--pagination-nav__page`);
activePage = pagination.find(
`.${prefix}--pagination-nav__page--active`
);
expect(activePage.matchesElement(pages.get(pages.length - 1))).toBe(
true
);
});

it('should move to first page when "Next" button is pressed on last page and props.loop = true', () => {
const pagination = renderPaginationNav({
page: 23,
loop: true,
});

let pages = pagination.find(`.${prefix}--pagination-nav__page`);
let activePage = pagination.find(
`.${prefix}--pagination-nav__page--active`
);
expect(activePage.matchesElement(pages.get(pages.length - 1))).toBe(
true
);
pagination.find(`.${prefix}--btn`).last().simulate('click');

pages = pagination.find(`.${prefix}--pagination-nav__page`);
activePage = pagination.find(
`.${prefix}--pagination-nav__page--active`
);
expect(activePage.matchesElement(pages.get(0))).toBe(true);
});
it('should move to next page when "Next" is pressed', () => {
render(<PaginationNav totalItems={4} loop />);

userEvent.click(screen.getByLabelText('Next'));
expect(screen.getByText('2')).toHaveAttribute('aria-current', 'page');
});

it('should move to previous page when "Previous" is pressed', () => {
render(<PaginationNav totalItems={4} loop />);

userEvent.click(screen.getByText('4'));

userEvent.click(screen.getByLabelText('Previous'));
expect(screen.getByText('3')).toHaveAttribute('aria-current', 'page');
});

it('should move to page that is pressed', () => {
render(<PaginationNav totalItems={4} loop />);

userEvent.click(screen.getByText('4'));

expect(screen.getByText('4')).toHaveAttribute('aria-current', 'page');
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -464,7 +464,7 @@ PaginationNav.propTypes = {
onChange: PropTypes.func,

/**
* The current page.
* The index of current page.
*/
page: PropTypes.number,

Expand Down
20 changes: 17 additions & 3 deletions packages/react/tasks/build-test-rtl.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ function writeTestFile(props, componentName, isSubComponent) {
prop === 'onBlur' ||
prop === 'onMouseEnter' ||
prop === 'onMouseLeave' ||
prop === 'onFocus'
prop === 'onFocus' ||
prop === 'onChange'
) {
test = `it('should call ${prop} when expected', () => {
const ${prop} = jest.fn();
Expand All @@ -51,7 +52,14 @@ function writeTestFile(props, componentName, isSubComponent) {
});

const testFile = isSubComponent
? `import React from 'react';
? `/**
* 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 React from 'react';
import ${componentName} from '../${componentName}';
import userEvent from '@testing-library/user-event';
import { render, screen } from '@testing-library/react';
Expand All @@ -72,7 +80,13 @@ function writeTestFile(props, componentName, isSubComponent) {
})
});
`
: `
: `/**
* 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 React from 'react';
import ${componentName} from './${componentName}';
import userEvent from '@testing-library/user-event';
Expand Down

0 comments on commit c66e77f

Please sign in to comment.