Drop unintended json date encoding

This commit is contained in:
medmunds
2015-11-29 14:42:12 -08:00
parent 699216ba00
commit 942a6df8c3
4 changed files with 18 additions and 84 deletions

View File

@@ -6,7 +6,6 @@ from django.core.mail.backends.base import BaseEmailBackend
from django.core.mail.message import sanitize_address, DEFAULT_ATTACHMENT_MIME_TYPE from django.core.mail.message import sanitize_address, DEFAULT_ATTACHMENT_MIME_TYPE
from djrill import MANDRILL_API_URL, MandrillAPIError, NotSupportedByMandrillError, __version__ from djrill import MANDRILL_API_URL, MandrillAPIError, NotSupportedByMandrillError, __version__
from djrill.exceptions import removed_in_djrill_2
from base64 import b64encode from base64 import b64encode
from datetime import date, datetime from datetime import date, datetime
@@ -37,19 +36,6 @@ def encode_date_for_mandrill(dt):
return dt return dt
class JSONDateUTCEncoder(json.JSONEncoder):
"""[deprecated] JSONEncoder that encodes dates in string format used by Mandrill."""
def default(self, obj):
if isinstance(obj, date):
removed_in_djrill_2(
"You've used the date '%r' as a Djrill message attribute "
"(perhaps in merge vars or metadata). Djrill 2.0 will require "
"you to explicitly convert this date to a string." % obj
)
return encode_date_for_mandrill(obj)
return super(JSONDateUTCEncoder, self).default(obj)
class DjrillBackend(BaseEmailBackend): class DjrillBackend(BaseEmailBackend):
""" """
Mandrill API Email Backend Mandrill API Email Backend
@@ -153,7 +139,7 @@ class DjrillBackend(BaseEmailBackend):
return False return False
try: try:
api_data = json.dumps(api_params, cls=JSONDateUTCEncoder) api_data = json.dumps(api_params)
except TypeError as err: except TypeError as err:
# Add some context to the "not JSON serializable" message # Add some context to the "not JSON serializable" message
if not err.args: if not err.args:

View File

@@ -1,58 +1,8 @@
# Tests deprecated Djrill features # Tests deprecated Djrill features
from datetime import date, datetime
import warnings
from django.core import mail
from django.test import TestCase from django.test import TestCase
from djrill import NotSupportedByMandrillError from djrill import NotSupportedByMandrillError
from djrill.tests.mock_backend import DjrillBackendMockAPITestCase
from djrill.tests.utils import reset_warning_registry
class DjrillBackendDeprecationTests(DjrillBackendMockAPITestCase):
def setUp(self):
reset_warning_registry()
super(DjrillBackendDeprecationTests, self).setUp()
def test_deprecated_json_date_encoding(self):
"""Djrill 2.0+ avoids a blanket JSONDateUTCEncoder"""
# Djrill allows dates for send_at, so shouldn't warn:
message = mail.EmailMessage('Subject', 'Body', 'from@example.com', ['to@example.com'])
message.send_at = datetime(2022, 10, 11, 12, 13, 14, 567)
self.assertNotWarns(DeprecationWarning, message.send)
# merge_vars need to be json-serializable, so should generate a warning:
message = mail.EmailMessage('Subject', 'Body', 'from@example.com', ['to@example.com'])
message.global_merge_vars = {'DATE': date(2022, 10, 11)}
self.assertWarnsMessage(DeprecationWarning,
"Djrill 2.0 will require you to explicitly convert this date to a string",
message.send)
# ... but should still encode the date (for now):
data = self.get_api_call_data()
self.assertEqual(data['message']['global_merge_vars'],
[{'name': 'DATE', 'content': "2022-10-11 00:00:00"}])
def assertWarnsMessage(self, warning, message, callable, *args, **kwds):
"""Checks that `callable` issues a warning of category `warning` containing `message`"""
with warnings.catch_warnings(record=True) as warned:
warnings.simplefilter("always")
callable(*args, **kwds)
self.assertGreater(len(warned), 0, msg="No warnings issued")
self.assertTrue(
any(issubclass(w.category, warning) and message in str(w.message) for w in warned),
msg="%r(%r) not found in %r" % (warning, message, [str(w) for w in warned]))
def assertNotWarns(self, warning, callable, *args, **kwds):
"""Checks that `callable` does not issue any warnings of category `warning`"""
with warnings.catch_warnings(record=True) as warned:
warnings.simplefilter("always")
callable(*args, **kwds)
relevant_warnings = [w for w in warned if issubclass(w.category, warning)]
self.assertEqual(len(relevant_warnings), 0,
msg="Unexpected warnings %r" % [str(w) for w in relevant_warnings])
class DjrillLegacyExceptionTests(TestCase): class DjrillLegacyExceptionTests(TestCase):

