def test_fetches_multiple_pages_for_count(self): "Fetches subsequent pages until enough counted tweets are returned." qs = { 'user_id': self.account_1.user.twitter_id, 'tweet_mode': 'extended', 'include_rts': 'true', 'count': 200 } # Return "[{id:999}, {id:998}, {id:997},...]" and patch _save_results() # as we're only interested in how many times we ask for more results. body = json.dumps([{'id': x} for x in reversed(range(800, 1000))]) # We're going to request 3 x 200 Tweets and then... # ...1 x 100 Tweets = 700 Tweets. self.add_response(body=body, querystring=qs, match_querystring=True) qs['max_id'] = 799 self.add_response(body=body, querystring=qs, match_querystring=True) qs['max_id'] = 599 self.add_response(body=body, querystring=qs, match_querystring=True) qs['max_id'] = 399 qs['count'] = 100 self.add_response(body=body, querystring=qs, match_querystring=True) with patch.object(FetchTweetsRecent, '_save_results'): with patch('time.sleep'): result = RecentTweetsFetcher(screen_name='jill').fetch( count=700) self.assertEqual(4, len(responses.calls))
def test_returns_error_if_api_call_fails(self): self.add_response( body='{"errors":[{"message":"Rate limit exceeded","code":88}]}', status=429) result = RecentTweetsFetcher(screen_name='jill').fetch() self.assertFalse(result[0]['success']) self.assertIn('Rate limit exceeded', result[0]['messages'][0])
def test_omits_last_recent_id_from_response(self): "If an account has no last_recent_id, it is not used in the request" self.account_1.last_recent_id = None self.account_1.save() # Stop us fetching multiple pages of results: self.add_response(body='[]') result = RecentTweetsFetcher(screen_name='jill').fetch() self.assertNotIn('since_id=100', responses.calls[0][0].url)
def test_returns_correct_success_response(self): "Data returned is correct" self.add_response(body=self.make_response_body()) result = RecentTweetsFetcher().fetch() self.assertEqual(len(result), 2) self.assertTrue(result[1]['account'], 'jill') self.assertTrue(result[1]['success']) self.assertEqual(result[1]['fetched'], 3)
def test_updates_last_recent_id_new(self): "The account's last_recent_id should be set to the most recent tweet's" self.account_1.last_recent_id = 9876543210 self.account_1.save() self.add_response(body=self.make_response_body()) result = RecentTweetsFetcher(screen_name='jill').fetch() self.account_1.refresh_from_db() self.assertEqual(self.account_1.last_recent_id, 300)
def test_ignores_account_with_no_creds(self, download): # Quietly prevents avatar files being fetched: download.side_effect = DownloadException('Oops') user_3 = UserFactory() account_3 = AccountFactory(user=user_3) self.add_response(body=self.make_response_body()) result = RecentTweetsFetcher().fetch() self.assertEqual(2, len(responses.calls))
def test_returns_error_if_no_creds(self): "If an account has no API credentials, the result is correct" user = UserFactory(screen_name='bobby') account = AccountFactory(user=user) self.add_response(body=self.make_response_body()) result = RecentTweetsFetcher(screen_name='bobby').fetch() self.assertFalse(result[0]['success']) self.assertIn('Account has no API credentials', result[0]['messages'][0])
def test_saves_correct_tweet_data(self, save_tweet): """Assert save_tweet is called once per tweet. Not actually checking what's passed in.""" save_tweet.side_effect = [ TweetFactory(), TweetFactory(), TweetFactory() ] self.add_response(body=self.make_response_body()) result = RecentTweetsFetcher(screen_name='jill').fetch() self.assertEqual(save_tweet.call_count, 3)
def test_includes_count(self): "If fetching a number of tweets, requests that number, not since_id" # We're patching the saving of results, so just need the correct # number of 'Tweets' in the results: body = json.dumps([{'id': 1} for x in range(25)]) self.add_response(body=body) with patch.object(FetchTweetsRecent, '_save_results'): result = RecentTweetsFetcher(screen_name='jill').fetch(count=25) self.assertIn('count=25', responses.calls[0][0].url) self.assertNotIn('since_id=100', responses.calls[0][0].url)
def test_updates_last_recent_id_count(self): """The account's last_recent_id should also be changed if requesting count tweets """ self.account_1.last_recent_id = 9876543210 self.account_1.save() body = json.dumps([{'id': 999} for x in range(25)]) self.add_response(body=body) with patch.object(FetchTweetsRecent, '_save_results'): result = RecentTweetsFetcher(screen_name='jill').fetch(count=25) self.account_1.refresh_from_db() self.assertEqual(self.account_1.last_recent_id, 999)
def test_fetches_multiple_pages_for_new(self, download): "Fetches subsequent pages until no more recent results are returned." # Quietly prevents avatar files being fetched: download.side_effect = DownloadException('Oops') self.account_1.last_recent_id = 10 self.account_1.save() qs = { 'user_id': self.account_1.user.twitter_id, 'include_rts': 'true', 'count': 200, 'since_id': 10 } self.add_response(body=self.make_response_body(), querystring=qs, match_querystring=True) qs['max_id'] = 99 self.add_response(body='[]', querystring=qs, match_querystring=True) with patch('time.sleep'): result = RecentTweetsFetcher(screen_name='jill').fetch() self.assertEqual(2, len(responses.calls))
def test_raises_error_with_invalid_screen_name(self): user = UserFactory(screen_name='goodname') account = AccountFactory(user=user) with self.assertRaises(FetchError): result = RecentTweetsFetcher(screen_name='badname')
def test_saves_tweets(self): self.add_response(body=self.make_response_body()) result = RecentTweetsFetcher(screen_name='jill').fetch() self.assertEqual(Tweet.objects.count(), 3) # Our sample tweets are from a different user, so there'll now be 3: self.assertEqual(User.objects.count(), 3)
def test_includes_last_recent_id_in_response(self): "If an account has a last_recent_id, use it in the request" self.add_response(body=self.make_response_body()) result = RecentTweetsFetcher(screen_name='jill').fetch() self.assertIn('since_id=100', responses.calls[0][0].url)
def test_api_requests_for_all_accounts(self, download): # Quietly prevents avatar files being fetched: download.side_effect = DownloadException('Oops') self.add_response(body=self.make_response_body()) result = RecentTweetsFetcher().fetch() self.assertEqual(2, len(responses.calls))