Files
Tasks/backend/tests/test-category-endpoints.js
2025-12-25 00:24:11 +02:00

243 lines
9.7 KiB
JavaScript

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();