87 lines
2.5 KiB
Python
87 lines
2.5 KiB
Python
"""线索/NLQ/看板 API 集成测试(需 PostgreSQL)。"""
|
||
|
||
from __future__ import annotations
|
||
|
||
import pytest
|
||
from fastapi.testclient import TestClient
|
||
|
||
from app.db import get_session
|
||
from app.engines import scan
|
||
from app.main import app
|
||
from app.scenarios.split_contract import ContractRecord
|
||
|
||
|
||
@pytest.fixture()
|
||
def client(session):
|
||
app.dependency_overrides[get_session] = lambda: session
|
||
try:
|
||
yield TestClient(app)
|
||
finally:
|
||
app.dependency_overrides.pop(get_session, None)
|
||
|
||
|
||
def _seed_clue(session):
|
||
contracts = [ContractRecord(f"C{i}", f"CUST{i}", 850000) for i in range(8)]
|
||
return scan.run_split_contract_scan(
|
||
session, contracts, approval_threshold=1_000_000, shared_controller=True
|
||
).clue
|
||
|
||
|
||
def test_list_and_get_clue(client, session):
|
||
clue = _seed_clue(session)
|
||
session.flush()
|
||
resp = client.get("/clues")
|
||
assert resp.status_code == 200
|
||
assert any(c["id"] == str(clue.id) for c in resp.json())
|
||
|
||
resp2 = client.get(f"/clues/{clue.id}")
|
||
assert resp2.status_code == 200
|
||
assert resp2.json()["scenario_code"] == "R8"
|
||
|
||
|
||
def test_assign_and_adjudicate_flow(client, session):
|
||
clue = _seed_clue(session)
|
||
session.flush()
|
||
|
||
r1 = client.post(
|
||
f"/clues/{clue.id}/assign", json={"assignee": "auditor_w", "actor": "manager_l"}
|
||
)
|
||
assert r1.status_code == 200
|
||
assert r1.json()["assignee"] == "auditor_w"
|
||
assert r1.json()["status"] == "assigned"
|
||
|
||
r2 = client.post(
|
||
f"/clues/{clue.id}/adjudicate",
|
||
json={"confirmed": True, "actor": "auditor_w", "note": "属实"},
|
||
)
|
||
assert r2.status_code == 200
|
||
assert r2.json()["status"] == "confirmed"
|
||
assert r2.json()["feedback"] == "confirmed"
|
||
|
||
|
||
def test_summary_endpoint(client, session):
|
||
_seed_clue(session)
|
||
session.flush()
|
||
resp = client.get("/clues/summary")
|
||
assert resp.status_code == 200
|
||
body = resp.json()
|
||
assert body["total"] >= 1
|
||
assert body["total_amount_involved"] > 0
|
||
|
||
|
||
def test_no_delete_endpoint(client, session):
|
||
"""R19:不存在删除线索的 API 端点。"""
|
||
clue = _seed_clue(session)
|
||
session.flush()
|
||
resp = client.delete(f"/clues/{clue.id}")
|
||
assert resp.status_code in (404, 405) # 方法不允许/路由不存在
|
||
|
||
|
||
def test_nlq_endpoint_uses_local_provider(client):
|
||
# 默认 .env 为 mock/dashscope;mock 不出域
|
||
resp = client.post("/nlq", json={"question": "列出政企拆单线索"})
|
||
assert resp.status_code == 200
|
||
body = resp.json()
|
||
assert "answer" in body
|
||
assert body["egress"] in (True, False)
|