from __future__ import annotations import os from types import SimpleNamespace os.environ.setdefault("QT_QPA_PLATFORM", "offscreen") import pytest from PySide6.QtCore import QPoint, Qt from PySide6.QtWidgets import QApplication, QTabWidget, QWidget from doctor_workstation.ui.dialogs.prescription import PrescriptionEditorDialog @pytest.fixture(scope="module") def application() -> QApplication: return QApplication.instance() or QApplication([]) def _repository() -> SimpleNamespace: return SimpleNamespace(list_medicines=lambda **_kwargs: {"lists": [], "count": 0}) def _seed() -> dict[str, object]: return { "id": 502, "diagnosis_id": 301, "appointment_id": 401, "patient_name": "林晓岚", "phone": "13800138000", "gender": 0, "age": 34, "visit_no": "1K00000401", "tongue": "舌淡红、苔薄白", "pulse": "面色少华", "pulse_condition": "脉细", "clinical_diagnosis": "气阴两虚", "doctor_name": "陈医生", "herbs": [ {"medicine_id": 11, "name": "黄芪", "dosage": 15, "formula_type": "主方"}, {"medicine_id": 12, "name": "党参", "dosage": 12, "formula_type": "主方"}, {"medicine_id": 13, "name": "白术", "dosage": 10, "formula_type": "主方"}, {"medicine_id": 14, "name": "茯苓", "dosage": 12, "formula_type": "主方"}, {"medicine_id": 15, "name": "酸枣仁", "dosage": 9, "formula_type": "辅方"}, ], } def _show(editor: PrescriptionEditorDialog, application: QApplication) -> None: editor.show() for _ in range(5): application.processEvents() def test_editor_is_a_fixed_header_body_footer_right_drawer( application: QApplication, ) -> None: host = QWidget() host.resize(1440, 900) host.show() editor = PrescriptionEditorDialog( _repository(), _seed(), current_user=SimpleNamespace(id=7, name="陈医生"), parent=host, ) _show(editor, application) origin = host.mapToGlobal(QPoint(0, 0)) assert editor.windowFlags() & Qt.WindowType.FramelessWindowHint assert editor.width() == 1200 assert editor.height() == host.height() assert editor.x() + editor.width() == origin.x() + host.width() assert editor.y() == origin.y() assert not editor.findChildren(QTabWidget) assert editor.tabs.count() == 4 assert editor.tabs.tabText(2) == "剂型与用法" assert editor.body_scroll.verticalScrollBar().maximum() > 0 assert editor.body_scroll.horizontalScrollBar().maximum() == 0 section_tops = [section.geometry().top() for section in editor.section_widgets] assert section_tops == sorted(section_tops) assert [section.parentWidget() for section in editor.section_widgets] == [ editor.body_content ] * 5 header_y = editor.header.mapToGlobal(QPoint(0, 0)).y() footer_y = editor.footer.mapToGlobal(QPoint(0, 0)).y() editor.body_scroll.verticalScrollBar().setValue( editor.body_scroll.verticalScrollBar().maximum() ) application.processEvents() assert editor.header.mapToGlobal(QPoint(0, 0)).y() == header_y assert editor.footer.mapToGlobal(QPoint(0, 0)).y() == footer_y editor.close() host.close() application.processEvents() def test_drawer_uses_full_width_on_a_narrow_host(application: QApplication) -> None: host = QWidget() host.resize(760, 720) host.show() editor = PrescriptionEditorDialog(_repository(), _seed(), parent=host) _show(editor, application) origin = host.mapToGlobal(QPoint(0, 0)) assert editor.width() == host.width() assert editor.x() == origin.x() assert editor.body_scroll.horizontalScrollBar().maximum() == 0 assert editor.herbs._grid_columns == 3 editor.close() host.close() application.processEvents() def test_duplicate_guard_and_admin_dto_survive_the_visual_restructure( application: QApplication, ) -> None: source = _seed() source["herbs"] = [ {"medicine_id": 11, "name": "黄芪", "dosage": 15, "formula_type": "主方"}, {"medicine_id": 11, "name": " 黄芪 ", "dosage": 9, "formula_type": "辅方"}, ] editor = PrescriptionEditorDialog( _repository(), source, mode="edit", current_user=SimpleNamespace(id=7, name="陈医生"), ) editor.signature._has_strokes = True payload = editor.payload() assert payload["id"] == 502 assert payload["diagnosis_id"] == 301 assert payload["herbs"][0]["formula_type"] == "主方" assert payload["herbs"][1]["formula_type"] == "辅方" assert all(bool(row.property("duplicate")) for row in editor.herbs.rows) editor.accept() assert editor.result() == 0 assert editor.tabs.currentIndex() == 1 assert "药材不可重复:黄芪" in editor.validation.label.text() editor.close() application.processEvents() def test_locked_template_rows_keep_the_existing_mutation_contract( application: QApplication, ) -> None: source = _seed() source["herbs"] = [ { "medicine_id": 11, "name": "黄芪", "dosage": 15, "formula_type": "主方", "locked": True, } ] editor = PrescriptionEditorDialog(_repository(), source) assert editor.herbs.locked assert not editor.add_main_button.isEnabled() assert not editor.add_aux_button.isEnabled() assert editor.import_library_button.isEnabled() assert editor.paste_button.isEnabled() assert not editor.herbs.rows[0].medicine.isEnabled() assert not editor.herbs.rows[0].dosage.isEnabled() assert editor.herbs.rows[0].remove_button.isHidden() assert editor.payload()["herbs"][0]["locked"] is True editor.close() application.processEvents()