Files
RenewCMS/web/src/lib/__tests__/seoPreview.spec.ts
T

76 lines
2.2 KiB
TypeScript

import { describe, expect, it } from 'vitest'
import { EMPTY_SEO } from '@/lib/articleSeo'
import {
applyTitleTemplate,
bodyText,
firstSentence,
previewTitle,
siteDisplayName,
socialTitle,
} from '@/lib/seoPreview'
import type { Site } from '@/composables/useSites'
const site = {
id: 1,
name: 'Renew',
key: 'renew',
base_url: 'https://renew.example',
default_social_image_id: null,
default_robots: 'index',
locale: null,
site_name: '',
title_template: '%title% | %site%',
is_default: true,
article_count: 1,
} as Site
describe('applyTitleTemplate', () => {
it('replaces every occurrence in a single pass', () => {
expect(applyTitleTemplate('%site%: %title% (%title%)', 'A', 'S')).toBe('S: A (A)')
})
it('does not expand replacement patterns or substitute tokens inside the title', () => {
expect(applyTitleTemplate('%title% | %site%', "Cost $& $' $` %site%", 'Renew')).toBe(
"Cost $& $' $` %site% | Renew",
)
})
it('falls back to the default template and trims', () => {
expect(applyTitleTemplate('', 'A', '')).toBe('A |')
})
})
describe('bodyText', () => {
it('separates block elements with a space', () => {
expect(bodyText('<p>One.</p><p>Two</p>')).toBe('One. Two')
expect(firstSentence('<p>One.</p><p>Two</p>')).toBe('One.')
})
it('skips script and style text', () => {
expect(bodyText('<style>p{}</style><p>Kept</p><script>alert(1)</script>')).toBe('Kept')
})
it('does not run markup', () => {
const img = '<img src=x onerror="document.body.dataset.ran=1">'
bodyText(img)
expect(document.body.dataset.ran).toBeUndefined()
})
})
describe('titles', () => {
const input = { seo: { ...EMPTY_SEO }, title: 'Article', body: '', site }
it('uses the site name, then the site key name, for the template', () => {
expect(siteDisplayName(site)).toBe('Renew')
expect(previewTitle(input)).toBe('Article | Renew')
})
it('falls back to the templated title for the social title', () => {
expect(socialTitle(input)).toBe('Article | Renew')
expect(socialTitle({ ...input, seo: { ...EMPTY_SEO, seo_title: 'Meta' } })).toBe(
'Meta | Renew',
)
expect(socialTitle({ ...input, seo: { ...EMPTY_SEO, social_title: 'Own' } })).toBe('Own')
})
})