Files
summercms/admin/tests/list/Pagination.test.ts
Jakub Zych 1c2a66df45 test(10-05): bring every SPA module, composable and component under Vitest
- 41 unit and component suites under admin/tests/{app,state,shell,list,form,relation,views,ui}
  covering states and a11y roles; every src module is imported by a test
- typed fixture helper assigns each JSON fixture to its generated OpenAPI type
- fix: iconFor ignores inherited object members such as "constructor"
- fix: field controls import ./control instead of the registry (import cycle
  left a renderer unregistered depending on module load order)
- fix: dropdown shows the placeholder for an unknown stored value next to an emptyOption
- fix: list announces a failed schema load even when the rows arrive after it
- tailwind no longer scans admin/tests; boardwalk/dist rebuilt
2026-09-27 17:53:57 +02:00

85 lines
4.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { beforeEach, describe, expect, it } from 'vitest'
import { mount } from '@vue/test-utils'
import Pagination from '../../src/components/list/Pagination.vue'
import type { ListMeta } from '../../src/api/types'
import { resetState } from '../helpers'
function meta(page: number, lastPage: number, total = lastPage * 20, perPage = 20): ListMeta {
return { page, last_page: lastPage, total, per_page: perPage }
}
function pager(page: number, lastPage: number) {
const wrapper = mount(Pagination, { props: { meta: meta(page, lastPage), loading: false, perPageOptions: [20], perPage: 20 } })
return wrapper
.findAll('nav > *')
.filter((element) => !['prev', 'next'].includes(element.attributes('data-page') ?? ''))
.map((element) => element.text())
.join(' ')
}
beforeEach(() => {
resetState()
})
describe('pagination', () => {
it('shows the range of the page and a labelled pager', () => {
const wrapper = mount(Pagination, { props: { meta: meta(2, 3, 45), loading: false, perPageOptions: [20], perPage: 20 } })
expect(wrapper.find('[data-range]').text()).toBe('21–40 z 45')
expect(wrapper.find('nav').attributes('aria-label')).toBe('Stronicowanie')
expect(wrapper.find('[data-page="2"]').attributes('aria-current')).toBe('page')
expect(wrapper.find('[data-page="1"]').attributes('aria-current')).toBeUndefined()
})
it.each([
[1, 1, '1'],
[1, 5, '1 2 3 … 5'],
[3, 5, '1 2 3 4 5'],
[5, 10, '1 … 4 5 6 … 10'],
[10, 10, '1 … 8 9 10'],
[2, 3, '1 2 3'],
])('page %i of %i shows %s', (page, last, expected) => {
expect(pager(page, last)).toBe(expected)
})
it('disables prev on the first and next on the last page and emits pages', async () => {
const wrapper = mount(Pagination, { props: { meta: meta(1, 3), loading: false, perPageOptions: [20], perPage: 20 } })
expect(wrapper.find('[data-page="prev"]').attributes('disabled')).toBeDefined()
expect(wrapper.find('[data-page="next"]').attributes('disabled')).toBeUndefined()
await wrapper.find('[data-page="next"]').trigger('click')
await wrapper.find('[data-page="3"]').trigger('click')
await wrapper.find('[data-page="1"]').trigger('click')
expect(wrapper.emitted('page')).toEqual([[2], [3]])
await wrapper.setProps({ meta: meta(3, 3) })
expect(wrapper.find('[data-page="next"]').attributes('disabled')).toBeDefined()
await wrapper.find('[data-page="prev"]').trigger('click')
expect(wrapper.emitted('page')!.at(-1)).toEqual([2])
})
it('shows the plural zero-results message and no pager without rows', () => {
const wrapper = mount(Pagination, { props: { meta: meta(1, 0, 0), loading: false, perPageOptions: [20], perPage: 20 } })
expect(wrapper.find('[data-range]').text()).toBe('0 wyników')
expect(wrapper.find('nav').exists()).toBe(false)
const none = mount(Pagination, { props: { meta: null, loading: false, perPageOptions: [20], perPage: 20 } })
expect(none.find('[data-range]').text()).toBe('0 wyników')
})
it('shows the loading text and hides the pager while loading', () => {
const wrapper = mount(Pagination, { props: { meta: meta(1, 2), loading: true, perPageOptions: [20], perPage: 20 } })
expect(wrapper.find('[data-range]').text()).toBe('Wczytywanie…')
expect(wrapper.find('nav').exists()).toBe(false)
})
it('offers the per-page select only with more than one option and emits a valid choice', async () => {
const one = mount(Pagination, { props: { meta: meta(1, 2), loading: false, perPageOptions: [20], perPage: 20 } })
expect(one.find('[data-per-page]').exists()).toBe(false)
const wrapper = mount(Pagination, { props: { meta: meta(1, 2), loading: false, perPageOptions: [10, 20, 50], perPage: 20 } })
const select = wrapper.find('[data-per-page]')
expect(select.findAll('option').map((option) => option.text())).toEqual(['10', '20', '50'])
expect((select.element as HTMLSelectElement).value).toBe('20')
await select.setValue('50')
expect(wrapper.emitted('perPage')).toEqual([[50]])
})
})