Files
sena_db_api_layer/scripts/test-teacher-profile.js
2026-01-19 09:33:35 +07:00

268 lines
7.4 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 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();