Skip to content

Commit 3eebe2b

Browse files
author
minaorangina
committed
limits number of interests to 100
1 parent 4b0bf54 commit 3eebe2b

File tree

3 files changed

+124
-61
lines changed

3 files changed

+124
-61
lines changed

dev_requirements.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
11
nose
22
pylint
33
requests-mock
4-
collective.checkdocs

pusher_push_notifications/__init__.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,26 +9,31 @@
99
SDK_VERSION = '0.9.2'
1010
INTEREST_MAX_LENGTH = 164
1111
INTEREST_REGEX = re.compile('^(_-|=|@|,|\\.|:|[A-Z]|[a-z]|[0-9])*$')
12+
MAX_NUMBER_OF_INTERESTS = 100
1213

1314

1415
class PusherValidationError(ValueError):
1516
"""Error thrown when the Push Notifications publish body is invalid"""
1617
pass
1718

19+
1820
class PusherAuthError(ValueError):
1921
"""Error thrown when the Push Notifications secret key is incorrect"""
2022
pass
2123

24+
2225
class PusherMissingInstanceError(KeyError):
2326
"""Error thrown when the instance id used does not exist"""
2427
pass
2528

29+
2630
class PusherServerError(Exception):
2731
"""Error thrown when the Push Notifications service has an internal server
2832
error
2933
"""
3034
pass
3135

36+
3237
def handle_http_error(response_body, status_code):
3338
"""Handle different http error codes from the Push Notifications service"""
3439
error_string = '{}: {}'.format(
@@ -96,6 +101,7 @@ def publish(self, interests, publish_body):
96101
TypeError: if publish_body is not a dict
97102
TypeError: if any interest is not a string
98103
ValueError: if len(interests) < 1
104+
ValueError: if len(interests) > 100
99105
ValueError: if any interest length is greater than the max
100106
ValueError: if any interest contains a forbidden character
101107
@@ -106,7 +112,11 @@ def publish(self, interests, publish_body):
106112
raise TypeError('publish_body must be a dictionary')
107113
if not interests:
108114
raise ValueError('Publishes must target at least one interest')
109-
115+
if len(interests) > MAX_NUMBER_OF_INTERESTS:
116+
raise ValueError('Number of interests ({}) exceeds maximum of {}'.format(
117+
len(interests),
118+
MAX_NUMBER_OF_INTERESTS
119+
))
110120
for interest in interests:
111121
if not isinstance(interest, six.string_types):
112122
raise TypeError(

tests/test_push_notifications.py

Lines changed: 113 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
import requests_mock
66

7+
import random
8+
79
from pusher_push_notifications import (
810
PushNotifications,
911
PusherAuthError,
@@ -130,22 +132,21 @@ def test_publish_should_make_correct_http_request(self):
130132
},
131133
)
132134

133-
134135
def test_publish_should_fail_if_interests_not_list(self):
135136
pn_client = PushNotifications(
136137
'INSTANCE_ID',
137138
'SECRET_KEY'
138139
)
139140
with self.assertRaises(TypeError):
140141
pn_client.publish(
141-
interests=False,
142-
publish_body={
143-
'apns': {
144-
'aps': {
145-
'alert': 'Hello World!',
146-
},
142+
interests=False,
143+
publish_body={
144+
'apns': {
145+
'aps': {
146+
'alert': 'Hello World!',
147147
},
148148
},
149+
},
149150
)
150151

151152
def test_publish_should_fail_if_body_not_dict(self):
@@ -155,8 +156,8 @@ def test_publish_should_fail_if_body_not_dict(self):
155156
)
156157
with self.assertRaises(TypeError):
157158
pn_client.publish(
158-
interests=['donuts'],
159-
publish_body=False,
159+
interests=['donuts'],
160+
publish_body=False,
160161
)
161162

162163
def test_publish_should_fail_if_no_interests_passed(self):
@@ -166,15 +167,68 @@ def test_publish_should_fail_if_no_interests_passed(self):
166167
)
167168
with self.assertRaises(ValueError):
168169
pn_client.publish(
169-
interests=[],
170+
interests=[],
171+
publish_body={
172+
'apns': {
173+
'aps': {
174+
'alert': 'Hello World!',
175+
},
176+
},
177+
},
178+
)
179+
180+
def test_publish_should_succeed_if_100_interests_passed(self):
181+
pn_client = PushNotifications(
182+
'INSTANCE_ID',
183+
'SECRET_KEY'
184+
)
185+
with requests_mock.Mocker() as http_mock:
186+
http_mock.register_uri(
187+
requests_mock.ANY,
188+
requests_mock.ANY,
189+
status_code=200,
190+
json={
191+
'publishId': '1234',
192+
},
193+
)
194+
pn_client.publish(
195+
interests=[str(el) for el in random.sample(range(1000), 100)],
196+
publish_body={
197+
'apns': {
198+
'aps': {
199+
'alert': 'Hello World!',
200+
},
201+
},
202+
},
203+
)
204+
205+
def test_publish_should_fail_if_too_many_interests_passed(self):
206+
pn_client = PushNotifications(
207+
'INSTANCE_ID',
208+
'SECRET_KEY'
209+
)
210+
interests_ints = random.sample(range(1000), 101)
211+
212+
with requests_mock.Mocker() as http_mock:
213+
http_mock.register_uri(
214+
requests_mock.ANY,
215+
requests_mock.ANY,
216+
status_code=200,
217+
json={
218+
'publishId': '1234',
219+
},
220+
)
221+
with self.assertRaises(ValueError):
222+
pn_client.publish(
223+
interests=[str(el) for el in interests_ints],
170224
publish_body={
171225
'apns': {
172226
'aps': {
173227
'alert': 'Hello World!',
174228
},
175229
},
176230
},
177-
)
231+
)
178232

