Files
vue-seo-layer/tests/usePagination.test.ts
Jakub Zych 75cc100336 test: usePagination hrefs, head links and page count; drift pattern forms
- the query and path forms from the resolve answer, the site answer and
  the layer option, page 1 unnumbered
- prev and next links at the ends, %pages% from the page count
- routeServes reads {param} and :param alike and ignores the query part
2026-11-04 19:47:18 +01:00

107 lines
4.5 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.
// usePagination (D-40 to D-42, UI-SPEC L2) with the Nuxt composables it
// calls stubbed on globalThis: the page hrefs in the form the resolve
// answer, the site answer or the layer option names; the prev and next
// head links at the ends; the number of pages handed to the CMS head,
// whose %pages% seoFillPages replaces.
import assert from 'node:assert/strict'
import test from 'node:test'
import { computed, ref, toValue, watch } from 'vue'
import { seoFillPages } from '../app/utils/seo.ts'
interface Stubs {
fullPath: string
answer: unknown
site: unknown
option?: unknown
}
const g = globalThis as Record<string, unknown>
let heads: Array<() => { link: Array<{ rel: string; href: string }> }> = []
const states = new Map<string, ReturnType<typeof ref>>()
function stub(s: Stubs) {
heads = []
states.clear()
Object.assign(g, {
computed,
toValue,
watch,
useRoute: () => ({ fullPath: s.fullPath }),
useSeoAnswer: () => ref(s.answer),
useRuntimeConfig: () => ({ public: { seo: s.option === undefined ? {} : { pagination: s.option } } }),
useNuxtData: () => ({ data: ref(s.site) }),
useState: (key: string, init: () => unknown) => {
if (!states.has(key)) states.set(key, ref(init()))
return states.get(key)
},
useHead: (input: { value: { link: Array<{ rel: string; href: string }> } }) => heads.push(() => input.value),
})
}
const { usePagination, useSeoPages } = await import('../app/composables/usePagination.ts')
test('the query form from the resolve answer: page 1 unnumbered, other parameters kept', () => {
stub({ fullPath: '/blog?sort=new&page=2', answer: { locale: 'pl', pagination: { form: 'query', param: 'page', segment: '' } }, site: null })
const p = usePagination({ current: 2, last: 4 })
assert.equal(p.href(1), '/blog?sort=new')
assert.equal(p.href(3), '/blog?sort=new&page=3')
assert.deepEqual(p.form.value, { form: 'query', param: 'page', segment: '' })
})
test('the path form from the site answer with the locale segment', () => {
stub({
fullPath: '/en/blog/page/2',
answer: { locale: 'en' },
site: { default_locale: 'pl', pagination: { form: 'path', param: 'page', segments: { pl: 'strona', en: 'page' } } },
})
const p = usePagination({ current: 2, last: 3 })
assert.equal(p.href(1), '/en/blog')
assert.equal(p.href(3), '/en/blog/page/3')
stub({
fullPath: '/blog',
answer: null,
site: { default_locale: 'pl', pagination: { form: 'path', segments: { pl: 'strona' } } },
})
assert.equal(usePagination({ current: 1, last: 3 }).href(2), '/blog/strona/2')
})
test('the layer option without a CMS answer, with the given locale', () => {
stub({ fullPath: '/de/blog', answer: null, site: null, option: { form: 'path', segments: { de: 'seite' } } })
const p = usePagination({ current: 1, last: 2, locale: 'de' })
assert.equal(p.href(2), '/de/blog/seite/2')
})
test('prev and next head links: none on a single page, only next on the first, only prev on the last', () => {
const links = (current: number, last: number) => {
stub({ fullPath: '/blog', answer: { pagination: { form: 'query', param: 'page' } }, site: null })
usePagination({ current, last })
return heads[0]!().link.map((l) => `${l.rel} ${l.href}`)
}
assert.deepEqual(links(1, 1), [])
assert.deepEqual(links(1, 3), ['next /blog?page=2'])
assert.deepEqual(links(2, 3), ['prev /blog', 'next /blog?page=3'])
assert.deepEqual(links(3, 3), ['prev /blog?page=2'])
assert.deepEqual(links(5, 3), [])
})
test('the number of pages for %pages%: set from last, null without pages', () => {
stub({ fullPath: '/blog', answer: null, site: null })
usePagination({ current: 1, last: 7 })
assert.equal(useSeoPages().value, 7)
const head = seoFillPages({ title: 'Blog – strona 1 z %pages%', meta: [{ content: 'Wpisy (%pages% stron)' }, { content: 'x' }] }, useSeoPages().value as number)
assert.equal(head.title, 'Blog – strona 1 z 7')
assert.equal(head.meta[0]!.content, 'Wpisy (7 stron)')
stub({ fullPath: '/blog', answer: null, site: null })
usePagination({ current: 1, last: 0 })
assert.equal(useSeoPages().value, null)
assert.equal(seoFillPages({ title: '%pages%', meta: [] }, null).title, '%pages%')
})
test('current and last are whole numbers: current at least 1, last at least 0', () => {
stub({ fullPath: '/blog', answer: null, site: null })
const p = usePagination({ current: 0, last: -2.5 })
assert.equal(p.current.value, 1)
assert.equal(p.last.value, 0)
assert.equal(usePagination({ current: 2.9, last: '4' as unknown as number }).current.value, 2)
})