Skip to content

Commit 1f6407a

Browse files
committed
Refactor tests into separate files
1 parent d92d1ff commit 1f6407a

File tree

3 files changed

+450
-9
lines changed

3 files changed

+450
-9
lines changed

tests/test_interests.py

Lines changed: 389 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,389 @@
1+
"""Unit tests interests based publishing"""
2+
3+
import time
4+
import unittest
5+
6+
import requests_mock
7+
8+
from pusher_push_notifications import (
9+
PushNotifications,
10+
PusherAuthError,
11+
PusherMissingInstanceError,
12+
PusherServerError,
13+
PusherValidationError,
14+
)
15+
16+
17+
class TestPushNotificationsInterests(unittest.TestCase):
18+
def test_publish_should_make_correct_http_request(self):
19+
pn_client = PushNotifications(
20+
'INSTANCE_ID',
21+
'SECRET_KEY'
22+
)
23+
with requests_mock.Mocker() as http_mock:
24+
http_mock.register_uri(
25+
requests_mock.ANY,
26+
requests_mock.ANY,
27+
status_code=200,
28+
json={
29+
'publishId': '1234',
30+
},
31+
)
32+
response = pn_client.publish(
33+
interests=['donuts'],
34+
publish_body={
35+
'apns': {
36+
'aps': {
37+
'alert': 'Hello World!',
38+
},
39+
},
40+
},
41+
)
42+
req = http_mock.request_history[0]
43+
44+
method = req.method
45+
path = req.path
46+
headers = dict(req._request.headers.lower_items())
47+
body = req.json()
48+
49+
self.assertEqual(
50+
method,
51+
'POST',
52+
)
53+
self.assertEqual(
54+
path,
55+
'/publish_api/v1/instances/instance_id/publishes',
56+
)
57+
self.assertDictEqual(
58+
headers,
59+
{
60+
'content-type': 'application/json',
61+
'content-length': '69',
62+
'authorization': 'Bearer SECRET_KEY',
63+
'x-pusher-library': 'pusher-push-notifications-python 1.0.1',
64+
'host': 'instance_id.pushnotifications.pusher.com',
65+
},
66+
)
67+
self.assertDictEqual(
68+
body,
69+
{
70+
'interests': ['donuts'],
71+
'apns': {
72+
'aps': {
73+
'alert': 'Hello World!',
74+
},
75+
},
76+
},
77+
)
78+
self.assertDictEqual(
79+
response,
80+
{
81+
'publishId': '1234',
82+
},
83+
)
84+
85+
def test_publish_should_fail_if_interests_not_list(self):
86+
pn_client = PushNotifications(
87+
'INSTANCE_ID',
88+
'SECRET_KEY'
89+
)
90+
with self.assertRaises(TypeError) as e:
91+
pn_client.publish(
92+
interests=False,
93+
publish_body={
94+
'apns': {
95+
'aps': {
96+
'alert': 'Hello World!',
97+
},
98+
},
99+
},
100+
)
101+
self.assertIn('interests must be a list', str(e.exception))
102+
103+
def test_publish_should_fail_if_body_not_dict(self):
104+
pn_client = PushNotifications(
105+
'INSTANCE_ID',
106+
'SECRET_KEY'
107+
)
108+
with self.assertRaises(TypeError) as e:
109+
pn_client.publish(
110+
interests=['donuts'],
111+
publish_body=False,
112+
)
113+
self.assertIn('publish_body must be a dictionary', str(e.exception))
114+
115+
def test_publish_should_fail_if_no_interests_passed(self):
116+
pn_client = PushNotifications(
117+
'INSTANCE_ID',
118+
'SECRET_KEY'
119+
)
120+
with self.assertRaises(ValueError) as e:
121+
pn_client.publish(
122+
interests=[],
123+
publish_body={
124+
'apns': {
125+
'aps': {
126+
'alert': 'Hello World!',
127+
},
128+
},
129+
},
130+
)
131+
self.assertIn('must target at least one interest', str(e.exception))
132+
133+
def test_publish_should_succeed_if_100_interests_passed(self):
134+
pn_client = PushNotifications(
135+
'INSTANCE_ID',
136+
'SECRET_KEY'
137+
)
138+
with requests_mock.Mocker() as http_mock:
139+
http_mock.register_uri(
140+
requests_mock.ANY,
141+
requests_mock.ANY,
142+
status_code=200,
143+
json={
144+
'publishId': '1234',
145+
},
146+
)
147+
pn_client.publish(
148+
interests=['interest-' + str(i) for i in range(0, 100)],
149+
publish_body={
150+
'apns': {
151+
'aps': {
152+
'alert': 'Hello World!',
153+
},
154+
},
155+
},
156+
)
157+
158+
def test_publish_should_fail_if_too_many_interests_passed(self):
159+
pn_client = PushNotifications(
160+
'INSTANCE_ID',
161+
'SECRET_KEY'
162+
)
163+
with requests_mock.Mocker() as http_mock:
164+
http_mock.register_uri(
165+
requests_mock.ANY,
166+
requests_mock.ANY,
167+
status_code=200,
168+
json={
169+
'publishId': '1234',
170+
},
171+
)
172+
with self.assertRaises(ValueError) as e:
173+
pn_client.publish(
174+
interests=['interest-' + str(i) for i in range(0, 101)],
175+
publish_body={
176+
'apns': {
177+
'aps': {
178+
'alert': 'Hello World!',
179+
},
180+
},
181+
},
182+
)
183+
self.assertIn('Number of interests (101) exceeds maximum', str(e.exception))
184+
185+
def test_publish_should_fail_if_interest_not_a_string(self):
186+
pn_client = PushNotifications(
187+
'INSTANCE_ID',
188+
'SECRET_KEY'
189+
)
190+
with self.assertRaises(TypeError) as e:
191+
pn_client.publish(
192+
interests=[False],
193+
publish_body={
194+
'apns': {
195+
'aps': {
196+
'alert': 'Hello World!',
197+
},
198+
},
199+
},
200+
)
201+
self.assertIn('Interest False is not a string', str(e.exception))
202+
203+
def test_publish_should_fail_if_interest_too_long(self):
204+
pn_client = PushNotifications(
205+
'INSTANCE_ID',
206+
'SECRET_KEY'
207+
)
208+
with self.assertRaises(ValueError) as e:
209+
pn_client.publish(
210+
interests=['A'*200],
211+
publish_body={
212+
'apns': {
213+
'aps': {
214+
'alert': 'Hello World!',
215+
},
216+
},
217+
},
218+
)
219+
self.assertIn('longer than the maximum of 164 chars', str(e.exception))
220+
221+
def test_publish_should_fail_if_interest_contains_invalid_chars(self):
222+
pn_client = PushNotifications(
223+
'INSTANCE_ID',
224+
'SECRET_KEY'
225+
)
226+
with self.assertRaises(ValueError) as e:
227+
pn_client.publish(
228+
interests=['bad:interest'],
229+
publish_body={
230+
'apns': {
231+
'aps': {
232+
'alert': 'Hello World!',
233+
},
234+
},
235+
},
236+
)
237+
self.assertIn('"bad:interest" contains a forbidden character', str(e.exception))
238+
239+
with self.assertRaises(ValueError) as e:
240+
pn_client.publish(
241+
interests=['bad|interest'],
242+
publish_body={
243+
'apns': {
244+
'aps': {
245+
'alert': 'Hello World!',
246+
},
247+
},
248+
},
249+
)
250+
self.assertIn('"bad|interest" contains a forbidden character', str(e.exception))
251+
252+
with self.assertRaises(ValueError) as e:
253+
pn_client.publish(
254+
interests=['bad(interest)'],
255+
publish_body={
256+
'apns': {
257+
'aps': {
258+
'alert': 'Hello World!',
259+
},
260+
},
261+
},
262+
)
263+
self.assertIn('"bad(interest)" contains a forbidden character', str(e.exception))
264+
265+
def test_publish_should_raise_on_http_4xx_error(self):
266+
pn_client = PushNotifications(
267+
'INSTANCE_ID',
268+
'SECRET_KEY'
269+
)
270+
with requests_mock.Mocker() as http_mock:
271+
http_mock.register_uri(
272+
requests_mock.ANY,
273+
requests_mock.ANY,
274+
status_code=400,
275+
json={'error': 'Invalid request', 'description': 'blah'},
276+
)
277+
with self.assertRaises(PusherValidationError) as e:
278+
pn_client.publish(
279+
interests=['donuts'],
280+
publish_body={
281+
'apns': {
282+
'aps': {
283+
'alert': 'Hello World!',
284+
},
285+
},
286+
},
287+
)
288+
self.assertIn('Invalid request: blah', str(e.exception))
289+
290+
def test_publish_should_raise_on_http_5xx_error(self):
291+
pn_client = PushNotifications(
292+
'INSTANCE_ID',
293+
'SECRET_KEY'
294+
)
295+
with requests_mock.Mocker() as http_mock:
296+
http_mock.register_uri(
297+
requests_mock.ANY,
298+
requests_mock.ANY,
299+
status_code=500,
300+
json={'error': 'Server error', 'description': 'blah'},
301+
)
302+
with self.assertRaises(PusherServerError) as e:
303+
pn_client.publish(
304+
interests=['donuts'],
305+
publish_body={
306+
'apns': {
307+
'aps': {
308+
'alert': 'Hello World!',
309+
},
310+
},
311+
},
312+
)
313+
self.assertIn('Server error: blah', str(e.exception))
314+
315+
def test_publish_should_raise_on_http_401_error(self):
316+
pn_client = PushNotifications(
317+
'INSTANCE_ID',
318+
'SECRET_KEY'
319+
)
320+
with requests_mock.Mocker() as http_mock:
321+
http_mock.register_uri(
322+
requests_mock.ANY,
323+
requests_mock.ANY,
324+
status_code=401,
325+
json={'error': 'Auth error', 'description': 'blah'},
326+
)
327+
with self.assertRaises(PusherAuthError) as e:
328+
pn_client.publish(
329+
interests=['donuts'],
330+
publish_body={
331+
'apns': {
332+
'aps': {
333+
'alert': 'Hello World!',
334+
},
335+
},
336+
},
337+
)
338+
self.assertIn('Auth error: blah', str(e.exception))
339+
340+
def test_publish_should_raise_on_http_404_error(self):
341+
pn_client = PushNotifications(
342+
'INSTANCE_ID',
343+
'SECRET_KEY'
344+
)
345+
with requests_mock.Mocker() as http_mock:
346+
http_mock.register_uri(
347+
requests_mock.ANY,
348+
requests_mock.ANY,
349+
status_code=404,
350+
json={'error': 'Instance not found', 'description': 'blah'},
351+
)
352+
with self.assertRaises(PusherMissingInstanceError) as e:
353+
pn_client.publish(
354+
interests=['donuts'],
355+
publish_body={
356+
'apns': {
357+
'aps': {
358+
'alert': 'Hello World!',
359+
},
360+
},
361+
},
362+
)
363+
self.assertIn('Instance not found: blah', str(e.exception))
364+
365+
366+
def test_publish_should_error_correctly_if_error_not_json(self):
367+
pn_client = PushNotifications(
368+
'INSTANCE_ID',
369+
'SECRET_KEY'
370+
)
371+
with requests_mock.Mocker() as http_mock:
372+
http_mock.register_uri(
373+
requests_mock.ANY,
374+
requests_mock.ANY,
375+
status_code=500,
376+
text='<notjson></notjson>',
377+
)
378+
with self.assertRaises(PusherServerError) as e:
379+
pn_client.publish(
380+
interests=['donuts'],
381+
publish_body={
382+
'apns': {
383+
'aps': {
384+
'alert': 'Hello World!',
385+
},
386+
},
387+
},
388+
)
389+
self.assertIn('Unknown error: no description', str(e.exception))

0 commit comments

Comments
 (0)