const axios = require('axios'); const BASE_URL = 'http://localhost:3000/api'; // Helper function to print test results function printTestResult(testNumber, testName, success, details = '') { const emoji = success ? '✅' : '❌'; console.log(`\n${emoji} Test ${testNumber}: ${testName}`); if (details) console.log(details); } // Helper function to print section header function printSection(title) { console.log('\n' + '='.repeat(60)); console.log(title); console.log('='.repeat(60)); } async function runTests() { console.log('\n╔════════════════════════════════════════════════════════════╗'); console.log('║ Category Management Tests (Task 18) ║'); console.log('╚════════════════════════════════════════════════════════════╝\n'); console.log('Make sure the server is running on http://localhost:3000\n'); let userToken = null; try { // Test 1: Get all categories as guest (public access) printSection('Test 1: Get all categories as guest (public)'); try { const response = await axios.get(`${BASE_URL}/categories`); if (response.status === 200 && response.data.success) { const categories = response.data.data; printTestResult(1, 'Get all categories as guest', true, `Count: ${response.data.count}\n` + `Categories: ${categories.map(c => c.name).join(', ')}\n` + `Message: ${response.data.message}`); console.log('\nGuest-accessible categories:'); categories.forEach(cat => { console.log(` - ${cat.icon} ${cat.name} (${cat.questionCount} questions)`); console.log(` Slug: ${cat.slug}`); console.log(` Guest Accessible: ${cat.guestAccessible}`); }); } else { throw new Error('Unexpected response'); } } catch (error) { printTestResult(1, 'Get all categories as guest', false, `Error: ${error.response?.data?.message || error.message}`); } // Test 2: Verify only guest-accessible categories returned printSection('Test 2: Verify only guest-accessible categories returned'); try { const response = await axios.get(`${BASE_URL}/categories`); const categories = response.data.data; const allGuestAccessible = categories.every(cat => cat.guestAccessible === true); if (allGuestAccessible) { printTestResult(2, 'Guest-accessible filter', true, `All ${categories.length} categories are guest-accessible\n` + `Expected: JavaScript, Angular, React`); } else { printTestResult(2, 'Guest-accessible filter', false, `Some categories are not guest-accessible`); } } catch (error) { printTestResult(2, 'Guest-accessible filter', false, `Error: ${error.message}`); } // Test 3: Login as user and get all categories printSection('Test 3: Login as user and get all categories'); try { // Login first const loginResponse = await axios.post(`${BASE_URL}/auth/login`, { email: 'admin@quiz.com', password: 'Admin@123' }); userToken = loginResponse.data.data.token; console.log('✅ Logged in as admin user'); // Now get categories with auth token const response = await axios.get(`${BASE_URL}/categories`, { headers: { 'Authorization': `Bearer ${userToken}` } }); if (response.status === 200 && response.data.success) { const categories = response.data.data; printTestResult(3, 'Get all categories as authenticated user', true, `Count: ${response.data.count}\n` + `Categories: ${categories.map(c => c.name).join(', ')}\n` + `Message: ${response.data.message}`); console.log('\nAll active categories:'); categories.forEach(cat => { console.log(` - ${cat.icon} ${cat.name} (${cat.questionCount} questions)`); console.log(` Guest Accessible: ${cat.guestAccessible ? 'Yes' : 'No'}`); }); } else { throw new Error('Unexpected response'); } } catch (error) { printTestResult(3, 'Get all categories as authenticated user', false, `Error: ${error.response?.data?.message || error.message}`); } // Test 4: Verify authenticated users see more categories printSection('Test 4: Compare guest vs authenticated category counts'); try { const guestResponse = await axios.get(`${BASE_URL}/categories`); const authResponse = await axios.get(`${BASE_URL}/categories`, { headers: { 'Authorization': `Bearer ${userToken}` } }); const guestCount = guestResponse.data.count; const authCount = authResponse.data.count; if (authCount >= guestCount) { printTestResult(4, 'Category count comparison', true, `Guest sees: ${guestCount} categories\n` + `Authenticated sees: ${authCount} categories\n` + `Difference: ${authCount - guestCount} additional categories for authenticated users`); } else { printTestResult(4, 'Category count comparison', false, `Authenticated user sees fewer categories than guest`); } } catch (error) { printTestResult(4, 'Category count comparison', false, `Error: ${error.message}`); } // Test 5: Verify response structure printSection('Test 5: Verify response structure and data types'); try { const response = await axios.get(`${BASE_URL}/categories`); const hasCorrectStructure = response.data.success === true && typeof response.data.count === 'number' && Array.isArray(response.data.data) && typeof response.data.message === 'string'; if (hasCorrectStructure && response.data.data.length > 0) { const category = response.data.data[0]; const categoryHasFields = category.id && category.name && category.slug && category.description && category.icon && category.color && typeof category.questionCount === 'number' && typeof category.displayOrder === 'number' && typeof category.guestAccessible === 'boolean'; if (categoryHasFields) { printTestResult(5, 'Response structure verification', true, 'All required fields present with correct types\n' + 'Category fields: id, name, slug, description, icon, color, questionCount, displayOrder, guestAccessible'); } else { printTestResult(5, 'Response structure verification', false, 'Missing or incorrect fields in category object'); } } else { printTestResult(5, 'Response structure verification', false, 'Missing or incorrect fields in response'); } } catch (error) { printTestResult(5, 'Response structure verification', false, `Error: ${error.message}`); } // Test 6: Verify categories are ordered by displayOrder printSection('Test 6: Verify categories ordered by displayOrder'); try { const response = await axios.get(`${BASE_URL}/categories`); const categories = response.data.data; let isOrdered = true; for (let i = 1; i < categories.length; i++) { if (categories[i].displayOrder < categories[i-1].displayOrder) { isOrdered = false; break; } } if (isOrdered) { printTestResult(6, 'Category ordering', true, `Categories correctly ordered by displayOrder:\n` + categories.map(c => ` ${c.displayOrder}: ${c.name}`).join('\n')); } else { printTestResult(6, 'Category ordering', false, 'Categories not properly ordered by displayOrder'); } } catch (error) { printTestResult(6, 'Category ordering', false, `Error: ${error.message}`); } // Test 7: Verify expected guest categories are present printSection('Test 7: Verify expected guest categories present'); try { const response = await axios.get(`${BASE_URL}/categories`); const categories = response.data.data; const categoryNames = categories.map(c => c.name); const expectedCategories = ['JavaScript', 'Angular', 'React']; const allPresent = expectedCategories.every(name => categoryNames.includes(name)); if (allPresent) { printTestResult(7, 'Expected categories present', true, `All expected guest categories found: ${expectedCategories.join(', ')}`); } else { const missing = expectedCategories.filter(name => !categoryNames.includes(name)); printTestResult(7, 'Expected categories present', false, `Missing categories: ${missing.join(', ')}`); } } catch (error) { printTestResult(7, 'Expected categories present', false, `Error: ${error.message}`); } } catch (error) { console.error('\n❌ Fatal error during testing:', error.message); } console.log('\n╔════════════════════════════════════════════════════════════╗'); console.log('║ Tests Completed ║'); console.log('╚════════════════════════════════════════════════════════════╝\n'); } // Run tests runTests();