aegisai / backend / tests / test_main.py
test_main.py
Raw
"""
Main Application Tests
Run with: pytest tests/test_main.py -v
"""

import pytest
from fastapi.testclient import TestClient
from unittest.mock import patch, MagicMock
from pathlib import Path

# Import the app instance from main
from main import app

@pytest.fixture
def client():
    """
    Test client fixture that handles the lifespan (startup/shutdown)
    'with' statement triggers the @asynccontextmanager lifespan in main.py
    """
    with TestClient(app) as c:
        yield c

def test_root_endpoint(client):
    """Test the root GET endpoint for status and version"""
    response = client.get("/")
    assert response.status_code == 200
    data = response.json()
    assert data["name"] == "AegisAI"
    assert data["status"] == "operational"
    assert "version" in data

def test_docs_accessible(client):
    """Test that API documentation is available"""
    response = client.get("/docs")
    assert response.status_code == 200

@patch("main.db_service")
@patch("main.settings")
def test_lifespan_startup_shutdown(mock_settings, mock_db_service):
    """
    Test the startup and shutdown logic specifically.
    - Startup: Creates evidence directory.
    - Shutdown: Cleans up old incidents.
    """
    # Setup mocks
    mock_settings.EVIDENCE_DIR = MagicMock(spec=Path)
    mock_settings.MAX_EVIDENCE_AGE_DAYS = 30
    mock_db_service.cleanup_old_incidents.return_value = 5
    
    # Trigger lifespan by using the context manager
    with TestClient(app):
        # Startup checks
        mock_settings.EVIDENCE_DIR.mkdir.assert_called_once_with(
            exist_ok=True, parents=True
        )
    
    # Shutdown checks (after 'with' block ends)
    mock_db_service.cleanup_old_incidents.assert_called_once_with(30)

def test_cors_headers(client):
    """Test that CORS middleware is active"""
    response = client.options(
        "/",
        headers={
            "Origin": "http://localhost:3000",
            "Access-Control-Request-Method": "GET",
            "Access-Control-Request-Headers": "X-Requested-With",
        },
    )
    # If the origin is allowed in settings, this should be 200
    assert response.status_code == 200
    assert "access-control-allow-origin" in response.headers