Skip to content
This repository has been archived by the owner on Jul 13, 2023. It is now read-only.

Commit

Permalink
bug: Serialize Decimal correctly for ios aps
Browse files Browse the repository at this point in the history
closes #899
  • Loading branch information
jrconlin committed May 20, 2017
1 parent d265b66 commit 66f0803
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 1 deletion.
13 changes: 12 additions & 1 deletion autopush/router/apns2.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import json
from collections import deque
from decimal import Decimal

import hyper.tls
from hyper import HTTP20Connection
Expand All @@ -21,6 +22,16 @@
APNS_PRIORITY_LOW = '5'


class ComplexEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, Decimal):
return int(float(obj.to_integral_value()))
# for most data types, this function isn't called.
# the following is added for safety, but should not
# be required.
return json.JSONEncoder.default(self, obj) # pragma nocover


class APNSException(Exception):
pass

Expand Down Expand Up @@ -104,7 +115,7 @@ def send(self, router_token, payload, apns_id,
:type exp: timestamp
"""
body = json.dumps(payload)
body = json.dumps(payload, cls=ComplexEncoder)
priority = APNS_PRIORITY_IMMEDIATE if priority else APNS_PRIORITY_LOW
# NOTE: Hyper requires that all header values be strings. 'Priority'
# is a integer string, which may be "simplified" and cause an error.
Expand Down
20 changes: 20 additions & 0 deletions autopush/tests/test_router.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import uuid
import time
import json
import decimal

from autopush.utils import WebPushNotification
from mock import Mock, PropertyMock, patch
Expand Down Expand Up @@ -195,6 +196,25 @@ def test_route_notification(self):
"con": "aesgcm",
})

@inlineCallbacks
def test_route_notification_complex(self):
router_data = dict(
router_data=dict(token="connect_data",
rel_channel="firefox",
aps=dict(string="String",
array=['a', 'b', 'c'],
number=decimal.Decimal(4))))
result = yield self.router.route_notification(self.notif,
router_data)
yield self._waitfor(lambda:
self.mock_connection.request.called is True)
ok_(isinstance(result, RouterResponse))
ok_(self.mock_connection.request.called)
body = self.mock_connection.request.call_args[1]
body_json = json.loads(body['body'])
eq_(body_json['aps']['number'], 4)
eq_(body_json['aps']['string'], 'String')

@inlineCallbacks
def test_route_low_priority_notification(self):
"""low priority and empty apns_ids are not yet used, but may feature
Expand Down

0 comments on commit 66f0803

Please sign in to comment.