"""Lambda test module.""" from copy import deepcopy import datetime import json from unittest.mock import patch import botocore from src import app as index from src.common import lambda_exceptions import pytest test_filename = 'test_filename' test_bucket = 'test_bucket' event_mock = { 'bucket': test_bucket, 'key': test_filename, 'config': { 'output_bucket_name': 'bucket-name', 'preview_bucket_name': 'bucket-name', 'elastic_transcoder_id': '123' } } metadata = { 'Metadata': { 'asset_type': 'image', 'object_id': '123', 'object_type': 'episode', 'original_filename': 'original_filename.jpg' } } image_metadata = deepcopy(metadata) image_metadata['ContentType'] = 'image/jpeg' audio_metadata = deepcopy(metadata) audio_metadata['ContentType'] = 'audio/wav; charset=UTF-8' @patch('src.common.s3.client') @patch('src.common.status.client') @patch('src.common.status.datetime') @pytest.mark.parametrize('asset_metadata,transcoding_type,extension', [(image_metadata, 'image', 'jpeg'), (audio_metadata, 'audio', 'wav')]) def test_handler_success(datetime_mock, sns_client, s3_client, asset_metadata, transcoding_type, extension): """Test handler function success.""" datetime_mock.datetime.now.return_value = datetime.datetime(2020, 1, 1) s3_client.head_object.return_value = asset_metadata result = index.handler(event_mock, None) assert result == { 'key': test_filename, 'bucket': test_bucket, 'config': event_mock['config'], 'transcoding_type': transcoding_type, 'file_type': extension } sns_client.publish.assert_called_with( TopicArn='general-topic-arn', Message=json.dumps({ 'function': 'asset-transcoder-encoding-route', 'status': 'encoding_route_complete', 'filename': 'test_filename', 'bucket': 'test_bucket', 'status_time': '2020-01-01T00:00:00.000000Z', })) @patch('src.common.status.client') @patch('src.common.status.datetime') def test_handler_lambda_event_error(datetime_mock, sns_client): """Test handler function with an invalid lambda event.""" datetime_mock.datetime.now.return_value = datetime.datetime(2020, 1, 1) bad_event = deepcopy(event_mock) del bad_event['config']['elastic_transcoder_id'] with pytest.raises(lambda_exceptions.LambdaEventError) as err: index.handler(bad_event, None) assert err.value.error_code == 'lambda_event_error' assert str(err.value) == 'Lambda event from previous step is invalid. {message}'.format( message=json.dumps({'config': {'elastic_transcoder_id': ['Missing data for required field.']}}) ) sns_client.publish.assert_called_with( TopicArn='general-topic-arn', Message=json.dumps({ 'function': 'asset-transcoder-encoding-route', 'status': 'encoding_route_error', 'filename': 'test_filename', 'bucket': 'test_bucket', 'status_time': '2020-01-01T00:00:00.000000Z', 'errors': err.value.errors })) @patch('src.common.s3.client') @patch('src.common.status.client') @patch('src.common.status.datetime') def test_handler_object_not_found(datetime_mock, sns_client, s3_client): """Test handler function with an object that does not exist.""" datetime_mock.datetime.now.return_value = datetime.datetime(2020, 1, 1) error = {'Error': {'Code': '404', 'Message': 'Not found'}, 'ResponseMetadata': {'HTTPStatusCode': 404}} s3_client.head_object.side_effect = botocore.exceptions.ClientError(error, 'HeadObject') with pytest.raises(lambda_exceptions.S3Error) as err: index.handler(event_mock, None) sns_client.publish.assert_called_with( TopicArn='general-topic-arn', Message=json.dumps({ 'function': 'asset-transcoder-encoding-route', 'status': 'encoding_route_error', 'filename': 'test_filename', 'bucket': 'test_bucket', 'status_time': '2020-01-01T00:00:00.000000Z', 'errors': err.value.errors }) ) @patch('src.common.s3.client') @patch('src.common.status.client') @patch('src.common.status.datetime') @pytest.mark.parametrize('content_type', ['plain/text', 'image/png']) def test_handler_unknown_type(datetime_mock, sns_client, s3_client, content_type): """Test handler function with unknown asset type.""" datetime_mock.datetime.now.return_value = datetime.datetime(2020, 1, 1) invalid_metadata = deepcopy(metadata) invalid_metadata['ContentType'] = content_type s3_client.head_object.return_value = invalid_metadata with pytest.raises(index.EncodingRouteError) as err: index.handler(event_mock, None) sns_client.publish.assert_called_with( TopicArn='general-topic-arn', Message=json.dumps({ 'function': 'asset-transcoder-encoding-route', 'status': 'encoding_route_error', 'filename': 'test_filename', 'bucket': 'test_bucket', 'status_time': '2020-01-01T00:00:00.000000Z', 'errors': err.value.errors }) )