mirror of
https://github.com/DRYTRIX/TimeTracker.git
synced 2026-05-18 04:08:48 -05:00
3654a6a5d3
- queueForOffline now saves url, method, headers, body (replay-safe for localStorage); legacy items with options only still replayed via fallback - processOfflineQueue builds fetch options from stored method/body so replayed requests send the same payload when back online - Make queueForOffline async and await it in handleFetchResponse/handleFetchException - Add tests asserting queue stores method/body and replay uses them
228 lines
8.4 KiB
Python
228 lines
8.4 KiB
Python
"""
|
|
Tests for enhanced error handling system
|
|
"""
|
|
|
|
import pytest
|
|
|
|
# Skip entire test file - get_user_friendly_message function no longer exists
|
|
pytestmark = pytest.mark.skip(reason="get_user_friendly_message function no longer exists in error_handlers module")
|
|
|
|
from flask import jsonify
|
|
from app import db
|
|
from app.models import User
|
|
from app.utils.error_handlers import 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"
|
|
# Replay-safe: store method/body so POST/PUT replay correctly after JSON round-trip
|
|
assert "item.method" in content or "item.body" in content, "Offline queue should store method and body for replay"
|
|
assert "fetchOptions" in content and ("fetchOptions.body" in content or "body: item.body" in content), "Replay should use stored body"
|
|
|
|
|
|
@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"
|