import datetime from unittest import mock import pytest from campaigns.assets.exceptions import AssetDoesNotExist from campaigns.assets.models import Asset from campaigns.assets.repositories import AssetRepository from campaigns.assets.services import AssetService from campaigns.connectors.aws.sts import AssumedRoleCredentials from tests.unit.faker import FakerTyped from tests.unit.types import CreateModel @pytest.fixture def assumed_role_credentials() -> AssumedRoleCredentials: return AssumedRoleCredentials( access_key_id="ABC123", secret_access_key="def456", session_token="ghi789", expiration=datetime.datetime.now() + datetime.timedelta(minutes=30), ) async def test_generate_asset_upload_credentials( asset_service: AssetService, sts_client_mock: mock.MagicMock, assumed_role_credentials: AssumedRoleCredentials, ) -> None: filename = "asset.jpg" sts_client_mock.assume_role.return_value = assumed_role_credentials credentials = await asset_service.generate_asset_upload_credentials(filename) assert credentials.asset_id is not None assert credentials.upload_key.startswith(f"{Asset.RAW_UPLOAD_FOLDER}/") assert credentials.asset_id in credentials.upload_key assert credentials.upload_key.endswith(filename) assert credentials.access_key_id == assumed_role_credentials.access_key_id assert credentials.secret_access_key == assumed_role_credentials.secret_access_key assert credentials.session_token == assumed_role_credentials.session_token assert credentials.expiration == assumed_role_credentials.expiration async def test_get_asset( asset_service: AssetService, create_model: CreateModel ) -> None: asset = await create_model(Asset) result = await asset_service.get_asset(asset_id=asset.id) assert asset == result async def test_get_asset_not_found( asset_service: AssetService, fake: FakerTyped ) -> None: asset_id = fake.uuid4_string() with pytest.raises(AssetDoesNotExist): await asset_service.get_asset(asset_id=asset_id) async def test_save_asset_thumbnail( asset_service: AssetService, s3_client_mock: mock.MagicMock, create_model: CreateModel, fake: FakerTyped, ) -> None: asset = await create_model(Asset) content = fake.bytes() content_type = fake.pystr() extension = fake.pystr() result = await asset_service.save_asset_thumbnail( asset=asset, content=content, content_type=content_type, extension=extension, ) asset.set_thumbnail_key(extension=extension) s3_client_mock.put_object.assert_called_once_with( bucket=asset.bucket, key=asset.thumbnail_key, content=content, content_type=content_type, ) assert result.id == asset.id assert result.thumbnail_key == asset.thumbnail_key async def test_delete_asset( asset_service: AssetService, asset_repository: AssetRepository, s3_client_mock: mock.MagicMock, create_model: CreateModel, ) -> None: asset = await create_model(Asset) await asset_service.delete_asset(asset) s3_client_mock.delete_object.assert_any_call( bucket=asset.bucket, key=asset.key, ) s3_client_mock.delete_object.assert_any_call( bucket=asset.bucket, key=asset.thumbnail_key, ) result = await asset_repository.first() assert result is None