"""Lambda test module.""" import pytest from unittest import mock import index # noqa @pytest.fixture def event_fixture(): """S3 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': 'Hello from SNS!', 'MessageAttributes': { 'Test': { 'Type': 'String', 'Value': 'TestString' }, 'TestBinary': { 'Type': 'Binary', 'Value': 'TestBinary' } }, 'Type': 'Notification', 'UnsubscribeUrl': 'EXAMPLE', 'TopicArn': 'topicarn', 'Subject': 'TestInvoke' } } ] } @pytest.mark.parametrize('attachment_attrs, expected_key', [ ({'filename': 'test.jpg'}, 'test.jpg'), ({}, 'default/attachment_key.doc') ]) @mock.patch('index.dynamodb') @mock.patch('index.general') @mock.patch('index.statuses') def test_prepare_dynamodb_item( statuses, general, dynamodb, attachment_attrs, expected_key): """Test prepare_dynamodb_item utility function.""" key = 'default/attachment_key.doc' etag = 'test_etag' size = 4242 event = {'event': 'dict'} bucket_name = 'test_bucket' principal_id = 'principal_id' event_time = 'event time' version_id = 'version_id' fail_status = 'fail_status' statuses.STATUS_FAIL = fail_status expected_config_ttl = 4242 expected_ttl = 424242 general.DYNAMODB_ERROR_RECORD_TTL = expected_config_ttl dynamodb.get_ttl_value_for_item.return_value = expected_ttl principalId_status = 'principal_id_fail_status' s3_object = { 'key': key, 'eTag': etag, 'size': size, 'versionId': version_id, } s3_bucket = { 'name': bucket_name} s3_event = { 'Records': [ { 's3': { 'object': s3_object, 'bucket': s3_bucket }, 'userIdentity': {'principalId': principal_id}, 'eventTime': event_time, } ] } expected_result = { 'principalId_status': principalId_status, 'file_key': key, 'file_name': expected_key, 'etag': etag, 'file_version': version_id, # TODO: find out file version 'file_size': size, 'bucket_name': bucket_name, 'principalId': principal_id, 'status': fail_status, # TODO: replace with constant 'message': event, 'event_time': event_time, 'ttl': expected_ttl, } result = index.prepare_dynamodb_item(event, s3_event, attachment_attrs) assert result == expected_result dynamodb.get_ttl_value_for_item.assert_called_once_with( expected_config_ttl) @mock.patch('index.json') @mock.patch('index.prepare_dynamodb_item') @mock.patch('index.dynamodb') @mock.patch('index.common_config') def test_handler( common_config, dynamodb, prepare_dynamodb_item, json, event_fixture): """Test index.handler.""" table_name = 'test_table_fail' item = mock.MagicMock() prepare_dynamodb_item.return_value = item # ensure that ignore all events is not a MagicMock object. common_config.IGNORE_ALL_EVENTS = None common_config.DYNAMODB_TABLE_ERROR = table_name s3_event = mock.MagicMock() attachment_attrs = mock.MagicMock() message = { 's3_event': s3_event, 'attachment_attrs': attachment_attrs } json.loads.return_value = message index.handler(event_fixture, None) json.loads.assert_called_once_with( event_fixture['Records'][0]['Sns']['Message']) dynamodb.put_item.assert_called_once_with(table_name, item) prepare_dynamodb_item.assert_called_once_with( event_fixture, s3_event, attachment_attrs) @mock.patch('index.json') @mock.patch('index.prepare_dynamodb_item') @mock.patch('index.dynamodb') @mock.patch('index.common_config') def test_handler_no_s3_ignore_dlq( common_config, dynamodb, prepare_dynamodb_item, json, event_fixture): """Test index.handler.""" table_name = 'test_table_fail' # ensure that ignore all events is not a MagicMock object. common_config.IGNORE_ALL_EVENTS = None common_config.DYNAMODB_TABLE_ERROR = table_name message = {} json.loads.return_value = message index.handler(event_fixture, None) json.loads.assert_called_once_with( event_fixture['Records'][0]['Sns']['Message']) dynamodb.put_item.assert_not_called() prepare_dynamodb_item.assert_not_called() @mock.patch('index.json') @mock.patch('index.prepare_dynamodb_item') @mock.patch('index.dynamodb') @mock.patch('index.common_config') def test_handler_ignores_all_events( common_config, dynamodb, prepare_dynamodb_item, json, event_fixture): """Test index.handler.""" table_name = 'test_table_fail' # ensure that ignore all events is not a MagicMock object. common_config.IGNORE_ALL_EVENTS = 'Y' common_config.DYNAMODB_TABLE_ERROR = table_name message = {} json.loads.return_value = message index.handler(event_fixture, None) assert json.loads.call_count == 0 assert dynamodb.put_item.call_count == 0 assert prepare_dynamodb_item.call_count == 0