Files
Talks/tests/presentation-contracts.test.mjs
Le Prévost-Corvellec Arnault 354c8cd9ef Add Makefile, package.json, and initial configuration for VitePress and Slidev integration
- Introduced a Makefile for streamlined commands related to building, running, and managing presentations.
- Created package.json to define project metadata, dependencies, and scripts for development and testing.
- Added .gitignore entries to exclude build artifacts and temporary files from version control.
- Included playwright.config.mjs for end-to-end testing setup with Playwright.
- Added README.md for project documentation, outlining setup instructions and development guidelines.
2026-04-11 15:59:20 +02:00

147 lines
4.3 KiB
JavaScript

import { test, describe } from 'node:test'
import assert from 'node:assert'
import fs from 'node:fs'
import os from 'node:os'
import path from 'node:path'
import {
escHtml,
escMd,
pickFeatured,
buildFeaturedHtml,
readAllMeta,
generateListPageMarkdown,
generateDetailPageMarkdown,
patchIndexFeaturedContent,
FEATURED_START,
FEATURED_END,
} from '../tools/presentation-contracts.mjs'
function mockSitePath(p) {
return p.startsWith('/') ? p : `/${p}`
}
describe('escHtml / escMd', () => {
test('escHtml neutralise < > & "', () => {
assert.strictEqual(escHtml('<a href="x">'), '&lt;a href=&quot;x&quot;&gt;')
})
test('escMd échappe les pipes tableaux markdown', () => {
assert.strictEqual(escMd('a|b'), 'a\\|b')
})
})
describe('pickFeatured', () => {
test('priorité aux entrées featured puis order', () => {
const items = [
{ slug: 'c', title: 'C', order: 3, featured: false },
{ slug: 'a', title: 'A', order: 1, featured: true },
{ slug: 'b', title: 'B', order: 2, featured: true },
]
const got = pickFeatured(items)
assert.deepStrictEqual(
got.map((x) => x.slug),
['a', 'b'],
)
})
test('sans featured : trois premiers par order', () => {
const items = [
{ slug: 'z', title: 'Z', order: 10 },
{ slug: 'a', title: 'A', order: 1 },
{ slug: 'b', title: 'B', order: 2 },
{ slug: 'c', title: 'C', order: 3 },
]
const got = pickFeatured(items)
assert.deepStrictEqual(
got.map((x) => x.slug),
['a', 'b', 'c'],
)
})
test('liste vide', () => {
assert.deepStrictEqual(pickFeatured([]), [])
})
})
describe('buildFeaturedHtml', () => {
test('génère des liens et échappe le titre', () => {
const html = buildFeaturedHtml(
[{ slug: 'x', title: '<evil>', description: 'd & co', order: 1 }],
mockSitePath,
)
assert.match(html, /href="\/presentations\/x\/"/)
assert.match(html, /&lt;evil&gt;/)
assert.match(html, /d &amp; co/)
})
test('aucune présentation : commentaire', () => {
assert.strictEqual(buildFeaturedHtml([], mockSitePath), '<!-- (aucune présentation) -->')
})
})
describe('readAllMeta (répertoire temporaire)', () => {
test('ignore dossier sans meta.json', () => {
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'talks-slides-'))
fs.mkdirSync(path.join(dir, 'empty'), { recursive: true })
const okDir = path.join(dir, 'ok')
fs.mkdirSync(okDir, { recursive: true })
fs.writeFileSync(path.join(okDir, 'meta.json'), JSON.stringify({ title: 'T', description: '', order: 1 }))
const list = readAllMeta(dir)
assert.strictEqual(list.length, 1)
assert.strictEqual(list[0].slug, 'ok')
assert.strictEqual(list[0].title, 'T')
})
})
describe('generateListPageMarkdown / generateDetailPageMarkdown', () => {
const p = {
slug: 'demo',
title: 'Démo',
description: 'Desc',
tags: ['a', 'b'],
order: 1,
}
test('liste contient fiche + slides + tags', () => {
const md = generateListPageMarkdown([p], mockSitePath)
assert.match(md, /href="\/presentations\/demo\/"/)
assert.match(md, /href="\/slides\/demo\/1"/)
assert.match(md, /vp-raw/)
assert.match(md, /`a` · `b`/)
})
test('détail contient QrEncode et boutons', () => {
const md = generateDetailPageMarkdown(p, mockSitePath)
assert.match(md, /<QrEncode path="\/slides\/demo\/1" \/>/)
assert.match(md, /class="vp-button vp-raw"/)
assert.match(md, /Voir les slides/)
assert.match(md, /## Partager les slides/)
})
test('détail sans tags : pas de ligne Tags', () => {
const md = generateDetailPageMarkdown({ ...p, tags: [] }, mockSitePath)
assert.ok(!md.includes('**Tags :**'))
})
})
describe('patchIndexFeaturedContent', () => {
test('remplace la zone entre marqueurs', () => {
const raw = `head\n${FEATURED_START}\nold\n${FEATURED_END}\ntail`
const { ok, content } = patchIndexFeaturedContent(
raw,
[{ slug: 's', title: 'T', description: 'D', order: 1 }],
mockSitePath,
)
assert.strictEqual(ok, true)
assert.ok(content.includes('talk-card'))
assert.ok(content.includes('head'))
assert.ok(content.includes('tail'))
assert.ok(!content.includes('old'))
})
test('marqueurs absents : ok false', () => {
const { ok } = patchIndexFeaturedContent('nope', [], mockSitePath)
assert.strictEqual(ok, false)
})
})