204 lines
6.4 KiB
Python
204 lines
6.4 KiB
Python
"""
|
|
Tests for ViewportMixin
|
|
"""
|
|
|
|
import pytest
|
|
from unittest.mock import Mock, MagicMock, patch
|
|
from PyQt6.QtWidgets import QApplication
|
|
from PyQt6.QtOpenGLWidgets import QOpenGLWidget
|
|
from pyPhotoAlbum.mixins.viewport import ViewportMixin
|
|
from pyPhotoAlbum.project import Project, Page
|
|
from pyPhotoAlbum.page_layout import PageLayout
|
|
|
|
|
|
# Create a minimal test widget class
|
|
class TestViewportWidget(ViewportMixin, QOpenGLWidget):
|
|
"""Test widget combining ViewportMixin with QOpenGLWidget"""
|
|
pass
|
|
|
|
|
|
class TestViewportMixinInitialization:
|
|
"""Test ViewportMixin initialization"""
|
|
|
|
def test_initialization_sets_defaults(self, qtbot):
|
|
"""Test that mixin initializes with correct defaults"""
|
|
widget = TestViewportWidget()
|
|
qtbot.addWidget(widget)
|
|
|
|
assert widget.zoom_level == 1.0
|
|
assert widget.pan_offset == [0, 0]
|
|
assert widget.initial_zoom_set is False
|
|
|
|
def test_zoom_level_is_mutable(self, qtbot):
|
|
"""Test that zoom level can be changed"""
|
|
widget = TestViewportWidget()
|
|
qtbot.addWidget(widget)
|
|
|
|
widget.zoom_level = 1.5
|
|
assert widget.zoom_level == 1.5
|
|
|
|
def test_pan_offset_is_mutable(self, qtbot):
|
|
"""Test that pan offset can be changed"""
|
|
widget = TestViewportWidget()
|
|
qtbot.addWidget(widget)
|
|
|
|
widget.pan_offset = [100, 50]
|
|
assert widget.pan_offset == [100, 50]
|
|
|
|
|
|
class TestViewportCalculations:
|
|
"""Test viewport zoom calculations"""
|
|
|
|
def test_calculate_fit_to_screen_no_project(self, qtbot):
|
|
"""Test fit-to-screen with no project returns 1.0"""
|
|
widget = TestViewportWidget()
|
|
qtbot.addWidget(widget)
|
|
widget.resize(800, 600)
|
|
|
|
# Mock window() to return a window without project
|
|
mock_window = Mock()
|
|
mock_window.project = None
|
|
widget.window = Mock(return_value=mock_window)
|
|
|
|
zoom = widget._calculate_fit_to_screen_zoom()
|
|
assert zoom == 1.0
|
|
|
|
def test_calculate_fit_to_screen_empty_project(self, qtbot):
|
|
"""Test fit-to-screen with empty project returns 1.0"""
|
|
widget = TestViewportWidget()
|
|
qtbot.addWidget(widget)
|
|
widget.resize(800, 600)
|
|
|
|
# Mock window() to return a window with empty project
|
|
mock_window = Mock()
|
|
mock_window.project = Project(name="Empty")
|
|
mock_window.project.pages = []
|
|
widget.window = Mock(return_value=mock_window)
|
|
|
|
zoom = widget._calculate_fit_to_screen_zoom()
|
|
assert zoom == 1.0
|
|
|
|
def test_calculate_fit_to_screen_with_page(self, qtbot):
|
|
"""Test fit-to-screen calculates correct zoom for A4 page"""
|
|
widget = TestViewportWidget()
|
|
qtbot.addWidget(widget)
|
|
widget.resize(1000, 800)
|
|
|
|
# Mock window with project and A4 page
|
|
mock_window = Mock()
|
|
mock_window.project = Project(name="Test")
|
|
mock_window.project.working_dpi = 96
|
|
|
|
# A4 page: 210mm x 297mm
|
|
page = Page(
|
|
layout=PageLayout(width=210, height=297),
|
|
page_number=1
|
|
)
|
|
mock_window.project.pages = [page]
|
|
|
|
widget.window = Mock(return_value=mock_window)
|
|
|
|
zoom = widget._calculate_fit_to_screen_zoom()
|
|
|
|
# Calculate expected zoom
|
|
# A4 at 96 DPI: width=794px, height=1123px
|
|
# Window: 1000x800, margins: 100px each side
|
|
# Available: 800x600
|
|
# zoom_w = 800/794 ≈ 1.007, zoom_h = 600/1123 ≈ 0.534
|
|
# Should use min(zoom_w, zoom_h, 1.0) = 0.534
|
|
|
|
assert 0.5 < zoom < 0.6 # Approximately 0.534
|
|
assert zoom <= 1.0 # Never zoom beyond 100%
|
|
|
|
def test_calculate_fit_to_screen_small_window(self, qtbot):
|
|
"""Test fit-to-screen with small window returns small zoom"""
|
|
widget = TestViewportWidget()
|
|
qtbot.addWidget(widget)
|
|
widget.resize(400, 300) # Small window
|
|
|
|
mock_window = Mock()
|
|
mock_window.project = Project(name="Test")
|
|
mock_window.project.working_dpi = 96
|
|
|
|
page = Page(
|
|
layout=PageLayout(width=210, height=297),
|
|
page_number=1
|
|
)
|
|
mock_window.project.pages = [page]
|
|
|
|
widget.window = Mock(return_value=mock_window)
|
|
|
|
zoom = widget._calculate_fit_to_screen_zoom()
|
|
|
|
# With 400x300 window and 200px margins, available space is 200x100
|
|
# This should produce a very small zoom
|
|
assert zoom < 0.3
|
|
|
|
def test_calculate_fit_to_screen_large_window(self, qtbot):
|
|
"""Test fit-to-screen with large window caps at 1.0"""
|
|
widget = TestViewportWidget()
|
|
qtbot.addWidget(widget)
|
|
widget.resize(3000, 2000) # Very large window
|
|
|
|
mock_window = Mock()
|
|
mock_window.project = Project(name="Test")
|
|
mock_window.project.working_dpi = 96
|
|
|
|
page = Page(
|
|
layout=PageLayout(width=210, height=297),
|
|
page_number=1
|
|
)
|
|
mock_window.project.pages = [page]
|
|
|
|
widget.window = Mock(return_value=mock_window)
|
|
|
|
zoom = widget._calculate_fit_to_screen_zoom()
|
|
|
|
# Even with huge window, zoom should not exceed 1.0
|
|
assert zoom == 1.0
|
|
|
|
def test_calculate_fit_to_screen_different_dpi(self, qtbot):
|
|
"""Test fit-to-screen respects different DPI values"""
|
|
widget = TestViewportWidget()
|
|
qtbot.addWidget(widget)
|
|
widget.resize(1000, 800)
|
|
|
|
mock_window = Mock()
|
|
mock_window.project = Project(name="Test")
|
|
mock_window.project.working_dpi = 300 # High DPI
|
|
|
|
page = Page(
|
|
layout=PageLayout(width=210, height=297),
|
|
page_number=1
|
|
)
|
|
mock_window.project.pages = [page]
|
|
|
|
widget.window = Mock(return_value=mock_window)
|
|
|
|
zoom = widget._calculate_fit_to_screen_zoom()
|
|
|
|
# At 300 DPI, page is much larger in pixels
|
|
# So zoom should be smaller
|
|
assert zoom < 0.3
|
|
|
|
|
|
class TestViewportOpenGL:
|
|
"""Test OpenGL-related viewport methods"""
|
|
|
|
def test_initializeGL_sets_clear_color(self, qtbot):
|
|
"""Test that initializeGL is callable (actual GL testing is integration)"""
|
|
widget = TestViewportWidget()
|
|
qtbot.addWidget(widget)
|
|
|
|
# Just verify the method exists and is callable
|
|
assert hasattr(widget, 'initializeGL')
|
|
assert callable(widget.initializeGL)
|
|
|
|
def test_resizeGL_is_callable(self, qtbot):
|
|
"""Test that resizeGL is callable"""
|
|
widget = TestViewportWidget()
|
|
qtbot.addWidget(widget)
|
|
|
|
assert hasattr(widget, 'resizeGL')
|
|
assert callable(widget.resizeGL)
|