63 lines
2.5 KiB
React
63 lines
2.5 KiB
React
import React from 'react'
|
|
import { afterEach, describe, expect, it } from 'vitest'
|
|
import { render, cleanup } from '@testing-library/react'
|
|
import { HelmetProvider } from 'react-helmet-async'
|
|
import SEOHead from './SEOHead'
|
|
import { BRAND_SUFFIX } from './seo.js'
|
|
|
|
afterEach(() => {
|
|
cleanup()
|
|
document.head.querySelectorAll('[data-rh="true"]').forEach(node => node.remove())
|
|
})
|
|
|
|
describe('SEOHead', () => {
|
|
it('renders one branded title, description, and canonical link', () => {
|
|
render(
|
|
<HelmetProvider>
|
|
<SEOHead title={`Artikel${BRAND_SUFFIX}`} description="Synthetic description" url="/artikel" />
|
|
</HelmetProvider>,
|
|
)
|
|
|
|
expect(document.head.querySelectorAll('title')).toHaveLength(1)
|
|
expect(document.title).toBe(`Artikel${BRAND_SUFFIX}`)
|
|
expect(document.title.match(/Dr\. André Knie/g)).toHaveLength(1)
|
|
expect(document.head.querySelectorAll('meta[name="description"]')).toHaveLength(1)
|
|
expect(document.head.querySelector('link[rel="canonical"]')?.getAttribute('href')).toBe('https://andreknie.de/artikel')
|
|
})
|
|
|
|
it('replaces static fallback metadata instead of duplicating it', () => {
|
|
document.head.insertAdjacentHTML('beforeend', `
|
|
<title data-seo-fallback>Fallback</title>
|
|
<meta data-seo-fallback name="description" content="Fallback description">
|
|
<link data-seo-fallback rel="canonical" href="https://andreknie.de/">
|
|
`)
|
|
|
|
render(
|
|
<HelmetProvider>
|
|
<SEOHead title="Artikel" description="Article description" url="/artikel" />
|
|
</HelmetProvider>,
|
|
)
|
|
|
|
expect(document.head.querySelectorAll('[data-seo-fallback]')).toHaveLength(0)
|
|
expect(document.head.querySelectorAll('title')).toHaveLength(1)
|
|
expect(document.head.querySelectorAll('meta[name="description"]')).toHaveLength(1)
|
|
expect(document.head.querySelectorAll('link[rel="canonical"]')).toHaveLength(1)
|
|
})
|
|
|
|
it('normalizes relative and absolute image URLs', () => {
|
|
const { rerender } = render(
|
|
<HelmetProvider>
|
|
<SEOHead title="Test" image="/images/andre-knie.webp" />
|
|
</HelmetProvider>,
|
|
)
|
|
|
|
expect(document.head.querySelector('meta[property="og:image"]')?.getAttribute('content')).toBe('https://andreknie.de/images/andre-knie.webp')
|
|
rerender(
|
|
<HelmetProvider>
|
|
<SEOHead title="Test" image="https://cdn.example.invalid/image.webp" />
|
|
</HelmetProvider>,
|
|
)
|
|
expect(document.head.querySelector('meta[property="og:image"]')?.getAttribute('content')).toBe('https://cdn.example.invalid/image.webp')
|
|
})
|
|
})
|