diff --git a/tapioca/tapioca.py b/tapioca/tapioca.py index c4849a1..52af499 100755 --- a/tapioca/tapioca.py +++ b/tapioca/tapioca.py @@ -261,8 +261,19 @@ def _reached_max_limits(self, page_count, item_count, max_pages, reached_item_limit = max_items is not None and max_items <= item_count return reached_page_limit or reached_item_limit - def pages(self, max_pages=None, max_items=None, **kwargs): - executor = self + def pages(self, max_pages=None, max_items=None, params=None, **kwargs): + if self._response is not None: + if params is not None: + raise Exception("Since you're paging after the first .get call, " + "you can't pass params here." + "Pass params on the .get call instead.") + executor = self + else: + # this mean .pages() was called before the first .get, + # like `api.statuses_user_timeline().pages()` + response = self.get(params=params) + executor = response() + iterator_list = executor._get_iterator_list() page_count = 0 item_count = 0 diff --git a/tests/client.py b/tests/client.py index 33850b4..1a3c2e9 100644 --- a/tests/client.py +++ b/tests/client.py @@ -42,7 +42,8 @@ def get_iterator_next_request_kwargs(self, iterator_request_kwargs, url = paging.get('next') if url: - return {'url': url} + iterator_request_kwargs['url'] = url + return iterator_request_kwargs TesterClient = generate_wrapper_from_adapter(TesterClientAdapter) diff --git a/tests/test_tapioca.py b/tests/test_tapioca.py index 5261fa7..411987a 100755 --- a/tests/test_tapioca.py +++ b/tests/test_tapioca.py @@ -333,6 +333,14 @@ def test_simple_pages_iterator(self): self.assertEqual(iterations_count, 2) + responses.mock.calls.reset() + iterations_count = 0 + for item in self.wrapper.test().pages(): + self.assertIn(item.key().data, 'value') + iterations_count += 1 + + self.assertEqual(iterations_count, 2) + @responses.activate def test_simple_pages_with_max_items_iterator(self): next_url = 'http://api.teste.com/next_batch' @@ -356,6 +364,14 @@ def test_simple_pages_with_max_items_iterator(self): self.assertEqual(iterations_count, 3) + responses.mock.calls.reset() + iterations_count = 0 + for item in self.wrapper.test().pages(max_items=3, max_pages=2): + self.assertIn(item.key().data, 'value') + iterations_count += 1 + + self.assertEqual(iterations_count, 3) + @responses.activate def test_simple_pages_with_max_pages_iterator(self): next_url = 'http://api.teste.com/next_batch' @@ -388,6 +404,14 @@ def test_simple_pages_with_max_pages_iterator(self): self.assertEqual(iterations_count, 7) + responses.mock.calls.reset() + iterations_count = 0 + for item in self.wrapper.test().pages(max_pages=3): + self.assertIn(item.key().data, 'value') + iterations_count += 1 + + self.assertEqual(iterations_count, 7) + @responses.activate def test_simple_pages_max_page_zero_iterator(self): next_url = 'http://api.teste.com/next_batch' @@ -411,6 +435,14 @@ def test_simple_pages_max_page_zero_iterator(self): self.assertEqual(iterations_count, 0) + responses.mock.calls.reset() + iterations_count = 0 + for item in self.wrapper.test().pages(max_pages=0): + self.assertIn(item.key().data, 'value') + iterations_count += 1 + + self.assertEqual(iterations_count, 0) + @responses.activate def test_simple_pages_max_item_zero_iterator(self): next_url = 'http://api.teste.com/next_batch' @@ -434,6 +466,68 @@ def test_simple_pages_max_item_zero_iterator(self): self.assertEqual(iterations_count, 0) + responses.mock.calls.reset() + iterations_count = 0 + for item in self.wrapper.test().pages(max_items=0): + self.assertIn(item.key().data, 'value') + iterations_count += 1 + + self.assertEqual(iterations_count, 0) + + @responses.activate + def test_cant_pass_param_after_first_get(self): + next_url = 'http://api.teste.com/next_batch' + + responses.add(responses.GET, self.wrapper.test().data, + body='{"data": [{"key": "value"}], "paging": {"next": "%s"}}' % next_url, + status=200, + content_type='application/json') + + responses.add(responses.GET, next_url, + body='{"data": [{"key": "value"}], "paging": {"next": ""}}', + status=200, + content_type='application/json') + + with self.assertRaises(Exception) as exception_cm: + response = self.wrapper.test().get() + for item in response().pages(params={'param-key': 'param-value'}): + break + + self.assertEqual(str(exception_cm.exception), + "Since you're paging after the first .get call, " + "you can't pass params here." + "Pass params on the .get call instead.") + + def test_params_are_kept_between_pages_gets(self): + def add_responses(rsps): + next_url = 'http://api.teste.com/next_batch' + + rsps.add(responses.GET, self.wrapper.test().data + '?keep-me=please', + body='{"data": [{"key": "value"}], "paging": {"next": "%s"}}' % next_url, + status=200, + content_type='application/json', + match_querystring=True) + + rsps.add(responses.GET, next_url + '?keep-me=please', + body='{"data": [{"key": "value"}], "paging": {"next": ""}}', + status=200, + content_type='application/json', + match_querystring=True) + + with responses.RequestsMock(assert_all_requests_are_fired=True) as rsps: + add_responses(rsps) + + response = self.wrapper.test().get(params={'keep-me': 'please'}) + + for item in response().pages(): + self.assertIn(item.key().data, 'value') + + with responses.RequestsMock(assert_all_requests_are_fired=True) as rsps: + add_responses(rsps) + + for item in self.wrapper.test().pages(params={'keep-me': 'please'}): + self.assertIn(item.key().data, 'value') + class TestTokenRefreshing(unittest.TestCase):