from unittest import mock import pytest from anydi import Container from faker.proxy import Faker from ows_text_campaigns.assets.exceptions import ( InvalidContentTypeError, InvalidFileSizeError, InvalidImageSizeError, ) from ows_text_campaigns.assets.models import Asset from ows_text_campaigns.assets.services import AssetService from ows_text_campaigns.assets.types import BinaryAsset from ows_text_campaigns.campaigns.exceptions import InvalidCampaignAttachmentError from ows_text_campaigns.campaigns.handlers import ( CreateCampaignAttachmentHandler, CreateCampaignAttachmentRequest, ) from ows_text_campaigns.campaigns.models import Campaign from tests.unit.types import CreateModel class TestCreateCampaignAttachmentHandler: @pytest.mark.db def test_create_campaign_attachment( self, container: Container, handler: CreateCampaignAttachmentHandler, create_model: CreateModel, identity_id: str, faker: Faker, ) -> None: attachment_key = "test.jpg" campaign = create_model(Campaign) asset = create_model( Asset, object_type="text_campaign", object_id=campaign.id, key=attachment_key, ) binary_asset = BinaryAsset.from_data( faker.image(size=(300, 300), image_format="jpeg"), ) asset_service_mock = mock.MagicMock(spec=AssetService) asset_service_mock.get_asset_from_s3.return_value = binary_asset asset_service_mock.create_and_upload_image_to_s3.return_value = asset with container.override(AssetService, asset_service_mock): result = handler.handle( CreateCampaignAttachmentRequest( identity_id=identity_id, campaign_id=campaign.id, attachment_key=attachment_key, ) ) assert result == asset @pytest.mark.db def test_create_campaign_attachment_invalid_asset( self, container: Container, handler: CreateCampaignAttachmentHandler, create_model: CreateModel, identity_id: str, ) -> None: campaign = create_model(Campaign) asset_service_mock = mock.MagicMock(spec=AssetService) asset_service_mock.get_asset_from_s3.side_effect = Exception("invalid") with ( container.override(AssetService, asset_service_mock), pytest.raises(InvalidCampaignAttachmentError), ): handler.handle( CreateCampaignAttachmentRequest( identity_id=identity_id, campaign_id=campaign.id, attachment_key="test.jpg", ) ) @pytest.mark.db def test_create_campaign_attachment_invalid_content( self, container: Container, handler: CreateCampaignAttachmentHandler, create_model: CreateModel, identity_id: str, faker: Faker, ) -> None: campaign = create_model(Campaign) attachment_key = "test.jpg" asset = BinaryAsset.from_data( data=faker.image(size=(300, 300), image_format="pdf"), ) asset_service_mock = mock.MagicMock(spec=AssetService) asset_service_mock.get_asset_from_s3.return_value = asset with ( container.override(AssetService, asset_service_mock), pytest.raises(InvalidContentTypeError), ): handler.handle( CreateCampaignAttachmentRequest( identity_id=identity_id, campaign_id=campaign.id, attachment_key=attachment_key, ) ) @pytest.mark.db def test_create_campaign_attachment_invalid_file_size( self, container: Container, handler: CreateCampaignAttachmentHandler, create_model: CreateModel, identity_id: str, faker: Faker, ) -> None: campaign = create_model(Campaign) attachment_key = "test.jpg" asset = BinaryAsset( data=faker.image(size=(1000, 1000), image_format="JPEG"), content_type="image/jpeg", extension=".jpg", file_size=6 * 1024 * 1024, # 6MB ) asset_service_mock = mock.MagicMock(spec=AssetService) asset_service_mock.get_asset_from_s3.return_value = asset with ( container.override(AssetService, asset_service_mock), pytest.raises(InvalidFileSizeError), ): handler.handle( CreateCampaignAttachmentRequest( identity_id=identity_id, campaign_id=campaign.id, attachment_key=attachment_key, ) ) @pytest.mark.db def test_create_campaign_attachment_invalid_image_size( self, container: Container, handler: CreateCampaignAttachmentHandler, create_model: CreateModel, identity_id: str, faker: Faker, ) -> None: campaign = create_model(Campaign) attachment_key = "test.jpg" asset = BinaryAsset.from_data( faker.image(size=(299, 299), image_format="jpeg"), ) asset_service_mock = mock.MagicMock(spec=AssetService) asset_service_mock.get_asset_from_s3.return_value = asset with ( container.override(AssetService, asset_service_mock), pytest.raises(InvalidImageSizeError) as exc_info, ): handler.handle( CreateCampaignAttachmentRequest( identity_id=identity_id, campaign_id=campaign.id, attachment_key=attachment_key, ) ) assert exc_info.value.width == 299 assert exc_info.value.height == 299 assert exc_info.value.min_width == 300 assert exc_info.value.min_height == 300