from __future__ import annotations import pytest from PySide6.QtGui import QPalette from PySide6.QtWidgets import QApplication, QPushButton from doctor_workstation.core import PermissionSet from doctor_workstation.ui.pages import reception as reception_module from doctor_workstation.ui.pages.reception import ReceptionDailyRecordsPanel, ReceptionPage from doctor_workstation.ui.theme import COLORS, apply_theme @pytest.fixture(scope="module") def application(): app = QApplication.instance() or QApplication([]) apply_theme(app) return app def settle(app): for _ in range(6): app.processEvents() @pytest.fixture def page(application, monkeypatch): monkeypatch.setattr(reception_module, "run_async", lambda *_args, **_kwargs: None) widget = ReceptionPage(object(), PermissionSet([])) widget.resize(1080, 760) widget.show() widget.poll_timer.stop() widget.detail_stack.setCurrentIndex(1) settle(application) yield widget widget.close() widget.deleteLater() settle(application) def test_reception_prompts_remain_readable_in_a_narrow_workspace(page, application): settle(application) for button in page.ai_prompt_buttons: assert button.width() >= button.minimumSizeHint().width() assert button.parentWidget().rect().contains(button.geometry()) analysis = page.ai_analysis_card.geometry() assistant = page.ai_assistant_card.geometry() assert assistant.top() > analysis.bottom() def test_hidden_tall_consultation_does_not_expand_daily_records(page, application): page.detail_tabs.setCurrentIndex(0) settle(application) consultation_height = page.clinical_pages.height() page.detail_tabs.setCurrentIndex(3) settle(application) assert page.clinical_pages.height() < consultation_height - 80 def test_short_risk_labels_stay_on_one_line(page, application): page._render_ai_risk_chips([{"label": "血糖波动风险", "level": "medium"}]) page.ai_analysis_stack.setCurrentWidget(page.ai_analysis_content_page) settle(application) chip = page.ai_risk_chip_layout.itemAt(0).widget() assert chip.width() >= chip.fontMetrics().horizontalAdvance(chip.text()) + 18 def test_seven_day_matrix_fits_readable_columns_without_unnecessary_horizontal_scroll(application): panel = ReceptionDailyRecordsPanel() panel.resize(900, 580) panel.set_data({}, []) panel.show() settle(application) try: assert panel.matrix.columnCount() == 8 assert panel.matrix.horizontalScrollBar().maximum() == 0 assert all(panel.matrix.columnWidth(i) >= 96 for i in range(1, 8)) panel.range_buttons["30"].click() panel.set_data({}, []) settle(application) assert panel.matrix.columnCount() == 31 assert panel.matrix.horizontalScrollBar().maximum() > 0 assert panel.matrix.columnWidth(1) >= 96 finally: panel.close() @pytest.mark.parametrize("variant", ["secondary", "success", "warning", "danger", "link"]) def test_disabled_semantic_buttons_do_not_look_actionable(application, variant): button = QPushButton("查看记录") button.setProperty("variant", variant) button.setEnabled(False) button.ensurePolished() assert button.palette().color(QPalette.ColorGroup.Disabled, QPalette.ColorRole.ButtonText).name() == COLORS["disabled_text"].lower() button.close()