484 lines
17 KiB
JavaScript
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);
|
|
});
|