179233
def test_publish_should_fail_if_interest_not_a_string(self):
180234
pn_client = PushNotifications(
@@ -183,14 +237,14 @@ def test_publish_should_fail_if_interest_not_a_string(self):
183237
)
184238
with self.assertRaises(TypeError):
185239
pn_client.publish(
186-
interests=[False],
187-
publish_body={
188-
'apns': {
189-
'aps': {
190-
'alert': 'Hello World!',
191-
},
240+
interests=[False],
241+
publish_body={
242+
'apns': {
243+
'aps': {
244+
'alert': 'Hello World!',
192245
},
193246
},
247+
},
194248
)
195249

196250
def test_publish_should_fail_if_interest_too_long(self):
@@ -200,14 +254,14 @@ def test_publish_should_fail_if_interest_too_long(self):
200254
)
201255
with self.assertRaises(ValueError):
202256
pn_client.publish(
203-
interests=['A'*200],
204-
publish_body={
205-
'apns': {
206-
'aps': {
207-
'alert': 'Hello World!',
208-
},
257+
interests=['A'*200],
258+
publish_body={
259+
'apns': {
260+
'aps': {
261+
'alert': 'Hello World!',
209262
},
210263
},
264+
},
211265
)
212266

213267
def test_publish_should_fail_if_interest_contains_invalid_chars(self):
@@ -217,25 +271,25 @@ def test_publish_should_fail_if_interest_contains_invalid_chars(self):
217271
)
218272
with self.assertRaises(ValueError):
219273
pn_client.publish(
220-
interests=['bad|interest'],
221-
publish_body={
222-
'apns': {
223-
'aps': {
224-
'alert': 'Hello World!',
225-
},
274+
interests=['bad|interest'],
275+
publish_body={
276+
'apns': {
277+
'aps': {
278+
'alert': 'Hello World!',
226279
},
227280
},
281+
},
228282
)
229283
with self.assertRaises(ValueError):
230284
pn_client.publish(
231-
interests=['bad(interest)'],
232-
publish_body={
233-
'apns': {
234-
'aps': {
235-
'alert': 'Hello World!',
236-
},
285+
interests=['bad(interest)'],
286+
publish_body={
287+
'apns': {
288+
'aps': {
289+
'alert': 'Hello World!',
237290
},
238291
},
292+
},
239293
)
240294

241295
def test_publish_should_raise_on_http_4xx_error(self):
@@ -252,14 +306,14 @@ def test_publish_should_raise_on_http_4xx_error(self):
252306
)
253307
with self.assertRaises(PusherValidationError):
254308
pn_client.publish(
255-
interests=['donuts'],
256-
publish_body={
257-
'apns': {
258-
'aps': {
259-
'alert': 'Hello World!',
260-
},
309+
interests=['donuts'],
310+
publish_body={
311+
'apns': {
312+
'aps': {
313+
'alert': 'Hello World!',
261314
},
262315
},
316+
},
263317
)
264318

265319
def test_publish_should_raise_on_http_5xx_error(self):
@@ -276,14 +330,14 @@ def test_publish_should_raise_on_http_5xx_error(self):
276330
)
277331
with self.assertRaises(PusherServerError):
278332
pn_client.publish(
279-
interests=['donuts'],
280-
publish_body={
281-
'apns': {
282-
'aps': {
283-
'alert': 'Hello World!',
284-
},
333+
interests=['donuts'],
334+
publish_body={
335+
'apns': {
336+
'aps': {
337+
'alert': 'Hello World!',
285338
},
286339
},
340+
},
287341
)
288342

289343
def test_publish_should_raise_on_http_401_error(self):
@@ -300,14 +354,14 @@ def test_publish_should_raise_on_http_401_error(self):
300354
)
301355
with self.assertRaises(PusherAuthError):
302356
pn_client.publish(
303-
interests=['donuts'],
304-
publish_body={
305-
'apns': {
306-
'aps': {
307-
'alert': 'Hello World!',
308-
},
357+
interests=['donuts'],
358+
publish_body={
359+
'apns': {
360+
'aps': {
361+
'alert': 'Hello World!',
309362
},
310363
},
364+
},
311365
)
312366

313367
def test_publish_should_raise_on_http_404_error(self):
@@ -324,12 +378,12 @@ def test_publish_should_raise_on_http_404_error(self):
324378
)
325379
with self.assertRaises(PusherMissingInstanceError):
326380
pn_client.publish(
327-
interests=['donuts'],
328-
publish_body={
329-
'apns': {
330-
'aps': {
331-
'alert': 'Hello World!',
332-
},
381+
interests=['donuts'],
382+
publish_body={
383+
'apns': {
384+
'aps': {
385+
'alert': 'Hello World!',
333386
},
334387
},
388+
},
335389
)

0 commit comments

Comments
 (0)