View File

@@ -529,7 +529,7 @@ class DjrillMandrillFeatureTests(DjrillBackendMockAPITestCase):
self.assertEqual(sent, 0) self.assertEqual(sent, 0)
self.assertIsNone(msg.mandrill_response) self.assertIsNone(msg.mandrill_response)
def test_json_serialization_warnings(self): def test_json_serialization_errors(self):
"""Try to provide more information about non-json-serializable data""" """Try to provide more information about non-json-serializable data"""
self.message.global_merge_vars = {'PRICE': Decimal('19.99')} self.message.global_merge_vars = {'PRICE': Decimal('19.99')}
with self.assertRaisesMessage( with self.assertRaisesMessage(
@@ -539,6 +539,12 @@ class DjrillMandrillFeatureTests(DjrillBackendMockAPITestCase):
): ):
self.message.send() self.message.send()
def test_dates_not_serialized(self):
"""Pre-2.0 Djrill accidentally serialized dates to ISO"""
self.message.global_merge_vars = {'SHIP_DATE': date(2015, 12, 2)}
with self.assertRaises(TypeError):
self.message.send()
@override_settings(MANDRILL_SETTINGS={ @override_settings(MANDRILL_SETTINGS={
'from_name': 'Djrill Test', 'from_name': 'Djrill Test',

View File

@@ -48,6 +48,16 @@ Removed DjrillAdminSite
(Do this only if you changed to SimpleAdminConfig for Djrill, and aren't (Do this only if you changed to SimpleAdminConfig for Djrill, and aren't
creating custom admin sites for any other Django apps you use.) creating custom admin sites for any other Django apps you use.)
Removed unintended date-to-string conversion
If your code was relying on Djrill to automatically convert date or datetime
values to strings in :attr:`merge_vars`, :attr:`metadata`, or other Mandrill
message attributes, you must now explicitly do the string conversion
yourself. See :ref:`formatting-merge-data` for an explanation.
(Djrill 1.4 reported a DeprecationWarning for this case.)
(The exception is :attr:`send_at`, which Djrill expects can be a date or
datetime.)
Removed DjrillMessage class Removed DjrillMessage class
The ``DjrillMessage`` class has not been needed since Djrill 0.2. The ``DjrillMessage`` class has not been needed since Djrill 0.2.
You should replace any uses of it with the standard You should replace any uses of it with the standard
@@ -58,24 +68,6 @@ Removed DjrillBackendHTTPError
with :exc:`djrill.MandrillAPIError`. with :exc:`djrill.MandrillAPIError`.
**Dates in merge data and other attributes**
Djrill automatically converts :attr:`send_at` date and datetime
values to the ISO 8601 string format expected by the Mandrill API.
Unintentionally, it also converts dates used in other Mandrill message
attributes (such as :attr:`merge_vars` or :attr:`metadata`) where it
might not be expected (or appropriate).
Djrill 2.0 will remove this automatic date formatting, except
for attributes that are inherently dates (currently only `send_at`).
To assist in detecting code relying on the (undocumented) current
behavior, Djrill 1.4 will report a DeprecationWarning for date
or datetime values used in any Mandrill message attributes other
than `send_at`. See :ref:`formatting-merge-data` for other options.
Older Releases Older Releases
-------------- --------------