177 lines
6.8 KiB
Python
177 lines
6.8 KiB
Python
"""Historical reception queries retain their day and include finished appointments."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
from datetime import date
|
|
from typing import Any
|
|
|
|
os.environ.setdefault("QT_QPA_PLATFORM", "offscreen")
|
|
|
|
import pytest
|
|
from PySide6.QtCore import QDate, QTimer
|
|
from PySide6.QtWidgets import QApplication
|
|
|
|
from doctor_workstation.core import PermissionSet
|
|
from doctor_workstation.services.repository import RemoteDoctorRepository
|
|
from doctor_workstation.ui.pages import reception as module
|
|
from doctor_workstation.ui.widgets import StatusBadge
|
|
|
|
|
|
class Today(date):
|
|
@classmethod
|
|
def today(cls):
|
|
return cls(2026, 11, 6)
|
|
|
|
|
|
class Client:
|
|
def __init__(self):
|
|
self.calls = []
|
|
|
|
def get(self, endpoint: str, params: Any = None):
|
|
params = dict(params or {})
|
|
self.calls.append((endpoint, params))
|
|
assert endpoint == "doctor.appointment/lists"
|
|
day = params["start_date"]
|
|
statuses = [2, 3, 4] if day == "2026-10-17" else []
|
|
rows = [
|
|
{"id": status, "patient_name": "测试患者", "status": status,
|
|
"status_desc": module.STATUS_TEXT[status], "appointment_date": day}
|
|
for status in statuses
|
|
if params.get("status") in (None, "", status)
|
|
]
|
|
offset = (params["page_no"] - 1) * params["page_size"]
|
|
return {
|
|
"lists": rows[offset:offset + params["page_size"]], "count": len(rows),
|
|
"extend": {"status_count": {str(status): statuses.count(status) for status in range(1, 5)}},
|
|
}
|
|
|
|
|
|
@pytest.fixture(scope="module")
|
|
def application():
|
|
return QApplication.instance() or QApplication([])
|
|
|
|
|
|
@pytest.fixture
|
|
def page(application, monkeypatch):
|
|
def immediate(function, **callbacks):
|
|
callbacks["on_success"](function())
|
|
callbacks["on_finished"]()
|
|
|
|
monkeypatch.setattr(module, "date", Today)
|
|
monkeypatch.setattr(module, "run_async", immediate)
|
|
client = Client()
|
|
widget = module.ReceptionPage(RemoteDoctorRepository(client), PermissionSet([]))
|
|
# Keep this test on the list boundary, without loading patient clinical details.
|
|
monkeypatch.setattr(widget, "_select_record", lambda *_args, **_kwargs: None)
|
|
monkeypatch.setattr(widget, "_maybe_load_more_queue", lambda: None)
|
|
yield widget, client
|
|
for timer in widget.findChildren(QTimer):
|
|
timer.stop()
|
|
widget.close()
|
|
widget.deleteLater()
|
|
application.processEvents()
|
|
|
|
|
|
def test_historical_day_opens_all_statuses_and_labels_cancelled_correctly(page):
|
|
widget, client = page
|
|
widget.queue_date_button._pick_date(QDate(2026, 10, 17))
|
|
assert widget.queue_title.text() == "历史接诊"
|
|
assert widget._queue_filter_status is None
|
|
assert widget._queue_filter_buttons[None].isChecked()
|
|
assert [record.status for record in widget._queue_records] == [2, 3, 4]
|
|
assert widget._queue_filter_buttons[None].text() == "全部 3"
|
|
assert widget._queue_filter_buttons[2].text() == "已取消 1"
|
|
row = widget.queue_list.itemWidget(widget.queue_list.item(0))
|
|
assert any(badge.text() == "已取消" and not badge.isHidden() for badge in row.findChildren(StatusBadge))
|
|
assert client.calls[-1][1]["start_date"] == client.calls[-1][1]["end_date"] == "2026-10-17"
|
|
assert not client.calls[-1][1].get("status")
|
|
assert "progress_board" not in client.calls[-1][1]
|
|
assert "diag_scope_relax" not in client.calls[-1][1]
|
|
|
|
|
|
@pytest.mark.parametrize("status", [None, 1, 2, 3, 4])
|
|
def test_history_status_refresh_and_poll_keep_exact_date(page, status):
|
|
widget, client = page
|
|
widget.queue_date_button._pick_date(QDate(2026, 10, 17))
|
|
widget._set_queue_filter(status)
|
|
widget.refresh(workspace_refresh=True)
|
|
widget._poll_queue()
|
|
assert all(params["start_date"] == params["end_date"] == "2026-10-17" for _, params in client.calls)
|
|
assert client.calls[-1][1].get("status") == status
|
|
assert widget._queue_filter_buttons[None].text() == "全部 3"
|
|
if status == 2:
|
|
assert "已取消" in widget.queue_filter_summary.text()
|
|
|
|
|
|
def test_history_pagination_keeps_date_and_status(page):
|
|
widget, client = page
|
|
widget._queue_page_size = 2
|
|
widget.queue_date_button._pick_date(QDate(2026, 10, 17))
|
|
widget._load_more()
|
|
assert [params["page_no"] for _, params in client.calls] == [1, 2]
|
|
assert len(widget._queue_records) == 3
|
|
assert client.calls[-1][1]["start_date"] == "2026-10-17"
|
|
assert not client.calls[-1][1].get("status")
|
|
|
|
|
|
def test_empty_day_explains_selected_date_and_explicit_today_selection_shows_all(page):
|
|
widget, _client = page
|
|
assert widget._queue_filter_status == 1
|
|
widget.queue_date_button._pick_date(QDate(2026, 10, 16))
|
|
assert widget.queue_stack.currentWidget() is widget.queue_empty
|
|
assert "2026-10-16" in widget.queue_empty_description.text()
|
|
assert "当前账号" in widget.queue_empty_description.text()
|
|
assert "挂号记录" in widget.queue_empty_description.text()
|
|
widget.queue_date_button._pick_date(QDate(2026, 11, 6))
|
|
assert widget.queue_title.text() == "今日接诊"
|
|
assert widget._queue_filter_status is None
|
|
widget.queue_date_button._pick_date(QDate(2026, 11, 7))
|
|
assert widget.queue_title.text() == "预约接诊"
|
|
|
|
|
|
@pytest.mark.parametrize("selected_date", ["2026-10-17", "2026-11-06", "2026-11-07"])
|
|
def test_selecting_any_day_clears_old_name_and_status_with_one_request(page, application, selected_date):
|
|
widget, client = page
|
|
widget.show()
|
|
application.processEvents()
|
|
widget.search_edit.setText("之前查过的患者")
|
|
widget._set_queue_filter(3)
|
|
client.calls.clear()
|
|
|
|
widget.queue_date_button._pick_date(QDate.fromString(selected_date, "yyyy-MM-dd"))
|
|
|
|
assert len(client.calls) == 1
|
|
endpoint, params = client.calls[0]
|
|
assert endpoint == "doctor.appointment/lists"
|
|
assert params["start_date"] == params["end_date"] == selected_date
|
|
assert params["page_no"] == 1
|
|
assert not params.get("patient_name")
|
|
assert not params.get("status")
|
|
assert widget.search_edit.text() == ""
|
|
assert widget._queue_filter_buttons[None].isChecked()
|
|
assert not any(key in params for key in ("progress_board", "diag_scope_relax", "assistant_id"))
|
|
|
|
|
|
def test_calendar_reselects_same_day_and_deduplicates_click_activation(page, application):
|
|
widget, client = page
|
|
widget.show()
|
|
application.processEvents()
|
|
widget._set_queue_filter(3)
|
|
widget.search_edit.setText("旧姓名")
|
|
client.calls.clear()
|
|
button = widget.queue_date_button
|
|
calendar = button.calendarWidget()
|
|
selected = QDate(2026, 11, 6)
|
|
button.click()
|
|
assert calendar.isVisible()
|
|
calendar.clicked.emit(selected)
|
|
calendar.activated.emit(selected)
|
|
assert len(client.calls) == 1
|
|
assert not calendar.isVisible()
|
|
assert widget.search_edit.text() == ""
|
|
assert widget._queue_filter_status is None
|
|
button.click()
|
|
calendar.activated.emit(selected)
|
|
assert len(client.calls) == 2
|