Files
zyt/app/tests/test_doctor_selection.py
2026-09-09 12:18:17 +08:00

103 lines
3.6 KiB
Python

"""Doctor choices remain explicit and transactional across mouse/search/keyboard use."""
import os
os.environ.setdefault("QT_QPA_PLATFORM", "offscreen")
import pytest
from PySide6.QtCore import QPoint, Qt, QTimer
from PySide6.QtTest import QTest
from PySide6.QtWidgets import QApplication
from doctor_workstation.ui.pages.prescriptions import DoctorMultiSelect, _DoctorSelectionDialog
from doctor_workstation.ui.theme import apply_theme
@pytest.fixture(scope="module")
def application():
app = QApplication.instance() or QApplication([])
apply_theme(app)
return app
@pytest.fixture
def dialog(application):
parent = DoctorMultiSelect()
widget = _DoctorSelectionDialog({1: "医生甲", 2: "医生乙", 3: "医生丙"}, {1}, parent)
widget.show()
application.processEvents()
yield widget
widget.close()
parent.deleteLater()
application.processEvents()
def item_for(dialog, doctor_id):
return next(dialog.listing.item(i) for i in range(dialog.listing.count())
if dialog.listing.item(i).data(Qt.ItemDataRole.UserRole) == doctor_id)
def test_row_and_checkbox_toggle_once_and_keyboard(dialog, application):
item = item_for(dialog, 2)
rect = dialog.listing.visualItemRect(item)
QTest.mouseClick(dialog.listing.viewport(), Qt.MouseButton.LeftButton, pos=rect.center())
assert dialog.selected_ids() == {1, 2}
assert dialog.count_label.text() == "已选 2 位医生"
QTest.mouseClick(dialog.listing.viewport(), Qt.MouseButton.LeftButton,
pos=QPoint(rect.left() + 20, rect.center().y()))
assert dialog.selected_ids() == {1}
dialog.listing.setCurrentItem(item)
dialog.listing.setFocus()
QTest.keyClick(dialog.listing, Qt.Key.Key_Space)
assert dialog.selected_ids() == {1, 2}
QTest.keyClick(dialog.listing, Qt.Key.Key_Space)
assert dialog.selected_ids() == {1}
def test_filter_preserves_checks_and_clear_includes_hidden(dialog):
dialog.search.setText("乙")
assert item_for(dialog, 1).isHidden()
assert not item_for(dialog, 2).isHidden()
assert dialog.selected_ids() == {1}
dialog.clear_button.click()
assert dialog.selected_ids() == set()
assert not dialog.clear_button.isEnabled()
dialog.search.clear()
assert not item_for(dialog, 1).isHidden()
def test_checked_row_blue_and_unchecked_white(dialog, application):
application.processEvents()
image = dialog.listing.viewport().grab().toImage()
scale = image.devicePixelRatio()
colors = []
for doctor_id in (1, 2):
rect = dialog.listing.visualItemRect(item_for(dialog, doctor_id))
colors.append(image.pixelColor(int((rect.right() - 70) * scale),
int(rect.center().y() * scale)).name())
assert colors == ["#eaf2ff", "#ffffff"]
def test_accept_commits_cancel_preserves_and_reopen_restores(application):
selector = DoctorMultiSelect()
selector.update_options([{"id": 1, "name": "医生甲"}, {"id": 2, "name": "医生乙"}])
seen = []
def choose(accept):
modal = application.activeModalWidget()
seen.append(modal.selected_ids())
item_for(modal, 2).setCheckState(Qt.CheckState.Checked)
modal.accept() if accept else modal.reject()
QTimer.singleShot(0, lambda: choose(False))
selector._choose()
assert selector.values() == []
QTimer.singleShot(0, lambda: choose(True))
selector._choose()
assert selector.values() == [2]
assert selector.button.text() == "医生乙"
QTimer.singleShot(0, lambda: choose(False))
selector._choose()
assert seen == [set(), set(), {2}]
assert selector.values() == [2]
selector.deleteLater()