sourcefinder/test-json-repository.js
Alexis Trouvé a7bd6115b7
Some checks failed
SourceFinder CI/CD Pipeline / Code Quality & Linting (push) Has been cancelled
SourceFinder CI/CD Pipeline / Unit Tests (push) Has been cancelled
SourceFinder CI/CD Pipeline / Security Tests (push) Has been cancelled
SourceFinder CI/CD Pipeline / Integration Tests (push) Has been cancelled
SourceFinder CI/CD Pipeline / Performance Tests (push) Has been cancelled
SourceFinder CI/CD Pipeline / Code Coverage Report (push) Has been cancelled
SourceFinder CI/CD Pipeline / Build & Deployment Validation (16.x) (push) Has been cancelled
SourceFinder CI/CD Pipeline / Build & Deployment Validation (18.x) (push) Has been cancelled
SourceFinder CI/CD Pipeline / Build & Deployment Validation (20.x) (push) Has been cancelled
SourceFinder CI/CD Pipeline / Regression Tests (push) Has been cancelled
SourceFinder CI/CD Pipeline / Security Audit (push) Has been cancelled
SourceFinder CI/CD Pipeline / Notify Results (push) Has been cancelled
feat: Implémentation complète du système SourceFinder avec tests
- Architecture modulaire avec injection de dépendances
- Système de scoring intelligent multi-facteurs (spécificité, fraîcheur, qualité, réutilisation)
- Moteur anti-injection 4 couches (preprocessing, patterns, sémantique, pénalités)
- API REST complète avec validation et rate limiting
- Repository JSON avec index mémoire et backup automatique
- Provider LLM modulaire pour génération de contenu
- Suite de tests complète (Jest) :
  * Tests unitaires pour sécurité et scoring
  * Tests d'intégration API end-to-end
  * Tests de sécurité avec simulation d'attaques
  * Tests de performance et charge
- Pipeline CI/CD avec GitHub Actions
- Logging structuré et monitoring
- Configuration ESLint et environnement de test

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-15 23:06:10 +08:00

219 lines
7.8 KiB
JavaScript

