WIP
This commit is contained in:
414
tests/test-resend-verification.js
Normal file
414
tests/test-resend-verification.js
Normal file
@ -0,0 +1,414 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* Test script to verify resend verification email functionality
|
||||
* This script tests the complete flow of resending verification emails
|
||||
*/
|
||||
|
||||
const readline = require('readline');
|
||||
|
||||
const API_BASE_URL = 'http://localhost:3001/api';
|
||||
|
||||
// Colors for console output
|
||||
const colors = {
|
||||
green: '\x1b[32m',
|
||||
red: '\x1b[31m',
|
||||
yellow: '\x1b[33m',
|
||||
blue: '\x1b[34m',
|
||||
reset: '\x1b[0m',
|
||||
bold: '\x1b[1m'
|
||||
};
|
||||
|
||||
function log(message, color = colors.reset) {
|
||||
console.log(`${color}${message}${colors.reset}`);
|
||||
}
|
||||
|
||||
function success(message) {
|
||||
log(`✅ ${message}`, colors.green);
|
||||
}
|
||||
|
||||
function error(message) {
|
||||
log(`❌ ${message}`, colors.red);
|
||||
}
|
||||
|
||||
function warning(message) {
|
||||
log(`⚠️ ${message}`, colors.yellow);
|
||||
}
|
||||
|
||||
function info(message) {
|
||||
log(`ℹ️ ${message}`, colors.blue);
|
||||
}
|
||||
|
||||
class ResendVerificationTester {
|
||||
constructor() {
|
||||
this.testEmail = `test-resend-${Date.now()}@example.com`;
|
||||
this.testPassword = 'TestPassword123!';
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the server is running
|
||||
*/
|
||||
async checkServerHealth() {
|
||||
try {
|
||||
const response = await fetch(`${API_BASE_URL.replace('/api', '')}/health`);
|
||||
if (response.ok) {
|
||||
const data = await response.json();
|
||||
success('Server is running and healthy');
|
||||
return true;
|
||||
} else {
|
||||
error('Server health check failed');
|
||||
return false;
|
||||
}
|
||||
} catch (err) {
|
||||
error(`Server is not running: ${err.message}`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a test user
|
||||
*/
|
||||
async registerTestUser() {
|
||||
try {
|
||||
info(`Registering test user: ${this.testEmail}`);
|
||||
|
||||
const response = await fetch(`${API_BASE_URL}/auth/register`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
email: this.testEmail,
|
||||
password: this.testPassword
|
||||
})
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (response.ok) {
|
||||
success('Test user registered successfully');
|
||||
info(`User ID: ${data.user?.id}`);
|
||||
return { success: true, user: data.user };
|
||||
} else {
|
||||
error(`Registration failed: ${data.error}`);
|
||||
return { success: false, error: data.error };
|
||||
}
|
||||
} catch (err) {
|
||||
error(`Registration error: ${err.message}`);
|
||||
return { success: false, error: err.message };
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test resend verification email with valid email
|
||||
*/
|
||||
async testResendVerificationValid() {
|
||||
try {
|
||||
info('Testing resend verification with valid unverified email...');
|
||||
|
||||
const response = await fetch(`${API_BASE_URL}/auth/resend-verification`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
email: this.testEmail
|
||||
})
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (response.ok) {
|
||||
success('Resend verification request successful');
|
||||
info(`Message: ${data.message}`);
|
||||
return { success: true, message: data.message };
|
||||
} else {
|
||||
error(`Resend verification failed: ${data.error}`);
|
||||
return { success: false, error: data.error };
|
||||
}
|
||||
} catch (err) {
|
||||
error(`Resend verification error: ${err.message}`);
|
||||
return { success: false, error: err.message };
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test resend verification email with non-existent email
|
||||
*/
|
||||
async testResendVerificationNonExistent() {
|
||||
try {
|
||||
info('Testing resend verification with non-existent email...');
|
||||
|
||||
const nonExistentEmail = `nonexistent-${Date.now()}@example.com`;
|
||||
|
||||
const response = await fetch(`${API_BASE_URL}/auth/resend-verification`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
email: nonExistentEmail
|
||||
})
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (response.ok) {
|
||||
success('Resend verification with non-existent email handled correctly');
|
||||
info(`Message: ${data.message}`);
|
||||
return { success: true, message: data.message };
|
||||
} else {
|
||||
warning(`Unexpected response for non-existent email: ${data.error}`);
|
||||
return { success: false, error: data.error };
|
||||
}
|
||||
} catch (err) {
|
||||
error(`Resend verification error: ${err.message}`);
|
||||
return { success: false, error: err.message };
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test resend verification email with missing email
|
||||
*/
|
||||
async testResendVerificationMissingEmail() {
|
||||
try {
|
||||
info('Testing resend verification with missing email...');
|
||||
|
||||
const response = await fetch(`${API_BASE_URL}/auth/resend-verification`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({})
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (response.status === 400) {
|
||||
success('Missing email validation working correctly');
|
||||
info(`Error: ${data.error}`);
|
||||
return { success: true, error: data.error };
|
||||
} else {
|
||||
error(`Expected 400 status for missing email, got ${response.status}`);
|
||||
return { success: false, error: 'Unexpected response status' };
|
||||
}
|
||||
} catch (err) {
|
||||
error(`Resend verification error: ${err.message}`);
|
||||
return { success: false, error: err.message };
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test resend verification email with invalid email format
|
||||
*/
|
||||
async testResendVerificationInvalidEmail() {
|
||||
try {
|
||||
info('Testing resend verification with invalid email format...');
|
||||
|
||||
const response = await fetch(`${API_BASE_URL}/auth/resend-verification`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
email: 'invalid-email-format'
|
||||
})
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
// The endpoint should still return success for security reasons
|
||||
if (response.ok) {
|
||||
success('Invalid email format handled correctly (security response)');
|
||||
info(`Message: ${data.message}`);
|
||||
return { success: true, message: data.message };
|
||||
} else {
|
||||
warning(`Unexpected response for invalid email: ${data.error}`);
|
||||
return { success: false, error: data.error };
|
||||
}
|
||||
} catch (err) {
|
||||
error(`Resend verification error: ${err.message}`);
|
||||
return { success: false, error: err.message };
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test rate limiting on resend verification
|
||||
*/
|
||||
async testResendVerificationRateLimit() {
|
||||
try {
|
||||
info('Testing rate limiting on resend verification...');
|
||||
|
||||
const requests = [];
|
||||
const maxRequests = 6; // Should exceed the rate limit
|
||||
|
||||
for (let i = 0; i < maxRequests; i++) {
|
||||
requests.push(
|
||||
fetch(`${API_BASE_URL}/auth/resend-verification`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
email: this.testEmail
|
||||
})
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
const responses = await Promise.all(requests);
|
||||
const rateLimitedResponses = responses.filter(r => r.status === 429);
|
||||
|
||||
if (rateLimitedResponses.length > 0) {
|
||||
success(`Rate limiting working: ${rateLimitedResponses.length} requests were rate limited`);
|
||||
return { success: true, rateLimited: rateLimitedResponses.length };
|
||||
} else {
|
||||
warning('Rate limiting may not be working as expected');
|
||||
return { success: false, error: 'No rate limiting detected' };
|
||||
}
|
||||
} catch (err) {
|
||||
error(`Rate limit test error: ${err.message}`);
|
||||
return { success: false, error: err.message };
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check email service configuration
|
||||
*/
|
||||
async checkEmailServiceConfig() {
|
||||
try {
|
||||
info('Checking email service configuration...');
|
||||
|
||||
// This would require a dedicated endpoint to check email config
|
||||
// For now, we'll just check if the service responds properly
|
||||
const response = await fetch(`${API_BASE_URL}/auth/resend-verification`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
email: 'test@example.com'
|
||||
})
|
||||
});
|
||||
|
||||
if (response.ok || response.status === 400) {
|
||||
success('Email service endpoint is accessible');
|
||||
return { success: true };
|
||||
} else {
|
||||
error('Email service endpoint may have issues');
|
||||
return { success: false };
|
||||
}
|
||||
} catch (err) {
|
||||
error(`Email service check error: ${err.message}`);
|
||||
return { success: false, error: err.message };
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up test data
|
||||
*/
|
||||
async cleanup() {
|
||||
try {
|
||||
info('Cleaning up test data...');
|
||||
// Note: In a real scenario, you'd want to clean up the test user
|
||||
// This would require a dedicated cleanup endpoint or direct database access
|
||||
warning('Manual cleanup may be required for test user data');
|
||||
return { success: true };
|
||||
} catch (err) {
|
||||
error(`Cleanup error: ${err.message}`);
|
||||
return { success: false, error: err.message };
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Run all tests
|
||||
*/
|
||||
async runAllTests() {
|
||||
log('\n' + '='.repeat(60), colors.bold);
|
||||
log('🧪 RESEND VERIFICATION EMAIL FUNCTIONALITY TEST', colors.bold);
|
||||
log('='.repeat(60), colors.bold);
|
||||
|
||||
const results = {
|
||||
total: 0,
|
||||
passed: 0,
|
||||
failed: 0
|
||||
};
|
||||
|
||||
const tests = [
|
||||
{ name: 'Server Health Check', fn: () => this.checkServerHealth() },
|
||||
{ name: 'Email Service Configuration', fn: () => this.checkEmailServiceConfig() },
|
||||
{ name: 'User Registration', fn: () => this.registerTestUser() },
|
||||
{ name: 'Resend Verification (Valid Email)', fn: () => this.testResendVerificationValid() },
|
||||
{ name: 'Resend Verification (Non-existent Email)', fn: () => this.testResendVerificationNonExistent() },
|
||||
{ name: 'Resend Verification (Missing Email)', fn: () => this.testResendVerificationMissingEmail() },
|
||||
{ name: 'Resend Verification (Invalid Email)', fn: () => this.testResendVerificationInvalidEmail() },
|
||||
{ name: 'Rate Limiting Test', fn: () => this.testResendVerificationRateLimit() },
|
||||
{ name: 'Cleanup', fn: () => this.cleanup() }
|
||||
];
|
||||
|
||||
for (const test of tests) {
|
||||
log(`\n📋 Running: ${test.name}`, colors.yellow);
|
||||
log('-'.repeat(40));
|
||||
|
||||
try {
|
||||
const result = await test.fn();
|
||||
results.total++;
|
||||
|
||||
if (result.success) {
|
||||
results.passed++;
|
||||
success(`${test.name} - PASSED`);
|
||||
} else {
|
||||
results.failed++;
|
||||
error(`${test.name} - FAILED: ${result.error || 'Unknown error'}`);
|
||||
}
|
||||
} catch (err) {
|
||||
results.total++;
|
||||
results.failed++;
|
||||
error(`${test.name} - ERROR: ${err.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Final results
|
||||
log('\n' + '='.repeat(60), colors.bold);
|
||||
log('📊 TEST RESULTS SUMMARY', colors.bold);
|
||||
log('='.repeat(60), colors.bold);
|
||||
|
||||
log(`Total Tests: ${results.total}`);
|
||||
success(`Passed: ${results.passed}`);
|
||||
if (results.failed > 0) {
|
||||
error(`Failed: ${results.failed}`);
|
||||
} else {
|
||||
log(`Failed: ${results.failed}`);
|
||||
}
|
||||
|
||||
const successRate = ((results.passed / results.total) * 100).toFixed(1);
|
||||
log(`Success Rate: ${successRate}%`);
|
||||
|
||||
if (results.failed === 0) {
|
||||
success('\n🎉 All tests passed! Resend verification functionality is working correctly.');
|
||||
} else {
|
||||
warning('\n⚠️ Some tests failed. Please review the issues above.');
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
}
|
||||
|
||||
// Main execution
|
||||
async function main() {
|
||||
const tester = new ResendVerificationTester();
|
||||
|
||||
try {
|
||||
await tester.runAllTests();
|
||||
} catch (err) {
|
||||
error(`Test execution failed: ${err.message}`);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
// Run if called directly
|
||||
if (require.main === module) {
|
||||
main().catch(console.error);
|
||||
}
|
||||
|
||||
module.exports = ResendVerificationTester;
|
||||
Reference in New Issue
Block a user