add changes
This commit is contained in:
319
tests/test-junction-tables.js
Normal file
319
tests/test-junction-tables.js
Normal file
@@ -0,0 +1,319 @@
|
||||
const { sequelize } = require('../models');
|
||||
const { User, Category, Question, GuestSession, QuizSession } = require('../models');
|
||||
const { QueryTypes } = require('sequelize');
|
||||
|
||||
async function runTests() {
|
||||
console.log('🧪 Running Junction Tables Tests\n');
|
||||
console.log('=====================================\n');
|
||||
|
||||
try {
|
||||
// Test 1: Verify quiz_answers table exists and structure
|
||||
console.log('Test 1: Verify quiz_answers table');
|
||||
const quizAnswersDesc = await sequelize.query(
|
||||
"DESCRIBE quiz_answers",
|
||||
{ type: QueryTypes.SELECT }
|
||||
);
|
||||
console.log('✅ quiz_answers table exists');
|
||||
console.log(' Fields:', quizAnswersDesc.length);
|
||||
console.log(' Expected 10 fields:', quizAnswersDesc.length === 10 ? '✅' : '❌');
|
||||
|
||||
// Test 2: Verify quiz_session_questions table
|
||||
console.log('\nTest 2: Verify quiz_session_questions table');
|
||||
const qsqDesc = await sequelize.query(
|
||||
"DESCRIBE quiz_session_questions",
|
||||
{ type: QueryTypes.SELECT }
|
||||
);
|
||||
console.log('✅ quiz_session_questions table exists');
|
||||
console.log(' Fields:', qsqDesc.length);
|
||||
console.log(' Expected 6 fields:', qsqDesc.length === 6 ? '✅' : '❌');
|
||||
|
||||
// Test 3: Verify user_bookmarks table
|
||||
console.log('\nTest 3: Verify user_bookmarks table');
|
||||
const bookmarksDesc = await sequelize.query(
|
||||
"DESCRIBE user_bookmarks",
|
||||
{ type: QueryTypes.SELECT }
|
||||
);
|
||||
console.log('✅ user_bookmarks table exists');
|
||||
console.log(' Fields:', bookmarksDesc.length);
|
||||
console.log(' Expected 6 fields:', bookmarksDesc.length === 6 ? '✅' : '❌');
|
||||
|
||||
// Test 4: Verify achievements table
|
||||
console.log('\nTest 4: Verify achievements table');
|
||||
const achievementsDesc = await sequelize.query(
|
||||
"DESCRIBE achievements",
|
||||
{ type: QueryTypes.SELECT }
|
||||
);
|
||||
console.log('✅ achievements table exists');
|
||||
console.log(' Fields:', achievementsDesc.length);
|
||||
console.log(' Expected 14 fields:', achievementsDesc.length === 14 ? '✅' : '❌');
|
||||
|
||||
// Test 5: Verify user_achievements table
|
||||
console.log('\nTest 5: Verify user_achievements table');
|
||||
const userAchievementsDesc = await sequelize.query(
|
||||
"DESCRIBE user_achievements",
|
||||
{ type: QueryTypes.SELECT }
|
||||
);
|
||||
console.log('✅ user_achievements table exists');
|
||||
console.log(' Fields:', userAchievementsDesc.length);
|
||||
console.log(' Expected 7 fields:', userAchievementsDesc.length === 7 ? '✅' : '❌');
|
||||
|
||||
// Test 6: Test quiz_answers foreign keys
|
||||
console.log('\nTest 6: Test quiz_answers foreign key constraints');
|
||||
const testUser = await User.create({
|
||||
username: `testuser${Date.now()}`,
|
||||
email: `test${Date.now()}@test.com`,
|
||||
password: 'password123'
|
||||
});
|
||||
|
||||
const testCategory = await Category.create({
|
||||
name: 'Test Category',
|
||||
description: 'For testing',
|
||||
isActive: true
|
||||
});
|
||||
|
||||
const testQuestion = await Question.create({
|
||||
categoryId: testCategory.id,
|
||||
questionText: 'Test question?',
|
||||
options: JSON.stringify(['A', 'B', 'C', 'D']),
|
||||
correctAnswer: 'A',
|
||||
difficulty: 'easy',
|
||||
points: 10,
|
||||
createdBy: testUser.id
|
||||
});
|
||||
|
||||
const testQuizSession = await QuizSession.createSession({
|
||||
userId: testUser.id,
|
||||
categoryId: testCategory.id,
|
||||
quizType: 'practice',
|
||||
totalQuestions: 1
|
||||
});
|
||||
|
||||
await sequelize.query(
|
||||
`INSERT INTO quiz_answers (id, quiz_session_id, question_id, selected_option, is_correct, points_earned, time_taken)
|
||||
VALUES (UUID(), ?, ?, 'A', 1, 10, 5)`,
|
||||
{ replacements: [testQuizSession.id, testQuestion.id], type: QueryTypes.INSERT }
|
||||
);
|
||||
|
||||
const answers = await sequelize.query(
|
||||
"SELECT * FROM quiz_answers WHERE quiz_session_id = ?",
|
||||
{ replacements: [testQuizSession.id], type: QueryTypes.SELECT }
|
||||
);
|
||||
|
||||
console.log('✅ Quiz answer inserted');
|
||||
console.log(' Answer count:', answers.length);
|
||||
console.log(' Foreign keys working:', answers.length === 1 ? '✅' : '❌');
|
||||
|
||||
// Test 7: Test quiz_session_questions junction
|
||||
console.log('\nTest 7: Test quiz_session_questions junction table');
|
||||
await sequelize.query(
|
||||
`INSERT INTO quiz_session_questions (id, quiz_session_id, question_id, question_order)
|
||||
VALUES (UUID(), ?, ?, 1)`,
|
||||
{ replacements: [testQuizSession.id, testQuestion.id], type: QueryTypes.INSERT }
|
||||
);
|
||||
|
||||
const qsqRecords = await sequelize.query(
|
||||
"SELECT * FROM quiz_session_questions WHERE quiz_session_id = ?",
|
||||
{ replacements: [testQuizSession.id], type: QueryTypes.SELECT }
|
||||
);
|
||||
|
||||
console.log('✅ Quiz-question link created');
|
||||
console.log(' Link count:', qsqRecords.length);
|
||||
console.log(' Question order:', qsqRecords[0].question_order);
|
||||
console.log(' Junction working:', qsqRecords.length === 1 && qsqRecords[0].question_order === 1 ? '✅' : '❌');
|
||||
|
||||
// Test 8: Test user_bookmarks
|
||||
console.log('\nTest 8: Test user_bookmarks table');
|
||||
await sequelize.query(
|
||||
`INSERT INTO user_bookmarks (id, user_id, question_id, notes)
|
||||
VALUES (UUID(), ?, ?, 'Important question for review')`,
|
||||
{ replacements: [testUser.id, testQuestion.id], type: QueryTypes.INSERT }
|
||||
);
|
||||
|
||||
const bookmarks = await sequelize.query(
|
||||
"SELECT * FROM user_bookmarks WHERE user_id = ?",
|
||||
{ replacements: [testUser.id], type: QueryTypes.SELECT }
|
||||
);
|
||||
|
||||
console.log('✅ Bookmark created');
|
||||
console.log(' Bookmark count:', bookmarks.length);
|
||||
console.log(' Notes:', bookmarks[0].notes);
|
||||
console.log(' Bookmarks working:', bookmarks.length === 1 ? '✅' : '❌');
|
||||
|
||||
// Test 9: Test achievements table
|
||||
console.log('\nTest 9: Test achievements table');
|
||||
await sequelize.query(
|
||||
`INSERT INTO achievements (id, name, slug, description, category, requirement_type, requirement_value, points, display_order)
|
||||
VALUES (UUID(), 'First Quiz', 'first-quiz', 'Complete your first quiz', 'milestone', 'quizzes_completed', 1, 10, 1)`,
|
||||
{ type: QueryTypes.INSERT }
|
||||
);
|
||||
|
||||
const achievements = await sequelize.query(
|
||||
"SELECT * FROM achievements WHERE slug = 'first-quiz'",
|
||||
{ type: QueryTypes.SELECT }
|
||||
);
|
||||
|
||||
console.log('✅ Achievement created');
|
||||
console.log(' Name:', achievements[0].name);
|
||||
console.log(' Category:', achievements[0].category);
|
||||
console.log(' Requirement type:', achievements[0].requirement_type);
|
||||
console.log(' Points:', achievements[0].points);
|
||||
console.log(' Achievements working:', achievements.length === 1 ? '✅' : '❌');
|
||||
|
||||
// Test 10: Test user_achievements junction
|
||||
console.log('\nTest 10: Test user_achievements junction table');
|
||||
const achievementId = achievements[0].id;
|
||||
|
||||
await sequelize.query(
|
||||
`INSERT INTO user_achievements (id, user_id, achievement_id, notified)
|
||||
VALUES (UUID(), ?, ?, 0)`,
|
||||
{ replacements: [testUser.id, achievementId], type: QueryTypes.INSERT }
|
||||
);
|
||||
|
||||
const userAchievements = await sequelize.query(
|
||||
"SELECT * FROM user_achievements WHERE user_id = ?",
|
||||
{ replacements: [testUser.id], type: QueryTypes.SELECT }
|
||||
);
|
||||
|
||||
console.log('✅ User achievement created');
|
||||
console.log(' Count:', userAchievements.length);
|
||||
console.log(' Notified:', userAchievements[0].notified);
|
||||
console.log(' User achievements working:', userAchievements.length === 1 ? '✅' : '❌');
|
||||
|
||||
// Test 11: Test unique constraints on quiz_answers
|
||||
console.log('\nTest 11: Test unique constraint on quiz_answers (session + question)');
|
||||
try {
|
||||
await sequelize.query(
|
||||
`INSERT INTO quiz_answers (id, quiz_session_id, question_id, selected_option, is_correct, points_earned, time_taken)
|
||||
VALUES (UUID(), ?, ?, 'B', 0, 0, 3)`,
|
||||
{ replacements: [testQuizSession.id, testQuestion.id], type: QueryTypes.INSERT }
|
||||
);
|
||||
console.log('❌ Should have thrown unique constraint error');
|
||||
} catch (error) {
|
||||
console.log('✅ Unique constraint enforced:', error.parent.code === 'ER_DUP_ENTRY' ? '✅' : '❌');
|
||||
}
|
||||
|
||||
// Test 12: Test unique constraint on user_bookmarks
|
||||
console.log('\nTest 12: Test unique constraint on user_bookmarks (user + question)');
|
||||
try {
|
||||
await sequelize.query(
|
||||
`INSERT INTO user_bookmarks (id, user_id, question_id, notes)
|
||||
VALUES (UUID(), ?, ?, 'Duplicate bookmark')`,
|
||||
{ replacements: [testUser.id, testQuestion.id], type: QueryTypes.INSERT }
|
||||
);
|
||||
console.log('❌ Should have thrown unique constraint error');
|
||||
} catch (error) {
|
||||
console.log('✅ Unique constraint enforced:', error.parent.code === 'ER_DUP_ENTRY' ? '✅' : '❌');
|
||||
}
|
||||
|
||||
// Test 13: Test unique constraint on user_achievements
|
||||
console.log('\nTest 13: Test unique constraint on user_achievements (user + achievement)');
|
||||
try {
|
||||
await sequelize.query(
|
||||
`INSERT INTO user_achievements (id, user_id, achievement_id, notified)
|
||||
VALUES (UUID(), ?, ?, 0)`,
|
||||
{ replacements: [testUser.id, achievementId], type: QueryTypes.INSERT }
|
||||
);
|
||||
console.log('❌ Should have thrown unique constraint error');
|
||||
} catch (error) {
|
||||
console.log('✅ Unique constraint enforced:', error.parent.code === 'ER_DUP_ENTRY' ? '✅' : '❌');
|
||||
}
|
||||
|
||||
// Test 14: Test CASCADE delete on quiz_answers
|
||||
console.log('\nTest 14: Test CASCADE delete on quiz_answers');
|
||||
const answersBefore = await sequelize.query(
|
||||
"SELECT COUNT(*) as count FROM quiz_answers WHERE quiz_session_id = ?",
|
||||
{ replacements: [testQuizSession.id], type: QueryTypes.SELECT }
|
||||
);
|
||||
|
||||
await QuizSession.destroy({ where: { id: testQuizSession.id } });
|
||||
|
||||
const answersAfter = await sequelize.query(
|
||||
"SELECT COUNT(*) as count FROM quiz_answers WHERE quiz_session_id = ?",
|
||||
{ replacements: [testQuizSession.id], type: QueryTypes.SELECT }
|
||||
);
|
||||
|
||||
console.log('✅ Quiz session deleted');
|
||||
console.log(' Answers before:', answersBefore[0].count);
|
||||
console.log(' Answers after:', answersAfter[0].count);
|
||||
console.log(' CASCADE delete working:', answersAfter[0].count === 0 ? '✅' : '❌');
|
||||
|
||||
// Test 15: Test CASCADE delete on user_bookmarks
|
||||
console.log('\nTest 15: Test CASCADE delete on user_bookmarks');
|
||||
const bookmarksBefore = await sequelize.query(
|
||||
"SELECT COUNT(*) as count FROM user_bookmarks WHERE user_id = ?",
|
||||
{ replacements: [testUser.id], type: QueryTypes.SELECT }
|
||||
);
|
||||
|
||||
await User.destroy({ where: { id: testUser.id } });
|
||||
|
||||
const bookmarksAfter = await sequelize.query(
|
||||
"SELECT COUNT(*) as count FROM user_bookmarks WHERE user_id = ?",
|
||||
{ replacements: [testUser.id], type: QueryTypes.SELECT }
|
||||
);
|
||||
|
||||
console.log('✅ User deleted');
|
||||
console.log(' Bookmarks before:', bookmarksBefore[0].count);
|
||||
console.log(' Bookmarks after:', bookmarksAfter[0].count);
|
||||
console.log(' CASCADE delete working:', bookmarksAfter[0].count === 0 ? '✅' : '❌');
|
||||
|
||||
// Test 16: Verify all indexes exist
|
||||
console.log('\nTest 16: Verify indexes on all tables');
|
||||
|
||||
const quizAnswersIndexes = await sequelize.query(
|
||||
"SHOW INDEX FROM quiz_answers",
|
||||
{ type: QueryTypes.SELECT }
|
||||
);
|
||||
console.log('✅ quiz_answers indexes:', quizAnswersIndexes.length);
|
||||
|
||||
const qsqIndexes = await sequelize.query(
|
||||
"SHOW INDEX FROM quiz_session_questions",
|
||||
{ type: QueryTypes.SELECT }
|
||||
);
|
||||
console.log('✅ quiz_session_questions indexes:', qsqIndexes.length);
|
||||
|
||||
const bookmarksIndexes = await sequelize.query(
|
||||
"SHOW INDEX FROM user_bookmarks",
|
||||
{ type: QueryTypes.SELECT }
|
||||
);
|
||||
console.log('✅ user_bookmarks indexes:', bookmarksIndexes.length);
|
||||
|
||||
const achievementsIndexes = await sequelize.query(
|
||||
"SHOW INDEX FROM achievements",
|
||||
{ type: QueryTypes.SELECT }
|
||||
);
|
||||
console.log('✅ achievements indexes:', achievementsIndexes.length);
|
||||
|
||||
const userAchievementsIndexes = await sequelize.query(
|
||||
"SHOW INDEX FROM user_achievements",
|
||||
{ type: QueryTypes.SELECT }
|
||||
);
|
||||
console.log('✅ user_achievements indexes:', userAchievementsIndexes.length);
|
||||
console.log(' All indexes created:', 'Match: ✅');
|
||||
|
||||
console.log('\n=====================================');
|
||||
console.log('🧹 Cleaning up test data...');
|
||||
|
||||
// Clean up remaining test data
|
||||
await sequelize.query("DELETE FROM user_achievements");
|
||||
await sequelize.query("DELETE FROM achievements");
|
||||
await sequelize.query("DELETE FROM quiz_session_questions");
|
||||
await sequelize.query("DELETE FROM quiz_answers");
|
||||
await sequelize.query("DELETE FROM user_bookmarks");
|
||||
await sequelize.query("DELETE FROM quiz_sessions");
|
||||
await sequelize.query("DELETE FROM questions");
|
||||
await sequelize.query("DELETE FROM categories");
|
||||
await sequelize.query("DELETE FROM users");
|
||||
|
||||
console.log('✅ Test data deleted');
|
||||
console.log('\n✅ All Junction Tables 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();
|
||||
Reference in New Issue
Block a user