import { describe, it, expect } from 'vitest'; import { alternates, buildJsonLd, absUrl, ogImagePath } from '@lib/seo'; import { PAGE_IDS } from '@i18n/slugMap'; const ORIGIN = 'https://cesnimda.co.uk/'; describe('SEO builders (SEO_SPEC §2–4)', () => { it('alternates include en, nb and x-default for every page', () => { for (const id of PAGE_IDS) { const alts = alternates(id, ORIGIN); const langs = alts.map((a) => a.hreflang); expect(langs).toContain('en'); expect(langs).toContain('nb'); expect(langs).toContain('x-default'); for (const a of alts) expect(a.href.startsWith('https://')).toBe(true); } }); it('x-default points at the English URL', () => { const alts = alternates('projects', ORIGIN); const xd = alts.find((a) => a.hreflang === 'x-default'); const en = alts.find((a) => a.hreflang === 'en'); expect(xd?.href).toBe(en?.href); }); it('home JSON-LD is a valid Person graph', () => { const graph = buildJsonLd('home', 'en', ORIGIN); const person = graph.find((g) => (g as { '@type': string })['@type'] === 'Person') as Record< string, unknown >; expect(person).toBeTruthy(); expect(person.name).toBe('Connor Babbington'); expect(person.jobTitle).toBe('Systems Developer'); expect(() => JSON.stringify(graph)).not.toThrow(); }); it('Norwegian home uses the localised job title', () => { const graph = buildJsonLd('home', 'no', ORIGIN); const person = graph.find((g) => (g as { '@type': string })['@type'] === 'Person') as Record< string, unknown >; expect(person.jobTitle).toBe('Systemutvikler'); }); it('case-study JSON-LD carries the project name and author', () => { const graph = buildJsonLd('jobtrack', 'en', ORIGIN, { projectName: 'JobTrack', projectType: 'SoftwareApplication', }); const work = graph[0] as Record; expect(work['@type']).toBe('SoftwareApplication'); expect(work.name).toBe('JobTrack'); expect((work.author as Record)['@type']).toBe('Person'); }); it('helpers build absolute URLs and OG paths', () => { expect(absUrl('/projects/', ORIGIN)).toBe('https://cesnimda.co.uk/projects/'); expect(ogImagePath('home', 'no')).toBe('/og/home-no.png'); }); });