import { AutoReporter } from '../reporters/AutoReporter.js'; import assert from 'node:assert'; import { test, describe, before, after } from 'node:test'; import axios from 'axios'; import { requireCommonJS } from '../_helpers/commonjs-bridge.js'; // ======================================== // TESTS D'INTÉGRATION - COHÉRENCE APIs // Description: Valide que toutes les APIs utilisent le même système // ======================================== // Imports système const { ManualServer } = requireCommonJS('modes/ManualServer'); const { sessionManager } = requireCommonJS('StepByStepSessionManager'); // Auto-Reporter Configuration const autoReporter = new AutoReporter(); describe('🔥 Tests cohérence APIs - Step-by-step vs Generate-simple vs Main', () => { let server; let baseURL = 'http://localhost:3002'; // Port test before(async () => { // Démarrer serveur test server = new ManualServer({ port: 3002, wsPort: 8082 }); await server.start(); console.log('🚀 Serveur test démarré sur port 3002'); }); after(async () => { if (server) { await server.stop(); console.log('🛑 Serveur test arrêté'); } }); // ======================================== // TEST: MÊME COMPORTEMENT STEP-BY-STEP vs API SIMPLE // ======================================== test('🔥 CRITIQUE: Step-by-step et Generate-simple donnent des résultats cohérents', async () => { console.log('🧪 Test cohérence step-by-step ↔ generate-simple...'); const testKeyword = 'plaque test cohérence'; // ============= TEST GENERATE-SIMPLE ============= console.log('📡 Test /api/generate-simple...'); const simpleResponse = await axios.post(`${baseURL}/api/generate-simple`, { keyword: testKeyword }); assert.ok(simpleResponse.data.success, 'Generate-simple doit réussir'); assert.ok(simpleResponse.data.article, 'Doit retourner un article'); const simpleArticle = simpleResponse.data.article; console.log(`📊 Generate-simple: ${JSON.stringify(simpleArticle).length} chars`); // ============= TEST STEP-BY-STEP ============= console.log('📡 Test step-by-step workflow...'); // Étape 1: Initialisation const initResponse = await axios.post(`${baseURL}/api/step-by-step/init`, { t0: `Guide complet sur ${testKeyword}`, mc0: testKeyword, personality: 'Marc' }); assert.ok(initResponse.data.success, 'Step-by-step init doit réussir'); const sessionId = initResponse.data.sessionId; console.log(`📊 Session step-by-step: ${sessionId}`); // Étape 2: Génération initiale const genResponse = await axios.post(`${baseURL}/api/step-by-step/execute`, { sessionId, stepId: 1, options: {} }); assert.ok(genResponse.data.success, 'Step génération initiale doit réussir'); assert.ok(genResponse.data.result.content, 'Doit générer du contenu'); const stepContent = genResponse.data.result.content; console.log(`📊 Step-by-step: ${Object.keys(stepContent).length} éléments`); // ============= VALIDATIONS COHÉRENCE ============= // Valider que les deux approches génèrent du contenu assert.ok(simpleArticle.content, 'Generate-simple doit avoir du contenu'); assert.ok(Object.keys(stepContent).length > 0, 'Step-by-step doit avoir des éléments'); // Valider cohérence du mot-clé const simpleText = JSON.stringify(simpleArticle).toLowerCase(); const stepText = JSON.stringify(stepContent).toLowerCase(); assert.ok(simpleText.includes(testKeyword.toLowerCase()), 'Generate-simple doit contenir le mot-clé'); assert.ok(stepText.includes(testKeyword.toLowerCase()), 'Step-by-step doit contenir le mot-clé'); console.log('✅ Cohérence step-by-step ↔ generate-simple validée'); }, { timeout: 90000 }); // ======================================== // TEST: OPTIONS SELECTIVESTACK DANS STEP-BY-STEP // ======================================== test('🔥 CRITIQUE: Options selectiveStack vraiment appliquées dans step-by-step', async () => { console.log('🧪 Test options selectiveStack step-by-step...'); const testData = { t0: 'Test options selective', mc0: 'test selective stack', personality: 'Marc' }; // ============= TEST AVEC LIGHTENHANCEMENT ============= const initLight = await axios.post(`${baseURL}/api/step-by-step/init`, testData); const sessionLight = initLight.data.sessionId; // Génération initiale const genLight = await axios.post(`${baseURL}/api/step-by-step/execute`, { sessionId: sessionLight, stepId: 1 }); // Selective avec lightEnhancement const selectiveLight = await axios.post(`${baseURL}/api/step-by-step/execute`, { sessionId: sessionLight, stepId: 2, options: { selectiveStack: 'lightEnhancement' } }); // ============= TEST AVEC STANDARDENHANCEMENT ============= const initStandard = await axios.post(`${baseURL}/api/step-by-step/init`, testData); const sessionStandard = initStandard.data.sessionId; // Génération initiale const genStandard = await axios.post(`${baseURL}/api/step-by-step/execute`, { sessionId: sessionStandard, stepId: 1 }); // Selective avec standardEnhancement const selectiveStandard = await axios.post(`${baseURL}/api/step-by-step/execute`, { sessionId: sessionStandard, stepId: 2, options: { selectiveStack: 'standardEnhancement' } }); // ============= VALIDATIONS ============= assert.ok(selectiveLight.data.success, 'lightEnhancement doit réussir'); assert.ok(selectiveStandard.data.success, 'standardEnhancement doit réussir'); const lightResult = selectiveLight.data.result.content; const standardResult = selectiveStandard.data.result.content; console.log(`📊 Light enhancement: ${Object.keys(lightResult).length} éléments`); console.log(`📊 Standard enhancement: ${Object.keys(standardResult).length} éléments`); // Les deux doivent avoir du contenu assert.ok(Object.keys(lightResult).length > 0, 'lightEnhancement doit générer du contenu'); assert.ok(Object.keys(standardResult).length > 0, 'standardEnhancement doit générer du contenu'); // Valider que les options sont bien passées (via logs ou différences) const lightText = JSON.stringify(lightResult); const standardText = JSON.stringify(standardResult); console.log(`📊 Différence contenu: ${Math.abs(lightText.length - standardText.length)} chars`); console.log('✅ Options selectiveStack appliquées dans step-by-step'); }, { timeout: 120000 }); // ======================================== // TEST: ADVERSARIAL MODE MAPPING // ======================================== test('🔥 CRITIQUE: Adversarial mode mapping fonctionne dans APIs', async () => { console.log('🧪 Test adversarial mode mapping...'); const testData = { t0: 'Test adversarial mapping', mc0: 'test adversarial mode', personality: 'Marc' }; // ============= INIT SESSION ============= const initResponse = await axios.post(`${baseURL}/api/step-by-step/init`, testData); const sessionId = initResponse.data.sessionId; // Génération initiale await axios.post(`${baseURL}/api/step-by-step/execute`, { sessionId, stepId: 1 }); // ============= TEST ADVERSARIAL LIGHT ============= const adversarialResponse = await axios.post(`${baseURL}/api/step-by-step/execute`, { sessionId, stepId: 3, // adversarial step options: { adversarialMode: 'light' } }); // ============= VALIDATIONS ============= assert.ok(adversarialResponse.data.success, 'Adversarial mode=light doit réussir'); const result = adversarialResponse.data.result; assert.ok(result.content, 'Adversarial doit retourner du contenu'); console.log(`📊 Adversarial result: ${Object.keys(result.content).length} éléments`); // Valider que le mode 'light' est bien mappé vers 'lightDefense' // (cela sera visible dans les logs de debug si activés) console.log('✅ Adversarial mode mapping fonctionne'); }, { timeout: 90000 }); // ======================================== // TEST: STATUS ET MONITORING APIS // ======================================== test('🔥 CRITIQUE: APIs status et monitoring fonctionnent', async () => { console.log('🧪 Test APIs status et monitoring...'); // ============= TEST STATUS ============= const statusResponse = await axios.get(`${baseURL}/api/status`); assert.ok(statusResponse.data.success, 'API status doit réussir'); assert.equal(statusResponse.data.mode, 'MANUAL', 'Doit être en mode MANUAL'); assert.equal(statusResponse.data.status, 'running', 'Serveur doit être running'); console.log(`📊 Uptime: ${statusResponse.data.uptime}ms`); console.log(`📊 Requests: ${statusResponse.data.stats.requests}`); // ============= TEST STATS ============= const statsResponse = await axios.get(`${baseURL}/api/stats`); assert.ok(statsResponse.data.success, 'API stats doit réussir'); assert.ok(statsResponse.data.stats, 'Doit retourner des stats'); console.log(`📊 Memory: ${JSON.stringify(statsResponse.data.stats.memory).length} chars`); // ============= TEST CONFIG MODULAIRE ============= const configResponse = await axios.get(`${baseURL}/api/modulaire-config`); assert.ok(configResponse.data.success, 'API config doit réussir'); assert.ok(configResponse.data.config.selectiveStacks, 'Doit avoir config selective'); assert.ok(configResponse.data.config.adversarialModes, 'Doit avoir config adversarial'); const selectiveStacks = configResponse.data.config.selectiveStacks; const adversarialModes = configResponse.data.config.adversarialModes; console.log(`📊 Selective stacks: ${selectiveStacks.length}`); console.log(`📊 Adversarial modes: ${adversarialModes.length}`); // Valider que les stacks importantes sont présentes const stackNames = selectiveStacks.map(s => s.value); assert.ok(stackNames.includes('lightEnhancement'), 'lightEnhancement doit être disponible'); assert.ok(stackNames.includes('standardEnhancement'), 'standardEnhancement doit être disponible'); const modeNames = adversarialModes.map(m => m.value); assert.ok(modeNames.includes('light'), 'Adversarial light doit être disponible'); assert.ok(modeNames.includes('standard'), 'Adversarial standard doit être disponible'); console.log('✅ APIs status et monitoring fonctionnent'); }, { timeout: 30000 }); // ======================================== // TEST: GESTION ERREURS ET ROBUSTESSE // ======================================== test('🔥 CRITIQUE: Gestion erreurs APIs robuste', async () => { console.log('🧪 Test gestion erreurs...'); // ============= TEST DONNÉES INVALIDES ============= try { const invalidResponse = await axios.post(`${baseURL}/api/generate-simple`, { keyword: '' // Mot-clé vide }); // Doit retourner une erreur 400 assert.equal(invalidResponse.status, 400, 'Doit retourner erreur 400 pour données invalides'); } catch (error) { assert.equal(error.response.status, 400, 'Doit capturer erreur 400'); assert.ok(error.response.data.error, 'Doit retourner message d\'erreur'); console.log(`📊 Erreur capturée: ${error.response.data.error}`); } // ============= TEST SESSION INEXISTANTE ============= try { const invalidSession = await axios.post(`${baseURL}/api/step-by-step/execute`, { sessionId: 'session_inexistante', stepId: 1 }); // Doit échouer gracieusement assert.ok(!invalidSession.data.success || invalidSession.status >= 400, 'Session inexistante doit échouer'); } catch (error) { assert.ok(error.response.status >= 400, 'Doit retourner erreur pour session inexistante'); console.log(`📊 Session inexistante gérée: ${error.response.status}`); } console.log('✅ Gestion erreurs robuste'); }, { timeout: 30000 }); });