PMFlow/backend/tests/test_ai_steward_fail_fast.py

108 lines
4.1 KiB
Python

import asyncio
import unittest
from types import SimpleNamespace
from unittest.mock import AsyncMock, patch
from app.services.ai_steward import AIStewardService
from app.models import CognitiveConflict
class AIStewardFailFastTest(unittest.IsolatedAsyncioTestCase):
async def test_analyze_project_input_times_out_to_structured_fallback(self) -> None:
service = AIStewardService(db=None) # type: ignore[arg-type]
with patch.object(service.llm, "generate", AsyncMock(side_effect=asyncio.TimeoutError())):
result = await service._analyze_project_input(
"创建一个 3 周上线的 AI 客服项目,先出可运行 MVP。",
tenant_id=1,
)
self.assertEqual(result["primary_role"], "ai_engineer")
self.assertEqual(result["timeline"], "3周")
async def test_generate_task_chain_draft_times_out_to_default_tasks(self) -> None:
service = AIStewardService(db=None) # type: ignore[arg-type]
with patch.object(service.llm, "generate", AsyncMock(side_effect=asyncio.TimeoutError())):
tasks = await service._generate_task_chain_draft(
analysis={
"project_title": "AI 客服项目",
"tech_stack": ["FastAPI", "React"],
"timeline": "3周",
"primary_role": "ai_engineer",
},
tenant_id=1,
)
self.assertGreaterEqual(len(tasks), 2)
self.assertEqual(tasks[0]["title"], "技术方案设计")
async def test_persist_project_creation_draft_writes_conflict_user_ids_as_list(self) -> None:
added_rows = []
class FakeDB:
def add(self, row):
added_rows.append(row)
async def flush(self):
current = len(added_rows)
for index, row in enumerate(added_rows, start=1):
if getattr(row, "id", None) is None:
row.id = index
service = AIStewardService(db=FakeDB()) # type: ignore[arg-type]
with patch(
"app.services.ai_steward.persist_task",
AsyncMock(
return_value=SimpleNamespace(
id=101,
title="任务A",
description="desc",
estimated_hours=8.0,
priority="high",
status="todo",
)
),
):
payload = await service._persist_project_creation_draft(
normalized={
"project": {
"name": "测试项目",
"title": "测试项目",
"description": "desc",
"assigned_role": "ai_engineer",
"domain_id": 1,
},
"signal": {
"content": "signal",
"impact_score": 0.8,
"priority": "high",
"strategic_analysis": {},
},
"charter": {
"title": "项目宪章",
"content": {"success_criteria": ["ok"]},
},
"tasks": [SimpleNamespace(title="任务A", description="desc")],
"task_audit": [],
"risks": [
{
"type": "schedule_delay",
"description": "任务超时预警",
"threshold_hours": 48.0,
"severity": "medium",
}
],
"analysis": {},
},
input_text="创建测试项目",
creator_id=2,
tenant_id=1,
)
risk_rows = [row for row in added_rows if isinstance(row, CognitiveConflict)]
self.assertEqual(len(risk_rows), 1)
self.assertEqual(risk_rows[0].involved_user_ids, [])
self.assertEqual(payload["risks"][0]["description"], "任务超时预警")