seo-generator-server/tests/llm/pipeline-dryrun.test.js
2025-09-03 15:29:19 +08:00

82 lines
3.2 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import test from 'node:test';
import assert from 'node:assert';
import { safeImport } from '../_helpers/path.js';
import { MemoryArticleStorage } from '../_helpers/memoryStorage.js';
import { MockLLMManager } from '../_helpers/mockLLMManager.js';
function skip(msg) { console.warn('[SKIP]', msg); }
test('Pipeline dry-run with mock LLM returns structured article', async (t) => {
const extr = safeImport('ElementExtraction');
const gen = safeImport('ContentGeneration');
const asm = safeImport('ContentAssembly');
const enh = safeImport('SelectiveEnhancement');
const miss = safeImport('MissingKeywords');
const utils= safeImport('Utils');
const stor = new MemoryArticleStorage();
const llm = new MockLLMManager();
if (![extr,gen,asm,enh,miss].every(r=>r.ok)) {
skip('One or more pipeline modules missing; dry-run skipped.');
return;
}
const ElementExtraction = extr.mod;
const ContentGeneration = gen.mod;
const ContentAssembly = asm.mod;
const SelectiveEnh = enh.mod;
const MissingKeywords = miss.mod;
// Inputs minimaux (adapte selon tes contrats)
const inputs = {
instructions: 'Write about hunting jackets: materials, weatherproofing, sizes.',
persona: { name: 'Persona A', tone: 'pragmatic' },
template: '<article><h1>{{title}}</h1>{{body}}</article>',
seed: 42
};
// Étape 1: extraction
const elements = await (ElementExtraction.extractElements
? ElementExtraction.extractElements(inputs)
: { topics: ['materials', 'weatherproofing', 'sizes'] });
assert.ok(elements, 'elements should be produced');
// Étape 2: génération (mock via injection simple si API supporte un client)
// Si ContentGeneration accepte un LLM param, on lutilise, sinon on simule simple:
const parts = await (ContentGeneration.generateArticleParts
? ContentGeneration.generateArticleParts({ inputs, elements, llm })
: (Array.isArray(elements.topics) ? elements.topics : Object.keys(elements))
.map(t => ({ key:String(t), text:`MOCK SECTION ${t}` })));
assert.ok(parts && Array.isArray(parts), 'parts array expected');
assert.ok(parts.length > 0, 'non-empty parts');
// Étape 3: enhancement sélectif (facultatif)
const enhanced = await (SelectiveEnh.enhanceParts
? SelectiveEnh.enhanceParts({ parts, llm })
: parts);
assert.ok(enhanced && Array.isArray(enhanced), 'enhanced parts array');
// Étape 4: missing keywords
const completed = await (MissingKeywords.fillMissingKeywords
? MissingKeywords.fillMissingKeywords({ parts: enhanced, targetKeywords:['chasse','imperméable'] , llm })
: enhanced);
// Étape 5: assemblage
const html = await (ContentAssembly.assembleArticle
? ContentAssembly.assembleArticle({ template: inputs.template, parts: completed, meta:{title:'Veste de chasse: guide complet'} })
: `<article>${completed.map(p=>`<section>${p.text}</section>`).join('')}</article>`);
assert.equal(typeof html, 'string');
assert.ok(html.includes('<article'), 'html should be article-like');
// “Stockage final” simulé
const key = JSON.stringify(inputs); // simplifié
await stor.writeFinal(key, { html });
assert.ok(await stor.hasFinal(key), 'final should be stored');
});