const axios = require('axios'); const BASE_URL = 'http://localhost:9000'; async function runTests() { console.log('=== STARTING INTEGRATION TESTS FOR ADMIN & MENTOR ROLES ===\n'); let adminToken = ''; let mentorToken = ''; let createdProjectId = null; const mentorEmail = `mentor_${Date.now()}@internify.com`; const mentorPassword = 'Password123'; // Helper config generator const getHeader = (token) => ({ headers: { Authorization: `Bearer ${token}` } }); try { // 1. Login as Admin console.log('1. Logging in as Admin (admin1@internify.com)...'); const loginRes = await axios.post(`${BASE_URL}/auth-api/login`, { email: 'admin1@internify.com', password: 'password123' }); adminToken = loginRes.data.data.token; console.log(' Admin logged in successfully!\n'); // 2. Create Mentor Account via Admin API console.log(`2. Creating a new Mentor account (${mentorEmail}) via Admin endpoint...`); await axios.post(`${BASE_URL}/admin-api/add`, { nama_depan: 'John', nama_belakang: 'Mentor', email: mentorEmail, password: mentorPassword, role: 'mentor' }, getHeader(adminToken)); console.log(' Mentor account created successfully!\n'); // 3. Login as Mentor console.log('3. Logging in as the newly created Mentor...'); const mentorLoginRes = await axios.post(`${BASE_URL}/auth-api/login`, { email: mentorEmail, password: mentorPassword }); mentorToken = mentorLoginRes.data.data.token; console.log(` Mentor logged in successfully! Role: ${mentorLoginRes.data.data.user.role}\n`); // 4. Mentor creates a project console.log('4. Creating a project as Mentor...'); const createProjectRes = await axios.post(`${BASE_URL}/project-api/add`, { project_icon: 'code', project_name: `Mentor's Custom Project - ${Date.now()}`, description: 'A project created specifically to test mentor ownership isolation.', start_date: '2026-07-01', end_date: '2026-10-01', member_emails: [] }, getHeader(mentorToken)); createdProjectId = createProjectRes.data.data.id; console.log(` Project created successfully! ID: ${createdProjectId}\n`); // 5. Mentor lists projects (should ONLY see their own created project) console.log('5. Mentor lists their projects...'); const mentorProjectsRes = await axios.get(`${BASE_URL}/project-api/get`, getHeader(mentorToken)); const mentorProjects = mentorProjectsRes.data.data; console.log(` Projects found for mentor: ${mentorProjects.length}`); mentorProjects.forEach(p => console.log(` - [ID: ${p.id}] ${p.project_name} (Created by Admin/Mentor ID: ${p.admin.id})`)); const hasOtherProjects = mentorProjects.some(p => p.id !== createdProjectId); if (hasOtherProjects) { throw new Error('TEST FAILED: Mentor is seeing projects they did not create!'); } console.log(' PASSED: Mentor only sees their own project.\n'); // 6. Admin lists projects (should see all projects, including the mentor\'s project and seeded projects) console.log('6. Admin lists all projects...'); const adminProjectsRes = await axios.get(`${BASE_URL}/project-api/get`, getHeader(adminToken)); const adminProjects = adminProjectsRes.data.data; console.log(` Projects found for admin: ${adminProjects.length}`); const containsMentorProject = adminProjects.some(p => p.id === createdProjectId); if (!containsMentorProject) { throw new Error('TEST FAILED: Admin cannot see the project created by the mentor!'); } console.log(' PASSED: Admin can see all projects in the system.\n'); // 7. Mentor tries to access another project details (e.g. Project 1, created by admin1) console.log('7. Testing isolation: Mentor trying to access Project ID 1 (which they do not own)...'); try { await axios.get(`${BASE_URL}/project-api/get/1`, getHeader(mentorToken)); throw new Error('TEST FAILED: Mentor successfully accessed another mentor/admin\'s project!'); } catch (err) { if (err.response && err.response.status === 403) { console.log(' PASSED: Access denied with 403 Forbidden as expected.\n'); } else { throw err; } } // 8. Admin accesses Project details of the mentor's project console.log(`8. Admin accessing details of the Mentor's project (ID: ${createdProjectId})...`); const adminDetailRes = await axios.get(`${BASE_URL}/project-api/get/${createdProjectId}`, getHeader(adminToken)); console.log(` PASSED: Admin retrieved project details successfully (Name: ${adminDetailRes.data.data.project_name}).\n`); // 9. Assign and Remove Member Test console.log('9. Testing Assign and Remove Member feature...'); // 9.1. Get active interns console.log(' Fetching active interns...'); const internsRes = await axios.get(`${BASE_URL}/project-api/interns`, getHeader(mentorToken)); const interns = internsRes.data.data; if (interns.length === 0) { throw new Error('TEST FAILED: No interns found to test assignment!'); } const testIntern = interns[0]; console.log(` Found intern: ${testIntern.name} (ID: ${testIntern.id})`); // 9.2. Assign intern to mentor's project console.log(` Assigning intern ID: ${testIntern.id} to project ID: ${createdProjectId}...`); await axios.post(`${BASE_URL}/project-api/assign-member`, { id_project: createdProjectId, id_user: testIntern.id }, getHeader(mentorToken)); console.log(' PASSED: Intern assigned successfully.'); // 9.3. Try to remove the intern as an intern (should fail with 401/403) console.log(' Testing authorization: Intern trying to remove themselves or others...'); let internToken = ''; try { const internLoginRes = await axios.post(`${BASE_URL}/auth-api/login`, { email: 'rafi@student.com', password: 'password123' }); internToken = internLoginRes.data.data.token; await axios.post(`${BASE_URL}/project-api/remove-member`, { id_project: createdProjectId, id_user: testIntern.id }, getHeader(internToken)); throw new Error('TEST FAILED: Intern successfully removed a member!'); } catch (err) { if (err.response && (err.response.status === 401 || err.response.status === 403)) { console.log(' PASSED: Intern request denied with 401 Unauthorized / 403 Forbidden as expected.'); } else { throw err; } } // 9.4. Remove the intern as Mentor (should succeed with 200) console.log(` Removing intern ID: ${testIntern.id} from project ID: ${createdProjectId} as Mentor...`); const removeRes = await axios.post(`${BASE_URL}/project-api/remove-member`, { id_project: createdProjectId, id_user: testIntern.id }, getHeader(mentorToken)); if (removeRes.status === 200 && removeRes.data.status === true) { console.log(' PASSED: Intern removed successfully (200 OK).'); } else { throw new Error(`TEST FAILED: Failed to remove intern. Response: ${JSON.stringify(removeRes.data)}`); } // 9.5. Try to remove the intern again (should fail with 400 because already removed) console.log(' Trying to remove the already removed intern again...'); try { await axios.post(`${BASE_URL}/project-api/remove-member`, { id_project: createdProjectId, id_user: testIntern.id }, getHeader(mentorToken)); throw new Error('TEST FAILED: Successfully removed already removed intern!'); } catch (err) { if (err.response && err.response.status === 400) { console.log(' PASSED: Request denied with 400 Bad Request as expected.\n'); } else { throw err; } } console.log('=== ALL INTEGRATION TESTS PASSED SUCCESSFULLY! ==='); } catch (err) { console.error('=== TEST EXECUTION ENCOUNTERED AN ERROR ==='); if (err.response) { console.error(`Status: ${err.response.status}`); console.error('Response Data:', JSON.stringify(err.response.data, null, 2)); } else { console.error(err.message); } process.exit(1); } } runTests();