const axios = require('axios'); const BASE_URL = 'http://localhost:3000/api'; // Test configuration const testConfig = { adminUser: { email: 'admin@example.com', password: 'Admin123!@#' }, regularUser: { email: 'stattest@example.com', password: 'Test123!@#' }, testUser: { email: 'usermgmttest@example.com', password: 'Test123!@#', username: 'usermgmttest' } }; // Test state let adminToken = null; let regularToken = null; let testUserId = null; // Test results let passedTests = 0; let failedTests = 0; const results = []; // Helper function to log test results function logTest(name, passed, error = null) { results.push({ name, passed, error }); if (passed) { console.log(`✓ ${name}`); passedTests++; } else { console.log(`✗ ${name}`); if (error) console.log(` Error: ${error}`); failedTests++; } } // Setup function async function setup() { console.log('Setting up test data...\n'); try { // Login admin user const adminLoginRes = await axios.post(`${BASE_URL}/auth/login`, { email: testConfig.adminUser.email, password: testConfig.adminUser.password }); adminToken = adminLoginRes.data.data.token; console.log('✓ Admin user logged in'); // Login regular user const userLoginRes = await axios.post(`${BASE_URL}/auth/login`, { email: testConfig.regularUser.email, password: testConfig.regularUser.password }); regularToken = userLoginRes.data.data.token; console.log('✓ Regular user logged in'); // Create test user try { const registerRes = await axios.post(`${BASE_URL}/auth/register`, testConfig.testUser); testUserId = registerRes.data.data.user.id; console.log('✓ Test user created'); } catch (error) { if (error.response?.status === 409) { // User already exists, login to get ID const loginRes = await axios.post(`${BASE_URL}/auth/login`, { email: testConfig.testUser.email, password: testConfig.testUser.password }); // Get user ID from token or fetch user list const usersRes = await axios.get(`${BASE_URL}/admin/users?email=${testConfig.testUser.email}`, { headers: { Authorization: `Bearer ${adminToken}` } }); if (usersRes.data.data.users.length > 0) { testUserId = usersRes.data.data.users[0].id; } console.log('✓ Test user already exists'); } } console.log('\n============================================================'); console.log('USER MANAGEMENT API TESTS'); console.log('============================================================\n'); } catch (error) { console.error('Setup failed:', error.response?.data || error.message); process.exit(1); } } // Test functions async function testGetAllUsers() { try { const response = await axios.get(`${BASE_URL}/admin/users`, { headers: { Authorization: `Bearer ${adminToken}` } }); const passed = response.status === 200 && response.data.success === true && Array.isArray(response.data.data.users) && response.data.data.pagination !== undefined; logTest('Get all users with pagination', passed); return response.data.data; } catch (error) { logTest('Get all users with pagination', false, error.response?.data?.message || error.message); return null; } } async function testPaginationStructure(data) { if (!data) { logTest('Pagination structure validation', false, 'No data available'); return; } try { const pagination = data.pagination; const passed = typeof pagination.currentPage === 'number' && typeof pagination.totalPages === 'number' && typeof pagination.totalItems === 'number' && typeof pagination.itemsPerPage === 'number' && typeof pagination.hasNextPage === 'boolean' && typeof pagination.hasPreviousPage === 'boolean'; logTest('Pagination structure validation', passed); } catch (error) { logTest('Pagination structure validation', false, error.message); } } async function testUserFieldsStructure(data) { if (!data || !data.users || data.users.length === 0) { logTest('User fields validation', false, 'No users available'); return; } try { const user = data.users[0]; const passed = user.id !== undefined && user.username !== undefined && user.email !== undefined && user.role !== undefined && typeof user.isActive === 'boolean' && user.password === undefined; // Password should be excluded logTest('User fields validation', passed); } catch (error) { logTest('User fields validation', false, error.message); } } async function testFilterByRole() { try { const response = await axios.get(`${BASE_URL}/admin/users?role=user`, { headers: { Authorization: `Bearer ${adminToken}` } }); const passed = response.status === 200 && response.data.data.users.every(u => u.role === 'user'); logTest('Filter users by role', passed); } catch (error) { logTest('Filter users by role', false, error.response?.data?.message || error.message); } } async function testFilterByActive() { try { const response = await axios.get(`${BASE_URL}/admin/users?isActive=true`, { headers: { Authorization: `Bearer ${adminToken}` } }); const passed = response.status === 200 && response.data.data.users.every(u => u.isActive === true); logTest('Filter users by isActive', passed); } catch (error) { logTest('Filter users by isActive', false, error.response?.data?.message || error.message); } } async function testSorting() { try { const response = await axios.get(`${BASE_URL}/admin/users?sortBy=username&sortOrder=asc`, { headers: { Authorization: `Bearer ${adminToken}` } }); const passed = response.status === 200 && response.data.data.sorting.sortBy === 'username' && response.data.data.sorting.sortOrder === 'ASC'; logTest('Sort users by username', passed); } catch (error) { logTest('Sort users by username', false, error.response?.data?.message || error.message); } } async function testGetUserById() { if (!testUserId) { logTest('Get user by ID', false, 'No test user ID available'); return; } try { const response = await axios.get(`${BASE_URL}/admin/users/${testUserId}`, { headers: { Authorization: `Bearer ${adminToken}` } }); const passed = response.status === 200 && response.data.success === true && response.data.data.id === testUserId && response.data.data.stats !== undefined && response.data.data.activity !== undefined && Array.isArray(response.data.data.recentSessions); logTest('Get user by ID', passed); } catch (error) { logTest('Get user by ID', false, error.response?.data?.message || error.message); } } async function testUpdateUserRole() { if (!testUserId) { logTest('Update user role', false, 'No test user ID available'); return; } try { const response = await axios.put(`${BASE_URL}/admin/users/${testUserId}/role`, { role: 'admin' }, { headers: { Authorization: `Bearer ${adminToken}` } } ); const passed = response.status === 200 && response.data.success === true && response.data.data.role === 'admin'; logTest('Update user role to admin', passed); // Revert back to user if (passed) { await axios.put(`${BASE_URL}/admin/users/${testUserId}/role`, { role: 'user' }, { headers: { Authorization: `Bearer ${adminToken}` } } ); } } catch (error) { logTest('Update user role to admin', false, error.response?.data?.message || error.message); } } async function testPreventLastAdminDemotion() { try { // Try to demote the admin user (should fail if it's the last admin) const usersRes = await axios.get(`${BASE_URL}/admin/users?role=admin`, { headers: { Authorization: `Bearer ${adminToken}` } }); if (usersRes.data.data.users.length <= 1) { const adminId = usersRes.data.data.users[0].id; await axios.put(`${BASE_URL}/admin/users/${adminId}/role`, { role: 'user' }, { headers: { Authorization: `Bearer ${adminToken}` } } ); logTest('Prevent demoting last admin', false, 'Should not allow demoting last admin'); } else { logTest('Prevent demoting last admin (skipped - multiple admins)', true); } } catch (error) { const passed = error.response?.status === 400 && error.response?.data?.message?.includes('last admin'); logTest('Prevent demoting last admin', passed, !passed ? `Expected 400 with last admin message, got ${error.response?.status}` : null); } } async function testDeactivateUser() { if (!testUserId) { logTest('Deactivate user', false, 'No test user ID available'); return; } try { const response = await axios.delete(`${BASE_URL}/admin/users/${testUserId}`, { headers: { Authorization: `Bearer ${adminToken}` } }); const passed = response.status === 200 && response.data.success === true && response.data.data.isActive === false; logTest('Deactivate user', passed); } catch (error) { logTest('Deactivate user', false, error.response?.data?.message || error.message); } } async function testReactivateUser() { if (!testUserId) { logTest('Reactivate user', false, 'No test user ID available'); return; } try { const response = await axios.put(`${BASE_URL}/admin/users/${testUserId}/activate`, {}, { headers: { Authorization: `Bearer ${adminToken}` } } ); const passed = response.status === 200 && response.data.success === true && response.data.data.isActive === true; logTest('Reactivate user', passed); } catch (error) { logTest('Reactivate user', false, error.response?.data?.message || error.message); } } async function testInvalidUserId() { try { await axios.get(`${BASE_URL}/admin/users/invalid-uuid`, { headers: { Authorization: `Bearer ${adminToken}` } }); logTest('Invalid user ID rejected', false, 'Should reject invalid UUID'); } catch (error) { const passed = error.response?.status === 400; logTest('Invalid user ID rejected', passed, !passed ? `Expected 400, got ${error.response?.status}` : null); } } async function testNonExistentUser() { try { await axios.get(`${BASE_URL}/admin/users/00000000-0000-0000-0000-000000000000`, { headers: { Authorization: `Bearer ${adminToken}` } }); logTest('Non-existent user returns 404', false, 'Should return 404'); } catch (error) { const passed = error.response?.status === 404; logTest('Non-existent user returns 404', passed, !passed ? `Expected 404, got ${error.response?.status}` : null); } } async function testInvalidRole() { if (!testUserId) { logTest('Invalid role rejected', false, 'No test user ID available'); return; } try { await axios.put(`${BASE_URL}/admin/users/${testUserId}/role`, { role: 'superadmin' }, { headers: { Authorization: `Bearer ${adminToken}` } } ); logTest('Invalid role rejected', false, 'Should reject invalid role'); } catch (error) { const passed = error.response?.status === 400; logTest('Invalid role rejected', passed, !passed ? `Expected 400, got ${error.response?.status}` : null); } } async function testNonAdminBlocked() { try { await axios.get(`${BASE_URL}/admin/users`, { headers: { Authorization: `Bearer ${regularToken}` } }); logTest('Non-admin user blocked', false, 'Regular user should not have access'); } catch (error) { const passed = error.response?.status === 403; logTest('Non-admin user blocked', passed, !passed ? `Expected 403, got ${error.response?.status}` : null); } } async function testUnauthenticated() { try { await axios.get(`${BASE_URL}/admin/users`); logTest('Unauthenticated request blocked', false, 'Should require authentication'); } catch (error) { const passed = error.response?.status === 401; logTest('Unauthenticated request blocked', passed, !passed ? `Expected 401, got ${error.response?.status}` : null); } } // Main test runner async function runTests() { await setup(); console.log('Running tests...\n'); // List users tests const data = await testGetAllUsers(); await new Promise(resolve => setTimeout(resolve, 100)); await testPaginationStructure(data); await new Promise(resolve => setTimeout(resolve, 100)); await testUserFieldsStructure(data); await new Promise(resolve => setTimeout(resolve, 100)); await testFilterByRole(); await new Promise(resolve => setTimeout(resolve, 100)); await testFilterByActive(); await new Promise(resolve => setTimeout(resolve, 100)); await testSorting(); await new Promise(resolve => setTimeout(resolve, 100)); // Get user by ID await testGetUserById(); await new Promise(resolve => setTimeout(resolve, 100)); // Update role tests await testUpdateUserRole(); await new Promise(resolve => setTimeout(resolve, 100)); await testPreventLastAdminDemotion(); await new Promise(resolve => setTimeout(resolve, 100)); // Deactivate/Reactivate tests await testDeactivateUser(); await new Promise(resolve => setTimeout(resolve, 100)); await testReactivateUser(); await new Promise(resolve => setTimeout(resolve, 100)); // Validation tests await testInvalidUserId(); await new Promise(resolve => setTimeout(resolve, 100)); await testNonExistentUser(); await new Promise(resolve => setTimeout(resolve, 100)); await testInvalidRole(); await new Promise(resolve => setTimeout(resolve, 100)); // Authorization tests await testNonAdminBlocked(); await new Promise(resolve => setTimeout(resolve, 100)); await testUnauthenticated(); // Print results console.log('\n============================================================'); console.log(`RESULTS: ${passedTests} passed, ${failedTests} failed out of ${passedTests + failedTests} tests`); console.log('============================================================\n'); if (failedTests > 0) { console.log('Failed tests:'); results.filter(r => !r.passed).forEach(r => { console.log(` - ${r.name}`); if (r.error) console.log(` ${r.error}`); }); } process.exit(failedTests > 0 ? 1 : 0); } // Run tests runTests().catch(error => { console.error('Test execution failed:', error); process.exit(1); });