Files
vue-journal-layer/tests/postView.test.ts
Jakub Zych adcea4d538 feat: category neighbours on the post page
The post page links previous_in_category and next_in_category (the
Journal's opt-in scored related mode) as server-rendered links with the
title in the anchor text when the Journal answers one, else the
site-wide previous_post and next_post (postNeighbours). Types, a fixture
post and expectation lines for both cases.
2026-11-04 14:15:22 +01:00

65 lines
2.7 KiB
TypeScript

// The post page's payload: the body is sanitized, never blanked, and the raw
// source, translations and related post bodies stay out of it.
import { test } from 'node:test'
import assert from 'node:assert/strict'
import { postNeighbours, toPostView } from '../app/utils/postView.ts'
import type { JournalPost, JournalPostDetail } from '../app/utils/types.ts'
function post(overrides: Partial<JournalPost> = {}): JournalPost {
return {
id: 1,
title: 'Hello',
slug: 'hello',
excerpt: null,
content: 'source',
content_html: '<p>Hello</p>',
reading_time: 1,
published: true,
published_at: '2026-01-01T00:00:00+00:00',
is_pinned: false,
metadata: null,
sources: null,
author: null,
categories: [],
tags: [],
featured_images: [],
featured_image_url: null,
translations: { en: { title: 'Hello' } },
created_at: null,
updated_at: null,
...overrides,
}
}
function detail(overrides: Partial<JournalPostDetail> = {}): JournalPostDetail {
return { ...post(), previous_post: null, next_post: null, related_posts: [], ...overrides }
}
test('the body is sanitized and the safe parts are kept', () => {
const view = toPostView(detail({ content_html: '<p>Data: 12 maja 2024</p><script>alert(1)</script><p>After</p>' }))
assert.equal(view.content_html, '<p>Data: 12 maja 2024</p><p>After</p>')
})
test('source, translations and related post bodies stay out of the payload', () => {
const view = toPostView(detail({ related_posts: [post({ id: 2, slug: 'other' })] }))
assert.equal(view.content, null)
assert.equal(view.translations, null)
assert.equal(view.related_posts.length, 1)
assert.equal(view.related_posts[0]!.content_html, null)
assert.equal(view.related_posts[0]!.content, null)
assert.equal(view.related_posts[0]!.translations, null)
})
test('a missing body becomes an empty string', () => {
assert.equal(toPostView(detail({ content_html: null })).content_html, '')
})
test('postNeighbours prefers the in-category neighbours when the Journal answers one', () => {
const site = { previous_post: { slug: 'p', title: 'P' }, next_post: { slug: 'n', title: 'N' } }
assert.deepEqual(postNeighbours(site), { previous: site.previous_post, next: site.next_post, inCategory: false })
assert.deepEqual(postNeighbours({ ...site, previous_in_category: null, next_in_category: null }), { previous: site.previous_post, next: site.next_post, inCategory: false })
const cat = { slug: 'c', title: 'C' }
assert.deepEqual(postNeighbours({ ...site, previous_in_category: null, next_in_category: cat }), { previous: null, next: cat, inCategory: true })
assert.deepEqual(postNeighbours({}), { previous: null, next: null, inCategory: false })
})