Files
Tasks/backend/tests/test-guest-quiz-limit.js
2025-12-25 00:24:11 +02:00

220 lines
8.9 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.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
const axios = require('axios');
const BASE_URL = 'http://localhost:3000/api';
// Store session data for testing
let testSession = {
guestId: null,
sessionToken: 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 Quiz Limit Tests (Task 16) ║');
console.log('╚════════════════════════════════════════════════════════════╝\n');
console.log('Make sure the server is running on http://localhost:3000\n');
try {
// Test 1: Create a guest session first
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) {
testSession.guestId = response.data.data.guestId;
testSession.sessionToken = response.data.data.sessionToken;
printTestResult(1, 'Guest session created', true,
`Guest ID: ${testSession.guestId}\nToken: ${testSession.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; // Can't continue without session
}
// Test 2: Check quiz limit with valid token (should have 3 remaining)
printSection('Test 2: Check quiz limit with valid token');
try {
const response = await axios.get(`${BASE_URL}/guest/quiz-limit`, {
headers: {
'X-Guest-Token': testSession.sessionToken
}
});
if (response.status === 200 && response.data.success) {
const { quizLimit, session } = response.data.data;
printTestResult(2, 'Quiz limit check with valid token', true,
`Max Quizzes: ${quizLimit.maxQuizzes}\n` +
`Quizzes Attempted: ${quizLimit.quizzesAttempted}\n` +
`Quizzes Remaining: ${quizLimit.quizzesRemaining}\n` +
`Has Reached Limit: ${quizLimit.hasReachedLimit}\n` +
`Time Remaining: ${session.timeRemaining}`);
} else {
throw new Error('Unexpected response');
}
} catch (error) {
printTestResult(2, 'Quiz limit check with valid token', false,
`Error: ${error.response?.data?.message || error.message}`);
}
// Test 3: Check quiz limit without token (should fail)
printSection('Test 3: Check quiz limit without token (should fail with 401)');
try {
const response = await axios.get(`${BASE_URL}/guest/quiz-limit`);
printTestResult(3, 'No token provided', false,
'Should have returned 401 but got: ' + response.status);
} catch (error) {
if (error.response?.status === 401) {
printTestResult(3, 'No token provided', true,
`Correctly returned 401: ${error.response.data.message}`);
} else {
printTestResult(3, 'No token provided', false,
`Wrong status code: ${error.response?.status || 'unknown'}`);
}
}
// Test 4: Check quiz limit with invalid token (should fail)
printSection('Test 4: Check quiz limit with invalid token (should fail with 401)');
try {
const response = await axios.get(`${BASE_URL}/guest/quiz-limit`, {
headers: {
'X-Guest-Token': 'invalid.token.here'
}
});
printTestResult(4, 'Invalid token provided', false,
'Should have returned 401 but got: ' + response.status);
} catch (error) {
if (error.response?.status === 401) {
printTestResult(4, 'Invalid token provided', true,
`Correctly returned 401: ${error.response.data.message}`);
} else {
printTestResult(4, 'Invalid token provided', false,
`Wrong status code: ${error.response?.status || 'unknown'}`);
}
}
// Test 5: Simulate reaching quiz limit
printSection('Test 5: Simulate quiz limit reached (update database manually)');
console.log('\n To test limit reached scenario:');
console.log(' Run this SQL query:');
console.log(` UPDATE guest_sessions SET quizzes_attempted = 3 WHERE guest_id = '${testSession.guestId}';`);
console.log('\n Then check quiz limit again with this curl command:');
console.log(` curl -H "X-Guest-Token: ${testSession.sessionToken}" ${BASE_URL}/guest/quiz-limit`);
console.log('\n Expected: hasReachedLimit: true, upgradePrompt with benefits');
// Test 6: Check with non-existent guest ID token
printSection('Test 6: Check with token for non-existent guest (should fail with 404)');
try {
// Create a token with fake guest ID
const jwt = require('jsonwebtoken');
const config = require('../config/config');
const fakeToken = jwt.sign(
{ guestId: 'guest_fake_12345' },
config.jwt.secret,
{ expiresIn: '24h' }
);
const response = await axios.get(`${BASE_URL}/guest/quiz-limit`, {
headers: {
'X-Guest-Token': fakeToken
}
});
printTestResult(6, 'Non-existent guest ID', false,
'Should have returned 404 but got: ' + response.status);
} catch (error) {
if (error.response?.status === 404) {
printTestResult(6, 'Non-existent guest ID', true,
`Correctly returned 404: ${error.response.data.message}`);
} else {
printTestResult(6, 'Non-existent guest ID', false,
`Wrong status code: ${error.response?.status || 'unknown'}`);
}
}
// Test 7: Verify response structure
printSection('Test 7: Verify response structure and data types');
try {
const response = await axios.get(`${BASE_URL}/guest/quiz-limit`, {
headers: {
'X-Guest-Token': testSession.sessionToken
}
});
const { data } = response.data;
const hasCorrectStructure =
data.guestId &&
data.quizLimit &&
typeof data.quizLimit.maxQuizzes === 'number' &&
typeof data.quizLimit.quizzesAttempted === 'number' &&
typeof data.quizLimit.quizzesRemaining === 'number' &&
typeof data.quizLimit.hasReachedLimit === 'boolean' &&
data.session &&
data.session.expiresAt &&
data.session.timeRemaining;
if (hasCorrectStructure) {
printTestResult(7, 'Response structure verification', true,
'All required fields present with correct types');
} else {
printTestResult(7, 'Response structure verification', false,
'Missing or incorrect fields in response');
}
} catch (error) {
printTestResult(7, 'Response structure verification', false,
`Error: ${error.message}`);
}
// Test 8: Verify calculations
printSection('Test 8: Verify quiz remaining calculation');
try {
const response = await axios.get(`${BASE_URL}/guest/quiz-limit`, {
headers: {
'X-Guest-Token': testSession.sessionToken
}
});
const { quizLimit } = response.data.data;
const expectedRemaining = quizLimit.maxQuizzes - quizLimit.quizzesAttempted;
if (quizLimit.quizzesRemaining === expectedRemaining) {
printTestResult(8, 'Quiz remaining calculation', true,
`Calculation correct: ${quizLimit.maxQuizzes} - ${quizLimit.quizzesAttempted} = ${quizLimit.quizzesRemaining}`);
} else {
printTestResult(8, 'Quiz remaining calculation', false,
`Expected ${expectedRemaining} but got ${quizLimit.quizzesRemaining}`);
}
} catch (error) {
printTestResult(8, 'Quiz remaining calculation', false,
`Error: ${error.message}`);
}
} catch (error) {
console.error('\n❌ Fatal error during testing:', error.message);
}
console.log('\n╔════════════════════════════════════════════════════════════╗');
console.log('║ Tests Completed ║');
console.log('╚════════════════════════════════════════════════════════════╝\n');
}
// Run tests
runTests();