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('

One.

Two

')).toBe('One. Two') expect(firstSentence('

One.

Two

')).toBe('One.') }) it('skips script and style text', () => { expect(bodyText('

Kept

')).toBe('Kept') }) it('does not run markup', () => { const img = '' 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') }) })