From 31cf3c4252264271276693948c8237cc8d49b219 Mon Sep 17 00:00:00 2001 From: usmangani1 Date: Tue, 18 May 2021 12:21:27 +0530 Subject: [PATCH] Fix:SES-Added params check in template (#3753) * Fix:SES-Added params check in template * Added more tests and handled message * linting * fixed tests * fix attribute name in message * fix logic for exception --- moto/ses/exceptions.py | 10 +++++++++ moto/ses/models.py | 17 +++++++++++++++ tests/test_ses/test_ses_boto3.py | 36 +++++++++++++++++++++++++++++++- 3 files changed, 62 insertions(+), 1 deletion(-) diff --git a/moto/ses/exceptions.py b/moto/ses/exceptions.py index 46564af1e..42f9a77bd 100644 --- a/moto/ses/exceptions.py +++ b/moto/ses/exceptions.py @@ -87,3 +87,13 @@ class RuleSetDoesNotExist(RESTError): def __init__(self, message): super(RuleSetDoesNotExist, self).__init__("RuleSetDoesNotExist", message) + + +class MissingRenderingAttributeException(RESTError): + code = 400 + + def __init__(self, var): + super(MissingRenderingAttributeException, self).__init__( + "MissingRenderingAttributeException", + "Attribute '{0}' is not present in the rendering data.".format(var), + ) diff --git a/moto/ses/models.py b/moto/ses/models.py index c6722c3d1..f5ebcefc4 100644 --- a/moto/ses/models.py +++ b/moto/ses/models.py @@ -1,5 +1,6 @@ from __future__ import unicode_literals +import re import json import email import datetime @@ -22,6 +23,7 @@ from .exceptions import ( RuleSetNameAlreadyExists, RuleSetDoesNotExist, RuleAlreadyExists, + MissingRenderingAttributeException, ) from .utils import get_random_message_id from .feedback import COMMON_MAIL, BOUNCE, COMPLAINT, DELIVERY @@ -91,6 +93,17 @@ class SESQuota(BaseModel): return self.sent +def are_all_variables_present(template, template_data): + subject_part = template["subject_part"] + text_part = template["text_part"] + html_part = template["html_part"] + + for var in re.findall("{{(.+?)}}", subject_part + text_part + html_part): + if not template_data.get(var): + return var, False + return None, True + + class SESBackend(BaseBackend): def __init__(self): self.addresses = [] @@ -352,6 +365,10 @@ class SESBackend(BaseBackend): "Template rendering data is invalid" ) + var, are_variables_present = are_all_variables_present(template, template_data) + if not are_variables_present: + raise MissingRenderingAttributeException(var) + subject_part = template["subject_part"] text_part = template["text_part"] html_part = template["html_part"] diff --git a/tests/test_ses/test_ses_boto3.py b/tests/test_ses/test_ses_boto3.py index c071ddc1c..a3a273e85 100644 --- a/tests/test_ses/test_ses_boto3.py +++ b/tests/test_ses/test_ses_boto3.py @@ -8,7 +8,7 @@ from six.moves.email_mime_text import MIMEText import pytest -import sure # noqa +# import sure # noqa from moto import mock_ses @@ -531,6 +531,40 @@ def test_render_template(): result["RenderedTemplate"].should.contain("

Hello John,

") result["RenderedTemplate"].should.contain("Your favorite animal is Lion") + kwargs = dict( + TemplateName="MyTestTemplate", + TemplateData=json.dumps({"name": "John", "favoriteanimal": "Lion"}), + ) + + conn.create_template( + Template={ + "TemplateName": "MyTestTemplate1", + "SubjectPart": "Greetings, {{name}}!", + "TextPart": "Dear {{name}}," + "\r\nYour favorite animal is {{favoriteanimal}}.", + "HtmlPart": "

Hello {{name}}," + "

Your favorite animal is {{favoriteanimal }}.

", + } + ) + + result = conn.test_render_template(**kwargs) + result["RenderedTemplate"].should.contain("Subject: Greetings, John!") + result["RenderedTemplate"].should.contain("Dear John,") + result["RenderedTemplate"].should.contain("

Hello John,

") + result["RenderedTemplate"].should.contain("Your favorite animal is Lion") + + kwargs = dict( + TemplateName="MyTestTemplate", TemplateData=json.dumps({"name": "John"}), + ) + + with pytest.raises(ClientError) as ex: + conn.test_render_template(**kwargs) + assert ex.value.response["Error"]["Code"] == "MissingRenderingAttributeException" + assert ( + ex.value.response["Error"]["Message"] + == "Attribute 'favoriteanimal' is not present in the rendering data." + ) + @mock_ses def test_update_ses_template():