This commit is contained in:
Your Name
2026-08-18 14:08:38 +08:00
parent 8b9df1154c
commit bc1228a310
77 changed files with 10763 additions and 1181 deletions
+96 -1
View File
@@ -7,7 +7,7 @@ from typing import Any
import pytest
from doctor_workstation.core.errors import ApiProtocolError
from doctor_workstation.core.errors import ApiBusinessError, ApiHttpError, ApiProtocolError
from doctor_workstation.core.models import Appointment, Consultation, PageResult, Prescription
from doctor_workstation.services.mock_repository import DemoDoctorRepository
from doctor_workstation.services.repository import (
@@ -271,6 +271,51 @@ def test_remote_reception_is_forcibly_scoped_to_today() -> None:
}
def test_remote_reception_daily_records_use_admin_endpoints_exactly() -> None:
client = RecordingClient()
repository = RemoteDoctorRepository(client) # type: ignore[arg-type]
repository.list_appointments(
status=1,
start_date="2026-08-11",
end_date="2026-08-17",
include_status_counts=1,
page_no=1,
page_size=15,
)
repository.get_reception(71)
repository.get_tracking_window(
271,
start_date="2026-08-11",
end_date="2026-08-17",
)
repository.list_tracking_notes(271)
assert client.get_calls[-4:] == [
(
"doctor.appointment/lists",
{
"status": 1,
"start_date": "2026-08-11",
"end_date": "2026-08-17",
"include_status_counts": 1,
"page_no": 1,
"page_size": 15,
},
),
("doctor.appointment/reception", {"id": 71}),
(
"tcm.diagnosis/trackingWindow",
{
"id": 271,
"start_date": "2026-08-11",
"end_date": "2026-08-17",
},
),
("tcm.diagnosis/trackingNotes", {"diagnosis_id": 271}),
]
def test_remote_new_contracts_use_exact_admin_endpoints_and_dtos() -> None:
"""Prescription, patient and diagnosis methods remain thin endpoint adapters."""
@@ -600,6 +645,56 @@ def test_remote_diagnosis_ai_assistant_uses_first_party_endpoint_only() -> None:
assert client.timeouts == [105.0]
def test_remote_diagnosis_ai_stream_normalises_chunks_in_order() -> None:
class StreamingClient(RecordingClient):
def post_event_stream(self, endpoint: str, payload: dict[str, Any], **kwargs: Any):
assert endpoint == "tcm.diagnosis/aiAssistantStream"
assert payload == {"id": 501, "prompt": "请辨证", "task": "tcm_pattern"}
assert kwargs["timeout"] == 105.0
yield {"event": "start", "data": {"model_key": "qwen"}}
yield {"event": "delta", "data": {"content": "肝郁"}}
yield {"event": "delta", "data": {"delta": "脾虚"}}
yield {"event": "done", "data": {"model_label": "千问"}}
client = StreamingClient()
events = list(
RemoteDoctorRepository(client).stream_diagnosis_ai(
501,
"请辨证",
task="tcm_pattern",
)
)
assert [event["event"] for event in events] == ["start", "delta", "delta", "done"]
assert "".join(event.get("text", "") for event in events) == "肝郁脾虚"
assert client.post_calls == []
def test_remote_diagnosis_ai_stream_falls_back_once_but_not_for_error_event() -> None:
class MissingStreamClient(RecordingClient):
def post_event_stream(self, *args: Any, **kwargs: Any):
raise ApiHttpError("missing", status_code=404)
missing_client = MissingStreamClient()
events = list(
RemoteDoctorRepository(missing_client).stream_diagnosis_ai(501, "请分析")
)
assert [event["event"] for event in events] == ["start", "delta", "done"]
assert events[1]["text"] == "服务端分析结果"
assert [call[0] for call in missing_client.post_calls] == [
"tcm.diagnosis/aiAssistant"
]
class ErrorStreamClient(RecordingClient):
def post_event_stream(self, *args: Any, **kwargs: Any):
yield {"event": "error", "data": {"message": "模型繁忙"}}
error_client = ErrorStreamClient()
with pytest.raises(ApiBusinessError, match="模型繁忙"):
list(RemoteDoctorRepository(error_client).stream_diagnosis_ai(501, "请分析"))
assert error_client.post_calls == []
def test_remote_diagnosis_ai_analysis_uses_exact_post_contract() -> None:
"""The legacy default is qwen, followed by an explicit OpenAI request."""