Skip to content

Commit b9382c2

Browse files
committed
Decoding the response content according to the supplied encoding.
1 parent 426a0d3 commit b9382c2

File tree

4 files changed

+52
-32
lines changed

4 files changed

+52
-32
lines changed

intercom/request.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ def send_request_to_path(cls, method, url, auth, params=None):
4242
@classmethod
4343
def parse_body(cls, resp):
4444
try:
45-
decoded_body = resp.content.decode()
45+
# use supplied encoding to decode the response content
46+
decoded_body = resp.content.decode(resp.encoding)
4647
if not decoded_body: # return early for empty responses (issue-72)
4748
return
4849
body = json.loads(decoded_body)

tests/unit/__init__.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,24 @@ def _call(*args, **kwargs):
3434
return _call
3535

3636

37-
def get_user(email="bob@example.com"):
37+
def mock_response(content, status_code=200, encoding='utf-8', headers=None):
38+
if headers is None:
39+
headers = {
40+
'x-ratelimit-limit': 500,
41+
'x-ratelimit-remaining': 500,
42+
'x-ratelimit-reset': 1427932858
43+
}
44+
return Mock(
45+
content=content, status_code=status_code, encoding=encoding, headers=headers)
46+
47+
48+
def get_user(email="bob@example.com", name="Joe Schmoe"):
3849
return {
3950
"type": "user",
4051
"id": "aaaaaaaaaaaaaaaaaaaaaaaa",
4152
"user_id": 'id-from-customers-app',
4253
"email": email,
43-
"name": "Joe Schmoe",
54+
"name": name,
4455
"avatar": {
4556
"type": "avatar",
4657
"image_url": "https://graph.facebook.com/1/picture?width=24&height=24"

tests/unit/test_request.py

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -13,59 +13,54 @@
1313
from nose.tools import eq_
1414
from nose.tools import ok_
1515
from nose.tools import istest
16-
17-
headers = {
18-
'x-ratelimit-limit': 500,
19-
'x-ratelimit-remaining': 500,
20-
'x-ratelimit-reset': 1427932858
21-
}
16+
from tests.unit import mock_response
2217

2318

2419
class RequestTest(unittest.TestCase):
2520

2621
@istest
2722
def it_raises_resource_not_found(self):
28-
resp = Mock(content='{}', status_code=404)
23+
resp = mock_response('{}', status_code=404)
2924
with patch('requests.request') as mock_method:
3025
mock_method.return_value = resp
3126
with assert_raises(intercom.ResourceNotFound):
3227
Request.send_request_to_path('GET', 'notes', ('x', 'y'), resp)
3328

3429
@istest
3530
def it_raises_authentication_error_unauthorized(self):
36-
resp = Mock(content='{}', status_code=401)
31+
resp = mock_response('{}', status_code=401)
3732
with patch('requests.request') as mock_method:
3833
mock_method.return_value = resp
3934
with assert_raises(intercom.AuthenticationError):
4035
Request.send_request_to_path('GET', 'notes', ('x', 'y'), resp)
4136

4237
@istest
4338
def it_raises_authentication_error_forbidden(self):
44-
resp = Mock(content='{}', status_code=403)
39+
resp = mock_response('{}', status_code=403)
4540
with patch('requests.request') as mock_method:
4641
mock_method.return_value = resp
4742
with assert_raises(intercom.AuthenticationError):
4843
Request.send_request_to_path('GET', 'notes', ('x', 'y'), resp)
4944

5045
@istest
5146
def it_raises_server_error(self):
52-
resp = Mock(content='{}', status_code=500)
47+
resp = Mock(encoding="utf-8", content='{}', status_code=500)
5348
with patch('requests.request') as mock_method:
5449
mock_method.return_value = resp
5550
with assert_raises(intercom.ServerError):
5651
Request.send_request_to_path('GET', 'notes', ('x', 'y'), resp)
5752

5853
@istest
5954
def it_raises_bad_gateway_error(self):
60-
resp = Mock(content='{}', status_code=502)
55+
resp = mock_response('{}', status_code=502)
6156
with patch('requests.request') as mock_method:
6257
mock_method.return_value = resp
6358
with assert_raises(intercom.BadGatewayError):
6459
Request.send_request_to_path('GET', 'notes', ('x', 'y'), resp)
6560

6661
@istest
6762
def it_raises_service_unavailable_error(self):
68-
resp = Mock(content='{}', status_code=503)
63+
resp = mock_response('{}', status_code=503)
6964
with patch('requests.request') as mock_method:
7065
mock_method.return_value = resp
7166
with assert_raises(intercom.ServiceUnavailableError):
@@ -83,7 +78,7 @@ def it_raises_an_unexpected_typed_error(self):
8378
]
8479
}
8580
content = json.dumps(payload).encode('utf-8')
86-
resp = Mock(content=content, status_code=200, headers=headers)
81+
resp = mock_response(content)
8782
with patch('requests.request') as mock_method:
8883
mock_method.return_value = resp
8984
try:
@@ -105,7 +100,7 @@ def it_raises_an_unexpected_untyped_error(self):
105100
]
106101
}
107102
content = json.dumps(payload).encode('utf-8')
108-
resp = Mock(content=content, status_code=200, headers=headers)
103+
resp = mock_response(content)
109104
with patch('requests.request') as mock_method:
110105
mock_method.return_value = resp
111106
try:
@@ -131,7 +126,7 @@ def it_raises_a_bad_request_error(self):
131126
payload['errors'][0]['type'] = code
132127

