Spaces:
Running
Running
| from unittest.mock import patch | |
| import pytest | |
| from app.services.cloudinary_service import ( | |
| delete_image, | |
| optimize_delivery_image_url, | |
| optimize_delivery_image_urls, | |
| upload_image, | |
| ) | |
| def mock_settings(): | |
| with patch("app.services.cloudinary_service.settings") as mock_settings: | |
| yield mock_settings | |
| def mock_uploader(): | |
| with patch("app.services.cloudinary_service.cloudinary.uploader") as mock_uploader: | |
| yield mock_uploader | |
| def test_upload_image_not_configured(mock_settings): | |
| mock_settings.CLOUDINARY_CLOUD_NAME = None | |
| result = upload_image(b"test_bytes") | |
| assert result == { | |
| "url": None, | |
| "public_id": None, | |
| "error": "Cloudinary not configured", | |
| } | |
| def test_upload_image_success(mock_settings, mock_uploader): | |
| mock_settings.CLOUDINARY_CLOUD_NAME = "test_cloud" | |
| mock_uploader.upload.return_value = { | |
| "secure_url": "https://res.cloudinary.com/test_cloud/image/upload/v1/test_id.jpg", | |
| "public_id": "test_id", | |
| } | |
| result = upload_image(b"test_bytes") | |
| assert result == { | |
| "url": "https://res.cloudinary.com/test_cloud/image/upload/f_auto,q_auto/v1/test_id.jpg", | |
| "public_id": "test_id", | |
| } | |
| mock_uploader.upload.assert_called_once_with( | |
| b"test_bytes", | |
| folder="gate-prep/questions", | |
| resource_type="image", | |
| transformation=[ | |
| {"fetch_format": "auto", "quality": "auto"}, | |
| {"width": 1200, "crop": "limit"}, | |
| ], | |
| ) | |
| def test_optimize_delivery_image_url_adds_auto_transforms(): | |
| url = "https://res.cloudinary.com/test_cloud/image/upload/v1/test_id.jpg" | |
| result = optimize_delivery_image_url(url) | |
| assert ( | |
| result | |
| == "https://res.cloudinary.com/test_cloud/image/upload/f_auto,q_auto/v1/test_id.jpg" | |
| ) | |
| def test_optimize_delivery_image_url_is_idempotent(): | |
| url = "https://res.cloudinary.com/test_cloud/image/upload/f_auto,q_auto/v1/test_id.jpg" | |
| result = optimize_delivery_image_url(url) | |
| assert result == url | |
| def test_optimize_delivery_image_url_ignores_non_cloudinary_url(): | |
| url = "/uploads/test_id.jpg" | |
| result = optimize_delivery_image_url(url) | |
| assert result == url | |
| def test_optimize_delivery_image_urls_transforms_mapping_values(): | |
| image_urls = { | |
| "A": "https://res.cloudinary.com/test_cloud/image/upload/v1/option_a.jpg", | |
| "B": "/uploads/option_b.jpg", | |
| } | |
| result = optimize_delivery_image_urls(image_urls) | |
| assert result == { | |
| "A": "https://res.cloudinary.com/test_cloud/image/upload/f_auto,q_auto/v1/option_a.jpg", | |
| "B": "/uploads/option_b.jpg", | |
| } | |
| assert result is not image_urls | |
| def test_upload_image_exception(mock_settings, mock_uploader): | |
| mock_settings.CLOUDINARY_CLOUD_NAME = "test_cloud" | |
| mock_uploader.upload.side_effect = Exception("Upload failed") | |
| result = upload_image(b"test_bytes") | |
| assert result == {"url": None, "public_id": None, "error": "Upload failed"} | |
| def test_delete_image_not_configured(mock_settings): | |
| mock_settings.CLOUDINARY_CLOUD_NAME = None | |
| result = delete_image("test_id") | |
| assert result is False | |
| def test_delete_image_no_public_id(mock_settings): | |
| mock_settings.CLOUDINARY_CLOUD_NAME = "test_cloud" | |
| assert delete_image(None) is False | |
| assert delete_image("") is False | |
| def test_delete_image_success(mock_settings, mock_uploader): | |
| mock_settings.CLOUDINARY_CLOUD_NAME = "test_cloud" | |
| mock_uploader.destroy.return_value = {"result": "ok"} | |
| result = delete_image("test_id") | |
| assert result is True | |
| mock_uploader.destroy.assert_called_once_with("test_id") | |
| def test_delete_image_exception(mock_settings, mock_uploader): | |
| mock_settings.CLOUDINARY_CLOUD_NAME = "test_cloud" | |
| mock_uploader.destroy.side_effect = Exception("Delete failed") | |
| result = delete_image("test_id") | |
| assert result is False | |