SendGrid: Fix multiple recipients with only merge_global_data

In SendGrid backend, support non-batch template send to multiple
recipients when `merge_global_data` is set without `merge_data`.
Regression introduced in v6.0.

Fixes #179
This commit is contained in:
Mike Edmunds
2020-03-18 17:08:10 -04:00
committed by GitHub
parent 4245d468ec
commit 920d8dd70f
3 changed files with 30 additions and 1 deletions

View File

@@ -25,6 +25,19 @@ Release history
^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^
.. This extra heading level keeps the ToC from becoming unmanageably long .. This extra heading level keeps the ToC from becoming unmanageably long
vNext
-----
*Unreleased changes on master*
Fixes
~~~~~
* **SendGrid:** Allow non-batch template send to multiple recipients when
`merge_global_data` is set without `merge_data`. (Broken in v6.0. Thanks to
`@vgrebenschikov`_ for the bug report.)
v7.0 v7.0
---- ----
@@ -1021,4 +1034,5 @@ Features
.. _@sebbacon: https://github.com/sebbacon .. _@sebbacon: https://github.com/sebbacon
.. _@Thorbenl: https://github.com/Thorbenl .. _@Thorbenl: https://github.com/Thorbenl
.. _@varche1: https://github.com/varche1 .. _@varche1: https://github.com/varche1
.. _@vgrebenschikov: https://github.com/vgrebenschikov
.. _@yourcelf: https://github.com/yourcelf .. _@yourcelf: https://github.com/yourcelf

View File

@@ -133,8 +133,9 @@ class SendGridPayload(RequestsPayload):
if self.merge_data or self.merge_global_data: if self.merge_data or self.merge_global_data:
# Always build dynamic_template_data first, # Always build dynamic_template_data first,
# then convert it to legacy template format if needed # then convert it to legacy template format if needed
only_global_merge_data = self.merge_global_data and not self.merge_data
for personalization in self.data["personalizations"]: for personalization in self.data["personalizations"]:
assert len(personalization["to"]) == 1 assert len(personalization["to"]) == 1 or only_global_merge_data
recipient_email = personalization["to"][0]["email"] recipient_email = personalization["to"][0]["email"]
dynamic_template_data = self.merge_global_data.copy() dynamic_template_data = self.merge_global_data.copy()
dynamic_template_data.update(self.merge_data.get(recipient_email, {})) dynamic_template_data.update(self.merge_data.get(recipient_email, {}))

View File

@@ -493,6 +493,20 @@ class SendGridBackendAnymailFeatureTests(SendGridBackendMockAPITestCase):
'custom_args': {'anymail_id': 'mocked-uuid-2'}, 'custom_args': {'anymail_id': 'mocked-uuid-2'},
'substitutions': {"<%test%>": "data"}}]) 'substitutions': {"<%test%>": "data"}}])
def test_merge_data_global_only(self):
# a template with only global data can be used to send the same message
# to multiple recipients (non-batch)
self.message.template_id = "d-5a963add2ec84305813ff860db277d7a"
self.message.merge_global_data = {"test": "data"}
self.message.to = ["one@example.com", "two@example.com"]
self.message.send()
data = self.get_api_call_json()
self.assertEqual(data['personalizations'], [
{'to': [{'email': 'one@example.com'}, {'email': 'two@example.com'}], # not batch
'custom_args': {'anymail_id': 'mocked-uuid-1'},
'dynamic_template_data': {"test": "data"}}])
def test_legacy_merge_data(self): def test_legacy_merge_data(self):
# unless a new "dynamic template" is specified, Anymail assumes the legacy # unless a new "dynamic template" is specified, Anymail assumes the legacy
# "substitutions" format for merge data # "substitutions" format for merge data