""" Tests for DistributionOperationsMixin """ import pytest from unittest.mock import Mock, patch from PyQt6.QtWidgets import QMainWindow from pyPhotoAlbum.mixins.operations.distribution_ops import DistributionOperationsMixin from pyPhotoAlbum.models import ImageData from pyPhotoAlbum.commands import CommandHistory class TestDistributionWindow(DistributionOperationsMixin, QMainWindow): """Test window with distribution 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._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 update_view(self): self._update_view_called = True def show_status(self, message, timeout=0): self._status_message = message class TestGetSelectedElementsList: """Test _get_selected_elements_list helper""" def test_get_selected_elements_list(self, qtbot): window = TestDistributionWindow() qtbot.addWidget(window) element1 = ImageData(image_path="/test1.jpg", x=0, y=0, width=100, height=100) element2 = ImageData(image_path="/test2.jpg", x=100, y=100, width=100, height=100) element3 = ImageData(image_path="/test3.jpg", x=200, y=200, width=100, height=100) window.gl_widget.selected_elements = {element1, element2, element3} result = window._get_selected_elements_list() assert isinstance(result, list) assert len(result) == 3 class TestDistributeHorizontally: """Test distribute_horizontally method""" @patch('pyPhotoAlbum.mixins.operations.distribution_ops.AlignmentManager') def test_distribute_horizontally_success(self, mock_manager, qtbot): window = TestDistributionWindow() 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=100, height=100) element3 = ImageData(image_path="/test3.jpg", x=500, y=0, width=100, height=100) window.gl_widget.selected_elements = {element1, element2, element3} mock_manager.distribute_horizontally.return_value = [ (element1, (0, 0)), (element2, (150, 0)), (element3, (500, 0)) ] window.distribute_horizontally() assert mock_manager.distribute_horizontally.called assert window._update_view_called assert "distributed" in window._status_message.lower() assert "horizontally" in window._status_message.lower() def test_distribute_horizontally_insufficient_selection(self, qtbot): window = TestDistributionWindow() qtbot.addWidget(window) element1 = ImageData(image_path="/test1.jpg", x=0, y=0, width=100, height=100) element2 = ImageData(image_path="/test2.jpg", x=100, y=100, width=100, height=100) window.gl_widget.selected_elements = {element1, element2} window.distribute_horizontally() assert window._require_selection_count == 3 assert not window._update_view_called class TestDistributeVertically: """Test distribute_vertically method""" @patch('pyPhotoAlbum.mixins.operations.distribution_ops.AlignmentManager') def test_distribute_vertically_success(self, mock_manager, qtbot): window = TestDistributionWindow() qtbot.addWidget(window) element1 = ImageData(image_path="/test1.jpg", x=0, y=0, width=100, height=100) element2 = ImageData(image_path="/test2.jpg", x=0, y=150, width=100, height=100) element3 = ImageData(image_path="/test3.jpg", x=0, y=500, width=100, height=100) window.gl_widget.selected_elements = {element1, element2, element3} mock_manager.distribute_vertically.return_value = [ (element1, (0, 0)), (element2, (0, 150)), (element3, (0, 500)) ] window.distribute_vertically() assert mock_manager.distribute_vertically.called assert window._update_view_called assert "vertically" in window._status_message.lower() class TestSpaceHorizontally: """Test space_horizontally method""" @patch('pyPhotoAlbum.mixins.operations.distribution_ops.AlignmentManager') def test_space_horizontally_success(self, mock_manager, qtbot): window = TestDistributionWindow() qtbot.addWidget(window) element1 = ImageData(image_path="/test1.jpg", x=0, y=0, width=100, height=100) element2 = ImageData(image_path="/test2.jpg", x=100, y=0, width=100, height=100) element3 = ImageData(image_path="/test3.jpg", x=200, y=0, width=100, height=100) window.gl_widget.selected_elements = {element1, element2, element3} mock_manager.space_horizontally.return_value = [ (element1, (0, 0)), (element2, (100, 0)), (element3, (200, 0)) ] window.space_horizontally() assert mock_manager.space_horizontally.called assert window._update_view_called assert "spaced" in window._status_message.lower() class TestSpaceVertically: """Test space_vertically method""" @patch('pyPhotoAlbum.mixins.operations.distribution_ops.AlignmentManager') def test_space_vertically_success(self, mock_manager, qtbot): window = TestDistributionWindow() qtbot.addWidget(window) element1 = ImageData(image_path="/test1.jpg", x=0, y=0, width=100, height=100) element2 = ImageData(image_path="/test2.jpg", x=0, y=100, width=100, height=100) element3 = ImageData(image_path="/test3.jpg", x=0, y=200, width=100, height=100) window.gl_widget.selected_elements = {element1, element2, element3} mock_manager.space_vertically.return_value = [ (element1, (0, 0)), (element2, (0, 100)), (element3, (0, 200)) ] window.space_vertically() assert mock_manager.space_vertically.called assert window._update_view_called class TestDistributionCommandPattern: """Test distribution operations with command pattern""" @patch('pyPhotoAlbum.mixins.operations.distribution_ops.AlignmentManager') def test_distribution_creates_command(self, mock_manager, qtbot): window = TestDistributionWindow() qtbot.addWidget(window) element1 = ImageData(image_path="/test1.jpg", x=0, y=0, width=100, height=100) element2 = ImageData(image_path="/test2.jpg", x=100, y=0, width=100, height=100) element3 = ImageData(image_path="/test3.jpg", x=200, y=0, width=100, height=100) window.gl_widget.selected_elements = {element1, element2, element3} mock_manager.distribute_horizontally.return_value = [ (element1, (0, 0)), (element2, (100, 0)), (element3, (200, 0)) ] assert not window.project.history.can_undo() window.distribute_horizontally() assert window.project.history.can_undo()