| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697 |
- import os
- import pytest
- from unittest.mock import patch, AsyncMock
- from httpx import AsyncClient, ASGITransport
- from app.main import app
- # B-66:真样本 PDF 路径改为可移植解析(原写死容器内绝对路径 /app/cfc/...,
- # 任何非容器宿主机都会 400 失败)。仓库根 = tests/<-> cfc-langgraph/<-> cfc。
- _REPO_ROOT = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
- SAMPLE_PDF = os.path.join(_REPO_ROOT, "docs", "参考资料", "501999942-某人.pdf")
- requires_sample_pdf = pytest.mark.skipif(
- not os.path.exists(SAMPLE_PDF),
- reason=f"真样本 PDF 不存在(分发副本/容器内未挂载): {SAMPLE_PDF}",
- )
- @pytest.mark.asyncio
- async def test_report_parse_nonexistent_file():
- transport = ASGITransport(app=app)
- async with AsyncClient(transport=transport, base_url="http://test") as client:
- resp = await client.post("/api/v1/report/parse", json={
- "file_path": "/nonexistent.pdf",
- "family_id": 1,
- "user_id": 1,
- })
- assert resp.status_code == 400
- data = resp.json()
- assert "文件不存在" in data["detail"]
- @pytest.mark.asyncio
- @requires_sample_pdf
- async def test_report_parse_with_real_pdf_algorithm_path():
- transport = ASGITransport(app=app)
- async with AsyncClient(transport=transport, base_url="http://test") as client:
- resp = await client.post("/api/v1/report/parse", json={
- "file_path": SAMPLE_PDF,
- "family_id": 1,
- "user_id": 1,
- })
- assert resp.status_code == 200
- data = resp.json()
- assert data["code"] == 200
- result = data["data"]
- assert "format" in result
- assert "overview" in result
- assert "disease_risks" in result
- assert "nutrition" in result
- assert "amino_acids" in result
- assert isinstance(result["overview"], dict)
- assert isinstance(result["disease_risks"], list)
- assert isinstance(result["amino_acids"], list)
- @pytest.mark.asyncio
- @requires_sample_pdf
- async def test_report_parse_invalid_json_response():
- transport = ASGITransport(app=app)
- async with AsyncClient(transport=transport, base_url="http://test") as client:
- with patch("app.agents.report_parse_agent.ReportParseAgent._parse_with_llm",
- new_callable=AsyncMock, return_value=[1, 2, 3]):
- with patch("app.agents.report_parse_agent.parse_report_pdf_with_fallback",
- return_value={"format": "inline", "overview": {},
- "_parse_incomplete": True}):
- resp = await client.post("/api/v1/report/parse", json={
- "file_path": SAMPLE_PDF,
- "family_id": 1,
- "user_id": 1,
- })
- assert resp.status_code == 200
- data = resp.json()
- assert data["code"] == 500
- assert "解析失败" in data["message"]
- def test_indicator_constraint_contains_names():
- from app.agents.report_parse_agent import _indicator_constraint
- s = _indicator_constraint(["总分", "菌群健康"])
- assert "总分" in s and "菌群健康" in s
- assert _indicator_constraint(None) == ""
- assert _indicator_constraint([]) == ""
- @pytest.mark.asyncio
- async def test_report_parse_accepts_indicators_field():
- transport = ASGITransport(app=app)
- async with AsyncClient(transport=transport, base_url="http://test") as client:
- resp = await client.post("/api/v1/report/parse", json={
- "file_path": "/nonexistent.pdf",
- "family_id": 1,
- "user_id": 1,
- "indicators": ["总分", "菌群健康"],
- })
- # 字段被接受(非 422 校验错误),仅文件不存在
- assert resp.status_code == 400
- assert "文件不存在" in resp.json()["detail"]
|