"""Lambda test index module.""" import json from unittest.mock import MagicMock from unittest.mock import patch import config import pytest from src import app as index @patch('src.app.boto3') @patch('src.app.boto3') def test_handler_old_format(mock_boto3_stepfunction, mock_boto3_dynamo): """Test handler function.""" event = { 'eventSource': 'aws:kafka', 'records': { 'event.gdaApproval-0': [ { 'topic': 'event.gdaApproval', 'partition': 0, 'offset': 4, 'timestamp': 1626669809539, 'timestampType': 'CREATE_TIME', 'value': 'eyJzY2hlbWEiOiB7InR5cGUiOiAic3RyaW5nIiwgIm9wdGlvbmFsIjogImZhbHNlIn0sICJwYXlsb2FkIjogIntcIk9yY2hhcmRfTGVhZF9JZF9fY1wiOlwibnBhdGVsKzA3MjExMTExXCIsXCJUaWt0b2tVcmxfX2NcIjpcImh0dHBzOi8vdGlrdG9rLmNvbS9hc2RmYWRmXCIsXCJJbnN0YWdyYW1VcmxfX2NcIjpcImh0dHBzOi8vaW5zdGFncmFtLmNvbS9hc2RmYWRmXCIsXCJFbWFpbFwiOlwibnBhdGVsKzA3MjExQHRoZW9yY2hhcmQuY29tXCIsXCJGaXJzdE5hbWVcIjpcIm1hc2hhXCIsXCJSb2xlX19jXCI6XCJMYWJlbFwiLFwiU291bmRjbG91ZFVybF9fY1wiOlwiaHR0cHM6Ly9zb3VuZGNsb3VkLmNvbS9hc2RmYWRmXCIsXCJDb3JyZWxhdGlvbklkX19jXCI6XCJiYmJkNTRiYS1jNDdjLTQ3ZWQtYWM0OFwiLFwiU3BvdGlmeVVybF9fY1wiOlwiaHR0cHM6Ly9vcGVuLnNwb3RpZnkuY29tL2FydGlzdC8yRlB3WDNHaDB3NFFyMXYzelNUdGNUXCIsXCJBbWF6b25NdXNpY1VybF9fY1wiOlwiaHR0cHM6Ly9hbWF6b24uY29tL2FzZGZhZGZcIixcIk90aGVyVXJsX19jXCI6bnVsbCxcIlR3aXR0ZXJVcmxfX2NcIjpcImh0dHBzOi8vdHdpdHRlci5jb20vYXNkZmFkZlwiLFwiWW91VHViZVVybF9fY1wiOlwiaHR0cHM6Ly95b3V0dWJlLmNvbS9hc2RoZmFcIixcIkFydGlzdE5hbWVfX2NcIjpcIkNoYXJsaWUncyBCYW5kXCIsXCJEZWV6ZXJVcmxfX2NcIjpudWxsLFwiRmFjZWJvb2tVcmxfX2NcIjpudWxsLFwiTGFzdE5hbWVcIjpcImRldlwiLFwiSWRcIjpcIjAwMzBuMDAwMDBxdXNHd0FBSVwiLFwiUmVsZWFzZURhdGVfX2NcIjpcIjIwMjEtMDYtMjhUMDA6MDA6MDAuMDAwWlwiLFwiUmVsZWFzZVBsYW5uZWRfX2NcIjp0cnVlfSJ9' # noqa } ] } } config.STEP_FN_ARN = 'test-step-function-arn' mock_boto3_dynamo.client().get_item.return_value = {} execute_response = {'step_fn': 'result'} mock_boto3_stepfunction.client().start_execution.return_value = execute_response result = index.handler(event, None) assert result == {'status': {4: 'success'}} @patch('src.app.boto3') @patch('src.app.boto3') def test_handler_new_format(mock_boto3_stepfunction, mock_boto3_dynamo): """Test handler function.""" event = { 'eventSource': 'aws:kafka', 'records': { 'event.gdaApproval-0': [ { 'topic': 'event.gdaApproval', 'partition': 0, 'offset': 4, 'timestamp': 1626669809539, 'timestampType': 'CREATE_TIME', 'value': 'ewogICJhdHRyaWJ1dGVzIjogewogICAgInR5cGUiOiAiQ29udGFjdCIsCiAgICAidXJsIjogIi9zZXJ2aWNlcy9kYXRhL3Y0Mi4wL3NvYmplY3RzL0NvbnRhY3QvMDAzMDEwMDAwMEpQaW1VQUFUIgogIH0sCiAgIklkIjogIjAwMzAxMDAwMDBKUGltVUFBVCIsCiAgIkZpcnN0TmFtZSI6ICJRQUxUXzlmMGNlNjc4LTEyNmEtNGVkOS1hIiwKICAiTGFzdE5hbWUiOiAiVGVzdFV2YXJvdjMzNTU2NjMiLAogICJFbWFpbCI6ICJidXZhcm92KzEyOTg2NDlAdGhlb3JjaGFyZC5jb20iLAogICJSb2xlX19jIjogIkFydGlzdCBvciBCYW5kIiwKICAiQWNjb3VudCI6IHsKICAgICJhdHRyaWJ1dGVzIjogewogICAgICAidHlwZSI6ICJBY2NvdW50IiwKICAgICAgInVybCI6ICIvc2VydmljZXMvZGF0YS92NDIuMC9zb2JqZWN0cy9BY2NvdW50LzAwMTAxMDAwMDBOdmd4cEFBQiIKICAgIH0sCiAgICAiTmFtZSI6ICJVdmFDb3JwMzg3ODk4MiIsCiAgICAiU3BvdGlmeVVybF9fYyI6ICJodHRwczovL29wZW4uc3BvdGlmeS5jb20vYXJ0aXN0LzRvRDRQaEpOOTZ1cXNNUGFyZTk5QkwiLAogICAgIk9yY2hhcmRfTGVhZF9JZF9fYyI6ICJmNDQzNGJjMDVkNzVlNjJlZWFlOWUxNzNkNjVmN2RkNWNlNmVkMjhhMjcyM2JmOTcyNjVkMTRmZDhjY2ExYzMzIiwKICAgICJTb3VuZGNsb3VkVXJsX19jIjogbnVsbCwKICAgICJUaWt0b2tVcmxfX2MiOiAiaHR0cHM6Ly93d3cueW91dHViZS5jb20vY2hhbm5lbC9VQzZmYVBiZlhVenhVT1BaeXQ2YUllUHciLAogICAgIkluc3RhZ3JhbVVybF9fYyI6ICJodHRwczovL3d3dy5pbnN0YWdyYW0uY29tL2xhenlqYW5lbXVzaWMvP2hsPWVuIiwKICAgICJEZWV6ZXJVcmxfX2MiOiBudWxsLAogICAgIllvdXR1YmVVcmxfX2MiOiAiaHR0cHM6Ly93d3cueW91dHViZS5jb20vY2hhbm5lbC9VQzZmYVBiZlhVenhVT1BaeXQ2YUllUHciLAogICAgIkFtYXpvbk11c2ljVXJsX19jIjogbnVsbCwKICAgICJUd2l0dGVyVXJsX19jIjogImh0dHBzOi8vdHdpdHRlci5jb20vbGF6eWphbmVtdXNpYz9sYW5nPWVuIiwKICAgICJPdGhlclVybF9fYyI6IG51bGwsCiAgICAiRmFjZWJvb2tVcmxfX2MiOiAiaHR0cHM6Ly93d3cuZmFjZWJvb2suY29tL2xhenlqYW5lbXVzaWMvIiwKICAgICJMZWFkU2NvcmVfX2MiOiAiQXBwcm92ZSIsCiAgICAiQ3VycmVuY3lfX2MiOiAiVVNEIiwKICAgICJTaWduaW5nRW50aXR5X19jIjogIkdCUiIsCiAgICAiRXhpc3RpbmdMYWJlbFBhcnRpY2lwYW50c19fYyI6IG51bGwKICB9LAogICJMYW5ndWFnZV9fYyI6ICJlbiIsCiAgIkV4dGVybmFsVGVzdF9fYyI6IGZhbHNlLAogICJDb3JyZWxhdGlvbklkX19jIjogIjFjNzdlODg1LTYzZGUtNDdjOS05YzE5LTlhYTg4NzJlMGIyZCIsCiAgIlZvdWNoZXJDb2RlX19jIjogIm5ac3E4TURWIiwKICAiVm91Y2hlckNvZGVPd25lcl9fYyI6ICJidXZhcm92QHRoZW9yY2hhcmQuY29tIiwKICAiT3JjaGFyZFN5bmNJZF9fYyI6ICIyOTYxIiwKICAiQ29uc3VsdGFudF9fYyI6IGZhbHNlLAogICJNYWlsaW5nQ291bnRyeSI6ICJVU0EiCn0=' # noqa } ] } } config.STEP_FN_ARN = 'test-step-function-arn' mock_boto3_dynamo.client().get_item.return_value = {} execute_response = {'step_fn': 'result'} mock_boto3_stepfunction.client().start_execution.return_value = execute_response result = index.handler(event, None) assert result == {'status': {4: 'success'}} @patch('src.app.Producer') @patch('src.app.boto3') def test_handler_error(botoMock, kafkaProducerMock): """Test handler function.""" event = { 'eventSource': 'aws:kafka', 'records': { 'event.gdaApproval-0': [ { 'topic': 'event.gdaApproval', 'partition': 0, 'offset': 4, 'timestamp': 1626669809539, 'timestampType': 'CREATE_TIME', 'value': 'foo' } ] } } config.STEP_FN_ARN = 'test-step-function-arn' execute_response = {'step_fn': 'result'} botoMock.client().start_execution.return_value = execute_response result = index.handler(event, None) assert result == {'status': {4: 'failed'}} kafkaProducerMock().produce.assert_called() kafkaProducerMock().flush.assert_called() @patch('src.app.boto3') @patch('src.app.config') @pytest.mark.parametrize('env,skip', [('prod', True), ('qa', False)]) def test_handler_skip_external_test(configMock, botoMock, env, skip): """Test handler function skips execution for external tests.""" event = { 'eventSource': 'aws:kafka', 'records': { 'event.gdaApproval-0': [ { 'topic': 'event.gdaApproval', 'partition': 0, 'offset': 4, 'timestamp': 1626669809539, 'timestampType': 'CREATE_TIME', 'value': 'eyJwYXlsb2FkIjogIntcIkV4dGVybmFsVGVzdF9fY1wiOiB0cnVlfSJ9' } ] } } config.STEP_FN_ARN = 'test-step-function-arn' configMock.ENVIRONMENT = configMock.PROD_ENVIRONMENT = env result = index.handler(event, None) if skip: botoMock.client().start_execution.assert_not_called() assert result == {'status': {4: 'skipped'}} @patch('src.app.boto3') @patch('src.app.boto3') def test_handler_skip_existing_correlation_id(mock_boto3_stepfunction, mock_boto3_dynamo): """Test handler function skips execution for correlation id that exists in dynamo table.""" event = { 'eventSource': 'aws:kafka', 'records': { 'event.gdaApproval-0': [ { 'topic': 'event.gdaApproval', 'partition': 0, 'offset': 4, 'timestamp': 1626669809539, 'timestampType': 'CREATE_TIME', 'value': 'ewogICJhdHRyaWJ1dGVzIjogewogICAgInR5cGUiOiAiQ29udGFjdCIsCiAgICAidXJsIjogIi9zZXJ2aWNlcy9kYXRhL3Y0Mi4wL3NvYmplY3RzL0NvbnRhY3QvMDAzMDEwMDAwMEpQaW1VQUFUIgogIH0sCiAgIklkIjogIjAwMzAxMDAwMDBKUGltVUFBVCIsCiAgIkZpcnN0TmFtZSI6ICJRQUxUXzlmMGNlNjc4LTEyNmEtNGVkOS1hIiwKICAiTGFzdE5hbWUiOiAiVGVzdFV2YXJvdjMzNTU2NjMiLAogICJFbWFpbCI6ICJidXZhcm92KzEyOTg2NDlAdGhlb3JjaGFyZC5jb20iLAogICJSb2xlX19jIjogIkFydGlzdCBvciBCYW5kIiwKICAiQWNjb3VudCI6IHsKICAgICJhdHRyaWJ1dGVzIjogewogICAgICAidHlwZSI6ICJBY2NvdW50IiwKICAgICAgInVybCI6ICIvc2VydmljZXMvZGF0YS92NDIuMC9zb2JqZWN0cy9BY2NvdW50LzAwMTAxMDAwMDBOdmd4cEFBQiIKICAgIH0sCiAgICAiTmFtZSI6ICJVdmFDb3JwMzg3ODk4MiIsCiAgICAiU3BvdGlmeVVybF9fYyI6ICJodHRwczovL29wZW4uc3BvdGlmeS5jb20vYXJ0aXN0LzRvRDRQaEpOOTZ1cXNNUGFyZTk5QkwiLAogICAgIk9yY2hhcmRfTGVhZF9JZF9fYyI6ICJmNDQzNGJjMDVkNzVlNjJlZWFlOWUxNzNkNjVmN2RkNWNlNmVkMjhhMjcyM2JmOTcyNjVkMTRmZDhjY2ExYzMzIiwKICAgICJTb3VuZGNsb3VkVXJsX19jIjogbnVsbCwKICAgICJUaWt0b2tVcmxfX2MiOiAiaHR0cHM6Ly93d3cueW91dHViZS5jb20vY2hhbm5lbC9VQzZmYVBiZlhVenhVT1BaeXQ2YUllUHciLAogICAgIkluc3RhZ3JhbVVybF9fYyI6ICJodHRwczovL3d3dy5pbnN0YWdyYW0uY29tL2xhenlqYW5lbXVzaWMvP2hsPWVuIiwKICAgICJEZWV6ZXJVcmxfX2MiOiBudWxsLAogICAgIllvdXR1YmVVcmxfX2MiOiAiaHR0cHM6Ly93d3cueW91dHViZS5jb20vY2hhbm5lbC9VQzZmYVBiZlhVenhVT1BaeXQ2YUllUHciLAogICAgIkFtYXpvbk11c2ljVXJsX19jIjogbnVsbCwKICAgICJUd2l0dGVyVXJsX19jIjogImh0dHBzOi8vdHdpdHRlci5jb20vbGF6eWphbmVtdXNpYz9sYW5nPWVuIiwKICAgICJPdGhlclVybF9fYyI6IG51bGwsCiAgICAiRmFjZWJvb2tVcmxfX2MiOiAiaHR0cHM6Ly93d3cuZmFjZWJvb2suY29tL2xhenlqYW5lbXVzaWMvIiwKICAgICJMZWFkU2NvcmVfX2MiOiAiQXBwcm92ZSIsCiAgICAiQ3VycmVuY3lfX2MiOiAiVVNEIiwKICAgICJTaWduaW5nRW50aXR5X19jIjogIkdCUiIsCiAgICAiRXhpc3RpbmdMYWJlbFBhcnRpY2lwYW50c19fYyI6IG51bGwKICB9LAogICJMYW5ndWFnZV9fYyI6ICJlbiIsCiAgIkV4dGVybmFsVGVzdF9fYyI6IGZhbHNlLAogICJDb3JyZWxhdGlvbklkX19jIjogIjFjNzdlODg1LTYzZGUtNDdjOS05YzE5LTlhYTg4NzJlMGIyZCIsCiAgIlZvdWNoZXJDb2RlX19jIjogIm5ac3E4TURWIiwKICAiVm91Y2hlckNvZGVPd25lcl9fYyI6ICJidXZhcm92QHRoZW9yY2hhcmQuY29tIiwKICAiT3JjaGFyZFN5bmNJZF9fYyI6ICIyOTYxIiwKICAiQ29uc3VsdGFudF9fYyI6IGZhbHNlLAogICJNYWlsaW5nQ291bnRyeSI6ICJVU0EiCn0=' # noqa } ] } } config.STEP_FN_ARN = 'test-step-function-arn' mock_boto3_dynamo.client().get_item.return_value = {'Item': {'correlation_id': '1234'}} result = index.handler(event, None) mock_boto3_stepfunction.client().start_execution.assert_not_called() assert result == {'status': {4: 'skipped'}} @patch('src.app.boto3') def test_topic_name_is_present_in_sm_kwargs(mock_boto3): """Test topic name is passed as source param to invocation of a SM.""" event = { 'eventSource': 'aws:kafka', 'records': { 'event.gdaApproval-0': [ { 'topic': 'event.gdaApproval', 'partition': 0, 'offset': 4, 'timestamp': 1626669809539, 'timestampType': 'CREATE_TIME', 'value': 'ewogICJhdHRyaWJ1dGVzIjogewogICAgInR5cGUiOiAiQ29udGFjdCIsCiAgICAidXJsIjogIi9zZXJ2aWNlcy9kYXRhL3Y0Mi4wL3NvYmplY3RzL0NvbnRhY3QvMDAzMDEwMDAwMEpQaW1VQUFUIgogIH0sCiAgIklkIjogIjAwMzAxMDAwMDBKUGltVUFBVCIsCiAgIkZpcnN0TmFtZSI6ICJRQUxUXzlmMGNlNjc4LTEyNmEtNGVkOS1hIiwKICAiTGFzdE5hbWUiOiAiVGVzdFV2YXJvdjMzNTU2NjMiLAogICJFbWFpbCI6ICJidXZhcm92KzEyOTg2NDlAdGhlb3JjaGFyZC5jb20iLAogICJSb2xlX19jIjogIkFydGlzdCBvciBCYW5kIiwKICAiQWNjb3VudCI6IHsKICAgICJhdHRyaWJ1dGVzIjogewogICAgICAidHlwZSI6ICJBY2NvdW50IiwKICAgICAgInVybCI6ICIvc2VydmljZXMvZGF0YS92NDIuMC9zb2JqZWN0cy9BY2NvdW50LzAwMTAxMDAwMDBOdmd4cEFBQiIKICAgIH0sCiAgICAiTmFtZSI6ICJVdmFDb3JwMzg3ODk4MiIsCiAgICAiU3BvdGlmeVVybF9fYyI6ICJodHRwczovL29wZW4uc3BvdGlmeS5jb20vYXJ0aXN0LzRvRDRQaEpOOTZ1cXNNUGFyZTk5QkwiLAogICAgIk9yY2hhcmRfTGVhZF9JZF9fYyI6ICJmNDQzNGJjMDVkNzVlNjJlZWFlOWUxNzNkNjVmN2RkNWNlNmVkMjhhMjcyM2JmOTcyNjVkMTRmZDhjY2ExYzMzIiwKICAgICJTb3VuZGNsb3VkVXJsX19jIjogbnVsbCwKICAgICJUaWt0b2tVcmxfX2MiOiAiaHR0cHM6Ly93d3cueW91dHViZS5jb20vY2hhbm5lbC9VQzZmYVBiZlhVenhVT1BaeXQ2YUllUHciLAogICAgIkluc3RhZ3JhbVVybF9fYyI6ICJodHRwczovL3d3dy5pbnN0YWdyYW0uY29tL2xhenlqYW5lbXVzaWMvP2hsPWVuIiwKICAgICJEZWV6ZXJVcmxfX2MiOiBudWxsLAogICAgIllvdXR1YmVVcmxfX2MiOiAiaHR0cHM6Ly93d3cueW91dHViZS5jb20vY2hhbm5lbC9VQzZmYVBiZlhVenhVT1BaeXQ2YUllUHciLAogICAgIkFtYXpvbk11c2ljVXJsX19jIjogbnVsbCwKICAgICJUd2l0dGVyVXJsX19jIjogImh0dHBzOi8vdHdpdHRlci5jb20vbGF6eWphbmVtdXNpYz9sYW5nPWVuIiwKICAgICJPdGhlclVybF9fYyI6IG51bGwsCiAgICAiRmFjZWJvb2tVcmxfX2MiOiAiaHR0cHM6Ly93d3cuZmFjZWJvb2suY29tL2xhenlqYW5lbXVzaWMvIiwKICAgICJMZWFkU2NvcmVfX2MiOiAiQXBwcm92ZSIsCiAgICAiQ3VycmVuY3lfX2MiOiAiVVNEIiwKICAgICJTaWduaW5nRW50aXR5X19jIjogIkdCUiIsCiAgICAiRXhpc3RpbmdMYWJlbFBhcnRpY2lwYW50c19fYyI6IG51bGwKICB9LAogICJMYW5ndWFnZV9fYyI6ICJlbiIsCiAgIkV4dGVybmFsVGVzdF9fYyI6IGZhbHNlLAogICJDb3JyZWxhdGlvbklkX19jIjogIjFjNzdlODg1LTYzZGUtNDdjOS05YzE5LTlhYTg4NzJlMGIyZCIsCiAgIlZvdWNoZXJDb2RlX19jIjogIm5ac3E4TURWIiwKICAiVm91Y2hlckNvZGVPd25lcl9fYyI6ICJidXZhcm92QHRoZW9yY2hhcmQuY29tIiwKICAiT3JjaGFyZFN5bmNJZF9fYyI6ICIyOTYxIiwKICAiQ29uc3VsdGFudF9fYyI6IGZhbHNlLAogICJNYWlsaW5nQ291bnRyeSI6ICJVU0EiCn0=' # noqa } ] } } config.STEP_FN_ARN = 'test-step-function-arn' client_mock = MagicMock() mock_boto3.client.return_value = client_mock client_mock.get_item.return_value = {} index.handler(event, None) client_mock.start_execution.assert_called_once() assert 'event.gdaApproval' == json.loads( client_mock.start_execution.call_args[1].get('input')).get('source')