"""Lambda test module.""" from copy import deepcopy import datetime from io import BytesIO import json from unittest.mock import patch import botocore from PIL import Image import pytest from src import app as index from src import image_validator from src.common import lambda_exceptions test_filename = 'test_filename' test_bucket = 'test_bucket' event_mock = { 'key': test_filename, 'bucket': test_bucket, 'file_type': 'test_file_type', 'transcoding_type': 'test_transconding_type', 'config': { 'output_bucket_name': 'bucket-name', 'preview_bucket_name': 'bucket-name', 'elastic_transcoder_id': '123' } } def build_test_image(size, mode, fmt, convert=None): """Utils returns an image.""" file = BytesIO() image = Image.new(mode, size=size, color=(155, 0, 0)) if convert: image = image.convert(convert) image.save(file, fmt) file.name = 'test.{}'.format(fmt) file.seek(0) return file @patch('src.common.s3.download_file_object') @patch('src.common.status.client') @patch('src.common.status.datetime') def test_handler_success(datetime_mock, sns_client, s3_client): """Test handler function.""" datetime_mock.datetime.now.return_value = datetime.datetime(2020, 1, 1) test_image = build_test_image((3000, 3000), 'RGB', 'jpeg') s3_client.return_value = test_image result = index.handler(event_mock, None) assert result == event_mock sns_client.publish.assert_called_with( TopicArn='general-topic-arn', Message=json.dumps({ 'function': 'asset-transcoder-image-validation', 'status': 'validation_complete', 'filename': 'test_filename', 'bucket': 'test_bucket', 'status_time': '2020-01-01T00:00:00.000000Z' })) assert test_image.closed @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-image-validation', 'status': 'validation_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.download_fileobj.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-image-validation', 'status': 'validation_error', 'filename': 'test_filename', 'bucket': 'test_bucket', 'status_time': '2020-01-01T00:00:00.000000Z', 'errors': err.value.errors })) @patch('src.common.s3.download_file_object') @patch('src.common.status.client') @patch('src.common.status.datetime') def test_handler_with_failed_validation(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) test_image = build_test_image((2000, 2000), 'RGB', 'jpeg') s3_client.return_value = test_image with pytest.raises(image_validator.InvalidImageDimensions) as err: index.handler(event_mock, None) sns_client.publish.assert_called_with( TopicArn='general-topic-arn', Message=json.dumps({ 'function': 'asset-transcoder-image-validation', 'status': 'validation_error', 'filename': 'test_filename', 'bucket': 'test_bucket', 'status_time': '2020-01-01T00:00:00.000000Z', 'errors': err.value.errors })) assert test_image.closed