""" FastAPI routes tests using TestClient """ from unittest.mock import Mock, patch import pytest from fastapi.testclient import TestClient def test_submit_cta_backtest(): """Test POST /api/v1/backtest/cta returns task_id""" # Create app with temporary DB from sanguo_api.app import create_app import tempfile import os with tempfile.TemporaryDirectory() as tmp: db_path = os.path.join(tmp, "test.db") app = create_app(db_path=db_path, file_dir=None) # Mock get_orchestrator to return mock orchestrator with patch("sanguo_api.routes.get_orchestrator") as mock_get_orch: mock_orch = Mock() mock_orch.submit_cta.return_value = "cta_test_123" mock_get_orch.return_value = mock_orch client = TestClient(app) response = client.post( "/api/v1/backtest/cta", json={ "symbol": "600000SH", "strategy": "DoubleSMA", "params": {"fast": 5, "slow": 20}, "start": "2024-01-01", "end": "2024-12-31" } ) assert response.status_code == 200 data = response.json() assert "task_id" in data assert data["task_id"] == "cta_test_123" def test_get_task_status(): """Test GET /api/v1/task/{task_id} returns status""" from sanguo_api.app import create_app from sanguo_orchestrator.task import TaskState import tempfile import os with tempfile.TemporaryDirectory() as tmp: db_path = os.path.join(tmp, "test.db") app = create_app(db_path=db_path, file_dir=None) with patch("sanguo_api.routes.get_orchestrator") as mock_get_orch: mock_orch = Mock() mock_orch.get_status.return_value = TaskState.DONE mock_get_orch.return_value = mock_orch client = TestClient(app) response = client.get("/api/v1/task/cta_test_123") assert response.status_code == 200 data = response.json() assert "task_id" in data assert data["task_id"] == "cta_test_123" assert data["status"] == "done" def test_get_task_status_not_found(): """Test GET /api/v1/task/{task_id} returns 404 for unknown task""" from sanguo_api.app import create_app import tempfile import os with tempfile.TemporaryDirectory() as tmp: db_path = os.path.join(tmp, "test.db") app = create_app(db_path=db_path, file_dir=None) with patch("sanguo_api.routes.get_orchestrator") as mock_get_orch: mock_orch = Mock() mock_orch.get_status.return_value = None mock_get_orch.return_value = mock_orch client = TestClient(app) response = client.get("/api/v1/task/unknown_task") assert response.status_code == 404 def test_invalid_params_returns_422(): """Test POST /api/v1/backtest/cta with missing fields returns 422""" from sanguo_api.app import create_app import tempfile import os with tempfile.TemporaryDirectory() as tmp: db_path = os.path.join(tmp, "test.db") app = create_app(db_path=db_path, file_dir=None) client = TestClient(app) # Missing required field: strategy response = client.post( "/api/v1/backtest/cta", json={ "symbol": "600000SH", "params": {"fast": 5, "slow": 20}, "start": "2024-01-01", "end": "2024-12-31" } ) assert response.status_code == 422 def test_get_task_result(): """Test GET /api/v1/task/{task_id}/result returns statistics""" from sanguo_api.app import create_app from sanguo_orchestrator.task import TaskState import tempfile import os with tempfile.TemporaryDirectory() as tmp: db_path = os.path.join(tmp, "test.db") app = create_app(db_path=db_path, file_dir=None) with patch("sanguo_api.routes.get_orchestrator") as mock_get_orch: mock_orch = Mock() mock_result = Mock() mock_result.statistics = {"total_trades": 10, "total_return": 0.15} mock_orch.get_result.return_value = mock_result mock_get_orch.return_value = mock_orch client = TestClient(app) response = client.get("/api/v1/task/cta_test_123/result") assert response.status_code == 200 data = response.json() assert "task_id" in data assert data["task_id"] == "cta_test_123" assert "statistics" in data assert data["statistics"]["total_trades"] == 10 def test_get_task_result_not_found(): """Test GET /api/v1/task/{task_id}/result returns 404 when result not ready""" from sanguo_api.app import create_app import tempfile import os with tempfile.TemporaryDirectory() as tmp: db_path = os.path.join(tmp, "test.db") app = create_app(db_path=db_path, file_dir=None) with patch("sanguo_api.routes.get_orchestrator") as mock_get_orch: mock_orch = Mock() mock_orch.get_result.return_value = None mock_get_orch.return_value = mock_orch client = TestClient(app) response = client.get("/api/v1/task/unknown_task/result") assert response.status_code == 404 def test_submit_optimize_returns_pending(): """Test POST /api/v1/backtest/optimize returns pending placeholder""" from sanguo_api.app import create_app import tempfile import os with tempfile.TemporaryDirectory() as tmp: db_path = os.path.join(tmp, "test.db") app = create_app(db_path=db_path, file_dir=None) client = TestClient(app) response = client.post( "/api/v1/backtest/optimize", json={ "symbol": "600000SH", "strategy": "DoubleSMA", "grid": {"fast": [5, 10], "slow": [20, 30]}, "start": "2024-01-01", "end": "2024-12-31", "max_workers": 2 } ) assert response.status_code == 200 data = response.json() assert "task_id" in data assert data["task_id"] == "pending_impl" def test_submit_factor_returns_pending(): """Test POST /api/v1/factor/analyze returns pending placeholder""" from sanguo_api.app import create_app import tempfile import os with tempfile.TemporaryDirectory() as tmp: db_path = os.path.join(tmp, "test.db") app = create_app(db_path=db_path, file_dir=None) client = TestClient(app) response = client.post( "/api/v1/factor/analyze", json={ "symbols": ["600000SH", "000001SZ"], "factor_names": ["ts_mean_5", "ts_mean_20"], "start": "2024-01-01", "end": "2024-12-31" } ) assert response.status_code == 200 data = response.json() assert "task_id" in data assert data["task_id"] == "pending_impl"