// @vitest-environment node
import { describe, expect, it } from 'vitest'
import {
inlineCoverUrl,
resolveCoverDownloadUrl,
resolveCoverSource,
resolveMediaCoverSources,
slugFromFilename,
stripHtml,
} from '../../scripts/lib/wpArticles.mjs'
describe('inlineCoverUrl (OPS52-media — first inline image of the article body)', () => {
it('returns the src of the first ', () => {
const html = '
dek

texto sem imagem
mais texto

só texto
')).toBeNull() expect(inlineCoverUrl('')).toBeNull() }) it('keeps relative URLs as-is (same contract as the seed)', () => { expect(inlineCoverUrl('
')).toBe('/uploads/foo.webp')
})
})
describe('resolveCoverSource (OPS52-media — seed-identical cover resolution)', () => {
it('prefers the REST featured media URL', () => {
const article = {
slug: 'x',
title: 'x',
date: null,
html: 'sem img
', coverUrl: 'https://jorgesolla.com.br/featured.jpg', coverAlt: null, } expect(resolveCoverSource(article)).toBe('https://jorgesolla.com.br/featured.jpg') }) it('falls back to the first inline image when there is no featured media', () => { const article = { slug: 'x', title: 'x', date: null, html: '
sem img
', coverUrl: null, coverAlt: null, } expect(resolveCoverSource(article)).toBeNull() }) }) describe('slugFromFilename (OPS52-media — deterministic seed keyOlá mundo
')).toBe('Olá mundo') }) it('handles empty input', () => { expect(stripHtml('')).toBe('') }) }) describe('resolveCoverDownloadUrl (OPS52-media — covers constrained to the WP origin)', () => { it('keeps an absolute cover on the WordPress host', () => { expect( resolveCoverDownloadUrl('https://jorgesolla.com.br/wp-content/uploads/2026/07/x.jpeg'), ).toBe('https://jorgesolla.com.br/wp-content/uploads/2026/07/x.jpeg') }) it('resolves relative covers against the WordPress origin', () => { expect(resolveCoverDownloadUrl('/wp-content/uploads/x.png')).toBe( 'https://jorgesolla.com.br/wp-content/uploads/x.png', ) }) it('refuses covers on other hosts (no SSRF from the homeserver)', () => { expect(() => resolveCoverDownloadUrl('http://100.119.220.31:3900/internal')).toThrow( /fora do origin/, ) expect(() => resolveCoverDownloadUrl('https://evil.example.com/x.png')).toThrow( /fora do origin/, ) }) it('refuses non-http(s) schemes', () => { expect(() => resolveCoverDownloadUrl('file:///etc/passwd')).toThrow(/protocolo/) }) }) describe('resolveMediaCoverSources (OPS52-media — row→cover mapping)', () => { const article = (slug: string) => ({ slug, title: slug, date: null, html: '