133128
content = json.dumps(payload).encode('utf-8')
134-
resp = Mock(content=content, status_code=200, headers=headers)
129+
resp = mock_response(content)
135130
with patch('requests.request') as mock_method:
136131
mock_method.return_value = resp
137132
with assert_raises(intercom.BadRequestError):
@@ -152,7 +147,7 @@ def it_raises_an_authentication_error(self):
152147
payload['errors'][0]['type'] = code
153148

154149
content = json.dumps(payload).encode('utf-8')
155-
resp = Mock(content=content, status_code=200, headers=headers)
150+
resp = mock_response(content)
156151
with patch('requests.request') as mock_method:
157152
mock_method.return_value = resp
158153
with assert_raises(intercom.AuthenticationError):
@@ -170,7 +165,7 @@ def it_raises_resource_not_found_by_type(self):
170165
]
171166
}
172167
content = json.dumps(payload).encode('utf-8')
173-
resp = Mock(content=content, status_code=200, headers=headers)
168+
resp = mock_response(content)
174169
with patch('requests.request') as mock_method:
175170
mock_method.return_value = resp
176171
with assert_raises(intercom.ResourceNotFound):
@@ -188,7 +183,7 @@ def it_raises_rate_limit_exceeded(self):
188183
]
189184
}
190185
content = json.dumps(payload).encode('utf-8')
191-
resp = Mock(content=content, status_code=200, headers=headers)
186+
resp = mock_response(content)
192187
with patch('requests.request') as mock_method:
193188
mock_method.return_value = resp
194189
with assert_raises(intercom.RateLimitExceeded):
@@ -206,7 +201,7 @@ def it_raises_a_service_unavailable_error(self):
206201
]
207202
}
208203
content = json.dumps(payload).encode('utf-8')
209-
resp = Mock(content=content, status_code=200, headers=headers)
204+
resp = mock_response(content)
210205
with patch('requests.request') as mock_method:
211206
mock_method.return_value = resp
212207
with assert_raises(intercom.ServiceUnavailableError):
@@ -224,7 +219,7 @@ def it_raises_a_multiple_matching_users_error(self):
224219
]
225220
}
226221
content = json.dumps(payload).encode('utf-8')
227-
resp = Mock(content=content, status_code=200, headers=headers)
222+
resp = mock_response(content)
228223
with patch('requests.request') as mock_method:
229224
mock_method.return_value = resp
230225
with assert_raises(intercom.MultipleMatchingUsersError):

tests/unit/test_user.py

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,13 @@
1212
from intercom import User
1313
from intercom import MultipleMatchingUsersError
1414
from intercom.utils import create_class_instance
15-
from mock import Mock
1615
from mock import patch
1716
from nose.tools import assert_raises
1817
from nose.tools import eq_
1918
from nose.tools import ok_
2019
from nose.tools import istest
2120
from tests.unit import get_user
21+
from tests.unit import mock_response
2222

2323

2424
class UserTest(unittest.TestCase):
@@ -221,7 +221,6 @@ def it_saves_a_user_with_companies(self):
221221
user = User(
222222
email="jo@example.com", user_id="i-1224242",
223223
companies=[{'company_id': 6, 'name': 'Intercom'}])
224-
print ("+++++>", user.changed_attributes)
225224
body = {
226225
'email': 'jo@example.com',
227226
'user_id': 'i-1224242',
@@ -345,7 +344,6 @@ def it_returns_the_total_number_of_users(self):
345344
eq_(100, User.count())
346345

347346
@istest
348-
# @httpretty.activate
349347
def it_raises_a_multiple_matching_users_error_when_receiving_a_conflict(self): # noqa
350348
payload = {
351349
'type': 'error.list',
@@ -356,18 +354,33 @@ def it_raises_a_multiple_matching_users_error_when_receiving_a_conflict(self):
356354
}
357355
]
358356
}
359-
headers = {
360-
'x-ratelimit-limit': 500,
361-
'x-ratelimit-remaining': 500,
362-
'x-ratelimit-reset': 1427932858
363-
}
357+
# create bytes content
364358
content = json.dumps(payload).encode('utf-8')
365-
resp = Mock(content=content, status_code=200, headers=headers)
359+
# create mock response
360+
resp = mock_response(content)
366361
with patch('requests.request') as mock_method:
367362
mock_method.return_value = resp
368363
with assert_raises(MultipleMatchingUsersError):
369364
Intercom.get('/users')
370365

366+
@istest
367+
def it_handles_accented_characters(self):
368+
# create a user dict with a name that contains accented characters
369+
payload = get_user(name='Jóe Schmö')
370+
# create bytes content
371+
content = json.dumps(payload).encode('utf-8')
372+
# create mock response
373+
resp = mock_response(content)
374+
with patch('requests.request') as mock_method:
375+
mock_method.return_value = resp
376+
user = User.find(email='bob@example.com')
377+
try:
378+
# Python 2
379+
eq_(unicode('Jóe Schmö', 'utf-8'), user.name)
380+
except NameError:
381+
# Python 3
382+
eq_('Jóe Schmö', user.name)
383+
371384

372385
class DescribeIncrementingCustomAttributeFields(unittest.TestCase):
373386

0 commit comments

Comments
 (0)