import userEvent from '@testing-library/user-event'
import * as React from 'react'
import renderWithTheme from '../../tests/helpers/renderWithTheme'
import Pagination from './Pagination'
function ManagedPagination({ size, start, onClick }: any): React.ReactElement {
const [current, setCurrent] = React.useState(start)
const callback = !onClick
? setCurrent
: (page: number) => {
onClick(page)
setCurrent(page)
}
return
}
const expectIcon = (node: HTMLElement, disabled: boolean, label: string) => {
expect(node.childNodes).toHaveLength(1)
expect((node.firstChild as HTMLElement).tagName).toBe('svg')
expect(node).toHaveAttribute('aria-label', label)
if (disabled) {
expect(node).toHaveAttribute('aria-disabled', 'true')
} else {
expect(node).not.toHaveAttribute('aria-disabled')
}
}
const expectPageLink = (node: HTMLElement, page: number, currentPage: number) => {
expect(node).toHaveTextContent(`${page}`)
if (page === currentPage) {
expect(node).toHaveAttribute('aria-label', `Current page, ${page}`)
expect(node).toHaveAttribute('aria-disabled', 'true')
expect(node).toHaveAttribute('aria-current', 'page')
} else {
expect(node).toHaveAttribute('aria-label', `Go to page ${page}`)
expect(node).not.toHaveAttribute('aria-disabled')
expect(node).not.toHaveAttribute('aria-current')
}
}
const assertPages = (
links: HTMLElement[],
size: number,
currentPage: number,
hiddenPages: number[]
) => {
const length = size - hiddenPages.length + 4
expect(links).toHaveLength(length)
expect(length).toBeLessThan(14)
const prevPage = Math.max(1, currentPage - 1)
expectIcon(links[0], currentPage === 1, 'Go to page 1')
expectIcon(links[1], currentPage <= 1, `Go to previous page, ${prevPage}`)
expect(links[1]).toHaveAttribute('rel', 'prev')
let page = 1
for (let ix = 2; ix < length - 2; ix++) {
while (hiddenPages.includes(page)) {
page += 1
}
expectPageLink(links[ix], page++, currentPage)
}
const nextPage = Math.min(size, currentPage + 1)
expectIcon(links[length - 2], currentPage >= size, `Go to next page, ${nextPage}`)
expect(links[length - 2]).toHaveAttribute('rel', 'next')
expectIcon(links[length - 1], currentPage === size, `Go to last page, ${size}`)
}
describe('component: Pagination', () => {
test('11 pages, first page selected', () => {
const { getAllByRole } = renderWithTheme()
assertPages(getAllByRole('link'), 11, 1, [9, 10, 11])
})
test('11 pages, go to middle page', () => {
const { getAllByRole, getByLabelText } = renderWithTheme(
)
userEvent.click(getByLabelText('Go to page 6'))
assertPages(getAllByRole('link'), 11, 6, [1, 2, 10, 11])
})
test('11 pages, go to next page', () => {
const { getAllByRole, getByLabelText } = renderWithTheme(
)
userEvent.click(getByLabelText('Go to next page, 7'))
assertPages(getAllByRole('link'), 11, 7, [1, 2, 3])
})
test('11 pages, go to previous page', () => {
const { getAllByRole, getByLabelText } = renderWithTheme(
)
userEvent.click(getByLabelText('Go to previous page, 4'))
assertPages(getAllByRole('link'), 11, 4, [9, 10, 11])
})
test('11 pages, go to first page', () => {
const { getAllByRole, getByLabelText } = renderWithTheme(
)
userEvent.click(getByLabelText('Go to page 1'))
assertPages(getAllByRole('link'), 11, 1, [9, 10, 11])
})
test('11 pages, go to last page', () => {
const { getAllByRole, getByLabelText } = renderWithTheme(
)
userEvent.click(getByLabelText('Go to last page, 11'))
assertPages(getAllByRole('link'), 11, 11, [1, 2, 3])
})
test('9 pages, no hidden pages', () => {
const { getAllByRole, getByLabelText } = renderWithTheme(
)
assertPages(getAllByRole('link'), 9, 1, [])
userEvent.click(getByLabelText('Go to last page, 9'))
assertPages(getAllByRole('link'), 9, 9, [])
})
test('test onclick for disabled buttons', () => {
const func = jest.fn()
const { getAllByRole } = renderWithTheme(
)
const links = getAllByRole('link')
for (const link of links.slice(0, 3)) {
userEvent.click(link)
}
expect(func).not.toHaveBeenCalled()
userEvent.click(links[3])
expect(func).toHaveBeenCalledWith(2)
for (const link of getAllByRole('link').slice(3)) {
userEvent.click(link)
}
expect(func).toHaveBeenCalledTimes(1)
})
})