"""S3 module unit tests.""" from unittest.mock import patch from unittest.mock import MagicMock import botocore import pytest import s3 @pytest.fixture def temporary_file_descriptors_data(): """Correct input descriptors data.""" return [ { 'key': 'img/jpg/test_image_2000_2000.jpg', 'output_image_buffer': None, }, { 'key': 'img/jpg/test_image_110_110.jpg', 'output_image_buffer': None, }, { 'key': 'img/tif/test_image.tif', 'output_image_buffer': None, } ] @patch('s3.client') def test_put_object(boto3_client_mock): """Test put_object function.""" test_bucket = 'bucket' test_key = 'key' test_data = 'data' # test function call s3.put_object(test_bucket, test_key, test_data) # checking boto3_client_mock.put_object.assert_called_once_with( Bucket=test_bucket, Key=test_key, Body=test_data) @patch('s3.client') def test_get_object(boto3_client_mock): """Test get_object function.""" test_bucket = 'bucket' test_key = 'key' # test function call s3.get_object(test_bucket, test_key) # checking boto3_client_mock.get_object.assert_called_once_with( Bucket=test_bucket, Key=test_key) @patch('s3.client') def test_head_object(boto3_client_mock): """Test head_object function.""" test_bucket = 'bucket' test_key = 'key' # test function call s3.head_object(test_bucket, test_key) # checking boto3_client_mock.head_object.assert_called_once_with( Bucket=test_bucket, Key=test_key) @patch('s3.client') def test_key_exists_positive(boto3_client_mock): """Test key_exists function.""" # mocking test_bucket = 'bucket' test_key = 'key' # test function call result = s3.object_exists(test_bucket, test_key) # checking boto3_client_mock.head_object.assert_called_once_with( Bucket=test_bucket, Key=test_key) assert result @patch('s3.client') def test_key_exists_not_exist(boto3_client_mock): """Test key_exists function.""" # mocking test_bucket = 'bucket' test_key = 'key' error = {'Error': {'Code': '404'}} # errot = MagicMock boto3_client_mock.head_object.side_effect = ( botocore.exceptions.ClientError(error, 'foo')) # test function call result = s3.object_exists(test_bucket, test_key) # checking boto3_client_mock.head_object.assert_called_once_with( Bucket=test_bucket, Key=test_key) assert not result @patch('s3.client') def test_key_exists_internal_error(boto3_client_mock): """Test key_exists function.""" # mocking test_bucket = 'bucket' test_key = 'key' error = {'Error': {'Code': '500'}} # error = MagicMock boto3_client_mock.head_object.side_effect = ( botocore.exceptions.ClientError(error, 'foo')) # test function call with pytest.raises(botocore.exceptions.ClientError): s3.object_exists(test_bucket, test_key) boto3_client_mock.head_object.assert_called_once_with( Bucket=test_bucket, Key=test_key) @patch('s3.client') def test_key_exists_fail(boto3_client_mock): """Test key_exists function.""" # mocking test_bucket = 'bucket' test_key = 'key' boto3_client_mock.head_object.side_effect = ValueError('foo') # test function call with pytest.raises(ValueError): s3.object_exists(test_bucket, test_key) @patch('s3.put_object') def test_upload_file_objects( put_object_mock, temporary_file_descriptors_data): """Test for download_file_object call.""" # mocking test_bucket = 'bucket' descriptors_count = len(temporary_file_descriptors_data) buffers = [MagicMock() for i in range(descriptors_count)] input_descriptors = [] for descriptor in zip(temporary_file_descriptors_data, buffers): result_descriptor = dict.copy(descriptor[0]) result_descriptor['output_image_buffer'] = descriptor[1] input_descriptors.append(result_descriptor) # test function call s3.upload_file_objects(input_descriptors, test_bucket) # checking for descriptor in input_descriptors: descriptor['output_image_buffer'].seek.assert_called_once_with(0) put_object_mock.assert_any_call( bucket=test_bucket, key=descriptor['key'], data=descriptor['output_image_buffer'], ContentType='binary/octet' ) def test_upload_file_objects_failure(temporary_file_descriptors_data): """Test for download_file_object failure call.""" # mocking test_bucket = 'bucket' descriptors_count = len(temporary_file_descriptors_data) buffers = [MagicMock() for i in range(descriptors_count)] input_descriptors = [] for descriptor in zip(temporary_file_descriptors_data, buffers): result_descriptor = dict.copy(descriptor[0]) result_descriptor['output_image_buffer'] = descriptor[1] input_descriptors.append(result_descriptor) buffers[0].side_effect = Exception('Mock Exception!') # test function call and checking with pytest.raises(Exception): s3.upload_file_objects(input_descriptors, test_bucket) @patch('s3.client') def test_create_presigned_url(boto3_client_mock): """Test create_presigned_url function.""" test_bucket = 'bucket' test_key = 'key' # test function call s3.create_presigned_url(test_bucket, test_key) # checking boto3_client_mock.generate_presigned_url.assert_called_once_with( ClientMethod='get_object', ExpiresIn=86400, Params={ 'Bucket': test_bucket, 'Key': test_key } ) @patch('s3.client') def test_copy_object(boto3_client_mock): """Test copy_object function.""" # data definition test_source_bucket = 'source_bucket' test_source_key = 'source_key' test_destination_bucket = 'destination_bucket' test_destination_key = 'destination_key' test_destination_metadata = { 'track_id': '1', 'upc': '10', 'product_id': '2' } # test function call s3.copy_object( source_bucket=test_source_bucket, source_key=test_source_key, destination_bucket=test_destination_bucket, destination_key=test_destination_key, destination_metadata=test_destination_metadata) # checking boto3_client_mock.copy_object.assert_called_once_with( Bucket=test_destination_bucket, Key=test_destination_key, CopySource={'Bucket': test_source_bucket, 'Key': test_source_key}, Metadata=test_destination_metadata)