更新
This commit is contained in:
@@ -0,0 +1,149 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
os.environ.setdefault("QT_QPA_PLATFORM", "offscreen")
|
||||
|
||||
import pytest
|
||||
from PySide6.QtCore import QBuffer, QCoreApplication, QEvent, QIODevice, QPoint, Qt
|
||||
from PySide6.QtGui import QColor, QDesktopServices, QFont, QImage, QPainter
|
||||
from PySide6.QtTest import QTest
|
||||
from PySide6.QtWidgets import QApplication
|
||||
from test_diagnosis_drawer_visual import (
|
||||
ActionRepository,
|
||||
_open_dialog,
|
||||
_select_tab,
|
||||
)
|
||||
from test_diagnosis_drawer_visual import (
|
||||
application as application,
|
||||
)
|
||||
from test_diagnosis_drawer_visual import (
|
||||
immediate_async as immediate_async,
|
||||
)
|
||||
from test_diagnosis_media_thumbnail_visual import (
|
||||
_FakeManager,
|
||||
_hold_remote_load,
|
||||
_png_bytes,
|
||||
)
|
||||
|
||||
from doctor_workstation.ui.diagnosis_drawer import _RemoteImageButton
|
||||
from doctor_workstation.ui.diagnosis_media import ImagePreviewDialog
|
||||
from doctor_workstation.ui.theme import _register_preferred_cjk_fonts
|
||||
|
||||
|
||||
def _synthetic_image() -> bytes:
|
||||
image = QImage(1600, 1200, QImage.Format.Format_ARGB32)
|
||||
image.fill(QColor("#F4E3D8"))
|
||||
painter = QPainter(image)
|
||||
painter.setRenderHint(QPainter.RenderHint.Antialiasing)
|
||||
painter.setPen(Qt.PenStyle.NoPen)
|
||||
painter.setBrush(QColor("#C37B85"))
|
||||
painter.drawEllipse(440, 160, 720, 900)
|
||||
painter.setPen(QColor("#67434A"))
|
||||
painter.setFont(QFont("Arial", 36))
|
||||
painter.drawText(image.rect(), Qt.AlignmentFlag.AlignCenter, "SYNTHETIC TEST IMAGE")
|
||||
painter.end()
|
||||
buffer = QBuffer()
|
||||
assert buffer.open(QIODevice.OpenModeFlag.WriteOnly)
|
||||
assert image.save(buffer, "PNG")
|
||||
return bytes(buffer.data())
|
||||
|
||||
|
||||
@pytest.mark.parametrize("mode", ["edit", "readonly"])
|
||||
def test_real_note_thumbnail_click_keeps_drawer_and_previews_all_eight_images(
|
||||
application: QApplication, monkeypatch: pytest.MonkeyPatch, mode: str,
|
||||
) -> None:
|
||||
"""Exercise the wired drawer click, not just the standalone lightbox class."""
|
||||
monkeypatch.setattr(_RemoteImageButton, "load_url", _hold_remote_load)
|
||||
external: list[str] = []
|
||||
monkeypatch.setattr(QDesktopServices, "openUrl", lambda url: external.append(url.toString()) or True)
|
||||
application.setFont(QFont(_register_preferred_cjk_fonts(), 10))
|
||||
payload = _synthetic_image()
|
||||
|
||||
def offline_request(preview: ImagePreviewDialog, target: str) -> None:
|
||||
preview._invalidate_request()
|
||||
preview.apply_payload(payload, preview._generation)
|
||||
|
||||
monkeypatch.setattr(ImagePreviewDialog, "_request", offline_request)
|
||||
dialog = _open_dialog(application, (1440, 900), mode=mode, repository=ActionRepository())
|
||||
urls = [f"https://media.example.invalid/tongue-{index}.jpg" for index in range(8)]
|
||||
if mode == "edit":
|
||||
_select_tab(dialog, "notes")
|
||||
dialog._fill_notes([{"id": 7001, "note_date": "2026-09-08", "content": "合成测试图片", "tongue_images": urls}])
|
||||
QCoreApplication.sendPostedEvents(None, QEvent.Type.DeferredDelete)
|
||||
timeline = dialog.drawer_notes_timeline if mode == "edit" else dialog._notes_timelines[0]
|
||||
application.processEvents()
|
||||
thumbs = timeline.findChildren(_RemoteImageButton, "DiagnosisTongueThumb")
|
||||
assert len(thumbs) == 8
|
||||
for thumb in thumbs:
|
||||
assert thumb._apply_payload(payload, thumb._generation)
|
||||
original_parent = dialog.parentWidget()
|
||||
original_generation = dialog._generation
|
||||
for index in (0, 7, 3):
|
||||
QTest.mouseClick(thumbs[index], Qt.MouseButton.LeftButton, pos=QPoint(24, 32))
|
||||
application.processEvents()
|
||||
assert external == [], "Thumbnail click must not launch the system browser"
|
||||
preview = dialog._image_preview
|
||||
assert isinstance(preview, ImagePreviewDialog)
|
||||
assert preview.isVisible() and preview.parentWidget() is dialog
|
||||
assert dialog.isVisible() and dialog.parentWidget() is original_parent
|
||||
assert dialog._generation == original_generation
|
||||
assert preview.current_source == urls[index]
|
||||
assert preview.sources == urls
|
||||
assert not preview.canvas.pixmap().isNull()
|
||||
fitted_width = preview.canvas.pixmap().width()
|
||||
QTest.mouseClick(preview.zoom_button, Qt.MouseButton.LeftButton)
|
||||
assert preview.canvas.pixmap().width() == 1600 > fitted_width
|
||||
QTest.mouseClick(preview.next_button, Qt.MouseButton.LeftButton)
|
||||
assert preview.current_source == urls[(index + 1) % 8]
|
||||
QTest.mouseClick(preview.previous_button, Qt.MouseButton.LeftButton)
|
||||
assert preview.current_source == urls[index]
|
||||
if mode == "edit" and index == 7:
|
||||
output = Path(__file__).resolve().parents[2] / "artifacts/patient-render-image-fix"
|
||||
output.mkdir(parents=True, exist_ok=True)
|
||||
assert dialog.grab().save(str(output / "notes-eight-thumbnails.png"))
|
||||
QTest.mouseClick(preview.zoom_button, Qt.MouseButton.LeftButton)
|
||||
application.processEvents()
|
||||
assert preview.grab().save(str(output / "notes-image-preview.png"))
|
||||
if index == 3:
|
||||
QTest.keyClick(preview, Qt.Key.Key_Escape)
|
||||
else:
|
||||
QTest.mouseClick(preview.close_button, Qt.MouseButton.LeftButton)
|
||||
application.processEvents()
|
||||
assert dialog.isVisible() and timeline.isVisible()
|
||||
assert dialog._image_preview is None
|
||||
QCoreApplication.sendPostedEvents(None, QEvent.Type.DeferredDelete)
|
||||
assert external == []
|
||||
QTest.mouseClick(thumbs[4], Qt.MouseButton.LeftButton, pos=QPoint(24, 32))
|
||||
preview = dialog._image_preview
|
||||
QTest.mouseClick(preview.external_button, Qt.MouseButton.LeftButton)
|
||||
assert external == [urls[4]]
|
||||
dialog.reject()
|
||||
application.processEvents()
|
||||
assert dialog._image_preview is None
|
||||
|
||||
|
||||
@pytest.mark.parametrize("close_with_escape", [False, True])
|
||||
def test_preview_close_cancels_pending_response(
|
||||
application: QApplication, monkeypatch: pytest.MonkeyPatch, close_with_escape: bool,
|
||||
) -> None:
|
||||
monkeypatch.setattr(ImagePreviewDialog, "_request", lambda self, target: None)
|
||||
preview = ImagePreviewDialog(["https://media.example.invalid/pending.jpg"])
|
||||
manager = _FakeManager(preview)
|
||||
manager.queue(_png_bytes(80, 60))
|
||||
preview._manager = manager
|
||||
monkeypatch.undo()
|
||||
preview.reload_current()
|
||||
reply = manager.replies[-1]
|
||||
generation = preview._generation
|
||||
preview.show()
|
||||
if close_with_escape:
|
||||
QTest.keyClick(preview, Qt.Key.Key_Escape)
|
||||
else:
|
||||
QTest.mouseClick(preview.close_button, Qt.MouseButton.LeftButton)
|
||||
assert reply.aborted
|
||||
assert preview._generation > generation
|
||||
reply.finished.emit()
|
||||
assert preview._pixmap.isNull()
|
||||
application.processEvents()
|
||||
Reference in New Issue
Block a user