1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
|
from unittest import mock
from django.test import SimpleTestCase, override_settings, tag
from anymail.backends.base_requests import AnymailRequestsBackend, RequestsPayload
from anymail.message import AnymailMessage, AnymailRecipientStatus
from tests.utils import AnymailTestMixin
from .mock_requests_backend import RequestsBackendMockAPITestCase
class MinimalRequestsBackend(AnymailRequestsBackend):
"""(useful only for these tests)"""
esp_name = "Example"
api_url = "https://httpbin.org/post" # helpful echoback endpoint for live testing
def __init__(self, **kwargs):
super().__init__(self.api_url, **kwargs)
def build_message_payload(self, message, defaults):
_payload_init = getattr(message, "_payload_init", {})
return MinimalRequestsPayload(message, defaults, self, **_payload_init)
def parse_recipient_status(self, response, payload, message):
return {"to@example.com": AnymailRecipientStatus("message-id", "sent")}
class MinimalRequestsPayload(RequestsPayload):
def init_payload(self):
pass
def _noop(self, *args, **kwargs):
pass
set_from_email = _noop
set_recipients = _noop
set_subject = _noop
set_reply_to = _noop
set_extra_headers = _noop
set_text_body = _noop
set_html_body = _noop
add_attachment = _noop
@override_settings(EMAIL_BACKEND="tests.test_base_backends.MinimalRequestsBackend")
class RequestsBackendBaseTestCase(RequestsBackendMockAPITestCase):
"""Test common functionality in AnymailRequestsBackend"""
def setUp(self):
super().setUp()
self.message = AnymailMessage(
"Subject", "Text Body", "from@example.com", ["to@example.com"]
)
def test_minimal_requests_backend(self):
"""Make sure the testing backend defined above actually works"""
self.message.send()
self.assert_esp_called("https://httpbin.org/post")
def test_timeout_default(self):
"""All requests have a 30 second default timeout"""
self.message.send()
timeout = self.get_api_call_arg("timeout")
self.assertEqual(timeout, 30)
@override_settings(ANYMAIL_REQUESTS_TIMEOUT=5)
def test_timeout_setting(self):
"""You can use the Anymail setting REQUESTS_TIMEOUT to override the default"""
self.message.send()
timeout = self.get_api_call_arg("timeout")
self.assertEqual(timeout, 5)
@mock.patch(f"{__name__}.MinimalRequestsBackend.create_session")
def test_create_session_error_fail_silently(self, mock_create_session):
# If create_session fails and fail_silently is True,
# make sure _send doesn't raise a misleading error.
mock_create_session.side_effect = ValueError("couldn't create session")
sent = self.message.send(fail_silently=True)
self.assertEqual(sent, 0)
@tag("live")
@override_settings(EMAIL_BACKEND="tests.test_base_backends.MinimalRequestsBackend")
class RequestsBackendLiveTestCase(AnymailTestMixin, SimpleTestCase):
@override_settings(ANYMAIL_DEBUG_API_REQUESTS=True)
def test_debug_logging(self):
message = AnymailMessage(
"Subject", "Text Body", "from@example.com", ["to@example.com"]
)
message._payload_init = dict(
data="Request body",
headers={
"Content-Type": "text/plain",
"Accept": "application/json",
},
)
with self.assertPrints("===== Anymail API request") as outbuf:
message.send()
# Header order and response data vary too much to do a full comparison,
# but make sure that the output contains some expected pieces of the request
# and the response
output = outbuf.getvalue()
self.assertIn("\nPOST https://httpbin.org/post\n", output)
self.assertIn("\nUser-Agent: django-anymail/", output)
self.assertIn("\nAccept: application/json\n", output)
self.assertIn("\nContent-Type: text/plain\n", output) # request
self.assertIn("\n\nRequest body\n", output)
self.assertIn("\n----- Response\n", output)
self.assertIn("\nHTTP 200 OK\n", output)
self.assertIn("\nContent-Type: application/json\n", output) # response
def test_no_debug_logging(self):
# Make sure it doesn't output anything when DEBUG_API_REQUESTS is not set
message = AnymailMessage(
"Subject", "Text Body", "from@example.com", ["to@example.com"]
)
message._payload_init = dict(
data="Request body",
headers={
"Content-Type": "text/plain",
"Accept": "application/json",
},
)
with self.assertPrints("", match="equal"):
message.send()
|