import urllib.parse from typing import List from unittest import mock import pytest from botocore.exceptions import ClientError from dae_s3_consumer_events_distribution_lambda.handler import ( get_params_from_payload, handler, join_s3_path ) from dae_s3_consumer_events_distribution_lambda.validator import ( SchemaValidationError, validate_payload ) def test__get_params_from_payload(rti_event): file_name, params = get_params_from_payload(rti_event) assert file_name == '1612449797206_100500.json' assert params == { 'date': ['20210330'], 'hour': ['17'], 'app': ['rti'], 'event': ['milestone'], 'version': ['1'] } def test__handler(s3, sts, rti_event, lambda_env_config): s3.put_object( Bucket='dev-delphi-notifications-fake', Key=urllib.parse.unquote(rti_event['Records'][0]['s3']['object']['key']), Body=b"test" ) logger = mock.MagicMock() handler(logger, rti_event) head = s3.head_object( Bucket='dev-artistapp-notifications-fake', Key='event=milestone/version=1/date=20210330/hour=17/1612449797206_100500.json' ) assert head['ResponseMetadata']['HTTPStatusCode'] == 200 def test__source_file_does_not_exist(s3, sts, rti_event, lambda_env_config): rti_event['Records'][0]['s3']['object'].update( { 'key': 'date%3D20210204/hour%3D14/app%3Drti/' 'event%3Dmilestone/version%3D1/' 'file_not_exist.json' } ) logger = mock.MagicMock() with pytest.raises(ClientError) as ex: handler(logger, rti_event) assert ex.exception.response['Error']['Code'] == '404' def test__unexpected_project(s3, sts, rti_event, lambda_env_config): s3.put_object( Bucket='dev-delphi-notifications-fake', Key=rti_event['Records'][0]['s3']['object']['key'], Body=b"test" ) rti_event['Records'][0]['s3']['object'].update( { 'key': 'date%3D20210204/hour%3D14/' 'app%3Di_am_a_mistake/' 'event%3Dmilestone/version%3D1/' 'file_not_exist.json' } ) logger = mock.MagicMock() with pytest.raises(ValueError): handler(logger, rti_event) def test__validator(s3, sts, rti_event): s3.put_object( Bucket='dev-delphi-notifications-fake', Key=rti_event['Records'][0]['s3']['object']['key'], Body=b"test" ) logger = mock.MagicMock() validate_payload(logger, rti_event) def test__validator_fails_with_data_type(s3, sts, rti_event): rti_event['Records'][0]['userIdentity'] = 42 with pytest.raises(SchemaValidationError): logger = mock.MagicMock() validate_payload(logger, rti_event) def test__validator_fails_with_regex_mismatch(s3, sts, rti_event): logger = mock.MagicMock() rti_event['Records'][0]['s3']['object'].update({'key': 'date%3D20210204/hour%3D14/app%3Drti/'}) with pytest.raises(SchemaValidationError): validate_payload(logger, rti_event) @pytest.mark.parametrize( 'bucket,parts,expected', [ ( 'dev-bucket', ['a', 'b', 'c'], 's3://dev-bucket/a/b/c', ), ( 'dev-bucket', ['c'], 's3://dev-bucket/c', ), ( 'dev-bucket', [], 's3://dev-bucket', ) ] ) def test_join_s3_path(bucket: str, parts: List[str], expected: str): result = join_s3_path(bucket, *parts) assert result == expected