From 920d8dd70fb6479895b5391bbeb2cf2c1bbae0d9 Mon Sep 17 00:00:00 2001 From: Mike Edmunds Date: Wed, 18 Mar 2020 17:08:10 -0400 Subject: [PATCH] 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 --- CHANGELOG.rst | 14 ++++++++++++++ anymail/backends/sendgrid.py | 3 ++- tests/test_sendgrid_backend.py | 14 ++++++++++++++ 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index ff63534..b599f25 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -25,6 +25,19 @@ Release history ^^^^^^^^^^^^^^^ .. 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 ---- @@ -1021,4 +1034,5 @@ Features .. _@sebbacon: https://github.com/sebbacon .. _@Thorbenl: https://github.com/Thorbenl .. _@varche1: https://github.com/varche1 +.. _@vgrebenschikov: https://github.com/vgrebenschikov .. _@yourcelf: https://github.com/yourcelf diff --git a/anymail/backends/sendgrid.py b/anymail/backends/sendgrid.py index e2eef03..6232969 100644 --- a/anymail/backends/sendgrid.py +++ b/anymail/backends/sendgrid.py @@ -133,8 +133,9 @@ class SendGridPayload(RequestsPayload): if self.merge_data or self.merge_global_data: # Always build dynamic_template_data first, # 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"]: - assert len(personalization["to"]) == 1 + assert len(personalization["to"]) == 1 or only_global_merge_data recipient_email = personalization["to"][0]["email"] dynamic_template_data = self.merge_global_data.copy() dynamic_template_data.update(self.merge_data.get(recipient_email, {})) diff --git a/tests/test_sendgrid_backend.py b/tests/test_sendgrid_backend.py index 7820f57..b8a1b5f 100644 --- a/tests/test_sendgrid_backend.py +++ b/tests/test_sendgrid_backend.py @@ -493,6 +493,20 @@ class SendGridBackendAnymailFeatureTests(SendGridBackendMockAPITestCase): 'custom_args': {'anymail_id': 'mocked-uuid-2'}, '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): # unless a new "dynamic template" is specified, Anymail assumes the legacy # "substitutions" format for merge data