/** * Test-Script für API-Response-Validierung * Dieses Script testet die validateApiResponse() Funktion in verschiedenen Szenarien */ // Globale Test-Ergebnisse window.apiValidationTestResults = { passed: 0, failed: 0, tests: [] }; /** * Mock Response für Tests erstellen */ function createMockResponse(body, status = 200, headers = {}) { const defaultHeaders = { 'content-type': 'application/json', ...headers }; return new Response(body, { status: status, statusText: getStatusText(status), headers: defaultHeaders }); } function getStatusText(status) { const statusTexts = { 200: 'OK', 400: 'Bad Request', 401: 'Unauthorized', 403: 'Forbidden', 404: 'Not Found', 429: 'Too Many Requests', 500: 'Internal Server Error', 503: 'Service Unavailable' }; return statusTexts[status] || 'Unknown'; } /** * Test-Framework Funktionen */ function assert(condition, message) { if (condition) { console.log(`✅ PASS: ${message}`); window.apiValidationTestResults.passed++; window.apiValidationTestResults.tests.push({ test: message, result: 'PASS' }); } else { console.error(`❌ FAIL: ${message}`); window.apiValidationTestResults.failed++; window.apiValidationTestResults.tests.push({ test: message, result: 'FAIL' }); } } async function assertThrows(asyncFn, expectedErrorPattern, message) { try { await asyncFn(); console.error(`❌ FAIL: ${message} - Expected error but none was thrown`); window.apiValidationTestResults.failed++; window.apiValidationTestResults.tests.push({ test: message, result: 'FAIL - No error thrown' }); } catch (error) { if (expectedErrorPattern.test(error.message)) { console.log(`✅ PASS: ${message} - Correct error: ${error.message}`); window.apiValidationTestResults.passed++; window.apiValidationTestResults.tests.push({ test: message, result: 'PASS' }); } else { console.error(`❌ FAIL: ${message} - Wrong error: ${error.message}`); window.apiValidationTestResults.failed++; window.apiValidationTestResults.tests.push({ test: message, result: `FAIL - Wrong error: ${error.message}` }); } } } /** * Test-Funktion für validateApiResponse * Diese Funktion erwartet, dass validateApiResponse global verfügbar ist */ async function testValidateApiResponse() { console.log('🧪 Starte API-Response-Validierung Tests...\n'); // Test 1: Erfolgreiche JSON-Response console.log('📋 Test 1: Erfolgreiche JSON-Response'); try { const mockResponse = createMockResponse( JSON.stringify({ success: true, data: { message: 'Hello World' } }) ); const result = await validateApiResponse(mockResponse, 'Test 1'); assert(result.success === true, 'JSON-Response korrekt geparst'); assert(result.data.message === 'Hello World', 'Daten korrekt extrahiert'); } catch (error) { console.error(`❌ FAIL: Test 1 - Unexpected error: ${error.message}`); window.apiValidationTestResults.failed++; } // Test 2: HTTP 404 Fehler console.log('\n📋 Test 2: HTTP 404 Fehler'); await assertThrows( () => validateApiResponse(createMockResponse('Not Found', 404), 'Test 2'), /Ressource nicht gefunden \(Test 2\)/, 'HTTP 404 korrekt behandelt' ); // Test 3: HTTP 401 Fehler console.log('\n📋 Test 3: HTTP 401 Fehler'); await assertThrows( () => validateApiResponse(createMockResponse('Unauthorized', 401), 'Test 3'), /Authentifizierung fehlgeschlagen \(Test 3\)/, 'HTTP 401 korrekt behandelt' ); // Test 4: HTTP 500 Fehler console.log('\n📋 Test 4: HTTP 500 Fehler'); await assertThrows( () => validateApiResponse(createMockResponse('Internal Server Error', 500), 'Test 4'), /Serverfehler \(Test 4\)/, 'HTTP 500 korrekt behandelt' ); // Test 5: Falscher Content-Type console.log('\n📋 Test 5: Falscher Content-Type'); await assertThrows( () => validateApiResponse( createMockResponse('Plain text response', 200, { 'content-type': 'text/plain' }), 'Test 5' ), /Ungültiger Content-Type.*Test 5/, 'Falscher Content-Type korrekt behandelt' ); // Test 6: HTML-Fehlerseite console.log('\n📋 Test 6: HTML-Fehlerseite'); await assertThrows( () => validateApiResponse( createMockResponse('Error', 200, { 'content-type': 'text/html' }), 'Test 6' ), /Server-Fehlerseite erhalten statt JSON-Response \(Test 6\)/, 'HTML-Fehlerseite korrekt erkannt' ); // Test 7: Ungültiges JSON console.log('\n📋 Test 7: Ungültiges JSON'); await assertThrows( () => validateApiResponse( createMockResponse('{ invalid json }'), 'Test 7' ), /Ungültige JSON-Response.*Test 7/, 'Ungültiges JSON korrekt behandelt' ); // Test 8: Leere Response console.log('\n📋 Test 8: Leere Response (null)'); await assertThrows( () => validateApiResponse( createMockResponse('null'), 'Test 8' ), /Leere Response erhalten \(Test 8\)/, 'Null-Response korrekt behandelt' ); // Test 9: API-Fehler mit success: false console.log('\n📋 Test 9: API-Fehler mit success: false'); await assertThrows( () => validateApiResponse( createMockResponse(JSON.stringify({ success: false, error: 'Validation failed' })), 'Test 9' ), /API-Fehler: Validation failed \(Test 9\)/, 'API-Fehler mit success: false korrekt behandelt' ); // Test 10: JSON ohne success-Feld (sollte funktionieren) console.log('\n📋 Test 10: JSON ohne success-Feld'); try { const mockResponse = createMockResponse( JSON.stringify({ data: [1, 2, 3], total: 3 }) ); const result = await validateApiResponse(mockResponse, 'Test 10'); assert(Array.isArray(result.data), 'JSON ohne success-Feld korrekt verarbeitet'); assert(result.total === 3, 'Daten korrekt extrahiert'); } catch (error) { console.error(`❌ FAIL: Test 10 - Unexpected error: ${error.message}`); window.apiValidationTestResults.failed++; } // Ergebnisse ausgeben console.log('\n🏁 Test-Ergebnisse:'); console.log(`✅ Erfolgreiche Tests: ${window.apiValidationTestResults.passed}`); console.log(`❌ Fehlgeschlagene Tests: ${window.apiValidationTestResults.failed}`); console.log(`📊 Erfolgsrate: ${((window.apiValidationTestResults.passed / (window.apiValidationTestResults.passed + window.apiValidationTestResults.failed)) * 100).toFixed(1)}%`); return window.apiValidationTestResults; } /** * Live-Tests gegen echte API-Endpunkte */ async function testLiveAPI() { console.log('\n🌐 Starte Live-API-Tests...\n'); // API Base URL Detection (wie in den anderen Dateien) function detectApiBaseUrl() { const currentPort = window.location.port; const currentProtocol = window.location.protocol; const currentHost = window.location.hostname; if (currentPort === '5000') { return `${currentProtocol}//${currentHost}:${currentPort}`; } if (currentPort === '443' || currentPort === '') { return `${currentProtocol}//${currentHost}`; } return window.location.origin; } const apiBaseUrl = detectApiBaseUrl(); // Test 1: Live-API-Test - Stats-Endpunkt console.log('📋 Live-Test 1: Stats-Endpunkt'); try { const response = await fetch(`${apiBaseUrl}/api/stats`); const data = await validateApiResponse(response, 'Live-Stats-Test'); assert(typeof data === 'object', 'Stats-API liefert gültiges JSON'); console.log('📊 Stats-Daten erhalten:', Object.keys(data)); } catch (error) { console.warn(`⚠️ Live-Test 1 fehlgeschlagen (erwartet bei fehlendem Auth): ${error.message}`); } // Test 2: Live-API-Test - Nicht existierender Endpunkt (404) console.log('\n📋 Live-Test 2: Nicht existierender Endpunkt'); try { const response = await fetch(`${apiBaseUrl}/api/nonexistent-endpoint-12345`); await validateApiResponse(response, 'Live-404-Test'); console.error('❌ FAIL: 404-Test - Sollte einen Fehler werfen'); } catch (error) { if (error.message.includes('404') || error.message.includes('nicht gefunden')) { console.log('✅ PASS: 404-Fehler korrekt behandelt'); } else { console.log(`✅ PASS: Fehler korrekt behandelt: ${error.message}`); } } console.log('\n🌐 Live-API-Tests abgeschlossen'); } /** * Integration-Tests für spezifische JavaScript-Dateien */ async function testIntegration() { console.log('\n🔗 Starte Integration-Tests...\n'); // Test, ob validateApiResponse in verschiedenen Kontexten verfügbar ist const testFiles = [ { name: 'Admin Dashboard', check: () => window.adminDashboard && typeof window.adminDashboard.validateApiResponse === 'function' }, { name: 'Printer Monitor', check: () => window.printerMonitor && typeof window.printerMonitor.validateApiResponse === 'function' }, { name: 'Global validateApiResponse', check: () => typeof window.validateApiResponse === 'function' || typeof validateApiResponse === 'function' } ]; testFiles.forEach(test => { try { const isAvailable = test.check(); assert(isAvailable, `${test.name} - validateApiResponse verfügbar`); } catch (error) { console.warn(`⚠️ ${test.name} - Nicht geladen oder verfügbar: ${error.message}`); } }); console.log('\n🔗 Integration-Tests abgeschlossen'); } /** * Performance-Tests */ async function testPerformance() { console.log('\n⚡ Starte Performance-Tests...\n'); const iterations = 100; const startTime = performance.now(); for (let i = 0; i < iterations; i++) { const mockResponse = createMockResponse( JSON.stringify({ success: true, data: { iteration: i } }) ); await validateApiResponse(mockResponse, `Performance-Test-${i}`); } const endTime = performance.now(); const totalTime = endTime - startTime; const avgTime = totalTime / iterations; console.log(`📊 Performance-Ergebnisse:`); console.log(` Gesamtzeit für ${iterations} Calls: ${totalTime.toFixed(2)}ms`); console.log(` Durchschnittszeit pro Call: ${avgTime.toFixed(2)}ms`); console.log(` Overhead pro Call: ${avgTime < 1 ? 'Sehr niedrig' : avgTime < 5 ? 'Niedrig' : 'Hoch'}`); assert(avgTime < 5, 'Performance-Test - Durchschnittszeit unter 5ms'); console.log('\n⚡ Performance-Tests abgeschlossen'); } /** * Haupt-Test-Runner */ async function runAllTests() { console.clear(); console.log('🚀 API-Response-Validierung Test-Suite\n'); console.log('=' * 50 + '\n'); // Reset Test-Ergebnisse window.apiValidationTestResults = { passed: 0, failed: 0, tests: [] }; try { // Basis-Tests await testValidateApiResponse(); // Live-API-Tests await testLiveAPI(); // Integration-Tests await testIntegration(); // Performance-Tests await testPerformance(); // Finale Statistiken console.log('\n' + '=' * 50); console.log('🏆 FINALE TEST-ERGEBNISSE:'); console.log(`✅ Gesamt erfolgreich: ${window.apiValidationTestResults.passed}`); console.log(`❌ Gesamt fehlgeschlagen: ${window.apiValidationTestResults.failed}`); const total = window.apiValidationTestResults.passed + window.apiValidationTestResults.failed; const successRate = total > 0 ? (window.apiValidationTestResults.passed / total * 100).toFixed(1) : 0; console.log(`📊 Erfolgsrate: ${successRate}%`); if (window.apiValidationTestResults.failed === 0) { console.log('🎉 ALLE TESTS ERFOLGREICH!'); } else { console.log('⚠️ Einige Tests sind fehlgeschlagen. Siehe Details oben.'); } return window.apiValidationTestResults; } catch (error) { console.error('💥 Test-Suite Fehler:', error); return { error: error.message }; } } // Globale Funktionen verfügbar machen window.runAllTests = runAllTests; window.testValidateApiResponse = testValidateApiResponse; window.testLiveAPI = testLiveAPI; window.testIntegration = testIntegration; window.testPerformance = testPerformance; // Auto-Start wenn Test-Parameter in URL if (window.location.search.includes('run-api-tests=true')) { document.addEventListener('DOMContentLoaded', () => { setTimeout(runAllTests, 1000); // 1 Sekunde warten bis alles geladen ist }); } console.log('📝 API-Validation-Test-Suite geladen'); console.log('💡 Verwendung: runAllTests() in der Browser-Console ausführen'); console.log('💡 Oder URL-Parameter ?run-api-tests=true verwenden für Auto-Start');