#!/usr/bin/env node /** * Test du schéma Zod du formulaire assoupli (B5-M1). * Charge le VRAI schéma TS (utils/submitLibre.ts) via jiti (déjà une dépendance * transitive de Nuxt, pas de nouveau paquet) — pas de réimplémentation parallèle. * Usage : node scripts/test-submit-libre.mjs */ import { createJiti } from 'jiti' import { fileURLToPath } from 'node:url' import { dirname, join } from 'node:path' const __dirname = dirname(fileURLToPath(import.meta.url)) const jiti = createJiti(import.meta.url) const { LibreSubmitSchema, toOrgaPayload, toReferencePayload } = await jiti.import( join(__dirname, '..', 'utils', 'submitLibre.ts'), ) function baseInput(overrides) { return { liens: [], texte: '', site_web: '', ...overrides } } const cases = [ { name: 'vide (aucun lien, aucun texte) → refus', input: baseInput({}), expectOk: false, }, { name: '1 lien seul → ok', input: baseInput({ liens: ['https://exemple.fr'] }), expectOk: true, }, { name: 'texte seul → ok', input: baseInput({ texte: "Ça m'a beaucoup aidé pour ma reconversion." }), expectOk: true, }, { name: '11 liens → refus', input: baseInput({ liens: Array.from({ length: 11 }, (_, i) => `https://exemple${i}.fr`) }), expectOk: false, }, { name: 'URL invalide (pas de schéma) → refus', input: baseInput({ liens: ['exemple.fr'] }), expectOk: false, }, { name: 'ftp:// → refus', input: baseInput({ liens: ['ftp://exemple.fr/fichier.pdf'] }), expectOk: false, }, { name: 'double type valide (jobs + outils) → ok', input: baseInput({ liens: ['https://exemple.fr'], type_suggere: 'jobs', type_secondaire: 'outils' }), expectOk: true, }, { name: 'type_secondaire sans type_suggere → refus', input: baseInput({ liens: ['https://exemple.fr'], type_secondaire: 'outils' }), expectOk: false, }, { name: 'type_secondaire = type_suggere → refus', input: baseInput({ liens: ['https://exemple.fr'], type_suggere: 'jobs', type_secondaire: 'jobs' }), expectOk: false, }, { name: 'type inconnu → refus', input: baseInput({ liens: ['https://exemple.fr'], type_suggere: 'inconnu' }), expectOk: false, }, ] let failures = 0 for (const c of cases) { const result = LibreSubmitSchema.safeParse(c.input) const pass = result.success === c.expectOk const detail = result.success ? '' : ` (${JSON.stringify(result.error.flatten().fieldErrors)})` console.log(`${pass ? 'PASS' : 'FAIL'} — ${c.name}${pass ? '' : detail}`) if (!pass) failures++ } // ── Mappings (toOrgaPayload / toReferencePayload) ────────────────────────── function checkMapping(name, ok) { console.log(`${ok ? 'PASS' : 'FAIL'} — ${name}`) if (!ok) failures++ } { const data = LibreSubmitSchema.parse(baseInput({ liens: ['https://exemple.fr'] })) const payload = toOrgaPayload(data) checkMapping( 'aucun type → description_user commence par « Type : non précisé »', payload.description_user.startsWith('Type : non précisé'), ) } { const data = LibreSubmitSchema.parse(baseInput({ liens: ['https://exemple.fr'], type_suggere: 'jobs' })) const payload = toOrgaPayload(data) checkMapping( 'un type → pas de marqueur ni de ligne « Type suggéré »', !payload.description_user.startsWith('Type : non précisé') && !payload.description_user.includes('Type suggéré'), ) } { const data = LibreSubmitSchema.parse( baseInput({ liens: ['https://exemple.fr'], type_suggere: 'jobs', type_secondaire: 'outils' }), ) const payload = toOrgaPayload(data) checkMapping( 'double type → description_user commence par « Type suggéré : Jobs ou Outils »', payload.description_user.startsWith('Type suggéré : Jobs ou Outils'), ) checkMapping('double type → submission_type = le premier (job)', payload.submission_type === 'job') checkMapping( 'double type → ne commence PAS par « Type : non précisé »', !payload.description_user.startsWith('Type : non précisé'), ) } { const data = LibreSubmitSchema.parse( baseInput({ liens: ['https://exemple.fr'], type_suggere: 'references', type_secondaire: 'outils' }), ) const payload = toReferencePayload(data) checkMapping( 'premier = Références + second → description commence par « Type suggéré : Références ou Outils »', payload.description.startsWith('Type suggéré : Références ou Outils'), ) } const totalMappingChecks = 6 console.log(`\n${failures === 0 ? 'PASS' : 'FAIL'} — ${cases.length + totalMappingChecks - failures}/${cases.length + totalMappingChecks} tests passés`) process.exit(failures > 0 ? 1 : 0)