"""Lambda test module.""" import copy from unittest import mock import pytest import index # noqa @pytest.fixture def sns_event_fixture(): """SNS event fixture.""" return { 'Records': [ { 'EventVersion': '1.0', 'EventSubscriptionArn': 'eventsubscriptionarn', 'EventSource': 'aws:sns', 'Sns': { 'SignatureVersion': '1', 'Timestamp': '1970-01-01T00:00:00.000Z', 'Signature': 'EXAMPLE', 'SigningCertUrl': 'EXAMPLE', 'MessageId': '95df01b4-ee98-5cb9-9903-4c221d41eb5e', 'Message': '{"s3_event":{}, "attachment_attrs": {}}', 'Type': 'Notification', 'UnsubscribeUrl': 'EXAMPLE', 'TopicArn': 'topicarn', 'Subject': 'TestInvoke' } } ] } @pytest.fixture def attachment_obj_from_s3(): """SNS event fixture.""" return { 'file_key': '/testfolder/L10303_217_attac1.txt', 'file_name': 'attac1.txt', 'original_file_name': 'attac1.txt', 'file_type': 'txt', 'bucket_name': 'sourcebucket', 'file_size': '1024', 'etag': '0123456789abcdef0123456789abcdef', 'account_type': 'L', 'label_id': '10303', 'period_ids': '217', 'status': 'COMPLETED', 'upload_date': '1970-01-01T00:00:00.000Z' } @pytest.fixture def attachment_month_dynamodb_item(): """Attachment month item fixture.""" return { 'file_key': '/testfolder/L10303_217_attac1.txt', 'file_name': 'attac1.txt', 'original_file_name': 'attac1.txt', 'file_type': 'txt', 'bucket_name': 'sourcebucket', 'file_size': '1024', 'etag': '0123456789abcdef0123456789abcdef', 'account_type': 'L', 'label_id': '10303', 'period_ids': '217', 'status': 'COMPLETED', 'upload_date': '1970-01-01T00:00:00.000Z', 'event_timestamp': '1970-01-01T00:00:00.000Z', 'label_type_id_period_id': 'L10303_217' } @pytest.fixture def attachment_quarter_dynamodb_item(): """Attachment quarter item fixture.""" return { 'file_key': '/testfolder/L10303_217_attac1.txt', 'file_name': 'attac1.txt(217)', 'original_file_name': 'attac1.txt', 'file_type': 'txt', 'bucket_name': 'sourcebucket', 'file_size': '1024', 'etag': '0123456789abcdef0123456789abcdef', 'account_type': 'L', 'label_id': '10303', 'period_ids': '217,218,219', 'status': 'COMPLETED', 'upload_date': '1970-01-01T00:00:00.000Z', 'event_timestamp': '1970-01-01T00:00:00.000Z', 'label_type_id_period_id': 'L10303_217_218_219' } @pytest.mark.parametrize( 'account_id, account_type, file_name, expected_result', [ (123, 'L', 'L123_123_test.file', 'per-lablel-test/test-L123/L123_123_test.file'), (4242, 'L', 'L4242_123_test.file', 'per-lablel-test/test-L4242/L4242_123_test.file')]) @mock.patch('index.common_config') def test_get_attachment_destination_key( common_config, account_id, account_type, file_name, expected_result): """Test get_attachment_destination_key utility funciton.""" common_config.S3_DESTINATION_KEY_TEMPLATE = ( '{attachments_dir}/test-{account_dir}/{file_name}') common_config.S3_PER_LABEL_DIR = 'per-lablel-test' result = index.get_attachment_destination_key( account_id, account_type, file_name) assert result == expected_result @mock.patch('index.get_attachment_destination_key') @mock.patch('index.s3') @mock.patch('index.util') @mock.patch('index.dynamodb') @mock.patch('index.common_config') def test_handler( common_config, dynamodb, util, s3, get_attachment_destination_key, sns_event_fixture, attachment_obj_from_s3, attachment_month_dynamodb_item, attachment_quarter_dynamodb_item): """Test index.handler.""" table_name = 'test_table_name' # ensure that ignore all events is not a MagicMock object. common_config.IGNORE_ALL_EVENTS = None common_config.DYNAMODB_TABLE_SUCCESS = table_name file_key = attachment_obj_from_s3['file_key'] get_attachment_destination_key.return_value = file_key util.get_quarter_periods_by_period.return_value = [217, 218, 219] util.s3_event_get_attachment_details.return_value = attachment_obj_from_s3 util.get_attachment_primary_key_value.side_effect = [ 'L10303_217', 'L10303_217_218_219'] util.format_quarter_file_name.return_value = 'attac1.txt(217)' index.handler(sns_event_fixture, None) dynamodb.batch_write_data.assert_called_once_with( table_name, [ attachment_month_dynamodb_item, attachment_quarter_dynamodb_item]) @pytest.mark.parametrize('move_result, dest_key, expected_file_key', [ (True, 'another-path/another-key', 'another-path/another-key'), (False, 'another-path/another-key', '/testfolder/L10303_217_attac1.txt'), ]) @mock.patch('index.get_attachment_destination_key') @mock.patch('index.s3') @mock.patch('index.util') @mock.patch('index.dynamodb') @mock.patch('index.common_config') def test_handler_successful_move_operation( common_config, dynamodb, util, s3, get_attachment_destination_key, attachment_obj_from_s3, attachment_month_dynamodb_item, attachment_quarter_dynamodb_item, move_result, dest_key, expected_file_key, sns_event_fixture): """Test handler when s3.move was successful.""" table_name = 'test_table_name' s3_bucket_name = 'test_bucket_name' # ensure that ignore all events is not a MagicMock object. common_config.IGNORE_ALL_EVENTS = None common_config.DYNAMODB_TABLE_SUCCESS = table_name common_config.S3_BUCKET_NAME = s3_bucket_name get_attachment_destination_key.return_value = dest_key util.get_quarter_periods_by_period.return_value = [217, 218, 219] util.s3_event_get_attachment_details.return_value = copy.deepcopy( attachment_obj_from_s3) util.get_attachment_primary_key_value.side_effect = [ 'L10303_217', 'L10303_217_218_219'] util.format_quarter_file_name.return_value = 'attac1.txt(217)' util.get_file_name_from_key.return_value = 'L10303_217_attac1.txt' s3.move_object.return_value = move_result expected_moth_item = copy.deepcopy(attachment_month_dynamodb_item) expected_quarter_item = copy.deepcopy(attachment_quarter_dynamodb_item) expected_moth_item['file_key'] = expected_file_key expected_quarter_item['file_key'] = expected_file_key index.handler(sns_event_fixture, None) s3.move_object.assert_called_once_with( bucket=s3_bucket_name, source_key=attachment_obj_from_s3['file_key'], dest_key=dest_key ) dynamodb.batch_write_data.assert_called_once_with( table_name, [ expected_moth_item, expected_quarter_item]) @mock.patch('index.get_attachment_destination_key') @mock.patch('index.s3') @mock.patch('index.util') @mock.patch('index.dynamodb') @mock.patch('index.common_config') def test_handler_ignores_all_events( common_config, dynamodb, util, s3, get_attachment_destination_key, sns_event_fixture, attachment_obj_from_s3): """Test index.handler.""" table_name = 'test_table_name' common_config.IGNORE_ALL_EVENTS = 'True' common_config.DYNAMODB_TABLE_SUCCESS = table_name file_key = attachment_obj_from_s3['file_key'] get_attachment_destination_key.return_value = file_key util.get_quarter_periods_by_period.return_value = [217, 218, 219] util.s3_event_get_attachment_details.return_value = attachment_obj_from_s3 util.get_attachment_primary_key_value.side_effect = [ 'L10303_217', 'L10303_217_218_219'] util.format_quarter_file_name.return_value = 'attac1.txt(217)' index.handler(sns_event_fixture, None) assert dynamodb.batch_write_data.call_count == 0 @pytest.mark.parametrize('period_ids, expected_result', [ ([217, 218, 219], '217,218,219'), ([220, 221, 222], '220,221,222'), ([1, 2, 3], '1,2,3') ]) def test_format_period_ids_string(period_ids, expected_result): """Test format_quarter_file_name.""" result = index.format_period_ids_string(period_ids) assert expected_result == result