import React from 'react'; import 'jest-styled-components'; import 'jest-axe/extend-expect'; import 'regenerator-runtime/runtime'; import { render } from '@testing-library/react'; import { fireEvent } from '@testing-library/dom'; import { Grommet } from '../../Grommet'; import { Pagination } from '..'; const NUM_ITEMS = 237; const STEP = 10; const data = []; for (let i = 0; i < 95; i += 1) { data.push(`entry-${i}`); } describe('Pagination', () => { test(`should display the correct last page based on items length and step`, () => { const { container, getByText } = render( , ); // default step is 10 const expectedPageCount = Math.ceil(NUM_ITEMS / 10); const lastPageButton = getByText(expectedPageCount.toString()); expect(lastPageButton).toBeTruthy(); expect(container.firstChild).toMatchSnapshot(); }); test('should render correct numberEdgePages', () => { const { container } = render( , ); expect(container.firstChild).toMatchSnapshot(); }); test('should render correct numberMiddlePages when odd', () => { const { container } = render( , ); expect(container.firstChild).toMatchSnapshot(); }); test('should render correct numberMiddlePages when even', () => { const { container } = render( , ); expect(container.firstChild).toMatchSnapshot(); }); test('should show correct page when "page" is provided ', () => {}); test(`should disable previous and next controls when numberItems < step`, () => { const { container } = render( , ); const previousButtonDisabled = ( container.querySelector( `[aria-label="Go to previous page"]`, ) as HTMLButtonElement ).hasAttribute('disabled'); const nextButtonDisabled = ( container.querySelector( `[aria-label="Go to next page"]`, ) as HTMLButtonElement ).hasAttribute('disabled'); expect(previousButtonDisabled).toBeTruthy(); expect(nextButtonDisabled).toBeTruthy(); expect(container.firstChild).toMatchSnapshot(); }); test(`should disable previous and next controls when numberItems === step`, () => { const { container } = render( , ); const previousButtonDisabled = ( container.querySelector( `[aria-label="Go to previous page"]`, ) as HTMLButtonElement ).hasAttribute('disabled'); const nextButtonDisabled = ( container.querySelector( `[aria-label="Go to next page"]`, ) as HTMLButtonElement ).hasAttribute('disabled'); expect(previousButtonDisabled).toBeTruthy(); expect(nextButtonDisabled).toBeTruthy(); expect(container.firstChild).toMatchSnapshot(); }); test(`should disable previous and next controls when numberItems === 0`, () => { const { container } = render( , ); const previousButtonDisabled = ( container.querySelector( `[aria-label="Go to previous page"]`, ) as HTMLButtonElement ).hasAttribute('disabled'); const nextButtonDisabled = ( container.querySelector( `[aria-label="Go to next page"]`, ) as HTMLButtonElement ).hasAttribute('disabled'); expect(previousButtonDisabled).toBeTruthy(); expect(nextButtonDisabled).toBeTruthy(); expect(container.firstChild).toMatchSnapshot(); }); test(`should set page to last page if page prop > total possible pages`, () => { const numberItems = 500; const step = 50; const { container, getByText } = render( , ); const expectedPage = `${Math.ceil(numberItems / step)}`; fireEvent.click(getByText(expectedPage)); const activePage = ( container.querySelector(`[aria-current="page"]`) as HTMLButtonElement ).innerHTML; expect(activePage).toEqual(expectedPage); expect(container.firstChild).toMatchSnapshot(); }); // how to not hard code so many values test(`should allow user to control page via state with page + onChange`, () => { const onChange = jest.fn(); const { container, getByLabelText } = render( , ); const nextPageButton = getByLabelText('Go to next page'); fireEvent.click(nextPageButton); // step is 10 by default, so startIndex/endIndex are based on that expect(onChange).toBeCalledWith( expect.objectContaining({ page: 2, startIndex: 10, endIndex: 20 }), ); expect(container.firstChild).toMatchSnapshot(); }); test(`should display next page of results when "next" is selected`, () => { const onChange = jest.fn(); const { container, getByLabelText } = render( , ); const nextPageButton = getByLabelText('Go to next page'); // mouse click fireEvent.click(nextPageButton); expect(onChange).toBeCalledTimes(1); expect(container.firstChild).toMatchSnapshot(); // keyboard enter fireEvent.keyDown(nextPageButton, { key: 'Enter', keyCode: 13, which: 13, }); expect(onChange).toBeCalledTimes(1); expect(container.firstChild).toMatchSnapshot(); }); test(`should display previous page of results when "previous" is selected`, () => { const onChange = jest.fn(); const { container, getByLabelText } = render( , ); const previousPageButton = getByLabelText('Go to previous page'); // mouse click fireEvent.click(previousPageButton); expect(onChange).toBeCalledTimes(1); expect(container.firstChild).toMatchSnapshot(); // keyboard enter fireEvent.keyDown(previousPageButton, { key: 'Enter', keyCode: 13, which: 13, }); expect(onChange).toBeCalledTimes(1); expect(container.firstChild).toMatchSnapshot(); }); test(`should display page 'n' of results when "page n" is selected`, () => { const { container, getByText } = render( , ); const desiredPage = '2'; fireEvent.click(getByText(desiredPage)); const activePage = ( container.querySelector(`[aria-current="page"]`) as HTMLButtonElement ).innerHTML; expect(activePage).toEqual(desiredPage); expect(container.firstChild).toMatchSnapshot(); }); test(`should disable previous button if on first page`, () => { const { container } = render( , ); const previousButtonDisabled = ( container.querySelector( `[aria-label="Go to previous page"]`, ) as HTMLButtonElement ).hasAttribute('disabled'); expect(previousButtonDisabled).toBeTruthy(); expect(container.firstChild).toMatchSnapshot(); }); test(`should disable next button if on last page`, () => { const lastPage = Math.ceil(NUM_ITEMS / STEP); const { container } = render( , ); const nextButtonDisabled = ( container.querySelector( `[aria-label="Go to next page"]`, ) as HTMLButtonElement ).hasAttribute('disabled'); expect(nextButtonDisabled).toBeTruthy(); expect(container.firstChild).toMatchSnapshot(); }); test(`should set numberMiddlePages = 1 if user provides value < 1`, () => { console.warn = jest.fn(); const { container } = render( , ); expect(console.warn).toHaveBeenCalledTimes(1); expect(container.firstChild).toMatchSnapshot(); }); test(`should apply custom theme`, () => { const customTheme = { pagination: { container: { extend: `background: red;`, }, }, }; const { container } = render( , ); expect(container.firstChild).toMatchSnapshot(); }); test(`should apply button kind style when referenced by a string`, () => { const customTheme = { button: { default: {}, bright: { color: 'text-strong', border: { color: 'skyblue', width: '2px', }, }, active: { bright: { background: { color: '#CA9CEA', }, border: { color: 'transparent', }, color: 'text', }, }, }, pagination: { button: 'bright', }, }; const { container } = render( , ); expect(container.firstChild).toMatchSnapshot(); }); test(`should apply size`, () => { const { container } = render( , ); expect(container.firstChild).toMatchSnapshot(); }); test(`should change the page on prop change`, () => { const { container, rerender } = render( , ); expect( (container.querySelector(`[aria-current="page"]`) as HTMLButtonElement) .innerHTML, ).toBe('1'); rerender( , ); expect( (container.querySelector(`[aria-current="page"]`) as HTMLButtonElement) .innerHTML, ).toBe('2'); expect(container.firstChild).toMatchSnapshot(); }); test(`should apply a11yTitle and aria-label`, () => { const { container, getByLabelText } = render( , ); expect(getByLabelText('pagination-test')).toBeTruthy(); expect(getByLabelText('pagination-test-2')).toBeTruthy(); expect(container.firstChild).toMatchSnapshot(); }); });