268 lines
7.4 KiB
JavaScript
268 lines
7.4 KiB
JavaScript
/**
|
||
* Test Teacher Profile Service
|
||
*
|
||
* Usage:
|
||
* node src/scripts/test-teacher-profile.js
|
||
*/
|
||
|
||
require('dotenv').config();
|
||
const teacherProfileService = require('../services/teacherProfileService');
|
||
const { sequelize, TeacherDetail, UserProfile, UsersAuth } = require('../models');
|
||
|
||
async function testCreateTeacher() {
|
||
console.log('\n📝 Test 1: Create teacher với minimal data');
|
||
console.log('='.repeat(60));
|
||
|
||
try {
|
||
const minimalTeacher = {
|
||
teacher_code: `TEST_GV_${Date.now()}`,
|
||
teacher_type: 'homeroom',
|
||
};
|
||
|
||
console.log('Input:', JSON.stringify(minimalTeacher, null, 2));
|
||
|
||
const result = await teacherProfileService.createTeacherWithProfile(minimalTeacher);
|
||
|
||
console.log('\n✅ Success!');
|
||
console.log('Output:', JSON.stringify({
|
||
user_id: result.user_id,
|
||
username: result.username,
|
||
email: result.email,
|
||
temporary_password: result.temporary_password,
|
||
teacher_code: result.teacher_detail.teacher_code,
|
||
full_name: result.profile.full_name,
|
||
}, null, 2));
|
||
|
||
return result;
|
||
|
||
} catch (error) {
|
||
console.error('❌ Failed:', error.message);
|
||
throw error;
|
||
}
|
||
}
|
||
|
||
async function testCreateForeignTeacher() {
|
||
console.log('\n📝 Test 2: Create foreign teacher với full data');
|
||
console.log('='.repeat(60));
|
||
|
||
try {
|
||
const fullTeacher = {
|
||
// Required
|
||
teacher_code: `TEST_FT_${Date.now()}`,
|
||
teacher_type: 'foreign',
|
||
|
||
// Optional auth
|
||
username: 'test_john_smith',
|
||
email: `test_john_${Date.now()}@sena.edu.vn`,
|
||
password: 'TestPassword123!',
|
||
|
||
// Optional profile
|
||
full_name: 'John Smith',
|
||
first_name: 'John',
|
||
last_name: 'Smith',
|
||
phone: '+84-123-456-789',
|
||
date_of_birth: '1985-03-15',
|
||
gender: 'male',
|
||
address: '123 Test Street',
|
||
city: 'Ho Chi Minh City',
|
||
district: 'District 1',
|
||
|
||
// Optional teacher details
|
||
qualification: 'Master of Education',
|
||
specialization: 'English Literature',
|
||
hire_date: '2026-01-01',
|
||
skill_tags: [
|
||
{ name: 'IELTS', level: 'expert' },
|
||
{ name: 'TOEFL', level: 'advanced' }
|
||
],
|
||
certifications: [
|
||
{ name: 'TESOL', issued_by: 'Cambridge', issued_date: '2020-05-15' }
|
||
]
|
||
};
|
||
|
||
console.log('Input:', JSON.stringify(fullTeacher, null, 2));
|
||
|
||
const result = await teacherProfileService.createTeacherWithProfile(fullTeacher);
|
||
|
||
console.log('\n✅ Success!');
|
||
console.log('Output:', JSON.stringify({
|
||
user_id: result.user_id,
|
||
username: result.username,
|
||
email: result.email,
|
||
temporary_password: result.temporary_password, // Should be null
|
||
teacher_code: result.teacher_detail.teacher_code,
|
||
full_name: result.profile.full_name,
|
||
phone: result.profile.phone,
|
||
needs_update: result.profile.etc?.needs_profile_update,
|
||
}, null, 2));
|
||
|
||
return result;
|
||
|
||
} catch (error) {
|
||
console.error('❌ Failed:', error.message);
|
||
throw error;
|
||
}
|
||
}
|
||
|
||
async function testUpdateProfile(userId) {
|
||
console.log('\n📝 Test 3: Update teacher profile');
|
||
console.log('='.repeat(60));
|
||
|
||
try {
|
||
const updateData = {
|
||
full_name: 'John Smith Updated',
|
||
phone: '+84-987-654-321',
|
||
address: '456 New Address',
|
||
};
|
||
|
||
console.log('User ID:', userId);
|
||
console.log('Update data:', JSON.stringify(updateData, null, 2));
|
||
|
||
const result = await teacherProfileService.updateTeacherProfile(userId, updateData);
|
||
|
||
console.log('\n✅ Success!');
|
||
console.log('Updated profile:', JSON.stringify({
|
||
full_name: result.full_name,
|
||
phone: result.phone,
|
||
address: result.address,
|
||
needs_update: result.etc?.needs_profile_update,
|
||
last_updated: result.etc?.last_updated,
|
||
}, null, 2));
|
||
|
||
return result;
|
||
|
||
} catch (error) {
|
||
console.error('❌ Failed:', error.message);
|
||
throw error;
|
||
}
|
||
}
|
||
|
||
async function testSync() {
|
||
console.log('\n📝 Test 4: Sync existing teachers');
|
||
console.log('='.repeat(60));
|
||
|
||
try {
|
||
// First, create a teacher_detail without profile (simulate old data)
|
||
const testUserAuth = await UsersAuth.create({
|
||
username: `test_orphan_${Date.now()}`,
|
||
email: `test_orphan_${Date.now()}@sena.edu.vn`,
|
||
password_hash: 'dummy_hash',
|
||
salt: 'dummy_salt',
|
||
});
|
||
|
||
const orphanTeacher = await TeacherDetail.create({
|
||
user_id: testUserAuth.id,
|
||
teacher_code: `TEST_ORPHAN_${Date.now()}`,
|
||
teacher_type: 'subject',
|
||
});
|
||
|
||
console.log(`Created orphan teacher: ${orphanTeacher.teacher_code}`);
|
||
|
||
// Now sync
|
||
const results = await teacherProfileService.syncExistingTeachers(orphanTeacher.id);
|
||
|
||
console.log('\n✅ Sync completed!');
|
||
console.log('Results:', JSON.stringify({
|
||
success_count: results.success.length,
|
||
skipped_count: results.skipped.length,
|
||
failed_count: results.failed.length,
|
||
success: results.success,
|
||
skipped: results.skipped,
|
||
failed: results.failed,
|
||
}, null, 2));
|
||
|
||
return results;
|
||
|
||
} catch (error) {
|
||
console.error('❌ Failed:', error.message);
|
||
throw error;
|
||
}
|
||
}
|
||
|
||
async function cleanup(userIds) {
|
||
console.log('\n🧹 Cleaning up test data...');
|
||
|
||
try {
|
||
// Delete in correct order due to foreign keys
|
||
for (const userId of userIds) {
|
||
await TeacherDetail.destroy({ where: { user_id: userId }, force: true });
|
||
await UserProfile.destroy({ where: { user_id: userId }, force: true });
|
||
await UsersAuth.destroy({ where: { id: userId }, force: true });
|
||
}
|
||
|
||
console.log('✅ Cleanup completed');
|
||
|
||
} catch (error) {
|
||
console.error('❌ Cleanup failed:', error.message);
|
||
}
|
||
}
|
||
|
||
async function main() {
|
||
console.log('\n🚀 Starting Teacher Profile Service Tests\n');
|
||
|
||
const createdUserIds = [];
|
||
|
||
try {
|
||
// Test connection
|
||
await sequelize.authenticate();
|
||
console.log('✅ Database connected\n');
|
||
|
||
// Run tests
|
||
const result1 = await testCreateTeacher();
|
||
createdUserIds.push(result1.user_id);
|
||
|
||
const result2 = await testCreateForeignTeacher();
|
||
createdUserIds.push(result2.user_id);
|
||
|
||
await testUpdateProfile(result2.user_id);
|
||
|
||
const syncResult = await testSync();
|
||
if (syncResult.success.length > 0) {
|
||
createdUserIds.push(syncResult.success[0].user_id);
|
||
}
|
||
|
||
// Summary
|
||
console.log('\n' + '='.repeat(60));
|
||
console.log('📊 TEST SUMMARY');
|
||
console.log('='.repeat(60));
|
||
console.log('✅ All tests passed!');
|
||
console.log(`Created ${createdUserIds.length} test users`);
|
||
console.log('='.repeat(60));
|
||
|
||
// Cleanup
|
||
const readline = require('readline').createInterface({
|
||
input: process.stdin,
|
||
output: process.stdout
|
||
});
|
||
|
||
readline.question('\nDelete test data? (y/n): ', async (answer) => {
|
||
if (answer.toLowerCase() === 'y') {
|
||
await cleanup(createdUserIds);
|
||
} else {
|
||
console.log('\n⚠️ Test data NOT deleted. User IDs:');
|
||
createdUserIds.forEach((id, index) => {
|
||
console.log(` ${index + 1}. ${id}`);
|
||
});
|
||
}
|
||
|
||
readline.close();
|
||
process.exit(0);
|
||
});
|
||
|
||
} catch (error) {
|
||
console.error('\n❌ Test failed:', error.message);
|
||
console.error(error.stack);
|
||
|
||
// Cleanup on error
|
||
if (createdUserIds.length > 0) {
|
||
console.log('\nCleaning up partial test data...');
|
||
await cleanup(createdUserIds);
|
||
}
|
||
|
||
process.exit(1);
|
||
}
|
||
}
|
||
|
||
// Run tests
|
||
main();
|