Skip to content

Commit 55d6f4f

Browse files
committed
Added update_activities and update_activity method to client
1 parent f54e772 commit 55d6f4f

File tree

2 files changed

+109
-6
lines changed

2 files changed

+109
-6
lines changed

stream/client.py

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -178,14 +178,24 @@ def raise_exception(self, result, status_code):
178178
from stream.exceptions import get_exception_dict
179179
exception_class = exceptions.StreamApiException
180180

181+
def errors_from_fields(exception_fields):
182+
result = []
183+
for field, errors in exception_fields.items():
184+
errors.append('Field "%s" errors: %s' % (field, repr(errors)))
185+
return result
186+
181187
if result is not None:
182188
error_message = result['detail']
183189
exception_fields = result.get('exception_fields')
184190
if exception_fields is not None:
185191
errors = []
186-
for field, errors in exception_fields.items():
187-
errors.append('Field "%s" errors: %s' %
188-
(field, repr(errors)))
192+
193+
if isinstance(exception_fields, list):
194+
errors = [errors_from_fields(exception_dict) for exception_dict in exception_fields]
195+
errors = [item for sublist in errors for item in sublist]
196+
else:
197+
errors = errors_from_fields(exception_fields)
198+
189199
error_message = '\n'.join(errors)
190200
error_code = result.get('code')
191201
exception_dict = get_exception_dict()
@@ -234,6 +244,25 @@ def follow_many(self, follows):
234244
235245
'''
236246
self._make_signed_request('post', 'follow_many/', data=follows)
247+
248+
def update_activities(self, activities):
249+
'''
250+
Update or create activities
251+
'''
252+
if not isinstance(activities, (list, tuple, set)):
253+
raise TypeError('Activities parameter should be of type list')
254+
255+
auth_token = self.create_jwt_token('activities', '*', feed_id='*')
256+
257+
data = dict(activities=activities)
258+
259+
return self.post('activities/', auth_token, data=data)
260+
261+
def update_activity(self, activity):
262+
'''
263+
Update a single activity
264+
'''
265+
return self.update_activities([activity])
237266

238267
def create_redirect_url(self, target_url, user_id, events):
239268
'''

stream/tests.py

Lines changed: 77 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
import os
1010
import datetime
11+
import copy
1112
from stream import serializer
1213
from requests.exceptions import ConnectionError, MissingSchema
1314

@@ -18,8 +19,8 @@
1819

1920
def connect_debug():
2021
return stream.connect(
21-
'ahj2ndz7gsan',
22-
'gthc2t9gh7pzq52f6cky8w4r4up9dr6rju9w3fjgmkv6cdvvav2ufe5fv7e2r9qy',
22+
'ata9p5qqy7th',
23+
'vskczs6wmuss5svwdkfsntuz486rgetu2w9q4g9f86c2umfrh5pth2vujyg8wvwn',
2324
location='us-east',
2425
timeout=10
2526
)
@@ -41,7 +42,6 @@ def getfeed(feed_slug, user_id):
4142
topic1 = getfeed('topic', '1')
4243
flat3 = getfeed('flat', '3')
4344

44-
4545
class ClientTest(TestCase):
4646

4747
def setUp(self):
@@ -54,6 +54,80 @@ def setUp(self):
5454
self.topic1 = topic1
5555
self.flat3 = flat3
5656

57+
def test_update_activities_create(self):
58+
activities = [{
59+
'actor': 'user:1',
60+
'verb': 'do',
61+
'object': 'object:1',
62+
'foreign_id': 'object:1',
63+
'time': datetime.datetime.utcnow().isoformat()
64+
}]
65+
66+
self.c.update_activities(activities)
67+
68+
def test_update_activities_illegal_argument(self):
69+
activities = dict()
70+
71+
def invalid_activities():
72+
self.c.update_activities(activities)
73+
self.assertRaises(TypeError, invalid_activities)
74+
75+
def test_update_activities_update_illegal_change(self):
76+
def update_activity(activity):
77+
return lambda: self.c.update_activities([activity])
78+
79+
activity = {
80+
'actor': 'user:1',
81+
'verb': 'do',
82+
'object': 'object:2',
83+
'foreign_id': 'object:2',
84+
'to': ['notification:1'],
85+
'time': datetime.datetime.utcnow().isoformat()
86+
}
87+
activity_create = user1.add_activity(activity)
88+
activity_create.pop('duration')
89+
90+
activity = copy.deepcopy(activity_create)
91+
activity['foreign_id'] = 'object:3'
92+
93+
self.assertRaises(InputException, update_activity(activity))
94+
95+
activity = copy.deepcopy(activity_create)
96+
activity['time'] = datetime.datetime.utcnow().isoformat()
97+
98+
self.assertRaises(InputException, update_activity(activity))
99+
100+
activity = copy.deepcopy(activity)
101+
activity['to'] = ['notification:2']
102+
103+
self.assertRaises(InputException, update_activity(activity))
104+
105+
def test_update_activities_update(self):
106+
activities = []
107+
for i in range(0, 10):
108+
activities.append({
109+
'actor': 'user:1',
110+
'verb': 'do',
111+
'object': 'object:%s' % i,
112+
'foreign_id': 'object:%s' % i,
113+
'time': datetime.datetime.utcnow().isoformat()
114+
})
115+
activities_created = user1.add_activities(activities)['activities']
116+
activities = copy.deepcopy(activities_created)
117+
118+
for activity in activities:
119+
activity.pop('id')
120+
activity['popularity'] = 100
121+
122+
self.c.update_activities(activities)
123+
124+
activities_updated = user1.get(limit=len(activities))['results']
125+
activities_updated.reverse()
126+
127+
for i, activity in enumerate(activities_updated):
128+
self.assertEqual(activities_created[i].get('id'), activity.get('id'))
129+
self.assertEquals(activity['popularity'], 100)
130+
57131
def test_heroku(self):
58132
url = 'https://thierry:pass@getstream.io/?app_id=1'
59133
os.environ['STREAM_URL'] = url

0 commit comments

Comments
 (0)