Files
tasks-backend/tests/test-user-management.js
2025-12-26 23:56:32 +02:00

480 lines
15 KiB
JavaScript

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