Files
TimeTracker/tests/test_error_handling.py
Dries Peeters 8322c73ddc Update tests
2025-11-05 13:58:38 +01:00

236 lines
8.0 KiB
Python

"""
Tests for enhanced error handling system
"""
import pytest
from flask import jsonify
from app import db
from app.models import User
from app.utils.error_handlers import get_user_friendly_message, register_error_handlers
@pytest.mark.unit
@pytest.mark.error_handling
def test_user_friendly_message_404():
"""Test that 404 error has user-friendly message"""
message = get_user_friendly_message(404)
assert message is not None
assert 'title' in message
assert 'message' in message
assert 'recovery' in message
assert message['title'] == 'Page Not Found'
assert 'not found' in message['message'].lower()
@pytest.mark.unit
@pytest.mark.error_handling
def test_user_friendly_message_500():
"""Test that 500 error has user-friendly message"""
message = get_user_friendly_message(500)
assert message is not None
assert message['title'] == 'Server Error'
assert 'server error' in message['message'].lower() or 'error occurred' in message['message'].lower()
@pytest.mark.unit
@pytest.mark.error_handling
def test_user_friendly_message_401():
"""Test that 401 error has user-friendly message"""
message = get_user_friendly_message(401)
assert message is not None
assert message['title'] == 'Authentication Required'
assert 'log in' in message['message'].lower() or 'login' in message['message'].lower()
@pytest.mark.unit
@pytest.mark.error_handling
def test_user_friendly_message_403():
"""Test that 403 error has user-friendly message"""
message = get_user_friendly_message(403)
assert message is not None
assert message['title'] == 'Access Denied'
assert 'permission' in message['message'].lower() or 'access' in message['message'].lower()
@pytest.mark.unit
@pytest.mark.error_handling
def test_user_friendly_message_unknown_status():
"""Test that unknown status codes have fallback message"""
message = get_user_friendly_message(999)
assert message is not None
assert 'title' in message
assert 'message' in message
assert 'recovery' in message
@pytest.mark.unit
@pytest.mark.error_handling
def test_user_friendly_message_with_description():
"""Test that error messages can include custom descriptions"""
message = get_user_friendly_message(400, 'Custom error description')
assert message is not None
assert 'Custom error description' in message['message']
@pytest.mark.unit
@pytest.mark.error_handling
def test_recovery_options_include_dashboard():
"""Test that recovery options include dashboard"""
message = get_user_friendly_message(404)
assert 'Go to Dashboard' in message['recovery']
@pytest.mark.unit
@pytest.mark.error_handling
def test_error_handling_enhanced_file_exists():
"""Test that error handling enhanced file exists"""
import os
error_file = os.path.join(
os.path.dirname(os.path.dirname(__file__)),
'app', 'static', 'error-handling-enhanced.js'
)
assert os.path.exists(error_file), "Error handling enhanced file should exist"
@pytest.mark.unit
@pytest.mark.error_handling
def test_error_handling_retry_functionality():
"""Test that retry functionality is implemented"""
import os
error_file = os.path.join(
os.path.dirname(os.path.dirname(__file__)),
'app', 'static', 'error-handling-enhanced.js'
)
if os.path.exists(error_file):
with open(error_file, 'r', encoding='utf-8') as f:
content = f.read()
assert 'retryFetch' in content, "Retry functionality should be implemented"
assert 'showErrorWithRetry' in content, "Retry button should be shown"
@pytest.mark.unit
@pytest.mark.error_handling
def test_offline_queue_functionality():
"""Test that offline queue functionality is implemented"""
import os
error_file = os.path.join(
os.path.dirname(os.path.dirname(__file__)),
'app', 'static', 'error-handling-enhanced.js'
)
if os.path.exists(error_file):
with open(error_file, 'r', encoding='utf-8') as f:
content = f.read()
assert 'queueForOffline' in content, "Offline queue should be implemented"
assert 'processOfflineQueue' in content, "Offline queue processing should exist"
@pytest.mark.unit
@pytest.mark.error_handling
def test_graceful_degradation():
"""Test that graceful degradation is implemented"""
import os
error_file = os.path.join(
os.path.dirname(os.path.dirname(__file__)),
'app', 'static', 'error-handling-enhanced.js'
)
if os.path.exists(error_file):
with open(error_file, 'r', encoding='utf-8') as f:
content = f.read()
assert 'setupGracefulDegradation' in content, "Graceful degradation should be implemented"
assert 'checkRequiredFeatures' in content, "Feature checking should exist"
@pytest.mark.unit
@pytest.mark.error_handling
def test_error_handling_js_loaded(authenticated_client):
"""Test that error handling JavaScript is loaded in base template"""
response = authenticated_client.get('/dashboard')
assert response.status_code == 200
# Check that error-handling-enhanced.js is included
assert b'error-handling-enhanced.js' in response.data
@pytest.mark.unit
@pytest.mark.error_handling
def test_api_health_endpoint(client):
"""Test that API health endpoint exists"""
response = client.get('/api/health')
assert response.status_code == 200
data = response.get_json()
assert data is not None
assert 'status' in data
assert data['status'] == 'ok'
@pytest.mark.unit
@pytest.mark.error_handling
def test_error_handlers_registered(app):
"""Test that error handlers are registered"""
# Error handlers should be registered during app creation
assert app is not None
# Check that error handlers are callable
with app.app_context():
message = get_user_friendly_message(404)
assert message is not None
@pytest.mark.smoke
@pytest.mark.error_handling
def test_error_template_updates(client):
"""Smoke test: Verify error templates have retry buttons"""
# Test 404 page
response = client.get('/nonexistent-page')
assert response.status_code == 404
html = response.data.decode('utf-8')
# Should have retry/recovery options
assert 'Go to Dashboard' in html or 'Go Back' in html
@pytest.mark.unit
@pytest.mark.error_handling
def test_error_handling_network_monitoring():
"""Test that network monitoring is implemented"""
import os
error_file = os.path.join(
os.path.dirname(os.path.dirname(__file__)),
'app', 'static', 'error-handling-enhanced.js'
)
if os.path.exists(error_file):
with open(error_file, 'r', encoding='utf-8') as f:
content = f.read()
assert 'setupNetworkMonitoring' in content, "Network monitoring should be implemented"
assert 'checkOnlineStatus' in content, "Online status checking should exist"
@pytest.mark.unit
@pytest.mark.error_handling
def test_error_handling_offline_indicator():
"""Test that offline indicator is implemented"""
import os
error_file = os.path.join(
os.path.dirname(os.path.dirname(__file__)),
'app', 'static', 'error-handling-enhanced.js'
)
if os.path.exists(error_file):
with open(error_file, 'r', encoding='utf-8') as f:
content = f.read()
assert 'showOfflineIndicator' in content, "Offline indicator should be implemented"
assert 'offline-indicator' in content, "Offline indicator element should exist"
@pytest.mark.unit
@pytest.mark.error_handling
def test_error_handling_recovery_options():
"""Test that recovery options are implemented"""
import os
error_file = os.path.join(
os.path.dirname(os.path.dirname(__file__)),
'app', 'static', 'error-handling-enhanced.js'
)
if os.path.exists(error_file):
with open(error_file, 'r', encoding='utf-8') as f:
content = f.read()
assert 'getRecoveryOptions' in content, "Recovery options should be implemented"
assert 'error-recovery-btn' in content, "Recovery buttons should exist"