""" Tests for SizeOperationsMixin """ import pytest from unittest.mock import Mock, patch from PyQt6.QtWidgets import QMainWindow from pyPhotoAlbum.mixins.operations.size_ops import SizeOperationsMixin from pyPhotoAlbum.models import ImageData from pyPhotoAlbum.commands import CommandHistory class TestSizeWindow(SizeOperationsMixin, QMainWindow): """Test window with size operations mixin""" def __init__(self): super().__init__() self.gl_widget = Mock() self.gl_widget.selected_elements = set() self.project = Mock() self.project.history = CommandHistory() self._update_view_called = False self._status_message = None self._warning_message = None self._require_selection_count = None def require_selection(self, min_count=1): self._require_selection_count = min_count return len(self.gl_widget.selected_elements) >= min_count def get_current_page(self): if hasattr(self, '_current_page'): return self._current_page return None def update_view(self): self._update_view_called = True def show_status(self, message, timeout=0): self._status_message = message def show_warning(self, title, message): self._warning_message = message class TestMakeSameSize: """Test make_same_size method""" @patch('pyPhotoAlbum.mixins.operations.size_ops.AlignmentManager') def test_make_same_size_success(self, mock_manager, qtbot): window = TestSizeWindow() qtbot.addWidget(window) element1 = ImageData(image_path="/test1.jpg", x=0, y=0, width=100, height=100) element2 = ImageData(image_path="/test2.jpg", x=150, y=0, width=200, height=150) window.gl_widget.selected_elements = {element1, element2} mock_manager.make_same_size.return_value = [ (element1, (0, 0), (100, 100)), (element2, (150, 0), (200, 150)) ] window.make_same_size() assert mock_manager.make_same_size.called assert window._update_view_called assert "same size" in window._status_message.lower() def test_make_same_size_insufficient_selection(self, qtbot): window = TestSizeWindow() qtbot.addWidget(window) element1 = ImageData(image_path="/test1.jpg", x=0, y=0, width=100, height=100) window.gl_widget.selected_elements = {element1} window.make_same_size() assert window._require_selection_count == 2 assert not window._update_view_called class TestMakeSameWidth: """Test make_same_width method""" @patch('pyPhotoAlbum.mixins.operations.size_ops.AlignmentManager') def test_make_same_width_success(self, mock_manager, qtbot): window = TestSizeWindow() qtbot.addWidget(window) element1 = ImageData(image_path="/test1.jpg", x=0, y=0, width=100, height=100) element2 = ImageData(image_path="/test2.jpg", x=150, y=0, width=200, height=150) window.gl_widget.selected_elements = {element1, element2} mock_manager.make_same_width.return_value = [ (element1, (0, 0), (100, 100)), (element2, (150, 0), (200, 150)) ] window.make_same_width() assert mock_manager.make_same_width.called assert window._update_view_called assert "same width" in window._status_message.lower() class TestMakeSameHeight: """Test make_same_height method""" @patch('pyPhotoAlbum.mixins.operations.size_ops.AlignmentManager') def test_make_same_height_success(self, mock_manager, qtbot): window = TestSizeWindow() qtbot.addWidget(window) element1 = ImageData(image_path="/test1.jpg", x=0, y=0, width=100, height=100) element2 = ImageData(image_path="/test2.jpg", x=150, y=0, width=200, height=150) window.gl_widget.selected_elements = {element1, element2} mock_manager.make_same_height.return_value = [ (element1, (0, 0), (100, 100)), (element2, (150, 0), (200, 150)) ] window.make_same_height() assert mock_manager.make_same_height.called assert window._update_view_called assert "same height" in window._status_message.lower() class TestFitToWidth: """Test fit_to_width method""" @patch('pyPhotoAlbum.mixins.operations.size_ops.AlignmentManager') def test_fit_to_width_success(self, mock_manager, qtbot): window = TestSizeWindow() qtbot.addWidget(window) element = ImageData(image_path="/test.jpg", x=50, y=50, width=100, height=100) window.gl_widget.selected_elements = {element} # Setup page page = Mock() page.size = (210, 297) # A4 window._current_page = page mock_manager.fit_to_page_width.return_value = (element, (50, 50), (100, 100)) window.fit_to_width() assert mock_manager.fit_to_page_width.called assert window._update_view_called assert "width" in window._status_message.lower() def test_fit_to_width_no_page(self, qtbot): window = TestSizeWindow() qtbot.addWidget(window) element = ImageData(image_path="/test.jpg", x=50, y=50, width=100, height=100) window.gl_widget.selected_elements = {element} window._current_page = None window.fit_to_width() assert "page" in window._warning_message.lower() assert not window._update_view_called class TestFitToHeight: """Test fit_to_height method""" @patch('pyPhotoAlbum.mixins.operations.size_ops.AlignmentManager') def test_fit_to_height_success(self, mock_manager, qtbot): window = TestSizeWindow() qtbot.addWidget(window) element = ImageData(image_path="/test.jpg", x=50, y=50, width=100, height=100) window.gl_widget.selected_elements = {element} page = Mock() page.size = (210, 297) window._current_page = page mock_manager.fit_to_page_height.return_value = (element, (50, 50), (100, 100)) window.fit_to_height() assert mock_manager.fit_to_page_height.called assert window._update_view_called assert "height" in window._status_message.lower() class TestFitToPage: """Test fit_to_page method""" @patch('pyPhotoAlbum.mixins.operations.size_ops.AlignmentManager') def test_fit_to_page_success(self, mock_manager, qtbot): window = TestSizeWindow() qtbot.addWidget(window) element = ImageData(image_path="/test.jpg", x=50, y=50, width=100, height=100) window.gl_widget.selected_elements = {element} page = Mock() page.size = (210, 297) window._current_page = page mock_manager.fit_to_page.return_value = (element, (50, 50), (100, 100)) window.fit_to_page() assert mock_manager.fit_to_page.called assert window._update_view_called assert "fitted element to page" in window._status_message.lower() def test_fit_to_page_no_page(self, qtbot): window = TestSizeWindow() qtbot.addWidget(window) element = ImageData(image_path="/test.jpg", x=50, y=50, width=100, height=100) window.gl_widget.selected_elements = {element} window._current_page = None window.fit_to_page() assert "page" in window._warning_message.lower() assert not window._update_view_called class TestSizeCommandPattern: """Test size operations with command pattern""" @patch('pyPhotoAlbum.mixins.operations.size_ops.AlignmentManager') def test_size_operation_creates_command(self, mock_manager, qtbot): window = TestSizeWindow() qtbot.addWidget(window) element1 = ImageData(image_path="/test1.jpg", x=0, y=0, width=100, height=100) element2 = ImageData(image_path="/test2.jpg", x=150, y=0, width=200, height=150) window.gl_widget.selected_elements = {element1, element2} mock_manager.make_same_size.return_value = [ (element1, (0, 0), (100, 100)), (element2, (150, 0), (200, 150)) ] assert not window.project.history.can_undo() window.make_same_size() assert window.project.history.can_undo() @patch('pyPhotoAlbum.mixins.operations.size_ops.AlignmentManager') def test_fit_operation_creates_command(self, mock_manager, qtbot): window = TestSizeWindow() qtbot.addWidget(window) element = ImageData(image_path="/test.jpg", x=50, y=50, width=100, height=100) window.gl_widget.selected_elements = {element} page = Mock() page.size = (210, 297) window._current_page = page mock_manager.fit_to_page.return_value = (element, (50, 50), (100, 100)) assert not window.project.history.can_undo() window.fit_to_page() assert window.project.history.can_undo()