"""Test s3_file delete.""" from typing import Any import botocore import pytest from botocore.exceptions import ClientError from flexmock import flexmock from assets.models import s3_file @pytest.fixture def fixture_delete_response_success_bucket_1() -> dict[str, Any]: """Return successful delete response for bucket 1.""" return { "Deleted": [ {"Key": "bucket_1_file_1"}, {"Key": "bucket_1_file_2"}, ] } @pytest.fixture def fixture_delete_response_success_bucket_2() -> dict[str, Any]: """Return successful delete response for bucket 1.""" return {"Deleted": [{"Key": "bucket_2_file_1"}, {"Key": "bucket_2_file_2"}]} @pytest.fixture def fixture_delete_response_failure_bucket_2() -> dict[str, Any]: """Return error delete response for bucket 2.""" return { "Deleted": [{"Key": "bucket_2_file_1"}], "Errors": [ { "Key": "bucket_2_file_2", "Code": "AccessDenied", "Message": "Access Denied", } ], } @pytest.fixture def fixture_delete_files_args() -> list[dict[str, str]]: """Return files to delete.""" return [ {"bucket": "bucket_1", "file": "bucket_1_file_1"}, {"bucket": "bucket_1", "file": "bucket_1_file_2"}, {"bucket": "bucket_2", "file": "bucket_2_file_1"}, {"bucket": "bucket_2", "file": "bucket_2_file_2"}, ] def test_delete_s3_files_success( fixture_delete_files_args: list[dict[str, str]], fixture_delete_response_success_bucket_1: dict[str, Any], fixture_delete_response_success_bucket_2: dict[str, Any], ) -> None: """Test for success of delete_s3_files.""" ( flexmock(botocore.client.BaseClient) .should_receive("_make_api_call") .with_args( "DeleteObjects", { "Delete": { "Objects": [{"Key": "bucket_1_file_1"}, {"Key": "bucket_1_file_2"}] }, "Bucket": "bucket_1", }, ) .and_return(fixture_delete_response_success_bucket_1) .once() ) ( flexmock(botocore.client.BaseClient) .should_receive("_make_api_call") .with_args( "DeleteObjects", { "Delete": { "Objects": [{"Key": "bucket_2_file_1"}, {"Key": "bucket_2_file_2"}] }, "Bucket": "bucket_2", }, ) .and_return(fixture_delete_response_success_bucket_2) .once() ) result = s3_file.delete_s3_files(fixture_delete_files_args) assert result == { "bucket_1": { "succeeded": [{"Key": "bucket_1_file_1"}, {"Key": "bucket_1_file_2"}], "failed": [], }, "bucket_2": { "succeeded": [{"Key": "bucket_2_file_1"}, {"Key": "bucket_2_file_2"}], "failed": [], }, } def test_delete_s3_files_error( fixture_delete_files_args: list[dict[str, str]], fixture_delete_response_success_bucket_1: dict[str, Any], fixture_delete_response_failure_bucket_2: dict[str, Any], ) -> None: """Test for error during delete_s3_files.""" ( flexmock(botocore.client.BaseClient) .should_receive("_make_api_call") .with_args( "DeleteObjects", { "Delete": { "Objects": [{"Key": "bucket_1_file_1"}, {"Key": "bucket_1_file_2"}] }, "Bucket": "bucket_1", }, ) .and_return(fixture_delete_response_success_bucket_1) .once() ) ( flexmock(botocore.client.BaseClient) .should_receive("_make_api_call") .with_args( "DeleteObjects", { "Delete": { "Objects": [{"Key": "bucket_2_file_1"}, {"Key": "bucket_2_file_2"}] }, "Bucket": "bucket_2", }, ) .and_return(fixture_delete_response_failure_bucket_2) .once() ) result = s3_file.delete_s3_files(fixture_delete_files_args) assert result == { "bucket_1": { "succeeded": [{"Key": "bucket_1_file_1"}, {"Key": "bucket_1_file_2"}], "failed": [], }, "bucket_2": { "succeeded": [{"Key": "bucket_2_file_1"}], "failed": [ { "Key": "bucket_2_file_2", "Message": "Access Denied", "Code": "AccessDenied", } ], }, } def test_delete_s3_files_client_error( fixture_delete_files_args: list[dict[str, str]], fixture_delete_response_success_bucket_1: dict[str, Any], ) -> None: """Test for error during delete_s3_files.""" ( flexmock(botocore.client.BaseClient) .should_receive("_make_api_call") .with_args( "DeleteObjects", { "Delete": { "Objects": [{"Key": "bucket_1_file_1"}, {"Key": "bucket_1_file_2"}] }, "Bucket": "bucket_1", }, ) .and_return(fixture_delete_response_success_bucket_1) .once() ) ( flexmock(botocore.client.BaseClient) .should_receive("_make_api_call") .with_args( "DeleteObjects", { "Delete": { "Objects": [{"Key": "bucket_2_file_1"}, {"Key": "bucket_2_file_2"}] }, "Bucket": "bucket_2", }, ) .and_raise( ClientError, {"Error": {"Code": "some_code", "Message": "some_message"}}, "delete_objects", ) .once() ) result = s3_file.delete_s3_files(fixture_delete_files_args) assert result == { "bucket_1": { "succeeded": [{"Key": "bucket_1_file_1"}, {"Key": "bucket_1_file_2"}], "failed": [], }, "bucket_2": { "error_code": "some_code", "failed": [{"Key": "bucket_2_file_1"}, {"Key": "bucket_2_file_2"}], "succeeded": [], }, }