feat(api): 轻量 FastAPI 5 路由(无 JWT/WS/前端)

This commit is contained in:
2026-07-06 11:38:15 +08:00
parent 330b687e83
commit 0f894c8415
7 changed files with 368 additions and 0 deletions
+1
View File
@@ -0,0 +1 @@
# API 测试包
+219
View File
@@ -0,0 +1,219 @@
"""
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"