/**
* Script de test pour JSONStockRepository
* Valide toutes les fonctionnalités avec données réelles
*/
require('dotenv').config();
const JSONStockRepository = require('./src/implementations/storage/JSONStockRepository');
const logger = require('./src/utils/logger');
// Données de test
const testArticles = [
{
title: "Nouvelle étude sur les Bergers Allemands",
content: "Une récente étude de l'université vétérinaire de Munich révèle des informations importantes sur la santé des Bergers Allemands...",
url: "https://centrale-canine.fr/etude-bergers-allemands-2025",
publishDate: new Date(Date.now() - 5 * 24 * 60 * 60 * 1000).toISOString(), // 5 jours
sourceType: "premium",
sourceDomain: "centrale-canine.fr",
raceCode: "352-1",
race_tags: ["352-1", "bergers", "grands_chiens"],
angle_tags: ["sante", "recherche"],
finalScore: 285,
freshnessScore: 95,
qualityScore: 100,
specificityScore: 100,
reuseScore: 90
},
{
title: "Conseils dressage pour Golden Retriever",
content: "Les Golden Retrievers sont des chiens intelligents qui nécessitent une approche particulière pour l'éducation...",
url: "https://wamiz.com/conseils-dressage-golden-retriever",
publishDate: new Date(Date.now() - 15 * 24 * 60 * 60 * 1000).toISOString(), // 15 jours
sourceType: "standard",
sourceDomain: "wamiz.com",
raceCode: "111-1",
race_tags: ["111-1", "retrievers", "grands_chiens"],
angle_tags: ["education", "comportement"],
finalScore: 220,
freshnessScore: 70,
qualityScore: 80,
specificityScore: 100,
reuseScore: 70
},
{
title: "Actualités générales sur la santé canine",
content: "Les vaccinations annuelles restent essentielles pour maintenir la santé de votre compagnon à quatre pattes...",
url: "https://30millionsdamis.fr/actualites-sante-canine",
publishDate: new Date(Date.now() - 45 * 24 * 60 * 60 * 1000).toISOString(), // 45 jours
sourceType: "fallback",
sourceDomain: "30millionsdamis.fr",
raceCode: "general",
race_tags: ["chiens", "sante_generale"],
angle_tags: ["sante", "prevention"],
finalScore: 150,
freshnessScore: 40,
qualityScore: 60,
specificityScore: 25,
reuseScore: 85
},
{
title: "Législation sur les chiens dangereux",
content: "Les nouvelles réglementations concernant les chiens de catégorie entrent en vigueur ce mois-ci...",
url: "https://service-public.fr/legislation-chiens-dangereux",
publishDate: new Date(Date.now() - 2 * 24 * 60 * 60 * 1000).toISOString(), // 2 jours
sourceType: "premium",
sourceDomain: "service-public.fr",
raceCode: "legislation",
race_tags: ["legislation", "securite"],
angle_tags: ["legislation", "securite"],
finalScore: 270,
freshnessScore: 100,
qualityScore: 100,
specificityScore: 70,
reuseScore: 50
}
];
async function runTests() {
console.log('🧪 Testing JSONStockRepository...\n');
let repository;
try {
// 1. Initialisation
console.log('📦 1. Initializing repository...');
repository = new JSONStockRepository({
dataPath: './data/test-stock',
backupPath: './data/test-backup'
});
await repository.init();
console.log('✅ Repository initialized successfully');
// 2. Sauvegarde d'articles
console.log('\n💾 2. Saving test articles...');
const savedArticles = [];
for (const article of testArticles) {
const saved = await repository.save(article);
savedArticles.push(saved);
console.log(`✅ Saved: ${saved.title.substring(0, 50)}... (ID: ${saved.id})`);
}
// 3. Recherche par race
console.log('\n🔍 3. Testing search by race code...');
const bergersAllemands = await repository.findByRaceCode('352-1');
console.log(`✅ Found ${bergersAllemands.length} articles for Bergers Allemands (352-1)`);
const goldenRetrievers = await repository.findByRaceCode('111-1', {
minScore: 200,
limit: 2
});
console.log(`✅ Found ${goldenRetrievers.length} Golden Retrievers with score >= 200`);
// 4. Recherche par score
console.log('\n📊 4. Testing search by score...');
const highScoreArticles = await repository.findByScore(250);
console.log(`✅ Found ${highScoreArticles.length} articles with score >= 250`);
for (const article of highScoreArticles) {
console.log(` - ${article.title.substring(0, 40)}... (Score: ${article.finalScore})`);
}
// 5. Recherche par URL (unicité)
console.log('\n🔗 5. Testing search by URL...');
const foundByUrl = await repository.findByUrl(testArticles[0].url);
if (foundByUrl) {
console.log(`✅ Found article by URL: ${foundByUrl.title.substring(0, 50)}...`);
}
// Test doublon URL
try {
await repository.save({
...testArticles[0],
id: undefined, // Force nouveau ID
title: "Article doublon avec même URL"
});
console.log('❌ Duplicate URL should not be allowed');
} catch (error) {
console.log('✅ Duplicate URL correctly handled');
}
// 6. Mise à jour usage
console.log('\n📈 6. Testing usage updates...');
const firstArticle = savedArticles[0];
await repository.updateUsage(firstArticle.id, {
usageCount: 3,
lastUsed: new Date().toISOString(),
clientId: 'test-client'
});
const updatedArticle = await repository.findById(firstArticle.id);
console.log(`✅ Updated usage: ${updatedArticle.usageCount} uses, last used: ${updatedArticle.lastUsed}`);
// 7. Statistiques
console.log('\n📊 7. Testing statistics...');
const stats = await repository.getStats();
console.log('✅ Repository statistics:');
console.log(` - Total articles: ${stats.totalArticles}`);
console.log(` - By source type: ${JSON.stringify(stats.bySourceType)}`);
console.log(` - By race code: ${JSON.stringify(stats.byRaceCode)}`);
console.log(` - Average score: ${stats.avgScore}`);
console.log(` - Storage: ${stats.storage.totalSizeMB}MB`);
console.log(` - Operations: ${stats.operations}`);
console.log(` - Errors: ${stats.errors}`);
// 8. Backup
console.log('\n💾 8. Testing backup...');
await repository.createBackup();
console.log('✅ Backup created successfully');
// 9. Cleanup
console.log('\n🧹 9. Testing cleanup...');
const deletedCount = await repository.cleanup({
sourceTypes: ['fallback'], // Supprimer articles fallback
olderThan: new Date(Date.now() - 30 * 24 * 60 * 60 * 1000) // Plus de 30 jours
});
console.log(`✅ Cleaned up ${deletedCount} articles`);
// 10. Test recherche complexe
console.log('\n🔍 10. Testing complex search...');
const complexResults = await repository.findByRaceCode('352-1', {
minScore: 200,
maxAge: 10, // Derniers 10 jours
sourceTypes: ['premium'],
sortBy: 'finalScore',
sortOrder: 'desc',
limit: 5
});
console.log(`✅ Complex search returned ${complexResults.length} articles`);
// 11. Final stats
console.log('\n📊 11. Final statistics...');
const finalStats = await repository.getStats();
console.log('✅ Final repository state:');
console.log(` - Total articles: ${finalStats.totalArticles}`);
console.log(` - Memory usage: ~${finalStats.memoryUsage} bytes`);
console.log(` - Operations performed: ${finalStats.operations}`);
console.log('\n🎉 All tests passed successfully!');
} catch (error) {
console.error('\n❌ Test failed:', error);
console.error(error.stack);
} finally {
// Cleanup
if (repository) {
await repository.close();
console.log('\n🔒 Repository closed');
}
}
}
// Exécuter les tests
if (require.main === module) {
runTests().catch(console.error);
}
module.exports = { runTests, testArticles };