mirror of
https://github.com/pacnpal/django-anymail.git
synced 2025-12-20 03:41:05 -05:00
SendGrid: merge 'filters' in esp_extra
Previously, setting esp_extra['x-smtpapi']['filters'] would override the entire filters setting, potentially undoing other Anymail options that use SendGrid filters (like track_opens). Now, 'filters' is special-cased, and merged with any other Anymail filter options. (We don't do a fully deep merge, because otherwise there would be no way to use esp_extra to *clear* Anymail settings.)
This commit is contained in:
@@ -91,7 +91,13 @@ class SendGridPayload(RequestsPayload):
|
|||||||
# If esp_extra was also used to set x-smtpapi, need to merge it
|
# If esp_extra was also used to set x-smtpapi, need to merge it
|
||||||
if "x-smtpapi" in self.data:
|
if "x-smtpapi" in self.data:
|
||||||
esp_extra_smtpapi = self.data["x-smtpapi"]
|
esp_extra_smtpapi = self.data["x-smtpapi"]
|
||||||
self.smtpapi.update(esp_extra_smtpapi) # need to make this deep merge (for filters)!
|
for key, value in esp_extra_smtpapi.items():
|
||||||
|
if key == "filters":
|
||||||
|
# merge filters (else it's difficult to mix esp_extra with other features)
|
||||||
|
self.smtpapi.setdefault(key, {}).update(value)
|
||||||
|
else:
|
||||||
|
# all other keys replace any current value
|
||||||
|
self.smtpapi[key] = value
|
||||||
self.data["x-smtpapi"] = self.serialize_json(self.smtpapi)
|
self.data["x-smtpapi"] = self.serialize_json(self.smtpapi)
|
||||||
elif "x-smtpapi" in self.data:
|
elif "x-smtpapi" in self.data:
|
||||||
self.data["x-smtpapi"] = self.serialize_json(self.data["x-smtpapi"])
|
self.data["x-smtpapi"] = self.serialize_json(self.data["x-smtpapi"])
|
||||||
|
|||||||
@@ -117,7 +117,16 @@ Example:
|
|||||||
message.esp_extra = {
|
message.esp_extra = {
|
||||||
'x-smtpapi': {
|
'x-smtpapi': {
|
||||||
"asm_group": 1, # Assign SendGrid unsubscribe group for this message
|
"asm_group": 1, # Assign SendGrid unsubscribe group for this message
|
||||||
"asm_groups_to_display": [1, 2, 3]
|
"asm_groups_to_display": [1, 2, 3],
|
||||||
|
"filters": {
|
||||||
|
"subscriptiontrack": { # Insert SendGrid subscription management links
|
||||||
|
"settings": {
|
||||||
|
"text/html": "If you would like to unsubscribe <% click here %>.",
|
||||||
|
"text/plain": "If you would like to unsubscribe click here: <% %>.",
|
||||||
|
"enable": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -423,18 +423,35 @@ class SendGridBackendAnymailFeatureTests(SendGridBackendMockAPITestCase):
|
|||||||
|
|
||||||
def test_esp_extra(self):
|
def test_esp_extra(self):
|
||||||
self.message.tags = ["tag"]
|
self.message.tags = ["tag"]
|
||||||
|
self.message.track_clicks = True
|
||||||
self.message.esp_extra = {
|
self.message.esp_extra = {
|
||||||
'x-smtpapi': {'asm_group_id': 1},
|
'x-smtpapi': {
|
||||||
|
# Most SendMail options go in the 'x-smtpapi' block...
|
||||||
|
'asm_group_id': 1,
|
||||||
|
'filters': {
|
||||||
|
# If you add a filter, you must supply all required settings for it.
|
||||||
|
'subscriptiontrack': {
|
||||||
|
'settings': {
|
||||||
|
'enable': 1,
|
||||||
|
'replace': '[unsubscribe_url]',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
'newthing': "some param not supported by Anymail",
|
'newthing': "some param not supported by Anymail",
|
||||||
}
|
}
|
||||||
self.message.send()
|
self.message.send()
|
||||||
# Additional send params:
|
# Additional send params:
|
||||||
data = self.get_api_call_data()
|
data = self.get_api_call_data()
|
||||||
self.assertEqual(data['newthing'], "some param not supported by Anymail")
|
self.assertEqual(data['newthing'], "some param not supported by Anymail")
|
||||||
# Should merge x-smtpapi
|
# Should merge x-smtpapi, and merge filters within x-smtpapi
|
||||||
smtpapi = self.get_smtpapi()
|
smtpapi = self.get_smtpapi()
|
||||||
self.assertEqual(smtpapi['category'], ["tag"])
|
self.assertEqual(smtpapi['category'], ["tag"])
|
||||||
self.assertEqual(smtpapi['asm_group_id'], 1)
|
self.assertEqual(smtpapi['asm_group_id'], 1)
|
||||||
|
self.assertEqual(smtpapi['filters']['subscriptiontrack'],
|
||||||
|
{'settings': {'enable': 1, 'replace': '[unsubscribe_url]'}}) # esp_extra merged
|
||||||
|
self.assertEqual(smtpapi['filters']['clicktrack'],
|
||||||
|
{'settings': {'enable': 1}}) # Anymail message option preserved
|
||||||
|
|
||||||
# noinspection PyUnresolvedReferences
|
# noinspection PyUnresolvedReferences
|
||||||
def test_send_attaches_anymail_status(self):
|
def test_send_attaches_anymail_status(self):
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
# Anymail test utils
|
# Anymail test utils
|
||||||
import sys
|
import sys
|
||||||
import unittest
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import six
|
|
||||||
import warnings
|
import warnings
|
||||||
from base64 import b64decode
|
from base64 import b64decode
|
||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
@@ -60,19 +58,23 @@ class AnymailTestMixin:
|
|||||||
finally:
|
finally:
|
||||||
warnings.resetwarnings()
|
warnings.resetwarnings()
|
||||||
|
|
||||||
# Plus these methods added below:
|
def assertCountEqual(self, *args, **kwargs):
|
||||||
# assertCountEqual
|
try:
|
||||||
# assertRaisesRegex
|
return super(AnymailTestMixin, self).assertCountEqual(*args, **kwargs)
|
||||||
# assertRegex
|
except TypeError:
|
||||||
|
return self.assertItemsEqual(*args, **kwargs) # Python 2
|
||||||
|
|
||||||
# Add the Python 3 TestCase assertions, if they're not already there.
|
def assertRaisesRegex(self, *args, **kwargs):
|
||||||
# (The six implementations cause infinite recursion if installed on
|
try:
|
||||||
# a py3 TestCase.)
|
return super(AnymailTestMixin, self).assertRaisesRegex(*args, **kwargs)
|
||||||
for method in ('assertCountEqual', 'assertRaisesRegex', 'assertRegex'):
|
except TypeError:
|
||||||
try:
|
return self.assertRaisesRegexp(*args, **kwargs) # Python 2
|
||||||
getattr(unittest.TestCase, method)
|
|
||||||
except AttributeError:
|
def assertRegex(self, *args, **kwargs):
|
||||||
setattr(AnymailTestMixin, method, getattr(six, method))
|
try:
|
||||||
|
return super(AnymailTestMixin, self).assertRegex(*args, **kwargs)
|
||||||
|
except TypeError:
|
||||||
|
return self.assertRegexpMatches(*args, **kwargs) # Python 2
|
||||||
|
|
||||||
|
|
||||||
# Backported from python 3.5
|
# Backported from python 3.5
|
||||||
|
|||||||
Reference in New Issue
Block a user