"""Test S3.""" from unittest.mock import MagicMock, patch import boto3 import pytest from accounting_run_utils.connectors import s3 @pytest.fixture() def mock_bucket_name() -> str: return "test-bucket" @pytest.fixture() def mock_object_name_prefix() -> str: return "s3_object" @pytest.fixture() def mock_object_prefix() -> str: return "object_prefix" @pytest.fixture() def mock_no_objects_prefix() -> str: return "no_objects_prefix" @pytest.fixture() def mock_object_count() -> int: return 100 def boto3_localstack_client() -> boto3.client: localstack_endpoint_url = "http://localstack:4566" s3_client = boto3.client( "s3", region_name="us-east-1", endpoint_url=localstack_endpoint_url ) return s3_client @pytest.fixture() def create_s3_bucket( mock_bucket_name: str, ) -> str: client = boto3_localstack_client() response = client.create_bucket(Bucket=mock_bucket_name) return response["Location"].strip("/") @pytest.fixture() def put_s3_objects( create_s3_bucket: str, mock_object_name_prefix: str, mock_object_prefix: str, mock_object_count: int, ) -> None: client = boto3_localstack_client() for num in range(mock_object_count): client.put_object( Body=f"{mock_object_name_prefix}{num}", Bucket=create_s3_bucket, Key=f"{mock_object_prefix}/{mock_object_name_prefix}{num}", ) def test_get_s3_client() -> None: client = s3._get_s3_client() assert client.meta.service_model.service_name == "s3" @pytest.mark.parametrize( "object_prefix", [ "mock_object_prefix", "mock_no_objects_prefix", ], ) @patch("accounting_run_utils.connectors.s3._get_s3_client") def test_get_s3_objects( mock_get_s3_client: MagicMock, mock_bucket_name: str, mock_object_name_prefix: str, object_prefix: str, mock_object_count: int, put_s3_objects: None, request: pytest.FixtureRequest, ) -> None: mock_get_s3_client.return_value = boto3_localstack_client() object_prefix = request.getfixturevalue(object_prefix) objects = s3.get_s3_objects(mock_bucket_name, f"{object_prefix}/") if objects: assert len(objects) == mock_object_count object_list = [ f"{object_prefix}{mock_object_name_prefix}{num}" for num in range(mock_object_count) ] assert [object in objects for object in object_list] else: assert objects == []