"""Tests for imageOptimization function.""" import pytest from pathlib import Path from unittest.mock import Mock, MagicMock, patch from PIL import Image import numpy as np from pptopic.lib import imageOptimization class TestImageOptimization: """Test imageOptimization function.""" @patch('pptopic.lib.Image.open') @patch('pptopic.lib.cv2.cvtColor') @patch('pptopic.lib.cv2.resize') @patch('pptopic.lib.subprocess.run') @patch('pptopic.lib.lastFile') def test_image_optimization_with_file_path(self, mock_last_file, mock_subprocess, mock_resize, mock_cvtcolor, mock_open, tmp_path): """Test imageOptimization with file path input.""" mock_img = MagicMock() mock_img.size = (100, 100) mock_img.mode = 'RGB' mock_open.return_value = mock_img mock_array = np.array([[[255, 0, 0]]]) mock_cvtcolor.return_value = mock_array mock_resized = np.array([[[255, 0, 0]]]) mock_resize.return_value = mock_resized mock_pil_img = MagicMock() with patch('pptopic.lib.Image.fromarray', return_value=mock_pil_img): with patch('pptopic.lib.Image.open', return_value=mock_img): mock_last_file.return_value = tmp_path / "optimized.png" result = imageOptimization(tmp_path / "test.png") assert result is not None @patch('pptopic.lib.cv2.cvtColor') @patch('pptopic.lib.cv2.resize') @patch('pptopic.lib.subprocess.run') @patch('pptopic.lib.lastFile') def test_image_optimization_with_pil_image(self, mock_last_file, mock_subprocess, mock_resize, mock_cvtcolor, tmp_path): """Test imageOptimization with PIL Image input.""" mock_img = MagicMock() mock_img.size = (100, 100) mock_img.mode = 'RGB' mock_array = np.array([[[255, 0, 0]]]) mock_cvtcolor.return_value = mock_array mock_resized = np.array([[[255, 0, 0]]]) mock_resize.return_value = mock_resized mock_pil_img = MagicMock() with patch('pptopic.lib.Image.fromarray', return_value=mock_pil_img): with patch('pptopic.lib.Image.open', return_value=mock_img): mock_last_file.return_value = tmp_path / "optimized.png" result = imageOptimization(mock_img) assert result is not None @patch('pptopic.lib.Image.open') @patch('pptopic.lib.cv2.cvtColor') @patch('pptopic.lib.cv2.resize') @patch('pptopic.lib.subprocess.run') @patch('pptopic.lib.shutil.copyfile') def test_image_optimization_with_save_file(self, mock_copyfile, mock_subprocess, mock_resize, mock_cvtcolor, mock_open, tmp_path): """Test imageOptimization with saveFile parameter.""" mock_img = MagicMock() mock_img.size = (100, 100) mock_img.mode = 'RGB' mock_open.return_value = mock_img mock_array = np.array([[[255, 0, 0]]]) mock_cvtcolor.return_value = mock_array mock_resized = np.array([[[255, 0, 0]]]) mock_resize.return_value = mock_resized mock_pil_img = MagicMock() with patch('pptopic.lib.Image.fromarray', return_value=mock_pil_img): with patch('pptopic.lib.lastFile') as mock_last_file: mock_last_file.return_value = tmp_path / "optimized.png" result = imageOptimization(tmp_path / "test.png", saveFile=tmp_path / "output.png") assert result is None mock_copyfile.assert_called_once() @patch('pptopic.lib.Image.open') @patch('pptopic.lib.cv2.cvtColor') @patch('pptopic.lib.cv2.resize') @patch('pptopic.lib.subprocess.run') @patch('pptopic.lib.lastFile') def test_image_optimization_with_max_width(self, mock_last_file, mock_subprocess, mock_resize, mock_cvtcolor, mock_open, tmp_path): """Test imageOptimization with max_width parameter.""" mock_img = MagicMock() mock_img.size = (200, 100) mock_img.mode = 'RGB' mock_open.return_value = mock_img mock_array = np.zeros((100, 200, 3), dtype=np.uint8) mock_cvtcolor.return_value = mock_array mock_resized = np.zeros((50, 100, 3), dtype=np.uint8) mock_resize.return_value = mock_resized mock_pil_img = MagicMock() with patch('pptopic.lib.Image.fromarray', return_value=mock_pil_img): with patch('pptopic.lib.Image.open', return_value=mock_img): mock_last_file.return_value = tmp_path / "optimized.png" result = imageOptimization(tmp_path / "test.png", max_width=100) mock_resize.assert_called_once() assert result is not None @patch('pptopic.lib.Image.open') @patch('pptopic.lib.cv2.cvtColor') @patch('pptopic.lib.cv2.resize') @patch('pptopic.lib.subprocess.run') @patch('pptopic.lib.lastFile') def test_image_optimization_with_max_height(self, mock_last_file, mock_subprocess, mock_resize, mock_cvtcolor, mock_open, tmp_path): """Test imageOptimization with max_height parameter.""" mock_img = MagicMock() mock_img.size = (100, 200) mock_img.mode = 'RGB' mock_open.return_value = mock_img mock_array = np.zeros((200, 100, 3), dtype=np.uint8) mock_cvtcolor.return_value = mock_array mock_resized = np.zeros((100, 50, 3), dtype=np.uint8) mock_resize.return_value = mock_resized mock_pil_img = MagicMock() with patch('pptopic.lib.Image.fromarray', return_value=mock_pil_img): with patch('pptopic.lib.Image.open', return_value=mock_img): mock_last_file.return_value = tmp_path / "optimized.png" result = imageOptimization(tmp_path / "test.png", max_height=100) mock_resize.assert_called_once() assert result is not None @patch('pptopic.lib.Image.open') @patch('pptopic.lib.cv2.cvtColor') @patch('pptopic.lib.cv2.resize') @patch('pptopic.lib.subprocess.run') @patch('pptopic.lib.lastFile') def test_image_optimization_with_fractional_width(self, mock_last_file, mock_subprocess, mock_resize, mock_cvtcolor, mock_open, tmp_path): """Test imageOptimization with fractional max_width (< 1).""" mock_img = MagicMock() mock_img.size = (200, 100) mock_img.mode = 'RGB' mock_open.return_value = mock_img mock_array = np.zeros((100, 200, 3), dtype=np.uint8) mock_cvtcolor.return_value = mock_array mock_resized = np.zeros((50, 100, 3), dtype=np.uint8) mock_resize.return_value = mock_resized mock_pil_img = MagicMock() with patch('pptopic.lib.Image.fromarray', return_value=mock_pil_img): with patch('pptopic.lib.Image.open', return_value=mock_img): mock_last_file.return_value = tmp_path / "optimized.png" result = imageOptimization(tmp_path / "test.png", max_width=0.5) mock_resize.assert_called_once() assert result is not None @patch('pptopic.lib.Image.open') @patch('pptopic.lib.cv2.cvtColor') @patch('pptopic.lib.subprocess.run') @patch('pptopic.lib.lastFile') def test_image_optimization_without_engine(self, mock_last_file, mock_subprocess, mock_cvtcolor, mock_open, tmp_path): """Test imageOptimization with engine=None.""" mock_img = MagicMock() mock_img.size = (100, 100) mock_img.mode = 'RGB' mock_open.return_value = mock_img mock_array = np.array([[[255, 0, 0]]]) mock_cvtcolor.return_value = mock_array mock_pil_img = MagicMock() with patch('pptopic.lib.Image.fromarray', return_value=mock_pil_img): with patch('pptopic.lib.Image.open', return_value=mock_img): mock_last_file.return_value = tmp_path / "optimized.png" result = imageOptimization(tmp_path / "test.png", engine=None) mock_subprocess.assert_not_called() assert result is not None @patch('pptopic.lib.Image.open') @patch('pptopic.lib.cv2.cvtColor') @patch('pptopic.lib.subprocess.run') def test_image_optimization_engine_failure(self, mock_subprocess, mock_cvtcolor, mock_open): """Test imageOptimization when engine subprocess fails.""" mock_img = MagicMock() mock_img.size = (100, 100) mock_img.mode = 'RGB' mock_open.return_value = mock_img mock_array = np.array([[[255, 0, 0]]]) mock_cvtcolor.return_value = mock_array mock_subprocess.side_effect = Exception("Engine not found") mock_pil_img = MagicMock() with patch('pptopic.lib.Image.fromarray', return_value=mock_pil_img): with pytest.raises(Exception): imageOptimization("test.png", engine="pngquant", engine_conf="--quality=85")