the-tip-top-backend/test-admin-features.js
2025-11-17 23:47:54 +01:00

484 lines
17 KiB
JavaScript

/**
* Script de test des fonctionnalités admin
* Test de connexion, statistiques et export marketing
*/
const API_URL = 'http://localhost:4000/api';
// Couleurs pour console
const colors = {
green: '\x1b[32m',
red: '\x1b[31m',
yellow: '\x1b[33m',
blue: '\x1b[34m',
reset: '\x1b[0m'
};
function log(color, message) {
console.log(`${color}${message}${colors.reset}`);
}
let authToken = null;
// 1. Test de connexion admin
async function testAdminLogin() {
log(colors.blue, '\n========================================');
log(colors.blue, '1. TEST DE CONNEXION ADMIN');
log(colors.blue, '========================================\n');
try {
const response = await fetch(`${API_URL}/auth/login`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
email: 'admin@thetiptop.com',
password: 'Admin123!'
})
});
const data = await response.json();
if (response.ok && data.success) {
authToken = data.token;
log(colors.green, '✅ Connexion admin réussie');
log(colors.green, ` Token: ${authToken.substring(0, 50)}...`);
log(colors.green, ` Role: ${data.user.role}`);
log(colors.green, ` Email: ${data.user.email}`);
log(colors.green, ` Nom: ${data.user.firstName} ${data.user.lastName}`);
return true;
} else {
log(colors.red, '❌ Échec de la connexion admin');
log(colors.red, ` Message: ${data.message || 'Erreur inconnue'}`);
return false;
}
} catch (error) {
log(colors.red, `❌ Erreur lors de la connexion: ${error.message}`);
return false;
}
}
// 2. Test des statistiques globales
async function testStatistics() {
log(colors.blue, '\n========================================');
log(colors.blue, '2. TEST DES STATISTIQUES GLOBALES');
log(colors.blue, '========================================\n');
if (!authToken) {
log(colors.red, '❌ Token manquant - connexion requise');
return false;
}
try {
const response = await fetch(`${API_URL}/admin/statistics`, {
method: 'GET',
headers: {
'Authorization': `Bearer ${authToken}`,
'Content-Type': 'application/json',
}
});
const data = await response.json();
if (response.ok && data.success) {
log(colors.green, '✅ Statistiques récupérées avec succès\n');
// Statistiques utilisateurs
log(colors.yellow, '👥 UTILISATEURS:');
log(colors.reset, ` Total: ${data.data.users.total}`);
log(colors.reset, ` Clients: ${data.data.users.clients}`);
log(colors.reset, ` Employés: ${data.data.users.employees}`);
log(colors.reset, ` Admins: ${data.data.users.admins}`);
log(colors.reset, ` Emails vérifiés: ${data.data.users.verifiedEmails}`);
// Statistiques tickets
log(colors.yellow, '\n🎫 TICKETS:');
log(colors.reset, ` Total: ${data.data.tickets.total}`);
log(colors.reset, ` Distribués: ${data.data.tickets.distributed}`);
log(colors.reset, ` Utilisés: ${data.data.tickets.used}`);
log(colors.reset, ` En attente: ${data.data.tickets.pending}`);
log(colors.reset, ` Réclamés: ${data.data.tickets.claimed}`);
log(colors.reset, ` Rejetés: ${data.data.tickets.rejected}`);
// Statistiques lots
log(colors.yellow, '\n🎁 LOTS:');
log(colors.reset, ` Total types: ${data.data.prizes.total}`);
log(colors.reset, ` Actifs: ${data.data.prizes.active}`);
log(colors.reset, ` Stock total: ${data.data.prizes.totalStock}`);
log(colors.reset, ` Distribués: ${data.data.prizes.distributed}`);
// Distribution par catégorie
if (data.data.prizes.byCategory && data.data.prizes.byCategory.length > 0) {
log(colors.yellow, '\n Distribution par catégorie:');
data.data.prizes.byCategory.forEach(category => {
log(colors.reset, ` - ${category.prizeName}: ${category.count} (${category.percentage.toFixed(2)}%)`);
});
}
// Démographie
if (data.data.demographics) {
log(colors.yellow, '\n📊 DÉMOGRAPHIE:');
if (data.data.demographics.gender) {
log(colors.yellow, ' Par sexe:');
log(colors.reset, ` - Hommes: ${data.data.demographics.gender.male}`);
log(colors.reset, ` - Femmes: ${data.data.demographics.gender.female}`);
log(colors.reset, ` - Autre: ${data.data.demographics.gender.other}`);
log(colors.reset, ` - Non spécifié: ${data.data.demographics.gender.notSpecified}`);
}
if (data.data.demographics.ageRanges && data.data.demographics.ageRanges.length > 0) {
log(colors.yellow, '\n Par tranche d\'âge:');
data.data.demographics.ageRanges.forEach(range => {
log(colors.reset, ` - ${range.range} ans: ${range.count} (${range.percentage.toFixed(2)}%)`);
});
}
if (data.data.demographics.topCities && data.data.demographics.topCities.length > 0) {
log(colors.yellow, '\n Top 10 villes:');
data.data.demographics.topCities.forEach((city, index) => {
log(colors.reset, ` ${index + 1}. ${city.city}: ${city.count} (${city.percentage.toFixed(2)}%)`);
});
}
}
// Paramètres du jeu
if (data.data.game) {
log(colors.yellow, '\n🎮 JEU:');
log(colors.reset, ` Début: ${new Date(data.data.game.start_date).toLocaleDateString()}`);
log(colors.reset, ` Fin: ${new Date(data.data.game.end_date).toLocaleDateString()}`);
log(colors.reset, ` Actif: ${data.data.game.is_active ? 'Oui' : 'Non'}`);
log(colors.reset, ` Tickets générés: ${data.data.game.tickets_generated} / ${data.data.game.total_tickets}`);
}
return true;
} else {
log(colors.red, '❌ Échec de récupération des statistiques');
log(colors.red, ` Status: ${response.status}`);
log(colors.red, ` Message: ${data.message || 'Erreur inconnue'}`);
return false;
}
} catch (error) {
log(colors.red, `❌ Erreur lors de la récupération des statistiques: ${error.message}`);
return false;
}
}
// 3. Test des statistiques marketing
async function testMarketingStats() {
log(colors.blue, '\n========================================');
log(colors.blue, '3. TEST DES STATISTIQUES MARKETING');
log(colors.blue, '========================================\n');
if (!authToken) {
log(colors.red, '❌ Token manquant - connexion requise');
return false;
}
try {
const response = await fetch(`${API_URL}/admin/marketing/stats`, {
method: 'GET',
headers: {
'Authorization': `Bearer ${authToken}`,
'Content-Type': 'application/json',
}
});
const data = await response.json();
if (response.ok && data.success) {
log(colors.green, '✅ Statistiques marketing récupérées\n');
log(colors.yellow, '📈 STATISTIQUES MARKETING:');
log(colors.reset, ` Total clients: ${data.data.totalClients}`);
log(colors.reset, ` Participants actifs: ${data.data.activeParticipants}`);
log(colors.reset, ` Participants inactifs: ${data.data.inactiveParticipants}`);
log(colors.reset, ` Gagnants: ${data.data.winners}`);
log(colors.reset, ` Non-gagnants: ${data.data.nonWinners}`);
if (data.data.geographicDistribution && data.data.geographicDistribution.length > 0) {
log(colors.yellow, '\n Distribution géographique (Top 5):');
data.data.geographicDistribution.slice(0, 5).forEach((city, index) => {
log(colors.reset, ` ${index + 1}. ${city.city}: ${city.count}`);
});
}
return true;
} else {
log(colors.red, '❌ Échec de récupération des stats marketing');
log(colors.red, ` Status: ${response.status}`);
log(colors.red, ` Message: ${data.message || 'Erreur inconnue'}`);
return false;
}
} catch (error) {
log(colors.red, `❌ Erreur: ${error.message}`);
return false;
}
}
// 4. Test de l'export marketing
async function testMarketingExport() {
log(colors.blue, '\n========================================');
log(colors.blue, '4. TEST DE L\'EXPORT MARKETING');
log(colors.blue, '========================================\n');
if (!authToken) {
log(colors.red, '❌ Token manquant - connexion requise');
return false;
}
try {
// Test 1: Export de tous les participants actifs
log(colors.yellow, 'Test 1: Export des participants actifs');
const response1 = await fetch(`${API_URL}/admin/marketing/export`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${authToken}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
hasPlayed: true
})
});
const data1 = await response1.json();
if (response1.ok && data1.success) {
log(colors.green, `✅ Export réussi: ${data1.data.length} participants actifs`);
if (data1.data.length > 0) {
const sample = data1.data[0];
log(colors.reset, ' Exemple de données exportées:');
log(colors.reset, ` - Email: ${sample.email}`);
log(colors.reset, ` - Nom: ${sample.first_name} ${sample.last_name}`);
log(colors.reset, ` - Tickets joués: ${sample.tickets_played}`);
log(colors.reset, ` - Lots gagnés: ${sample.prizes_won}`);
}
} else {
log(colors.red, '❌ Échec export participants actifs');
log(colors.red, ` Message: ${data1.message || 'Erreur inconnue'}`);
}
// Test 2: Export des gagnants uniquement
log(colors.yellow, '\nTest 2: Export des gagnants uniquement');
const response2 = await fetch(`${API_URL}/admin/marketing/export`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${authToken}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
hasWon: true
})
});
const data2 = await response2.json();
if (response2.ok && data2.success) {
log(colors.green, `✅ Export réussi: ${data2.data.length} gagnants`);
} else {
log(colors.red, '❌ Échec export gagnants');
}
// Test 3: Export avec filtre email vérifié
log(colors.yellow, '\nTest 3: Export emails vérifiés');
const response3 = await fetch(`${API_URL}/admin/marketing/export`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${authToken}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
verified: true
})
});
const data3 = await response3.json();
if (response3.ok && data3.success) {
log(colors.green, `✅ Export réussi: ${data3.data.length} utilisateurs vérifiés`);
} else {
log(colors.red, '❌ Échec export vérifiés');
}
return true;
} catch (error) {
log(colors.red, `❌ Erreur lors de l'export: ${error.message}`);
return false;
}
}
// 5. Test du rapport marketing
async function testMarketingReport() {
log(colors.blue, '\n========================================');
log(colors.blue, '5. TEST DU RAPPORT MARKETING');
log(colors.blue, '========================================\n');
if (!authToken) {
log(colors.red, '❌ Token manquant - connexion requise');
return false;
}
try {
const response = await fetch(`${API_URL}/admin/marketing/report`, {
method: 'GET',
headers: {
'Authorization': `Bearer ${authToken}`,
'Content-Type': 'application/json',
}
});
const data = await response.json();
if (response.ok && data.success) {
log(colors.green, '✅ Rapport marketing généré\n');
if (data.data.globalStats) {
log(colors.yellow, '📊 STATISTIQUES GLOBALES:');
log(colors.reset, ` Total clients: ${data.data.globalStats.totalClients}`);
log(colors.reset, ` Participants actifs: ${data.data.globalStats.activeParticipants}`);
log(colors.reset, ` Taux de participation: ${data.data.globalStats.participationRate?.toFixed(2)}%`);
log(colors.reset, ` Taux de conversion: ${data.data.globalStats.conversionRate?.toFixed(2)}%`);
}
if (data.data.recommendations && data.data.recommendations.length > 0) {
log(colors.yellow, '\n💡 RECOMMANDATIONS:');
data.data.recommendations.forEach(rec => {
log(colors.reset, ` - ${rec}`);
});
}
return true;
} else {
log(colors.red, '❌ Échec de génération du rapport');
log(colors.red, ` Status: ${response.status}`);
log(colors.red, ` Message: ${data.message || 'Erreur inconnue'}`);
return false;
}
} catch (error) {
log(colors.red, `❌ Erreur: ${error.message}`);
return false;
}
}
// 6. Test des participants éligibles au tirage
async function testEligibleParticipants() {
log(colors.blue, '\n========================================');
log(colors.blue, '6. TEST DES PARTICIPANTS ÉLIGIBLES');
log(colors.blue, '========================================\n');
if (!authToken) {
log(colors.red, '❌ Token manquant - connexion requise');
return false;
}
try {
const response = await fetch(`${API_URL}/draw/eligible-participants?minTickets=1`, {
method: 'GET',
headers: {
'Authorization': `Bearer ${authToken}`,
'Content-Type': 'application/json',
}
});
const data = await response.json();
if (response.ok && data.success) {
log(colors.green, `✅ Participants éligibles: ${data.data.length}\n`);
if (data.data.length > 0) {
log(colors.yellow, ' Top 5 participants:');
data.data.slice(0, 5).forEach((participant, index) => {
log(colors.reset, ` ${index + 1}. ${participant.email} - ${participant.tickets_played} tickets joués`);
});
}
return true;
} else {
log(colors.red, '❌ Échec de récupération des participants');
log(colors.red, ` Status: ${response.status}`);
log(colors.red, ` Message: ${data.message || 'Erreur inconnue'}`);
return false;
}
} catch (error) {
log(colors.red, `❌ Erreur: ${error.message}`);
return false;
}
}
// Exécution de tous les tests
async function runAllTests() {
log(colors.green, '\n╔════════════════════════════════════════╗');
log(colors.green, '║ TESTS DES FONCTIONNALITÉS ADMIN ║');
log(colors.green, '╚════════════════════════════════════════╝');
const results = {
login: false,
statistics: false,
marketingStats: false,
marketingExport: false,
marketingReport: false,
eligibleParticipants: false
};
// Test 1: Connexion
results.login = await testAdminLogin();
if (!results.login) {
log(colors.red, '\n❌ Tests arrêtés - échec de la connexion admin');
process.exit(1);
}
// Test 2: Statistiques
results.statistics = await testStatistics();
// Test 3: Stats marketing
results.marketingStats = await testMarketingStats();
// Test 4: Export marketing
results.marketingExport = await testMarketingExport();
// Test 5: Rapport marketing
results.marketingReport = await testMarketingReport();
// Test 6: Participants éligibles
results.eligibleParticipants = await testEligibleParticipants();
// Résumé final
log(colors.blue, '\n========================================');
log(colors.blue, 'RÉSUMÉ DES TESTS');
log(colors.blue, '========================================\n');
const allPassed = Object.values(results).every(r => r === true);
Object.entries(results).forEach(([test, passed]) => {
const icon = passed ? '✅' : '❌';
const color = passed ? colors.green : colors.red;
log(color, `${icon} ${test}`);
});
log(colors.blue, '\n========================================\n');
if (allPassed) {
log(colors.green, '🎉 TOUS LES TESTS SONT PASSÉS !');
log(colors.green, '\n✅ Les fonctionnalités admin sont opérationnelles:');
log(colors.green, ' - Connexion admin');
log(colors.green, ' - Visualisation des statistiques');
log(colors.green, ' - Export des données pour emailing');
log(colors.green, ' - Rapport marketing');
log(colors.green, ' - Gestion du tirage au sort');
} else {
log(colors.red, '⚠️ CERTAINS TESTS ONT ÉCHOUÉ');
log(colors.yellow, '\nVérifiez les logs ci-dessus pour plus de détails.');
}
process.exit(allPassed ? 0 : 1);
}
// Lancer les tests
runAllTests().catch(error => {
log(colors.red, `\n❌ Erreur fatale: ${error.message}`);
console.error(error);
process.exit(1);
});