Files
Tasks/backend/test-guest-conversion.js
2025-11-11 00:25:50 +02:00

310 lines
12 KiB
JavaScript

const axios = require('axios');
const BASE_URL = 'http://localhost:3000/api';
// Store test data
let testData = {
guestId: null,
sessionToken: null,
userId: null,
userToken: null
};
// Helper function to print test results
function printTestResult(testNumber, testName, success, details = '') {
const emoji = success ? '✅' : '❌';
console.log(`\n${emoji} Test ${testNumber}: ${testName}`);
if (details) console.log(details);
}
// Helper function to print section header
function printSection(title) {
console.log('\n' + '='.repeat(60));
console.log(title);
console.log('='.repeat(60));
}
async function runTests() {
console.log('\n╔════════════════════════════════════════════════════════════╗');
console.log('║ Guest to User Conversion Tests (Task 17) ║');
console.log('╚════════════════════════════════════════════════════════════╝\n');
console.log('Make sure the server is running on http://localhost:3000\n');
try {
// Test 1: Create a guest session
printSection('Test 1: Create guest session for testing');
try {
const response = await axios.post(`${BASE_URL}/guest/start-session`, {
deviceId: `test_device_${Date.now()}`
});
if (response.status === 201 && response.data.success) {
testData.guestId = response.data.data.guestId;
testData.sessionToken = response.data.data.sessionToken;
printTestResult(1, 'Guest session created', true,
`Guest ID: ${testData.guestId}\nToken: ${testData.sessionToken.substring(0, 50)}...`);
} else {
throw new Error('Failed to create session');
}
} catch (error) {
printTestResult(1, 'Guest session creation', false,
`Error: ${error.response?.data?.message || error.message}`);
return;
}
// Test 2: Try conversion without required fields
printSection('Test 2: Conversion without required fields (should fail)');
try {
const response = await axios.post(`${BASE_URL}/guest/convert`, {
username: 'testuser'
// Missing email and password
}, {
headers: {
'X-Guest-Token': testData.sessionToken
}
});
printTestResult(2, 'Missing required fields', false,
'Should have returned 400 but got: ' + response.status);
} catch (error) {
if (error.response?.status === 400) {
printTestResult(2, 'Missing required fields', true,
`Correctly returned 400: ${error.response.data.message}`);
} else {
printTestResult(2, 'Missing required fields', false,
`Wrong status code: ${error.response?.status || 'unknown'}`);
}
}
// Test 3: Try conversion with invalid email
printSection('Test 3: Conversion with invalid email (should fail)');
try {
const response = await axios.post(`${BASE_URL}/guest/convert`, {
username: 'testuser',
email: 'invalid-email',
password: 'Password123'
}, {
headers: {
'X-Guest-Token': testData.sessionToken
}
});
printTestResult(3, 'Invalid email format', false,
'Should have returned 400 but got: ' + response.status);
} catch (error) {
if (error.response?.status === 400) {
printTestResult(3, 'Invalid email format', true,
`Correctly returned 400: ${error.response.data.message}`);
} else {
printTestResult(3, 'Invalid email format', false,
`Wrong status code: ${error.response?.status || 'unknown'}`);
}
}
// Test 4: Try conversion with weak password
printSection('Test 4: Conversion with weak password (should fail)');
try {
const response = await axios.post(`${BASE_URL}/guest/convert`, {
username: 'testuser',
email: 'test@example.com',
password: 'weak'
}, {
headers: {
'X-Guest-Token': testData.sessionToken
}
});
printTestResult(4, 'Weak password', false,
'Should have returned 400 but got: ' + response.status);
} catch (error) {
if (error.response?.status === 400) {
printTestResult(4, 'Weak password', true,
`Correctly returned 400: ${error.response.data.message}`);
} else {
printTestResult(4, 'Weak password', false,
`Wrong status code: ${error.response?.status || 'unknown'}`);
}
}
// Test 5: Successful conversion
printSection('Test 5: Successful guest to user conversion');
const timestamp = Date.now();
const conversionData = {
username: `converted${timestamp}`,
email: `converted${timestamp}@test.com`,
password: 'Password123'
};
try {
const response = await axios.post(`${BASE_URL}/guest/convert`, conversionData, {
headers: {
'X-Guest-Token': testData.sessionToken
}
});
if (response.status === 201 && response.data.success) {
testData.userId = response.data.data.user.id;
testData.userToken = response.data.data.token;
printTestResult(5, 'Guest to user conversion', true,
`User ID: ${testData.userId}\n` +
`Username: ${response.data.data.user.username}\n` +
`Email: ${response.data.data.user.email}\n` +
`Quizzes Transferred: ${response.data.data.migration.quizzesTransferred}\n` +
`Token: ${testData.userToken.substring(0, 50)}...`);
console.log('\nMigration Stats:');
const stats = response.data.data.migration.stats;
console.log(` Total Quizzes: ${stats.totalQuizzes}`);
console.log(` Quizzes Passed: ${stats.quizzesPassed}`);
console.log(` Questions Answered: ${stats.totalQuestionsAnswered}`);
console.log(` Correct Answers: ${stats.correctAnswers}`);
console.log(` Accuracy: ${stats.accuracy}%`);
} else {
throw new Error('Unexpected response');
}
} catch (error) {
printTestResult(5, 'Guest to user conversion', false,
`Error: ${error.response?.data?.message || error.message}`);
return;
}
// Test 6: Try to convert the same guest session again (should fail)
printSection('Test 6: Try to convert already converted session (should fail)');
try {
const response = await axios.post(`${BASE_URL}/guest/convert`, {
username: `another${timestamp}`,
email: `another${timestamp}@test.com`,
password: 'Password123'
}, {
headers: {
'X-Guest-Token': testData.sessionToken
}
});
printTestResult(6, 'Already converted session', false,
'Should have returned 410 but got: ' + response.status);
} catch (error) {
if (error.response?.status === 410) {
printTestResult(6, 'Already converted session', true,
`Correctly returned 410: ${error.response.data.message}`);
} else {
printTestResult(6, 'Already converted session', false,
`Wrong status code: ${error.response?.status || 'unknown'}\nMessage: ${error.response?.data?.message}`);
}
}
// Test 7: Try conversion with duplicate email
printSection('Test 7: Create new guest and try conversion with duplicate email');
try {
// Create new guest session
const guestResponse = await axios.post(`${BASE_URL}/guest/start-session`, {
deviceId: `test_device_2_${Date.now()}`
});
const newGuestToken = guestResponse.data.data.sessionToken;
// Try to convert with existing email
const response = await axios.post(`${BASE_URL}/guest/convert`, {
username: `unique${Date.now()}`,
email: conversionData.email, // Use email from Test 5
password: 'Password123'
}, {
headers: {
'X-Guest-Token': newGuestToken
}
});
printTestResult(7, 'Duplicate email rejection', false,
'Should have returned 400 but got: ' + response.status);
} catch (error) {
if (error.response?.status === 400 && error.response.data.message.includes('Email already registered')) {
printTestResult(7, 'Duplicate email rejection', true,
`Correctly returned 400: ${error.response.data.message}`);
} else {
printTestResult(7, 'Duplicate email rejection', false,
`Wrong status code or message: ${error.response?.status || 'unknown'}`);
}
}
// Test 8: Try conversion with duplicate username
printSection('Test 8: Try conversion with duplicate username');
try {
// Create new guest session
const guestResponse = await axios.post(`${BASE_URL}/guest/start-session`, {
deviceId: `test_device_3_${Date.now()}`
});
const newGuestToken = guestResponse.data.data.sessionToken;
// Try to convert with existing username
const response = await axios.post(`${BASE_URL}/guest/convert`, {
username: conversionData.username, // Use username from Test 5
email: `unique${Date.now()}@test.com`,
password: 'Password123'
}, {
headers: {
'X-Guest-Token': newGuestToken
}
});
printTestResult(8, 'Duplicate username rejection', false,
'Should have returned 400 but got: ' + response.status);
} catch (error) {
if (error.response?.status === 400 && error.response.data.message.includes('Username already taken')) {
printTestResult(8, 'Duplicate username rejection', true,
`Correctly returned 400: ${error.response.data.message}`);
} else {
printTestResult(8, 'Duplicate username rejection', false,
`Wrong status code or message: ${error.response?.status || 'unknown'}`);
}
}
// Test 9: Verify user can login with new credentials
printSection('Test 9: Verify converted user can login');
try {
const response = await axios.post(`${BASE_URL}/auth/login`, {
email: conversionData.email,
password: conversionData.password
});
if (response.status === 200 && response.data.success) {
printTestResult(9, 'Login with converted credentials', true,
`Successfully logged in as: ${response.data.data.user.username}\n` +
`User ID matches: ${response.data.data.user.id === testData.userId}`);
} else {
throw new Error('Login failed');
}
} catch (error) {
printTestResult(9, 'Login with converted credentials', false,
`Error: ${error.response?.data?.message || error.message}`);
}
// Test 10: Verify conversion without token (should fail)
printSection('Test 10: Try conversion without guest token (should fail)');
try {
const response = await axios.post(`${BASE_URL}/guest/convert`, {
username: `notoken${Date.now()}`,
email: `notoken${Date.now()}@test.com`,
password: 'Password123'
});
printTestResult(10, 'No guest token provided', false,
'Should have returned 401 but got: ' + response.status);
} catch (error) {
if (error.response?.status === 401) {
printTestResult(10, 'No guest token provided', true,
`Correctly returned 401: ${error.response.data.message}`);
} else {
printTestResult(10, 'No guest token provided', false,
`Wrong status code: ${error.response?.status || 'unknown'}`);
}
}
} catch (error) {
console.error('\n❌ Fatal error during testing:', error.message);
}
console.log('\n╔════════════════════════════════════════════════════════════╗');
console.log('║ Tests Completed ║');
console.log('╚════════════════════════════════════════════════════════════╝\n');
}
// Run tests
runTests();