- <SeoPagination> (UI-SPEC L2): previous and next (left out at the ends), page 1, the last page and five pages around the current one with gap items; nothing when last <= 1; props current, last, labels, classPrefix, locale - usePagination(): hrefs in the CMS form (resolve answer, then site answer, then seo.pagination), other query parameters kept, page 1 unnumbered, <link rel=prev/next> in the head - the CMS head fills %pages% in the title and description once the listing's page count is known (seoFillPages) - seoPaginationWindow, seoPageHref, seoPageNumber; L2 default styles
48 lines
2.5 KiB
TypeScript
48 lines
2.5 KiB
TypeScript
import assert from 'node:assert/strict'
|
||
import test from 'node:test'
|
||
import { seoPageHref, seoPageNumber } from '../app/utils/pageHref.ts'
|
||
import { seoFillPages } from '../app/utils/seo.ts'
|
||
|
||
test('seoPageHref: the UI-SPEC L2 examples', () => {
|
||
assert.equal(seoPageHref('/blog', 1, 'query'), '/blog')
|
||
assert.equal(seoPageHref('/blog?sort=new', 3, 'query'), '/blog?sort=new&page=3')
|
||
assert.equal(seoPageHref('/blog', 3, 'path', 'strona'), '/blog/strona/3')
|
||
assert.equal(seoPageHref('/en/blog', 1, 'path', 'page'), '/en/blog')
|
||
})
|
||
|
||
test('seoPageHref: a page already in the URL is replaced', () => {
|
||
assert.equal(seoPageHref('/blog?page=5&sort=new', 6, 'query'), '/blog?sort=new&page=6')
|
||
assert.equal(seoPageHref('/blog?page=5', 1, 'query'), '/blog')
|
||
assert.equal(seoPageHref('/blog/strona/5', 4, 'path', 'strona'), '/blog/strona/4')
|
||
assert.equal(seoPageHref('/blog/strona/5?sort=new', 1, 'path', 'strona'), '/blog?sort=new')
|
||
assert.equal(seoPageHref('/strona/5', 1, 'path', 'strona'), '/')
|
||
assert.equal(seoPageHref('/docs/page/3', 2, 'query'), '/docs/page/3?page=2', 'a path segment is left alone in the query form')
|
||
assert.equal(seoPageHref('/blog?p=2', 3, 'query', '', 'p'), '/blog?p=3')
|
||
assert.equal(seoPageHref('/blog', 2, 'path'), '/blog/page/2', 'the param is the segment when none is given')
|
||
})
|
||
|
||
test('seoPageHref: query values are encoded, never concatenated raw', () => {
|
||
assert.equal(seoPageHref('/blog?q=%22%3E%3Cscript%3E', 2, 'query'), '/blog?q=%22%3E%3Cscript%3E&page=2')
|
||
assert.equal(seoPageHref('/blog#top', 2, 'query'), '/blog?page=2')
|
||
})
|
||
|
||
test('seoPageNumber: 1 without a page, null for an invalid one', () => {
|
||
assert.equal(seoPageNumber('/blog'), 1)
|
||
assert.equal(seoPageNumber('/blog?page=3'), 3)
|
||
assert.equal(seoPageNumber('/blog?page=abc'), null)
|
||
assert.equal(seoPageNumber('/blog?page=0'), null)
|
||
assert.equal(seoPageNumber('/blog?page=1&page=2'), null)
|
||
assert.equal(seoPageNumber('/blog/strona/4', 'path', 'strona'), 4)
|
||
assert.equal(seoPageNumber('/blog/strona/x', 'path', 'strona'), 1)
|
||
})
|
||
|
||
test('seoFillPages: %pages% in the title and meta, only once the count is known', () => {
|
||
const head = { title: 'Blog – strona 5 z %pages%', meta: [{ name: 'description', content: 'strona 5 z %pages%' }, { name: 'robots', content: 'index' }] }
|
||
const out = seoFillPages(head, 14)
|
||
assert.equal(out.title, 'Blog – strona 5 z 14')
|
||
assert.equal(out.meta[0]!.content, 'strona 5 z 14')
|
||
assert.equal(out.meta[1], head.meta[1])
|
||
assert.equal(seoFillPages(head, null), head)
|
||
assert.equal(seoFillPages(head, 0), head)
|
||
})
|