7b831d5bc4
- Installe vitest@4 + @vitest/coverage-v8 (40 tests, 0 échec) - lib/__tests__/format.test.js : 14 tests (formatKonstitisyon, formatDate, hasRestrictedChar) - lib/__tests__/version-utils.test.js : 17 tests (filterVersions par texte/auteur/date, getFilterStats) - lib/__tests__/rate-limit.test.js : 9 tests avec fake timers (limite, reset, retryAfter, keys indépendantes) - vitest.config.mjs : environnement node, imports explicites (pas de globals) - package.json : scripts test / test:watch / test:coverage + override XO pour les fichiers de test Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
112 lines
3.1 KiB
JavaScript
112 lines
3.1 KiB
JavaScript
import {describe, it, expect} from 'vitest'
|
|
import {formatKonstitisyon, formatDate, hasRestrictedChar} from '../format.js'
|
|
|
|
describe('formatKonstitisyon', () => {
|
|
it('renvoie un tableau vide si aucun titre', () => {
|
|
expect(formatKonstitisyon([], [])).toEqual([])
|
|
})
|
|
|
|
it('regroupe les articles sous leur titre', () => {
|
|
const titres = [{id: 1, contenu: 'Titre I'}]
|
|
const articles = [
|
|
{id: 10, titre: 1, contenu: 'Art. 1'},
|
|
{id: 20, titre: 2, contenu: 'Art. 2'}, // autre titre — exclu
|
|
]
|
|
|
|
expect(formatKonstitisyon(titres, articles)).toEqual([
|
|
{titre: 'Titre I', titreId: 1, articles: [{id: 10, titre: 1, contenu: 'Art. 1'}]},
|
|
])
|
|
})
|
|
|
|
it('produit un article vide si aucun article pour ce titre', () => {
|
|
const titres = [{id: 1, contenu: 'Titre I'}]
|
|
|
|
expect(formatKonstitisyon(titres, [])).toEqual([
|
|
{titre: 'Titre I', titreId: 1, articles: []},
|
|
])
|
|
})
|
|
|
|
it('gère plusieurs titres et plusieurs articles', () => {
|
|
const titres = [
|
|
{id: 1, contenu: 'Titre I'},
|
|
{id: 2, contenu: 'Titre II'},
|
|
]
|
|
const articles = [
|
|
{id: 10, titre: 1},
|
|
{id: 11, titre: 1},
|
|
{id: 20, titre: 2},
|
|
]
|
|
const result = formatKonstitisyon(titres, articles)
|
|
|
|
expect(result).toHaveLength(2)
|
|
expect(result[0].articles).toHaveLength(2)
|
|
expect(result[1].articles).toHaveLength(1)
|
|
})
|
|
})
|
|
|
|
describe('formatDate', () => {
|
|
const fixedDate = new Date('2024-03-15T10:30:00Z')
|
|
|
|
it('renvoie une chaîne non vide par défaut', () => {
|
|
const result = formatDate(fixedDate)
|
|
|
|
expect(typeof result).toBe('string')
|
|
expect(result.length).toBeGreaterThan(0)
|
|
})
|
|
|
|
it('ne contient pas de timezone par défaut', () => {
|
|
const result = formatDate(fixedDate)
|
|
|
|
expect(result).not.toMatch(/\(.+\)$/)
|
|
})
|
|
|
|
it('ajoute la timezone entre parenthèses quand withTimezone: true', () => {
|
|
const result = formatDate(fixedDate, 'PP', {withTimezone: true})
|
|
|
|
expect(result).toMatch(/\(.+\)$/)
|
|
})
|
|
|
|
it('utilise la locale française (contient un mois en français)', () => {
|
|
// date-fns format 'MMMM' en fr → mars / janvier / etc.
|
|
const result = formatDate(new Date('2024-01-15'), 'MMMM')
|
|
|
|
expect(result).toBe('janvier')
|
|
})
|
|
|
|
it('respecte le format personnalisé', () => {
|
|
const result = formatDate(new Date('2024-03-15'), 'dd/MM/yyyy')
|
|
|
|
expect(result).toBe('15/03/2024')
|
|
})
|
|
})
|
|
|
|
describe('hasRestrictedChar', () => {
|
|
it('détecte le caractère <', () => {
|
|
expect(hasRestrictedChar('<script>')).toBe(true)
|
|
})
|
|
|
|
it('détecte le caractère >', () => {
|
|
expect(hasRestrictedChar('a > b')).toBe(true)
|
|
})
|
|
|
|
it('détecte le caractère &', () => {
|
|
expect(hasRestrictedChar('a & b')).toBe(true)
|
|
})
|
|
|
|
it('détecte le caractère "', () => {
|
|
expect(hasRestrictedChar('"texte"')).toBe(true)
|
|
})
|
|
|
|
it('renvoie false pour un texte sans caractères restreints', () => {
|
|
expect(hasRestrictedChar('hello world')).toBe(false)
|
|
})
|
|
|
|
it('renvoie false pour une chaîne vide', () => {
|
|
expect(hasRestrictedChar('')).toBe(false)
|
|
})
|
|
|
|
it('renvoie false pour des apostrophes droites', () => {
|
|
expect(hasRestrictedChar('l\'article')).toBe(false)
|
|
})
|
|
})
|