import io from unittest import mock import pytest from faker import Faker from pytest_mock import MockerFixture from ows_text_campaigns.adapters.aws.sts import AssumedRoleCredentials from ows_text_campaigns.assets.exceptions import AssetNotFoundError from ows_text_campaigns.assets.models import Asset from ows_text_campaigns.assets.services import AssetService from ows_text_campaigns.assets.types import BinaryAsset, ImageAsset from tests.unit.types import BuildModel, CreateModel class TestAssetService: def test_get_asset_from_s3( self, service: AssetService, s3_client_mock: mock.MagicMock, faker: Faker ) -> None: s3_client_mock.get_object.return_value = { "Body": io.BytesIO(faker.image(size=(100, 100), image_format="JPEG")), "Metadata": {"original-filename": "image.jpeg"}, } asset = service.get_asset_from_s3("assets/image__123.jpeg") assert asset.filename == "image.jpeg" def test_get_asset_from_s3_empty_metadata( self, service: AssetService, s3_client_mock: mock.MagicMock, faker: Faker ) -> None: s3_client_mock.get_object.return_value = { "Body": io.BytesIO(faker.image(size=(100, 100), image_format="JPEG")), "Metadata": {}, } asset = service.get_asset_from_s3("assets/image__123.jpeg") assert asset.filename == "image__123.jpeg" def test_upload_asset_to_s3( self, service: AssetService, s3_client_mock: mock.MagicMock, faker: Faker ) -> None: asset = BinaryAsset.from_data(faker.image(size=(100, 100), image_format="JPEG")) service.upload_asset_to_s3(asset, key="assets/image.jpeg") s3_client_mock.put_object.assert_called_once() def test_delete_asset_from_s3( self, service: AssetService, s3_client_mock: mock.MagicMock ) -> None: service.delete_asset_from_s3("assets/image.jpeg") s3_client_mock.delete_object.assert_called_once() def test_generate_upload_credentials( self, service: AssetService, build_model: BuildModel, sts_client_mock: mock.MagicMock, ) -> None: credentials = build_model(AssumedRoleCredentials) sts_client_mock.assume_role.return_value = credentials result = service.generate_upload_credentials("assets/image.jpeg") assert result.key == "assets/image.jpeg" @pytest.mark.db def test_create_and_upload_image_to_s3( self, service: AssetService, faker: Faker, mocker: MockerFixture ) -> None: object_type = "album" object_id = faker.uuid4() identity_id = faker.uuid4() filename = "image.jpeg" binary = BinaryAsset.from_data( faker.image(size=(100, 100), image_format="JPEG"), filename=filename ) image = ImageAsset.from_binary(binary, size=(100, 100), is_compressed=True) mocker.patch( "ows_text_campaigns.assets.utils.unique_hash", return_value="abc123", ) asset = service.create_and_upload_image_to_s3( image, "assets/image.jpeg", object_type=object_type, object_id=object_id, identity_id=identity_id, ) assert asset.key == "assets/image-100x100__abc123.jpg" assert asset.object_type == object_type assert asset.object_id == object_id assert asset.original_filename == filename assert asset.created_by == identity_id @pytest.mark.db def test_get_asset( self, service: AssetService, create_model: CreateModel, faker: Faker, ): object_type = "album" object_id = faker.uuid4() asset = create_model(Asset, object_type=object_type, object_id=object_id) result = service.get_asset_for( asset_id=asset.id, object_type=object_type, object_id=object_id ) assert asset == result @pytest.mark.db def test_get_asset_not_found( self, service: AssetService, create_model: CreateModel, faker: Faker, ): object_type = "album" object_id = faker.uuid4() asset = create_model(Asset, object_type=object_type, object_id=object_id) with pytest.raises(AssetNotFoundError): service.get_asset_for( asset_id=asset.id, object_type="artist", object_id=object_id )