8000 SES: Fix sent email counter double incrementing (#7919) · codeperl/localstack@6ec5683 · GitHub
[go: up one dir, main page]

Skip to content

Commit 6ec5683

Browse files
SES: Fix sent email counter double incrementing (localstack#7919)
1 parent b4e4c5d commit 6ec5683

File tree

2 files changed

+71
-38
lines changed

2 files changed

+71
-38
lines changed

localstack/services/ses/provider.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,6 @@ def send_raw_email(
438438
tags: MessageTagList = None,
439439
configuration_set_name: ConfigurationSetName = None,
440440
) -> SendRawEmailResponse:
441-
response = call_moto(context)
442441
raw_data = to_str(raw_message["Data"])
443442

444443
if source is None or not source.strip():
@@ -449,6 +448,7 @@ def send_raw_email(
449448
LOGGER.warning("Source not specified. Rejecting message.")
450449
raise MessageRejected()
451450

451+
# TODO: On AWS, `destinations` is ignored if the `To` field is set in the raw email.
452452
destinations = destinations or []
453453

454454
backend = get_ses_backend(context)
@@ -464,7 +464,7 @@ def send_raw_email(
464464
continue
465465

466466
payload = SNSPayload(
467-
message_id=response["MessageId"],
467+
message_id=message.id 10000 ,
468468
sender_email=source,
469469
destination_addresses=destinations,
470470
tags=tags,

tests/integration/test_ses.py

Lines changed: 69 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,27 @@
1414
if TYPE_CHECKING:
1515
from mypy_boto3_ses import SESClient
1616

17-
TEST_TEMPLATE_ATTRIBUTES = {
17+
SAMPLE_TEMPLATE = {
1818
"TemplateName": "hello-world",
1919
"SubjectPart": "Subject test",
2020
"TextPart": "hello\nworld",
2121
"HtmlPart": "hello<br/>world",
2222
}
2323

24+
SAMPLE_SIMPLE_EMAIL = {
25+
"Subject": {
26+
"Data": "SOME_SUBJECT",
27+
},
28+
"Body": {
29+
"Text": {
30+
"Data": "SOME_MESSAGE",
31+
},
32+
"Html": {
33+
"Data": "<p>SOME_HTML</p>",
34+
},
35+
},
36+
}
37+
2438

2539
@pytest.fixture
2640
def create_template(ses_client):
@@ -81,27 +95,27 @@ def sort_mail_sqs_messages(message):
8195

8296
class TestSES:
8397
def test_list_templates(self, ses_client, create_template):
84-
create_template(Template=TEST_TEMPLATE_ATTRIBUTES)
98+
create_template(Template=SAMPLE_TEMPLATE)
8599
templ_list = ses_client.list_templates()["TemplatesMetadata"]
86100
assert 1 == len(templ_list)
87101
created_template = templ_list[0]
88-
assert TEST_TEMPLATE_ATTRIBUTES["TemplateName"] == created_template["Name"]
102+
assert SAMPLE_TEMPLATE["TemplateName"] == created_template["Name"]
89103
assert type(created_template["CreatedTimestamp"]) in (date, datetime)
90104

91105
# Should not fail after 2 consecutive tries
92106
templ_list = ses_client.list_templates()["TemplatesMetadata"]
93107
assert 1 == len(templ_list)
94108
created_template = templ_list[0]
95-
assert TEST_TEMPLATE_ATTRIBUTES["TemplateName"] == created_template["Name"]
109+
assert SAMPLE_TEMPLATE["TemplateName"] == created_template["Name"]
96110
assert type(created_template["CreatedTimestamp"]) in (date, datetime)
97111

98112
def test_delete_template(self, ses_client, create_template):
99113
templ_list = ses_client.list_templates()["TemplatesMetadata"]
100114
assert 0 == len(templ_list)
101-
create_template(Template=TEST_TEMPLATE_ATTRIBUTES)
115+
create_template(Template=SAMPLE_TEMPLATE)
102116
templ_list = ses_client.list_templates()["TemplatesMetadata"]
103117
assert 1 == len(templ_list)
104-
ses_client.delete_template(TemplateName=TEST_TEMPLATE_ATTRIBUTES["TemplateName"])
118+
ses_client.delete_template(TemplateName=SAMPLE_TEMPLATE["TemplateName"])
105119
templ_list = ses_client.list_templates()["TemplatesMetadata"]
106120
assert 0 == len(templ_list)
107121

@@ -134,19 +148,7 @@ def _read_message_from_filesystem(message_id: str) -> dict:
134148
# Send a regular message
135149
message1 = ses_client.send_email(
136150
Source=email,
137-
Message={
138-
"Subject": {
139-
"Data": "A_SUBJECT",
140-
},
141-
"Body": {
142-
"Text": {
143-
"Data": "A_MESSAGE",
144-
},
145-
"Html": {
146-
"Data": "A_HTML",
147-
},
148-
},
149-
},
151+
Message=SAMPLE_SIMPLE_EMAIL,
150152
Destination={
151153
"ToAddresses": ["success@example.com"],
152154
},
@@ -160,8 +162,11 @@ def _read_message_from_filesystem(message_id: str) -> dict:
160162
assert contents1["Region"]
161163
assert contents1["Source"] == email
162164
assert contents1["Destination"] == {"ToAddresses": ["success@example.com"]}
163-
assert contents1["Subject"] == "A_SUBJECT"
164-
assert contents1["Body"] == {"text_part": "A_MESSAGE", "html_part": "A_HTML"}
165+
assert contents1["Subject"] == SAMPLE_SIMPLE_EMAIL["Subject"]["Data"]
166+
assert contents1["Body"] == {
167+
"text_part": SAMPLE_SIMPLE_EMAIL["Body"]["Text"]["Data"],
168+
"html_part": SAMPLE_SIMPLE_EMAIL["Body"]["Html"]["Data"],
169+
}
165170
assert "RawData" not in contents1
166171

167172
# Send a raw message
@@ -208,12 +213,12 @@ def test_send_templated_email_can_retrospect(self, ses_client, create_template):
208213
data_dir = config.dirs.data or config.dirs.tmp
209214
email = f"user-{short_uid()}@example.com"
210215
ses_client.verify_email_address(EmailAddress=email)
211-
ses_client.delete_template(TemplateName=TEST_TEMPLATE_ATTRIBUTES["TemplateName"])
212-
create_template(Template=TEST_TEMPLATE_ATTRIBUTES)
216+
ses_client.delete_template(TemplateName=SAMPLE_TEMPLATE["TemplateName"])
217+
create_template(Template=SAMPLE_TEMPLATE)
213218

214219
message = ses_client.send_templated_email(
215220
Source=email,
216-
Template=TEST_TEMPLATE_ATTRIBUTES["TemplateName"],
221+
Template=SAMPLE_TEMPLATE["TemplateName"],
217222
TemplateData='{"A key": "A value"}',
218223
Destination={
219224
"ToAddresses": ["success@example.com"],
@@ -227,7 +232,7 @@ def test_send_templated_email_can_retrospect(self, ses_client, create_template):
227232
contents = json.loads(message)
228233

229234
assert email == contents["Source"]
230-
assert TEST_TEMPLATE_ATTRIBUTES["TemplateName"] == contents["Template"]
235+
assert SAMPLE_TEMPLATE["TemplateName"] == contents["Template"]
231236
assert '{"A key": "A value"}' == contents["TemplateData"]
232237
assert ["success@example.com"] == contents["Destination"]["ToAddresses"]
233238

@@ -239,6 +244,44 @@ def test_send_templated_email_can_retrospect(self, ses_client, create_template):
239244
assert requests.delete("http://localhost:4566/_aws/ses").status_code == 204
240245
assert requests.get("http://localhost:4566/_aws/ses").json() == {"messages": []}
241246

247+
def test_sent_message_counter(self, ses_client, create_template):
248+
# Ensure all email send operations correctly update the sent email counter
249+
email = f"user-{short_uid()}@example.com"
250+
ses_client.verify_email_address(EmailAddress=email)
251+
252+
counter = ses_client.get_send_quota()["SentLast24Hours"]
253+
254+
ses_client.send_email(
255+
Source=email,
256+
Message=SAMPLE_SIMPLE_EMAIL,
257+
Destination={
258+
"ToAddresses": ["success@example.com"],
259+
},
260+
)
261+
262+
new_counter = ses_client.get_send_quota()["SentLast24Hours"]
263+
assert new_counter == counter + 1
264+
counter = new_counter
265+
266+
create_template(Template=SAMPLE_TEMPLATE)
267+
ses_client.send_templated_email(
268+
Source=email,
269+
Template=SAMPLE_TEMPLATE["TemplateName"],
270+
TemplateData='{"A key": "A value"}',
271+
Destination={
272+
"ToAddresses": ["success@example.com", "lorem@ipsum.co"],
273+
},
274+
)
275+
276+
new_counter = ses_client.get_send_quota()["SentLast24Hours"]
277+
assert new_counter == counter + 2
278+
counter = new_counter
279+
280+
raw_message_data = f"From: {email}\nTo: recipient@example.com\nSubject: test\n\nThis is the message body.\n\n"
281+
ses_client.send_raw_email(RawMessage={"Data": raw_message_data})
282+
new_counter = ses_client.get_send_quota()["SentLast24Hours"]
283+
assert new_counter == counter + 1
284+
242285
def test_clone_receipt_rule_set(self, ses_client):
243286
# Test that rule set is cloned properly
244287

@@ -362,19 +405,9 @@ def test_ses_sns_topic_integration_send_email(
362405
destination = {
363406
"ToAddresses": [recipient_email_address],
364407
}
365-
message = {
366-
"Subject": {
367-
"Data": "foo subject",
368-
},
369-
"Body": {
370-
"Text": {
371-
"Data": "saml body",
372-
},
373-
},
374-
}
375408
ses_client.send_email(
376409
Destination=destination,
377-
Message=message,
410+
Message=SAMPLE_SIMPLE_EMAIL,
378411
ConfigurationSetName=config_set_name,
379412
Source=sender_email_address,
380413
Tags=[

0 commit comments

Comments
 (0)
0