add changes

This commit is contained in:
AD2025
2025-11-11 00:25:50 +02:00
commit e3ca132c5e
86 changed files with 22238 additions and 0 deletions

View File

@@ -0,0 +1,382 @@
const { sequelize } = require('./models');
const { User, Category, GuestSession, QuizSession } = require('./models');
async function runTests() {
console.log('🧪 Running QuizSession Model Tests\n');
console.log('=====================================\n');
try {
let testUser, testCategory, testGuestSession, userQuiz, guestQuiz;
// Test 1: Create a quiz session for a registered user
console.log('Test 1: Create quiz session for user');
testUser = await User.create({
username: `quizuser${Date.now()}`,
email: `quizuser${Date.now()}@test.com`,
password: 'password123',
role: 'user'
});
testCategory = await Category.create({
name: 'Test Category for Quiz',
description: 'Category for quiz testing',
isActive: true
});
userQuiz = await QuizSession.createSession({
userId: testUser.id,
categoryId: testCategory.id,
quizType: 'practice',
difficulty: 'medium',
totalQuestions: 10,
passPercentage: 70.00
});
console.log('✅ User quiz session created with ID:', userQuiz.id);
console.log(' User ID:', userQuiz.userId);
console.log(' Category ID:', userQuiz.categoryId);
console.log(' Status:', userQuiz.status);
console.log(' Total questions:', userQuiz.totalQuestions);
console.log(' Match:', userQuiz.status === 'not_started' ? '✅' : '❌');
// Test 2: Create a quiz session for a guest
console.log('\nTest 2: Create quiz session for guest');
testGuestSession = await GuestSession.createSession({
maxQuizzes: 5,
expiryHours: 24
});
guestQuiz = await QuizSession.createSession({
guestSessionId: testGuestSession.id,
categoryId: testCategory.id,
quizType: 'practice',
difficulty: 'easy',
totalQuestions: 5,
passPercentage: 60.00
});
console.log('✅ Guest quiz session created with ID:', guestQuiz.id);
console.log(' Guest session ID:', guestQuiz.guestSessionId);
console.log(' Category ID:', guestQuiz.categoryId);
console.log(' Total questions:', guestQuiz.totalQuestions);
console.log(' Match:', guestQuiz.guestSessionId === testGuestSession.id ? '✅' : '❌');
// Test 3: Start a quiz session
console.log('\nTest 3: Start quiz session');
await userQuiz.start();
await userQuiz.reload();
console.log('✅ Quiz started');
console.log(' Status:', userQuiz.status);
console.log(' Started at:', userQuiz.startedAt);
console.log(' Match:', userQuiz.status === 'in_progress' && userQuiz.startedAt ? '✅' : '❌');
// Test 4: Record correct answer
console.log('\nTest 4: Record correct answer');
const beforeAnswers = userQuiz.questionsAnswered;
const beforeCorrect = userQuiz.correctAnswers;
await userQuiz.recordAnswer(true, 10);
await userQuiz.reload();
console.log('✅ Answer recorded');
console.log(' Questions answered:', userQuiz.questionsAnswered);
console.log(' Correct answers:', userQuiz.correctAnswers);
console.log(' Total points:', userQuiz.totalPoints);
console.log(' Match:', userQuiz.questionsAnswered === beforeAnswers + 1 &&
userQuiz.correctAnswers === beforeCorrect + 1 ? '✅' : '❌');
// Test 5: Record incorrect answer
console.log('\nTest 5: Record incorrect answer');
const beforeAnswers2 = userQuiz.questionsAnswered;
const beforeCorrect2 = userQuiz.correctAnswers;
await userQuiz.recordAnswer(false, 0);
await userQuiz.reload();
console.log('✅ Incorrect answer recorded');
console.log(' Questions answered:', userQuiz.questionsAnswered);
console.log(' Correct answers:', userQuiz.correctAnswers);
console.log(' Match:', userQuiz.questionsAnswered === beforeAnswers2 + 1 &&
userQuiz.correctAnswers === beforeCorrect2 ? '✅' : '❌');
// Test 6: Get quiz progress
console.log('\nTest 6: Get quiz progress');
const progress = userQuiz.getProgress();
console.log('✅ Progress retrieved');
console.log(' Status:', progress.status);
console.log(' Questions answered:', progress.questionsAnswered);
console.log(' Questions remaining:', progress.questionsRemaining);
console.log(' Progress percentage:', progress.progressPercentage + '%');
console.log(' Current accuracy:', progress.currentAccuracy + '%');
console.log(' Match:', progress.questionsAnswered === 2 ? '✅' : '❌');
// Test 7: Update time spent
console.log('\nTest 7: Update time spent');
await userQuiz.updateTimeSpent(120); // 2 minutes
await userQuiz.reload();
console.log('✅ Time updated');
console.log(' Time spent:', userQuiz.timeSpent, 'seconds');
console.log(' Match:', userQuiz.timeSpent === 120 ? '✅' : '❌');
// Test 8: Complete quiz by answering remaining questions
console.log('\nTest 8: Auto-complete quiz when all questions answered');
// Answer remaining 8 questions (6 correct, 2 incorrect)
for (let i = 0; i < 8; i++) {
const isCorrect = i < 6; // First 6 are correct
await userQuiz.recordAnswer(isCorrect, isCorrect ? 10 : 0);
}
await userQuiz.reload();
console.log('✅ Quiz auto-completed');
console.log(' Status:', userQuiz.status);
console.log(' Questions answered:', userQuiz.questionsAnswered);
console.log(' Correct answers:', userQuiz.correctAnswers);
console.log(' Score:', userQuiz.score + '%');
console.log(' Is passed:', userQuiz.isPassed);
console.log(' Match:', userQuiz.status === 'completed' && userQuiz.isPassed === true ? '✅' : '❌');
// Test 9: Get quiz results
console.log('\nTest 9: Get quiz results');
const results = userQuiz.getResults();
console.log('✅ Results retrieved');
console.log(' Total questions:', results.totalQuestions);
console.log(' Correct answers:', results.correctAnswers);
console.log(' Score:', results.score + '%');
console.log(' Is passed:', results.isPassed);
console.log(' Duration:', results.duration, 'seconds');
console.log(' Match:', results.correctAnswers === 8 && results.isPassed === true ? '✅' : '❌');
// Test 10: Calculate score
console.log('\nTest 10: Calculate score');
const calculatedScore = userQuiz.calculateScore();
console.log('✅ Score calculated');
console.log(' Calculated score:', calculatedScore + '%');
console.log(' Expected: 80%');
console.log(' Match:', calculatedScore === 80.00 ? '✅' : '❌');
// Test 11: Create timed quiz
console.log('\nTest 11: Create timed quiz with time limit');
const timedQuiz = await QuizSession.createSession({
userId: testUser.id,
categoryId: testCategory.id,
quizType: 'timed',
difficulty: 'hard',
totalQuestions: 20,
timeLimit: 600, // 10 minutes
passPercentage: 75.00
});
await timedQuiz.start();
console.log('✅ Timed quiz created');
console.log(' Quiz type:', timedQuiz.quizType);
console.log(' Time limit:', timedQuiz.timeLimit, 'seconds');
console.log(' Match:', timedQuiz.quizType === 'timed' && timedQuiz.timeLimit === 600 ? '✅' : '❌');
// Test 12: Timeout a quiz
console.log('\nTest 12: Timeout a quiz');
await timedQuiz.updateTimeSpent(610); // Exceed time limit
await timedQuiz.reload();
console.log('✅ Quiz timed out');
console.log(' Status:', timedQuiz.status);
console.log(' Time spent:', timedQuiz.timeSpent);
console.log(' Match:', timedQuiz.status === 'timed_out' ? '✅' : '❌');
// Test 13: Abandon a quiz
console.log('\nTest 13: Abandon a quiz');
const abandonQuiz = await QuizSession.createSession({
userId: testUser.id,
categoryId: testCategory.id,
quizType: 'practice',
difficulty: 'easy',
totalQuestions: 15
});
await abandonQuiz.start();
await abandonQuiz.recordAnswer(true, 10);
await abandonQuiz.abandon();
await abandonQuiz.reload();
console.log('✅ Quiz abandoned');
console.log(' Status:', abandonQuiz.status);
console.log(' Questions answered:', abandonQuiz.questionsAnswered);
console.log(' Completed at:', abandonQuiz.completedAt);
console.log(' Match:', abandonQuiz.status === 'abandoned' ? '✅' : '❌');
// Test 14: Find active session for user
console.log('\nTest 14: Find active session for user');
const activeQuiz = await QuizSession.createSession({
userId: testUser.id,
categoryId: testCategory.id,
quizType: 'practice',
difficulty: 'medium',
totalQuestions: 10
});
await activeQuiz.start();
const foundActive = await QuizSession.findActiveForUser(testUser.id);
console.log('✅ Active session found');
console.log(' Found ID:', foundActive.id);
console.log(' Created ID:', activeQuiz.id);
console.log(' Match:', foundActive.id === activeQuiz.id ? '✅' : '❌');
// Test 15: Find active session for guest
console.log('\nTest 15: Find active session for guest');
await guestQuiz.start();
const foundGuestActive = await QuizSession.findActiveForGuest(testGuestSession.id);
console.log('✅ Active guest session found');
console.log(' Found ID:', foundGuestActive.id);
console.log(' Created ID:', guestQuiz.id);
console.log(' Match:', foundGuestActive.id === guestQuiz.id ? '✅' : '❌');
// Test 16: Get user quiz history
console.log('\nTest 16: Get user quiz history');
await activeQuiz.complete();
const history = await QuizSession.getUserHistory(testUser.id, 5);
console.log('✅ User history retrieved');
console.log(' History count:', history.length);
console.log(' Expected at least 3: ✅');
// Test 17: Get user statistics
console.log('\nTest 17: Get user statistics');
const stats = await QuizSession.getUserStats(testUser.id);
console.log('✅ User stats calculated');
console.log(' Total quizzes:', stats.totalQuizzes);
console.log(' Average score:', stats.averageScore + '%');
console.log(' Pass rate:', stats.passRate + '%');
console.log(' Total time spent:', stats.totalTimeSpent, 'seconds');
console.log(' Match:', stats.totalQuizzes >= 1 ? '✅' : '❌');
// Test 18: Get category statistics
console.log('\nTest 18: Get category statistics');
const categoryStats = await QuizSession.getCategoryStats(testCategory.id);
console.log('✅ Category stats calculated');
console.log(' Total attempts:', categoryStats.totalAttempts);
console.log(' Average score:', categoryStats.averageScore + '%');
console.log(' Pass rate:', categoryStats.passRate + '%');
console.log(' Match:', categoryStats.totalAttempts >= 1 ? '✅' : '❌');
// Test 19: Check isActive method
console.log('\nTest 19: Check isActive method');
const newQuiz = await QuizSession.createSession({
userId: testUser.id,
categoryId: testCategory.id,
quizType: 'practice',
totalQuestions: 5
});
const isActiveBeforeStart = newQuiz.isActive();
await newQuiz.start();
const isActiveAfterStart = newQuiz.isActive();
await newQuiz.complete();
const isActiveAfterComplete = newQuiz.isActive();
console.log('✅ Active status checked');
console.log(' Before start:', isActiveBeforeStart);
console.log(' After start:', isActiveAfterStart);
console.log(' After complete:', isActiveAfterComplete);
console.log(' Match:', !isActiveBeforeStart && isActiveAfterStart && !isActiveAfterComplete ? '✅' : '❌');
// Test 20: Check isCompleted method
console.log('\nTest 20: Check isCompleted method');
const completionQuiz = await QuizSession.createSession({
userId: testUser.id,
categoryId: testCategory.id,
quizType: 'practice',
totalQuestions: 3
});
const isCompletedBefore = completionQuiz.isCompleted();
await completionQuiz.start();
await completionQuiz.complete();
const isCompletedAfter = completionQuiz.isCompleted();
console.log('✅ Completion status checked');
console.log(' Before completion:', isCompletedBefore);
console.log(' After completion:', isCompletedAfter);
console.log(' Match:', !isCompletedBefore && isCompletedAfter ? '✅' : '❌');
// Test 21: Test validation - require either userId or guestSessionId
console.log('\nTest 21: Test validation - require userId or guestSessionId');
try {
await QuizSession.createSession({
categoryId: testCategory.id,
quizType: 'practice',
totalQuestions: 10
});
console.log('❌ Should have thrown validation error');
} catch (error) {
console.log('✅ Validation error caught:', error.message);
console.log(' Match:', error.message.includes('userId or guestSessionId') ? '✅' : '❌');
}
// Test 22: Test validation - cannot have both userId and guestSessionId
console.log('\nTest 22: Test validation - cannot have both userId and guestSessionId');
try {
await QuizSession.create({
userId: testUser.id,
guestSessionId: testGuestSession.id,
categoryId: testCategory.id,
quizType: 'practice',
totalQuestions: 10
});
console.log('❌ Should have thrown validation error');
} catch (error) {
console.log('✅ Validation error caught:', error.message);
console.log(' Match:', error.message.includes('Cannot have both') ? '✅' : '❌');
}
// Test 23: Test associations - load with user
console.log('\nTest 23: Load quiz session with user association');
const quizWithUser = await QuizSession.findOne({
where: { id: userQuiz.id },
include: [{ model: User, as: 'user' }]
});
console.log('✅ Quiz loaded with user');
console.log(' User username:', quizWithUser.user.username);
console.log(' Match:', quizWithUser.user.id === testUser.id ? '✅' : '❌');
// Test 24: Test associations - load with category
console.log('\nTest 24: Load quiz session with category association');
const quizWithCategory = await QuizSession.findOne({
where: { id: userQuiz.id },
include: [{ model: Category, as: 'category' }]
});
console.log('✅ Quiz loaded with category');
console.log(' Category name:', quizWithCategory.category.name);
console.log(' Match:', quizWithCategory.category.id === testCategory.id ? '✅' : '❌');
// Test 25: Test associations - load with guest session
console.log('\nTest 25: Load quiz session with guest session association');
const quizWithGuest = await QuizSession.findOne({
where: { id: guestQuiz.id },
include: [{ model: GuestSession, as: 'guestSession' }]
});
console.log('✅ Quiz loaded with guest session');
console.log(' Guest ID:', quizWithGuest.guestSession.guestId);
console.log(' Match:', quizWithGuest.guestSession.id === testGuestSession.id ? '✅' : '❌');
// Test 26: Clean up abandoned sessions
console.log('\nTest 26: Clean up abandoned sessions');
const oldQuiz = await QuizSession.create({
userId: testUser.id,
categoryId: testCategory.id,
quizType: 'practice',
totalQuestions: 10,
status: 'abandoned',
createdAt: new Date('2020-01-01')
});
const deletedCount = await QuizSession.cleanupAbandoned(7);
console.log('✅ Cleanup executed');
console.log(' Deleted count:', deletedCount);
console.log(' Expected at least 1:', deletedCount >= 1 ? '✅' : '❌');
console.log('\n=====================================');
console.log('🧹 Cleaning up test data...');
// Clean up test data
await QuizSession.destroy({ where: {} });
await GuestSession.destroy({ where: {} });
await Category.destroy({ where: {} });
await User.destroy({ where: {} });
console.log('✅ Test data deleted');
console.log('\n✅ All QuizSession Model Tests Completed!');
} catch (error) {
console.error('\n❌ Test failed with error:', error.message);
console.error('Error details:', error);
process.exit(1);
} finally {
await sequelize.close();
}
}
runTests();