diff --git a/samtranslator/plugins/api/implicit_api_plugin.py b/samtranslator/plugins/api/implicit_api_plugin.py index 194ac6a160..dfa74d610a 100644 --- a/samtranslator/plugins/api/implicit_api_plugin.py +++ b/samtranslator/plugins/api/implicit_api_plugin.py @@ -150,6 +150,11 @@ def _process_api_events(self, function, api_events, template, condition=None): raise InvalidEventException(logicalId, "Api Event must have a String specified for 'Method'.") + # !Ref is resolved by this time. If it is still a dict, we can't parse/use this Api. + if (isinstance(api_id, dict)): + raise InvalidEventException(logicalId, + "Api Event must reference an Api in the same template.") + api_dict = self.api_conditions.setdefault(api_id, {}) method_conditions = api_dict.setdefault(path, {}) method_conditions[method] = condition diff --git a/tests/plugins/api/test_implicit_api_plugin.py b/tests/plugins/api/test_implicit_api_plugin.py index 4dfa09a182..11f18ab855 100644 --- a/tests/plugins/api/test_implicit_api_plugin.py +++ b/tests/plugins/api/test_implicit_api_plugin.py @@ -447,6 +447,31 @@ def test_must_verify_method_is_string(self): with self.assertRaises(InvalidEventException) as context: self.plugin._process_api_events(function, api_events, template) + def test_must_verify_rest_api_id_is_string(self): + api_events = { + "Api1": { + "Type": "Api", + "Properties": { + "Path": "/", + "Method": ["POST"], + "RestApiId": {"Fn::ImportValue": {"Fn::Sub": {"ApiName"}}} + } + } + } + + template = Mock() + function_events_mock = Mock() + function = SamResource({ + "Type": SamResourceType.Function.value, + "Properties": { + "Events": function_events_mock + } + }) + function_events_mock.update = Mock() + + with self.assertRaises(InvalidEventException) as context: + self.plugin._process_api_events(function, api_events, template) + def test_must_verify_path_is_string(self): api_events = { "Api1": { diff --git a/tests/translator/input/error_api_event_import_vaule_reference.yaml b/tests/translator/input/error_api_event_import_vaule_reference.yaml new file mode 100644 index 0000000000..45e440bbcc --- /dev/null +++ b/tests/translator/input/error_api_event_import_vaule_reference.yaml @@ -0,0 +1,21 @@ +Parameters: + Api: + Type: String + Default: MyApi + +Resources: + Function: + Type: AWS::Serverless::Function + Properties: + CodeUri: s3://sam-demo-bucket/member_portal.zip + Handler: index.gethtml + Runtime: nodejs4.3 + Events: + GetHtml: + Type: Api + Properties: + Path: / + Method: get + RestApiId: + Fn::ImportValue: + Fn::Sub: ${Api} diff --git a/tests/translator/output/error_api_event_import_vaule_reference.json b/tests/translator/output/error_api_event_import_vaule_reference.json new file mode 100644 index 0000000000..fa85df16bc --- /dev/null +++ b/tests/translator/output/error_api_event_import_vaule_reference.json @@ -0,0 +1 @@ +{"errorMessage":"Invalid Serverless Application Specification document. Number of errors found: 1. Resource with id [Function] is invalid. Event with id [GetHtml] is invalid. Api Event must reference an Api in the same template."} \ No newline at end of file diff --git a/tests/translator/test_translator.py b/tests/translator/test_translator.py index 486e38faa4..52f1efdcd8 100644 --- a/tests/translator/test_translator.py +++ b/tests/translator/test_translator.py @@ -548,7 +548,8 @@ def _generate_new_deployment_hash(self, logical_id, dict_to_hash, rest_api_to_sw 'error_invalid_document_empty_semantic_version', 'error_api_with_invalid_open_api_version_type', 'error_api_with_custom_domains_invalid', - 'error_api_with_custom_domains_route53_invalid' + 'error_api_with_custom_domains_route53_invalid', + 'error_api_event_import_vaule_reference' ]) @patch('boto3.session.Session.region_name', 'ap-southeast-1') @patch('samtranslator.plugins.application.serverless_app_plugin.ServerlessAppPlugin._sar_service_call', mock_sar_service_call)