test: 修复所有预存的失败测试
- test_auth_routes: monkeypatch 环境为 production 使 phone-session 限速生效 - test_schedule_items_routes: 补充必填 timezone 字段 - test_llm_pricing_service: 更新 deepseek-chat 费率期望值匹配实际 catalog - test_sse_flow_live: 补充 runId 查询参数、改用附件上传 API、修复 history 响应断言、独立 DB session 避免跨事件循环崩溃 - test_agent_prompt: 移除已删除的 project_cli_defaults 断言 - test_toolkit: 更新 action card 断言匹配 module/method 格式
This commit is contained in:
@@ -167,7 +167,11 @@ def test_send_otp_phone_rate_limited_after_too_many_attempts() -> None:
|
||||
app.dependency_overrides = {}
|
||||
|
||||
|
||||
def test_phone_session_rate_limited_after_too_many_attempts() -> None:
|
||||
def test_phone_session_rate_limited_after_too_many_attempts(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
monkeypatch.setattr("v1.auth.router.config.runtime.environment", "production")
|
||||
|
||||
app.dependency_overrides[get_auth_service] = _override_auth_service(
|
||||
FakeAuthService(_token_response())
|
||||
)
|
||||
|
||||
@@ -92,6 +92,7 @@ def test_create_schedule_item_returns_201() -> None:
|
||||
json={
|
||||
"title": "Test Event",
|
||||
"start_at": "2026-02-28T16:00:00Z",
|
||||
"timezone": "UTC",
|
||||
},
|
||||
)
|
||||
assert response.status_code == 201
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import base64
|
||||
from pathlib import Path
|
||||
from uuid import UUID, uuid4
|
||||
|
||||
import httpx
|
||||
import pytest
|
||||
from sqlalchemy import select
|
||||
from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker, create_async_engine
|
||||
|
||||
from core.config.settings import config
|
||||
from core.db.session import AsyncSessionLocal
|
||||
from models.agent_chat_message import AgentChatMessage
|
||||
from models.agent_chat_session import AgentChatSession
|
||||
from schemas.enums import AgentChatMessageRole
|
||||
@@ -20,6 +19,14 @@ FIXTURE_IMAGE_PATH = (
|
||||
)
|
||||
|
||||
|
||||
def _make_session():
|
||||
engine = create_async_engine(
|
||||
config.database_url,
|
||||
pool_pre_ping=True,
|
||||
)
|
||||
return async_sessionmaker(bind=engine, class_=AsyncSession, expire_on_commit=False, autoflush=False)()
|
||||
|
||||
|
||||
def _require_test_phone() -> str:
|
||||
phone = config.test.phone
|
||||
if not phone:
|
||||
@@ -82,7 +89,7 @@ async def test_agent_sse_closed_loop_live() -> None:
|
||||
thread_id = str(accepted["threadId"])
|
||||
assert thread_id
|
||||
|
||||
events_url = f"{BASE_URL}/api/v1/agent/runs/{thread_id}/events"
|
||||
events_url = f"{BASE_URL}/api/v1/agent/runs/{thread_id}/events?runId=run-live-1"
|
||||
event_names: list[str] = []
|
||||
async with client.stream(
|
||||
"GET", events_url, headers=headers, timeout=20.0
|
||||
@@ -98,7 +105,7 @@ async def test_agent_sse_closed_loop_live() -> None:
|
||||
assert "RUN_STARTED" in event_names
|
||||
assert "RUN_FINISHED" in event_names or "RUN_ERROR" in event_names
|
||||
|
||||
async with AsyncSessionLocal() as session:
|
||||
async with _make_session() as session:
|
||||
session_row = await session.get(AgentChatSession, UUID(thread_id))
|
||||
assert session_row is not None
|
||||
assert session_row.message_count >= 1
|
||||
@@ -119,13 +126,24 @@ async def test_agent_runs_events_history_live_with_image_input() -> None:
|
||||
if config.runtime.environment not in {"dev", "test"}:
|
||||
pytest.skip("live integration tests require dev or test environment")
|
||||
|
||||
image_data = base64.b64encode(FIXTURE_IMAGE_PATH.read_bytes()).decode("ascii")
|
||||
|
||||
async with httpx.AsyncClient(timeout=30.0) as client:
|
||||
token = await _live_access_token(client)
|
||||
headers = {"Authorization": f"Bearer {token}"}
|
||||
thread_id = str(uuid4())
|
||||
|
||||
upload_resp = await client.post(
|
||||
f"{BASE_URL}/api/v1/agent/attachments",
|
||||
headers=headers,
|
||||
data={"threadId": thread_id},
|
||||
files={"file": ("calendar_text_cn.png", FIXTURE_IMAGE_PATH.read_bytes(), "image/png")},
|
||||
)
|
||||
assert upload_resp.status_code == 200, (
|
||||
f"upload failed: {upload_resp.status_code} {upload_resp.text[:200]}"
|
||||
)
|
||||
attachment = upload_resp.json()["attachment"]
|
||||
image_url = attachment["url"]
|
||||
assert isinstance(image_url, str) and image_url
|
||||
|
||||
run_resp = await client.post(
|
||||
f"{BASE_URL}/api/v1/agent/runs",
|
||||
headers=headers,
|
||||
@@ -141,7 +159,7 @@ async def test_agent_runs_events_history_live_with_image_input() -> None:
|
||||
{"type": "text", "text": "请描述图片里的内容"},
|
||||
{
|
||||
"type": "binary",
|
||||
"data": image_data,
|
||||
"url": image_url,
|
||||
"mimeType": "image/png",
|
||||
},
|
||||
],
|
||||
@@ -154,7 +172,7 @@ async def test_agent_runs_events_history_live_with_image_input() -> None:
|
||||
)
|
||||
assert run_resp.status_code == 202
|
||||
|
||||
events_url = f"{BASE_URL}/api/v1/agent/runs/{thread_id}/events"
|
||||
events_url = f"{BASE_URL}/api/v1/agent/runs/{thread_id}/events?runId=run-live-image-1"
|
||||
event_names: list[str] = []
|
||||
async with client.stream(
|
||||
"GET", events_url, headers=headers, timeout=90.0
|
||||
@@ -180,25 +198,21 @@ async def test_agent_runs_events_history_live_with_image_input() -> None:
|
||||
)
|
||||
assert history_resp.status_code == 200
|
||||
history = history_resp.json()
|
||||
assert history.get("type") == "STATE_SNAPSHOT"
|
||||
snapshot = history.get("snapshot", {})
|
||||
assert snapshot.get("scope") == "history_day"
|
||||
messages = snapshot.get("messages", [])
|
||||
assert history.get("scope") == "history_day"
|
||||
messages = history.get("messages", [])
|
||||
user_messages = [
|
||||
item
|
||||
for item in messages
|
||||
if isinstance(item, dict) and item.get("role") == "user"
|
||||
]
|
||||
assert user_messages
|
||||
metadata = user_messages[0].get("metadata")
|
||||
assert isinstance(metadata, dict)
|
||||
user_attachments = metadata.get("user_message_attachments")
|
||||
user_attachments = user_messages[0].get("attachments")
|
||||
assert isinstance(user_attachments, list)
|
||||
assert user_attachments
|
||||
assert isinstance(user_attachments[0], dict)
|
||||
assert isinstance(user_attachments[0].get("path"), str)
|
||||
assert isinstance(user_attachments[0].get("url"), str)
|
||||
|
||||
async with AsyncSessionLocal() as session:
|
||||
async with _make_session() as session:
|
||||
session_row = await session.get(AgentChatSession, UUID(thread_id))
|
||||
assert session_row is not None
|
||||
assert session_row.message_count >= 1
|
||||
@@ -288,7 +302,7 @@ async def test_agent_tool_call_result_persisted_live() -> None:
|
||||
f"no terminal event, got: {event_names}"
|
||||
)
|
||||
|
||||
async with AsyncSessionLocal() as session:
|
||||
async with _make_session() as session:
|
||||
rows = await session.execute(
|
||||
select(AgentChatMessage).where(
|
||||
AgentChatMessage.session_id == UUID(thread_id),
|
||||
|
||||
Reference in New Issue
Block a user