Files
django-anymail/tests/test_postmark_webhooks.py
medmunds 26cb882636 Postmark: Update docs and tests for "modular webhooks"
Existing tracking webhook code works fine with updated event payloads.
(So older Anymail versions will work, unmodified, with new Postmark
webhooks.)

Also update older doc links into Postmark docs.

Closes #101
2018-04-06 14:31:03 -07:00

205 lines
10 KiB
Python

import json
from datetime import datetime
from django.utils.timezone import get_fixed_timezone, utc
from mock import ANY
from anymail.signals import AnymailTrackingEvent
from anymail.webhooks.postmark import PostmarkTrackingWebhookView
from .webhook_cases import WebhookBasicAuthTestsMixin, WebhookTestCase
class PostmarkWebhookSecurityTestCase(WebhookTestCase, WebhookBasicAuthTestsMixin):
def call_webhook(self):
return self.client.post('/anymail/postmark/tracking/',
content_type='application/json', data=json.dumps({}))
# Actual tests are in WebhookBasicAuthTestsMixin
class PostmarkDeliveryTestCase(WebhookTestCase):
def test_bounce_event(self):
raw_event = {
"RecordType": "Bounce",
"ID": 901542550,
"Type": "HardBounce",
"TypeCode": 1,
"ServerID": 23,
"Name": "Hard bounce",
"MessageID": "2706ee8a-737c-4285-b032-ccd317af53ed",
"Description": "The server was unable to deliver your message (ex: unknown user, mailbox not found).",
"Details": "smtp;550 5.1.1 The email account that you tried to reach does not exist.",
"Email": "bounce@example.com",
"From": "sender@example.com",
"BouncedAt": "2016-04-27T16:28:50.3963933-04:00",
"DumpAvailable": True,
"Inactive": True,
"CanActivate": True,
"Subject": "Postmark event test",
"Content": "..."
}
response = self.client.post('/anymail/postmark/tracking/',
content_type='application/json', data=json.dumps(raw_event))
self.assertEqual(response.status_code, 200)
kwargs = self.assert_handler_called_once_with(self.tracking_handler, sender=PostmarkTrackingWebhookView,
event=ANY, esp_name='Postmark')
event = kwargs['event']
self.assertIsInstance(event, AnymailTrackingEvent)
self.assertEqual(event.event_type, "bounced")
self.assertEqual(event.esp_event, raw_event)
self.assertEqual(event.timestamp, datetime(2016, 4, 27, 16, 28, 50, microsecond=396393,
tzinfo=get_fixed_timezone(-4*60)))
self.assertEqual(event.message_id, "2706ee8a-737c-4285-b032-ccd317af53ed")
self.assertEqual(event.event_id, "901542550")
self.assertEqual(event.recipient, "bounce@example.com")
self.assertEqual(event.reject_reason, "bounced")
self.assertEqual(event.description,
"The server was unable to deliver your message (ex: unknown user, mailbox not found).")
self.assertEqual(event.mta_response,
"smtp;550 5.1.1 The email account that you tried to reach does not exist.")
def test_delivered_event(self):
raw_event = {
"RecordType": "Delivery",
"ServerId": 23,
"MessageID": "883953f4-6105-42a2-a16a-77a8eac79483",
"Recipient": "recipient@example.com",
"Tag": "welcome-email",
"DeliveredAt": "2014-08-01T13:28:10.2735393-04:00",
"Details": "Test delivery webhook details"
}
response = self.client.post('/anymail/postmark/tracking/',
content_type='application/json', data=json.dumps(raw_event))
self.assertEqual(response.status_code, 200)
kwargs = self.assert_handler_called_once_with(self.tracking_handler, sender=PostmarkTrackingWebhookView,
event=ANY, esp_name='Postmark')
event = kwargs['event']
self.assertIsInstance(event, AnymailTrackingEvent)
self.assertEqual(event.event_type, "delivered")
self.assertEqual(event.esp_event, raw_event)
self.assertEqual(event.timestamp, datetime(2014, 8, 1, 13, 28, 10, microsecond=273539,
tzinfo=get_fixed_timezone(-4*60)))
self.assertEqual(event.message_id, "883953f4-6105-42a2-a16a-77a8eac79483")
self.assertEqual(event.recipient, "recipient@example.com")
self.assertEqual(event.tags, ["welcome-email"])
self.assertEqual(event.metadata, {})
def test_open_event(self):
raw_event = {
"RecordType": "Open",
"FirstOpen": True,
"Client": {"Name": "Gmail", "Company": "Google", "Family": "Gmail"},
"OS": {"Name": "unknown", "Company": "unknown", "Family": "unknown"},
"Platform": "Unknown",
"UserAgent": "Mozilla/5.0 (Windows NT 5.1; rv:11.0) Gecko Firefox/11.0",
"ReadSeconds": 0,
"Geo": {},
"MessageID": "f4830d10-9c35-4f0c-bca3-3d9b459821f8",
"ReceivedAt": "2016-04-27T16:21:41.2493688-04:00",
"Recipient": "recipient@example.com"
}
response = self.client.post('/anymail/postmark/tracking/',
content_type='application/json', data=json.dumps(raw_event))
self.assertEqual(response.status_code, 200)
kwargs = self.assert_handler_called_once_with(self.tracking_handler, sender=PostmarkTrackingWebhookView,
event=ANY, esp_name='Postmark')
event = kwargs['event']
self.assertIsInstance(event, AnymailTrackingEvent)
self.assertEqual(event.event_type, "opened")
self.assertEqual(event.esp_event, raw_event)
self.assertEqual(event.timestamp, datetime(2016, 4, 27, 16, 21, 41, microsecond=249368,
tzinfo=get_fixed_timezone(-4*60)))
self.assertEqual(event.message_id, "f4830d10-9c35-4f0c-bca3-3d9b459821f8")
self.assertEqual(event.recipient, "recipient@example.com")
self.assertEqual(event.user_agent, "Mozilla/5.0 (Windows NT 5.1; rv:11.0) Gecko Firefox/11.0")
self.assertEqual(event.tags, [])
self.assertEqual(event.metadata, {})
def test_click_event(self):
raw_event = {
"RecordType": "Click",
"ClickLocation": "HTML",
"Client": {
"Name": "Chrome 35.0.1916.153",
"Company": "Google",
"Family": "Chrome"
},
"OS": {
"Name": "OS X 10.7 Lion",
"Company": "Apple Computer, Inc.",
"Family": "OS X 10"
},
"Platform": "Desktop",
"UserAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) etc.",
"OriginalLink": "https://example.com/click/me",
"Geo": {
"CountryISOCode": "RS",
"Country": "Serbia",
"RegionISOCode": "VO",
"Region": "Autonomna Pokrajina Vojvodina",
"City": "Novi Sad",
"Zip": "21000",
"Coords": "45.2517,19.8369",
"IP": "8.8.8.8"
},
"MessageID": "f4830d10-9c35-4f0c-bca3-3d9b459821f8",
"ReceivedAt": "2017-10-25T15:21:11.9065619Z",
"Tag": "welcome-email",
"Recipient": "recipient@example.com"
}
response = self.client.post('/anymail/postmark/tracking/',
content_type='application/json', data=json.dumps(raw_event))
self.assertEqual(response.status_code, 200)
kwargs = self.assert_handler_called_once_with(self.tracking_handler, sender=PostmarkTrackingWebhookView,
event=ANY, esp_name='Postmark')
event = kwargs['event']
self.assertIsInstance(event, AnymailTrackingEvent)
self.assertEqual(event.event_type, "clicked")
self.assertEqual(event.esp_event, raw_event)
self.assertEqual(event.timestamp, datetime(2017, 10, 25, 15, 21, 11, microsecond=906561,
tzinfo=utc))
self.assertEqual(event.message_id, "f4830d10-9c35-4f0c-bca3-3d9b459821f8")
self.assertEqual(event.recipient, "recipient@example.com")
self.assertEqual(event.user_agent, "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) etc.")
self.assertEqual(event.click_url, "https://example.com/click/me")
self.assertEqual(event.tags, ["welcome-email"])
self.assertEqual(event.metadata, {})
def test_spam_event(self):
raw_event = {
"RecordType": "SpamComplaint",
"ID": 901542550,
"Type": "SpamComplaint",
"TypeCode": 512,
"Name": "Spam complaint",
"Tag": "Test",
"MessageID": "2706ee8a-737c-4285-b032-ccd317af53ed",
"ServerID": 1234,
"Description": "",
"Details": "Test spam complaint details",
"Email": "spam@example.com",
"From": "sender@example.com",
"BouncedAt": "2016-04-27T16:28:50.3963933-04:00",
"DumpAvailable": True,
"Inactive": True,
"CanActivate": False,
"Subject": "Postmark event test"
}
response = self.client.post('/anymail/postmark/tracking/',
content_type='application/json', data=json.dumps(raw_event))
self.assertEqual(response.status_code, 200)
kwargs = self.assert_handler_called_once_with(self.tracking_handler, sender=PostmarkTrackingWebhookView,
event=ANY, esp_name='Postmark')
event = kwargs['event']
self.assertIsInstance(event, AnymailTrackingEvent)
self.assertEqual(event.event_type, "complained")
self.assertEqual(event.esp_event, raw_event)
self.assertEqual(event.timestamp, datetime(2016, 4, 27, 16, 28, 50, microsecond=396393,
tzinfo=get_fixed_timezone(-4*60)))
self.assertEqual(event.message_id, "2706ee8a-737c-4285-b032-ccd317af53ed")
self.assertEqual(event.event_id, "901542550")
self.assertEqual(event.recipient, "spam@example.com")
self.assertEqual(event.reject_reason, "spam")
self.assertEqual(event.description, "")
self.assertEqual(event.mta_response, "Test spam complaint details")