Files
bookmarksite/tests/test_enhanced_link_testing.html
Rainer Koschnick 0abee5b794 Add comprehensive database setup and user management system
- Implement PostgreSQL database schema with users and bookmarks tables
- Add database connection pooling with retry logic and error handling
- Create migration system with automatic schema initialization
- Add database CLI tools for management (init, status, validate, etc.)
- Include comprehensive error handling and diagnostics
- Add development seed data and testing utilities
- Implement health monitoring and connection pool statistics
- Create detailed documentation and troubleshooting guide

Database features:
- Users table with authentication fields and email verification
- Bookmarks table with user association and metadata
- Proper indexes for performance optimization
- Automatic timestamp triggers
- Transaction support with rollback handling
- Connection pooling (20 max connections, 30s idle timeout)
- Graceful shutdown handling

CLI commands available:
- npm run db:init - Initialize database
- npm run db:status - Check database status
- npm run db:validate - Validate schema
- npm run db:test - Run database tests
- npm run db:diagnostics - Full diagnostics
2025-07-19 23:21:50 +02:00

262 lines
11 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Enhanced Link Testing Test</title>
<style>
body { font-family: Arial, sans-serif; margin: 20px; }
.test-section { margin: 20px 0; padding: 15px; border: 1px solid #ddd; }
.test-result { margin: 10px 0; padding: 10px; background: #f5f5f5; }
.success { background: #d4edda; color: #155724; }
.error { background: #f8d7da; color: #721c24; }
button { margin: 5px; padding: 10px 15px; }
</style>
</head>
<body>
<h1>Enhanced Link Testing Test</h1>
<div class="test-section">
<h2>Test Configuration</h2>
<div id="configDisplay"></div>
<button onclick="showCurrentConfig()">Show Current Config</button>
<button onclick="testConfigMethods()">Test Config Methods</button>
</div>
<div class="test-section">
<h2>Error Categorization Test</h2>
<button onclick="testErrorCategorization()">Test Error Categories</button>
<div id="errorCategoryResults"></div>
</div>
<div class="test-section">
<h2>Link Testing Test</h2>
<button onclick="testSingleLink()">Test Single Link</button>
<button onclick="testMultipleLinks()">Test Multiple Links</button>
<div id="linkTestResults"></div>
</div>
<div class="test-section">
<h2>Utility Functions Test</h2>
<button onclick="testUtilityFunctions()">Test Utility Functions</button>
<div id="utilityResults"></div>
</div>
<script src="script.js"></script>
<script>
// Initialize bookmark manager for testing
const testManager = new BookmarkManager();
function showCurrentConfig() {
const configDiv = document.getElementById('configDisplay');
configDiv.innerHTML = `
<div class="test-result">
<strong>Current Configuration:</strong><br>
Timeout: ${testManager.linkTestConfig.timeout}ms<br>
Max Retries: ${testManager.linkTestConfig.maxRetries}<br>
Retry Delay: ${testManager.linkTestConfig.retryDelay}ms<br>
User Agent: ${testManager.linkTestConfig.userAgent}
</div>
`;
}
function testConfigMethods() {
const configDiv = document.getElementById('configDisplay');
try {
// Test saving and loading config
const originalConfig = {...testManager.linkTestConfig};
// Modify config
testManager.linkTestConfig.timeout = 15000;
testManager.linkTestConfig.maxRetries = 3;
testManager.saveLinkTestConfigToStorage();
// Reset and reload
testManager.linkTestConfig = {timeout: 10000, maxRetries: 2, retryDelay: 1000, userAgent: 'Test'};
testManager.loadLinkTestConfigFromStorage();
const success = testManager.linkTestConfig.timeout === 15000 && testManager.linkTestConfig.maxRetries === 3;
configDiv.innerHTML += `
<div class="test-result ${success ? 'success' : 'error'}">
Config save/load test: ${success ? 'PASSED' : 'FAILED'}
</div>
`;
// Restore original config
testManager.linkTestConfig = originalConfig;
testManager.saveLinkTestConfigToStorage();
} catch (error) {
configDiv.innerHTML += `
<div class="test-result error">
Config test error: ${error.message}
</div>
`;
}
}
function testErrorCategorization() {
const resultsDiv = document.getElementById('errorCategoryResults');
const testCases = [
{ error: new Error('fetch failed'), expected: 'network_error' },
{ error: { name: 'AbortError', message: 'aborted' }, expected: 'timeout' },
{ error: new Error('Invalid URL'), expected: 'invalid_url' },
{ error: new Error('DNS resolution failed'), expected: 'dns_error' },
{ error: new Error('SSL certificate error'), expected: 'ssl_error' },
{ error: new Error('connection refused'), expected: 'connection_refused' }
];
let results = '<h3>Error Categorization Results:</h3>';
testCases.forEach((testCase, index) => {
try {
const category = testManager.categorizeError(testCase.error);
const success = category === testCase.expected;
results += `
<div class="test-result ${success ? 'success' : 'error'}">
Test ${index + 1}: ${testCase.error.message}${category}
${success ? '✓' : `✗ (expected ${testCase.expected})`}
</div>
`;
} catch (error) {
results += `
<div class="test-result error">
Test ${index + 1} failed: ${error.message}
</div>
`;
}
});
resultsDiv.innerHTML = results;
}
async function testSingleLink() {
const resultsDiv = document.getElementById('linkTestResults');
resultsDiv.innerHTML = '<div class="test-result">Testing single link...</div>';
try {
// Test with a reliable URL
const result = await testManager.performLinkTest('https://httpbin.org/status/200', 'Test Link');
resultsDiv.innerHTML = `
<div class="test-result ${result.status === 'valid' ? 'success' : 'error'}">
Single link test result:<br>
Status: ${result.status}<br>
Error Category: ${result.errorCategory || 'None'}<br>
Attempts: ${result.errorDetails?.attempts || 'N/A'}
</div>
`;
} catch (error) {
resultsDiv.innerHTML = `
<div class="test-result error">
Single link test failed: ${error.message}
</div>
`;
}
}
async function testMultipleLinks() {
const resultsDiv = document.getElementById('linkTestResults');
resultsDiv.innerHTML = '<div class="test-result">Testing multiple links...</div>';
const testUrls = [
'https://httpbin.org/status/200',
'https://httpbin.org/status/404',
'https://invalid-url-that-does-not-exist.com',
'not-a-valid-url'
];
let results = '<h3>Multiple Link Test Results:</h3>';
for (let i = 0; i < testUrls.length; i++) {
try {
const result = await testManager.performLinkTest(testUrls[i], `Test Link ${i + 1}`);
results += `
<div class="test-result">
${testUrls[i]}<br>
Status: ${result.status}<br>
Category: ${result.errorCategory || 'None'}<br>
Attempts: ${result.errorDetails?.attempts || 'N/A'}
</div>
`;
} catch (error) {
results += `
<div class="test-result error">
${testUrls[i]}: ${error.message}
</div>
`;
}
}
resultsDiv.innerHTML = results;
}
function testUtilityFunctions() {
const resultsDiv = document.getElementById('utilityResults');
let results = '<h3>Utility Function Test Results:</h3>';
// Test formatErrorCategory
try {
const formatted = testManager.formatErrorCategory('network_error');
const success = formatted === 'Network Error';
results += `
<div class="test-result ${success ? 'success' : 'error'}">
formatErrorCategory test: ${success ? 'PASSED' : 'FAILED'} (${formatted})
</div>
`;
} catch (error) {
results += `
<div class="test-result error">
formatErrorCategory test failed: ${error.message}
</div>
`;
}
// Test formatRelativeTime
try {
const now = Date.now();
const fiveMinutesAgo = now - (5 * 60 * 1000);
const formatted = testManager.formatRelativeTime(fiveMinutesAgo);
const success = formatted.includes('5 minutes ago');
results += `
<div class="test-result ${success ? 'success' : 'error'}">
formatRelativeTime test: ${success ? 'PASSED' : 'FAILED'} (${formatted})
</div>
`;
} catch (error) {
results += `
<div class="test-result error">
formatRelativeTime test failed: ${error.message}
</div>
`;
}
// Test isTransientError
try {
const isTransient = testManager.isTransientError('network_error');
const isNotTransient = !testManager.isTransientError('invalid_url');
const success = isTransient && isNotTransient;
results += `
<div class="test-result ${success ? 'success' : 'error'}">
isTransientError test: ${success ? 'PASSED' : 'FAILED'}
</div>
`;
} catch (error) {
results += `
<div class="test-result error">
isTransientError test failed: ${error.message}
</div>
`;
}
resultsDiv.innerHTML = results;
}
// Show initial config on load
window.onload = function() {
showCurrentConfig();
};
</script>
</body>
</html>