"""Unit tests for image validation logic.""" from unittest.mock import MagicMock from PIL import Image import pytest from constants import errors from constants import image_standards from src import image_validation_logic from src import image_validator @pytest.fixture def file_contents(): """Return a mock file buffer.""" return MagicMock() @pytest.fixture def pil_image(): """Return a mock PIL image.""" pil_image_mock = MagicMock( mode='Depeche', size=(3000, 3000), ) return pil_image_mock def test_validate_image_success(file_contents, monkeypatch, pil_image): """Test for a successful return when all validations pass.""" monkeypatch.setattr(Image, 'open', MagicMock(return_value=pil_image)) monkeypatch.setattr( image_validator, 'validate_mode', MagicMock(return_value=True) ) monkeypatch.setattr( image_validator, 'validate_is_opaque', MagicMock(return_value=True) ) monkeypatch.setattr( image_validator, 'validate_dimensions', MagicMock(return_value=image_standards.VALID_DIMENSIONS_CODE) ) result = image_validation_logic.validate_image( file_contents=file_contents ) image_validator.validate_mode.assert_called_with(pil_image.mode) image_validator.validate_dimensions.assert_called_with( width=pil_image.size[0], height=pil_image.size[1], ) assert result is True @pytest.mark.parametrize('error_code', [ errors.IMAGE_TOO_SMALL_DIMENSIONS_CODE, errors.IMAGE_TOO_LARGE_DIMENSIONS_CODE, errors.IMAGE_WRONG_ASPECT_RATIO_CODE ]) def test_validate_image_wrong_dimensions( file_contents, monkeypatch, pil_image, error_code): """Test that validation fails if the dimensions are wrong.""" monkeypatch.setattr(Image, 'open', MagicMock(return_value=pil_image)) monkeypatch.setattr( image_validator, 'validate_mode', MagicMock(return_value=True) ) monkeypatch.setattr( image_validator, 'validate_is_opaque', MagicMock(return_value=True) ) monkeypatch.setattr( image_validator, 'validate_dimensions', MagicMock(return_value=error_code) ) with pytest.raises(image_validation_logic.InvalidImageError) as e: image_validation_logic.validate_image( file_contents=file_contents ) width, height = pil_image.size image_validator.validate_dimensions.assert_called_once_with( width=width, height=height, ) assert str(e.value) == errors.ERROR_MESSAGES[error_code] assert e.value.code == error_code def test_validate_image_bad_mode(file_contents, monkeypatch, pil_image): """Test that validation fails if the mode validation fails.""" monkeypatch.setattr(Image, 'open', MagicMock(return_value=pil_image)) monkeypatch.setattr( image_validator, 'validate_mode', MagicMock(return_value=False) ) with pytest.raises(image_validation_logic.InvalidImageError) as e: image_validation_logic.validate_image( file_contents=file_contents ) assert str(e.value) == errors.ERROR_MESSAGES[errors.IMAGE_INVALID_MODE_CODE].format( mode=pil_image.mode ) assert e.value.code == errors.IMAGE_INVALID_MODE_CODE def test_validate_image_not_opaque(file_contents, monkeypatch, pil_image): """Test that validation fails if the image is not opaque.""" monkeypatch.setattr(Image, 'open', MagicMock(return_value=pil_image)) monkeypatch.setattr( image_validator, 'validate_mode', MagicMock(return_value=True) ) monkeypatch.setattr( image_validator, 'validate_is_opaque', MagicMock(return_value=False) ) with pytest.raises(image_validation_logic.InvalidImageError) as e: image_validation_logic.validate_image( file_contents=file_contents ) assert str(e.value) == errors.ERROR_MESSAGES[errors.IMAGE_NOT_OPAQUE_CODE] assert e.value.code == errors.IMAGE_NOT_OPAQUE_CODE