Files
vue-journal-layer/tests/sitemap.test.ts
Jakub Zych a4dca42d77 test(16-05): Journal layer util tests
- node --test over routes, client (fake fetcher, include_empty=1),
  pagination, htmlGate (Go FormatHTML parity cases), sitemap, seo and
  pl/en i18n parity
- package script test and a Testing line in the README
2026-10-09 20:03:46 +02:00

99 lines
3.5 KiB
TypeScript

// Sitemap entries are built from journal.routes, never from fixed paths.
import { test } from 'node:test'
import assert from 'node:assert/strict'
import { buildJournalSitemapEntries } from '../app/utils/sitemap.ts'
import { DEFAULT_JOURNAL_ROUTES, normalizeJournalRoutes } from '../app/utils/routes.ts'
import type { JournalCategory, JournalPost } from '../app/utils/types.ts'
function post(id: number, slug: string, extra: Partial<JournalPost> = {}): JournalPost {
return {
id,
title: slug,
slug,
excerpt: null,
content: null,
content_html: null,
reading_time: 1,
published: true,
published_at: '2024-06-12T06:00:00+00:00',
is_pinned: false,
metadata: null,
sources: null,
author: null,
categories: [],
tags: [],
featured_images: [],
featured_image_url: null,
translations: null,
created_at: '2024-06-12T06:00:00+00:00',
updated_at: '2024-06-13T06:00:00+00:00',
...extra,
}
}
function category(id: number, slug: string, children?: JournalCategory[]): JournalCategory {
const row: JournalCategory = {
id,
name: slug,
slug,
description: null,
content: null,
parent_id: null,
nest_depth: 0,
post_count: 0,
}
if (children) row.children = children
return row
}
const POSTS = [post(1, 'blogbadania-nad-cordycepsem'), post(2, 'bez-daty', { updated_at: null })]
const CATEGORIES = [category(1, 'cordyceps', [category(2, 'militaris')]), category(3, 'amanita-muscaria')]
test('default routes give /blog/:slug and /blog/category/:category', () => {
assert.deepEqual(buildJournalSitemapEntries(POSTS, CATEGORIES, { ...DEFAULT_JOURNAL_ROUTES }), [
{ loc: '/blog/blogbadania-nad-cordycepsem', lastmod: '2024-06-13T06:00:00+00:00' },
{ loc: '/blog/bez-daty' },
{ loc: '/blog/category/cordyceps' },
{ loc: '/blog/category/militaris' },
{ loc: '/blog/category/amanita-muscaria' },
])
})
test('a custom root category route gives /cordyceps', () => {
const routes = normalizeJournalRoutes({ category: '/:category', tag: false })
const locs = buildJournalSitemapEntries(POSTS, CATEGORIES, routes).map((e) => e.loc)
assert.ok(locs.includes('/cordyceps'))
assert.ok(locs.includes('/militaris'), 'nested categories are flattened')
assert.ok(locs.includes('/amanita-muscaria'), 'empty categories are listed')
})
test('a disabled route contributes nothing', () => {
const noCategories = normalizeJournalRoutes({ category: false })
assert.deepEqual(
buildJournalSitemapEntries(POSTS, CATEGORIES, noCategories).map((e) => e.loc),
['/blog/blogbadania-nad-cordycepsem', '/blog/bez-daty'],
)
const noPosts = normalizeJournalRoutes({ post: false })
assert.equal(buildJournalSitemapEntries(POSTS, CATEGORIES, noPosts).filter((e) => e.loc.startsWith('/blog/b')).length, 0)
})
test('unpublished posts and empty slugs are skipped', () => {
const rows = [post(1, 'draft', { published: false }), post(2, ''), post(3, 'live')]
assert.deepEqual(
buildJournalSitemapEntries(rows, [category(9, '')], { ...DEFAULT_JOURNAL_ROUTES }).map((e) => e.loc),
['/blog/live'],
)
})
test('lastmod comes from updated_at', () => {
const [entry] = buildJournalSitemapEntries([post(1, 'x', { updated_at: '2025-01-02T03:04:05+00:00' })], [], {
...DEFAULT_JOURNAL_ROUTES,
})
assert.equal(entry?.lastmod, '2025-01-02T03:04:05+00:00')
})
test('slugs are encoded per segment', () => {
const [entry] = buildJournalSitemapEntries([post(1, 'a b/c')], [], { ...DEFAULT_JOURNAL_ROUTES })
assert.equal(entry?.loc, '/blog/a%20b/c')
})