SendinBlue: additional template/tags improvements

Additional changes related to SendinBlue improvements in #158:

* Support multiple tags in webhooks (closes #162)
* Remove additional outdated template code in backend
* Update integration tests
* Update docs and changelog; note breaking changes as discussed in #161
This commit is contained in:
Mike Edmunds
2019-09-04 15:45:08 -07:00
committed by GitHub
parent fd558e904e
commit 0a8887913c
7 changed files with 127 additions and 53 deletions

View File

@@ -344,19 +344,6 @@ class SendinBlueBackendAnymailFeatureTests(SendinBlueBackendMockAPITestCase):
self.assertEqual(data['subject'], 'My Subject')
self.assertEqual(data['to'], [{'email': "to@example.com", 'name': 'Recipient'}])
def test_unsupported_template_overrides(self):
# SendinBlue doesn't allow overriding any template headers/content
message = mail.EmailMessage(to=['to@example.com'])
message.template_id = "9"
message.body = "nope, can't change text body"
with self.assertRaisesMessage(AnymailUnsupportedFeature, "overriding template body content"):
message.send()
message.content_subtype = "html"
with self.assertRaisesMessage(AnymailUnsupportedFeature, "overriding template body content"):
message.send()
message.body = None
def test_merge_data(self):
self.message.merge_data = {
'alice@example.com': {':name': "Alice", ':group': "Developers"},

View File

@@ -63,7 +63,7 @@ class SendinBlueBackendIntegrationTests(SimpleTestCase, AnymailTestMixin):
headers={"X-Anymail-Test": "value", "X-Anymail-Count": 3},
metadata={"meta1": "simple string", "meta2": 2},
tags=["tag 1"], # SendinBlue only supports single tags
tags=["tag 1", "tag 2"],
)
message.attach_alternative('<p>HTML content</p>', "text/html") # SendinBlue requires an HTML body
@@ -76,22 +76,32 @@ class SendinBlueBackendIntegrationTests(SimpleTestCase, AnymailTestMixin):
def test_template(self):
message = AnymailMessage(
template_id=1, # There is a template with this id in the Anymail test account
to=["test+to1@anymail.info"], # SendinBlue doesn't allow recipient display names with templates
reply_to=["reply@example.com"],
template_id=5, # There is a *new-style* template with this id in the Anymail test account
from_email='Sender <from@test-sb.anymail.info>', # Override template sender
to=["Recipient <test+to1@anymail.info>"], # No batch send (so max one recipient suggested)
reply_to=["Do not reply <reply@example.com>"],
tags=["using-template"],
headers={"X-Anymail-Test": "group: A, variation: C"},
merge_global_data={
# The Anymail test template includes `%SHIP_DATE%` and `%ORDER_ID%` variables
# The Anymail test template includes `{{ params.SHIP_DATE }}`
# and `{{ params.ORDER_ID }}` substitutions
"SHIP_DATE": "yesterday",
"ORDER_ID": "12345",
},
metadata={"customer-id": "ZXK9123", "meta2": 2},
)
message.from_email = None # Required for SendinBlue templates
# Attachments don't work with templates in Sendinblue's newer API:
# message.attach("attachment1.txt", "Here is some\ntext for you", "text/plain")
# Normal attachments don't work with Sendinblue templates:
# message.attach("attachment1.txt", "Here is some\ntext for you", "text/plain")
# If you can host the attachment content on some publicly-accessible URL,
# this *non-portable* alternative allows sending attachments with templates:
message.esp_extra = {
'attachment': [{
'name': 'attachment1.txt',
# URL where Sendinblue can download the attachment content while sending:
'url': 'https://raw.githubusercontent.com/anymail/django-anymail/master/AUTHORS.txt',
}]
}
message.send()
self.assertEqual(message.anymail_status.status, {'queued'}) # SendinBlue always queues

View File

@@ -21,8 +21,9 @@ class SendinBlueWebhookSecurityTestCase(WebhookTestCase, WebhookBasicAuthTestsMi
@tag('sendinblue')
class SendinBlueDeliveryTestCase(WebhookTestCase):
# SendinBlue's webhook payload data doesn't seem to be documented anywhere.
# There's a list of webhook events at https://apidocs.sendinblue.com/webhooks/#3.
# SendinBlue's webhook payload data is partially documented at
# https://help.sendinblue.com/hc/en-us/articles/360007666479,
# but it's not completely up to date.
# The payloads below were obtained through live testing.
def test_sent_event(self):
@@ -40,7 +41,13 @@ class SendinBlueDeliveryTestCase(WebhookTestCase):
"ts_epoch": 1520363423000, # 2018-03-06 19:10:23.000+00:00 -- UTC (milliseconds)
"X-Mailin-custom": '{"meta": "data"}',
"tag": "test-tag", # note: for template send, is template name if no other tag provided
# "tag" is JSON-serialized tags array if `tags` param set on send,
# else single tag string if `X-Mailin-Tag` header set on send,
# else template name if sent using a template,
# else not present.
# "tags" is tags list if `tags` param set on send, else not present.
"tag": '["tag1","tag2"]',
"tags": ["tag1", "tag2"],
"template_id": 12,
"sending_ip": "333.33.33.33",
}
@@ -58,7 +65,7 @@ class SendinBlueDeliveryTestCase(WebhookTestCase):
self.assertIsNone(event.event_id) # SendinBlue does not provide a unique event id
self.assertEqual(event.recipient, "recipient@example.com")
self.assertEqual(event.metadata, {"meta": "data"})
self.assertEqual(event.tags, ["test-tag"])
self.assertEqual(event.tags, ["tag1", "tag2"])
def test_delivered_event(self):
raw_event = {
@@ -91,6 +98,7 @@ class SendinBlueDeliveryTestCase(WebhookTestCase):
"message-id": "<201803011158.9876543210@smtp-relay.mailin.fr>",
# the leading space in the reason is as received in actual testing:
"reason": " RecipientError: 550 5.5.0 Requested action not taken: mailbox unavailable.",
"tag": "header-tag",
}
response = self.client.post('/anymail/sendinblue/tracking/',
content_type='application/json', data=json.dumps(raw_event))
@@ -102,6 +110,7 @@ class SendinBlueDeliveryTestCase(WebhookTestCase):
self.assertEqual(event.reject_reason, "bounced")
self.assertEqual(event.mta_response,
" RecipientError: 550 5.5.0 Requested action not taken: mailbox unavailable.")
self.assertEqual(event.tags, ["header-tag"])
def test_soft_bounce_event(self):
raw_event = {