Skip to content

Commit d8ff5eb

Browse files
APIClient::item_iterator: reset query_parameters after returning all items
The item_iterator method uses a query parameter called `since` to get the next results from the API resource when the previous response includes a hasMore=True property. The problem here is the last API call leaves the query parameter defined to a value related to the previous resource retrieved, and if you use the same api client to iterate over different resources (i.e. campaigns), the results will always be affected by the previous call.
1 parent 5a90bae commit d8ff5eb

File tree

4 files changed

+32
-2
lines changed

4 files changed

+32
-2
lines changed

CHANGES.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
Changelog
22
=========
33

4+
Version 2.0.2
5+
-------------
6+
7+
- Reset query arguments after returning all items from generator
8+
49
Here you find a full list of changes.
510

611
Version 2.0.1

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
except ImportError:
44
from distutils.core import setup
55

6-
VERSION = '2.0.1'
6+
VERSION = '2.0.2'
77

88
setup(
99
name='usabilla-api',

tests.py

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import logging
2+
from unittest.mock import call
23
import requests
34
import usabilla as ub
45

@@ -124,18 +125,40 @@ def test_item_iterator(self):
124125
items = ['one', 'two', 'three', 'four']
125126
has_more = {'hasMore': True, 'items': items[:2], 'lastTimestamp': 1400000000001}
126127
no_more = {'hasMore': False, 'items': items[2:], 'lastTimestamp': 1400000000002}
128+
expected_set_query_parameters_calls = [ call({'since': 1400000000001}), call({'since': 1400000000002}), call({}) ]
129+
127130
self.client.set_query_parameters = Mock()
128131
self.client.send_signed_request = Mock(side_effect=[has_more, no_more])
132+
129133
index = 0
130134
for item in self.client.item_iterator('/some/url'):
131135
self.assertEqual(item, items[index])
132136
index += 1
133-
self.client.set_query_parameters.assert_called_with({'since': 1400000000002})
137+
138+
self.assertEqual(self.client.set_query_parameters.call_args_list, expected_set_query_parameters_calls)
134139
self.assertEqual(self.client.send_signed_request.call_count, 2)
140+
135141
self.client.send_signed_request.side_effect = requests.exceptions.HTTPError('mocked error')
136142
with self.assertRaises(requests.exceptions.HTTPError):
137143
list(self.client.item_iterator('/some/url'))
138144

145+
def test_item_iterator_resets_query_parameters_after_returning_all_items(self):
146+
first_response = {'hasMore': True, 'items': [1], 'lastTimestamp': 1400000000001}
147+
second_response = {'hasMore': False, 'items': [2], 'lastTimestamp': 1400000000002}
148+
third_response = {'hasMore': False, 'items': [3], 'lastTimestamp': 1400000000003}
149+
150+
self.client.send_signed_request = Mock(side_effect=[first_response, second_response, third_response])
151+
152+
expected_query_parameters = ['', 'since=1400000000001', '']
153+
154+
index = 0
155+
for response in [self.client.item_iterator('/some/url'), self.client.item_iterator('/some/url')]:
156+
for _ in response:
157+
self.assertEqual(expected_query_parameters[index], self.client.get_query_parameters())
158+
index+=1
159+
160+
self.assertEqual(self.client.send_signed_request.call_count, 3)
161+
139162
def test_get_resource(self):
140163
self.client.item_iterator = Mock()
141164
self.client.send_signed_request = Mock()

usabilla.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,8 @@ def item_iterator(self, url):
311311
yield item
312312
self.set_query_parameters({'since': results['lastTimestamp']})
313313

314+
self.set_query_parameters({})
315+
314316
def get_resource(self, scope, product, resource, resource_id=None, iterate=False):
315317
"""Retrieves resources of the specified type
316318

0 commit comments

Comments
 (0)