Files
leocrm/tests/test_ai_health_check.py
T
2026-07-23 22:37:25 +02:00

110 lines
4.1 KiB
Python

"""Tests for the AI health check script (scripts/ai_health_check.py)."""
from __future__ import annotations
import json
import os
import sys
from unittest.mock import AsyncMock, MagicMock, patch
import pytest
# Add scripts dir to path
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "scripts"))
def test_enumerate_routes_returns_api_routes():
"""enumerate_routes should return only /api/ routes with methods."""
from ai_health_check import enumerate_routes
routes = enumerate_routes()
assert isinstance(routes, list)
assert len(routes) > 0
for route in routes:
assert route["path"].startswith("/api/")
assert isinstance(route["methods"], list)
assert len(route["methods"]) > 0
def test_enumerate_routes_excludes_non_api():
"""enumerate_routes should not include non-API paths like /docs or /openapi.json."""
from ai_health_check import enumerate_routes
routes = enumerate_routes()
paths = [r["path"] for r in routes]
assert not any(p.startswith("/docs") for p in paths)
assert not any(p.startswith("/openapi") for p in paths)
def test_format_json_report_structure():
"""JSON report should have summary and endpoints keys."""
from ai_health_check import format_json_report
results = [
{"endpoint": "/api/v1/health", "method": "GET", "status": 200, "response_time_ms": 5.0, "healthy": True, "tags": ["health"], "note": ""},
{"endpoint": "/api/v1/users", "method": "POST", "status": "skipped", "response_time_ms": 0, "healthy": True, "tags": ["users"], "note": "Non-GET method — documented only"},
]
report = json.loads(format_json_report(results))
assert "summary" in report
assert "endpoints" in report
assert report["summary"]["total_endpoints"] == 2
assert report["summary"]["healthy"] == 1
assert report["summary"]["skipped"] == 1
assert report["summary"]["all_healthy"] is True
def test_format_json_report_with_failures():
"""JSON report should mark all_healthy=False when failures exist."""
from ai_health_check import format_json_report
results = [
{"endpoint": "/api/v1/health", "method": "GET", "status": 200, "response_time_ms": 5.0, "healthy": True, "tags": [], "note": ""},
{"endpoint": "/api/v1/broken", "method": "GET", "status": 500, "response_time_ms": 10.0, "healthy": False, "tags": [], "note": "HTTP 500"},
]
report = json.loads(format_json_report(results))
assert report["summary"]["failed"] == 1
assert report["summary"]["all_healthy"] is False
def test_format_csv_report_has_header():
"""CSV report should have a header row with expected columns."""
from ai_health_check import format_csv_report
results = [
{"endpoint": "/api/v1/health", "method": "GET", "status": 200, "response_time_ms": 5.0, "healthy": True, "tags": ["health"], "note": ""},
]
csv_output = format_csv_report(results)
lines = csv_output.strip().split("\n")
assert "endpoint" in lines[0]
assert "method" in lines[0]
assert "status" in lines[0]
assert "/api/v1/health" in lines[1]
@pytest.mark.asyncio
async def test_probe_all_endpoints_skips_non_get():
"""probe_all_endpoints should skip POST/PUT/DELETE methods."""
from ai_health_check import probe_all_endpoints
routes = [
{"path": "/api/v1/users", "methods": ["POST"], "tags": ["users"]},
]
results = await probe_all_endpoints("http://localhost:8000", "fake-token", routes)
assert len(results) == 1
assert results[0]["status"] == "skipped"
assert results[0]["healthy"] is True
@pytest.mark.asyncio
async def test_probe_all_endpoints_handles_connection_error():
"""probe_all_endpoints should handle connection errors gracefully."""
from ai_health_check import probe_all_endpoints
routes = [
{"path": "/api/v1/health", "methods": ["GET"], "tags": ["health"]},
]
results = await probe_all_endpoints("http://nonexistent-host:9999", "fake-token", routes)
assert len(results) == 1
assert results[0]["healthy"] is False
assert results[0]["status"] in ("connection_error", "error")