def test_tweets_get_all(): responses.add(responses.GET, with_resource('/' + API_VERSION + '/accounts/2iqph'), body=with_fixture('accounts_load'), content_type='application/json') responses.add(responses.GET, with_resource('/' + API_VERSION + '/accounts/2iqph/tweets'), body=with_fixture('tweets_get'), content_type='application/json') client = Client( characters(40), characters(40), characters(40), characters(40) ) account = Account.load(client, '2iqph') tweets = Tweets.all( account, tweet_ids=['1166476031668015104'], tweet_type=TWEET_TYPE.PUBLISHED, trim_user=True ) assert tweets is not None assert isinstance(tweets, Cursor) assert tweets.count == 1 assert tweets.first['tweet_id'] == '1166476031668015104'
def test_analytics_sync_stats(): responses.add(responses.GET, with_resource('/' + API_VERSION + '/accounts/2iqph'), body=with_fixture('accounts_load'), content_type='application/json') responses.add(responses.GET, with_resource('/' + API_VERSION + '/stats/accounts/2iqph'), body=with_fixture('analytics_sync_stats'), content_type='application/json') client = Client(characters(40), characters(40), characters(40), characters(40)) account = Account.load(client, '2iqph') ids = ['aaaa', 'bbbb'] metric_groups = [METRIC_GROUP.ENGAGEMENT] stats = Campaign.all_stats(account, ids, metric_groups, granularity=GRANULARITY.TOTAL) assert len(responses.calls) == 2 assert 'granularity=TOTAL' in responses.calls[1].request.url assert stats is not None assert isinstance(stats, list) assert len(stats) == 2 assert stats[0]['id'] == 'aaaa'
def test_promoted_tweets_all(): responses.add(responses.GET, with_resource('/' + API_VERSION + '/accounts/2iqph'), body=with_fixture('accounts_load'), content_type='application/json') responses.add(responses.GET, with_resource('/' + API_VERSION + '/accounts/2iqph/promoted_tweets'), body=with_fixture('promoted_tweets_all'), content_type='application/json') client = Client( characters(40), characters(40), characters(40), characters(40) ) account = Account.load(client, '2iqph') cursor = PromotedTweet.all(account) assert cursor is not None assert isinstance(cursor, Cursor) assert cursor.count == 20 promoted_tweet = cursor.next() assert promoted_tweet.id == '6thl4' assert promoted_tweet.entity_status == 'ACTIVE'
def test_campaigns_all(): responses.add(responses.GET, with_resource('/' + API_VERSION + '/accounts/2iqph'), body=with_fixture('accounts_load'), content_type='application/json') responses.add(responses.GET, with_resource('/' + API_VERSION + '/accounts/2iqph/campaigns'), body=with_fixture('campaigns_all'), content_type='application/json') client = Client( characters(40), characters(40), characters(40), characters(40) ) account = Account.load(client, '2iqph') cursor = account.campaigns() assert cursor is not None assert isinstance(cursor, Cursor) assert cursor.count == 10 campaign = cursor.next() assert campaign.id == '2wap7' assert campaign.entity_status == 'ACTIVE'
def test_rate_limit_cursor_class_access(): responses.add(responses.GET, with_resource('/' + API_VERSION + '/accounts/2iqph'), body=with_fixture('accounts_load'), content_type='application/json') responses.add(responses.GET, with_resource('/' + API_VERSION + '/accounts/2iqph/campaigns'), body=with_fixture('campaigns_all'), content_type='application/json', headers={ 'x-account-rate-limit-limit': '10000', 'x-account-rate-limit-remaining': '9999', 'x-account-rate-limit-reset': '1546300800' }) client = Client(characters(40), characters(40), characters(40), characters(40)) account = Account.load(client, '2iqph') cursor = Campaign.all(account) assert cursor is not None assert isinstance(cursor, Cursor) assert cursor.account_rate_limit_limit == '10000' assert cursor.account_rate_limit_remaining == '9999' assert cursor.account_rate_limit_reset == '1546300800'
def test_promoted_tweets_attach(): responses.add(responses.GET, with_resource('/' + API_VERSION + '/accounts/2iqph'), body=with_fixture('accounts_load'), content_type='application/json') responses.add(responses.POST, with_resource('/' + API_VERSION + '/accounts/2iqph/promoted_tweets'), body=with_fixture('promoted_tweets_attach'), content_type='application/json') client = Client( characters(40), characters(40), characters(40), characters(40) ) account = Account.load(client, '2iqph') response = PromotedTweet.attach( account, line_item_id='2b7xw', tweet_ids=['585127452231467008'] ) assert isinstance(response, Cursor) assert response.count == 1 assert response.first.id == '6thl4'
def test_targeted_audiences(): responses.add(responses.GET, with_resource('/' + API_VERSION + '/accounts/2iqph'), body=with_fixture('accounts_load')) responses.add(responses.GET, with_resource('/' + API_VERSION + '/accounts/2iqph/custom_audiences/2906h'), body=with_fixture('custom_audiences_load')) responses.add(responses.GET, with_resource('/' + API_VERSION + '/accounts/2iqph/custom_audiences/abc2/targeted?with_active=True'), body=with_fixture('targeted_audiences')) client = Client( characters(40), characters(40), characters(40), characters(40) ) account = Account.load(client, '2iqph') audience = CustomAudience.load(account, '2906h') targeted_audiences = audience.targeted( with_active=True ) assert isinstance(targeted_audiences, Cursor) assert isinstance(targeted_audiences.first.line_items, list) assert targeted_audiences.first.campaign_id == '59hod' assert targeted_audiences.first.line_items[0]['id'] == '5gzog' assert targeted_audiences.first.line_items[0]['name'] == 'test-line-item' assert targeted_audiences.first.line_items[0]['servable'] == True assert len(responses.calls) == 3
def test_line_items_all(): responses.add(responses.GET, with_resource('/' + API_VERSION + '/accounts/2iqph'), body=with_fixture('accounts_load'), content_type='application/json') responses.add(responses.GET, with_resource('/' + API_VERSION + '/accounts/2iqph/line_items'), body=with_fixture('line_items_all'), content_type='application/json') client = Client( characters(40), characters(40), characters(40), characters(40) ) account = Account.load(client, '2iqph') cursor = account.line_items() assert cursor is not None assert isinstance(cursor, Cursor) assert cursor.count == 10 lineitem = cursor.next() assert lineitem.id == 'bw2' assert lineitem.entity_status == 'ACTIVE'
def test_campaigns_all(): responses.add(responses.GET, with_resource('/' + API_VERSION + '/accounts/2iqph'), body=with_fixture('accounts_load'), content_type='application/json') responses.add(responses.GET, with_resource('/' + API_VERSION + '/accounts/2iqph/campaigns'), body=with_fixture('campaigns_all'), content_type='application/json') client = Client(characters(40), characters(40), characters(40), characters(40)) account = Account.load(client, '2iqph') cursor = account.campaigns() assert cursor is not None assert isinstance(cursor, Cursor) assert cursor.count == 10 campaign = cursor.next() assert campaign.id == '2wap7' assert campaign.entity_status == 'ACTIVE'
def test_active_entities(): responses.add(responses.GET, with_resource('/' + API_VERSION + '/accounts/2iqph'), body=with_fixture('accounts_load'), content_type='application/json') responses.add(responses.GET, with_resource('/' + API_VERSION + '/stats/accounts/2iqph/active_entities'), body=with_fixture('active_entities'), content_type='application/json') client = Client(characters(40), characters(40), characters(40), characters(40)) account = Account.load(client, '2iqph') end_time = datetime.utcnow().date() start_time = end_time - timedelta(days=1) active_entities = Campaign.active_entities(account, start_time, end_time, campaign_ids=['foo', 'bar']) assert len(responses.calls) == 2 assert 'campaign_ids=foo%2Cbar' in responses.calls[1].request.url assert active_entities is not None assert isinstance(active_entities, list) assert len(active_entities) == 4 assert active_entities[0]['entity_id'] == '2mvb28'
def test_tweet_previews_load(): responses.add(responses.GET, with_resource('/' + API_VERSION + '/accounts/2iqph'), body=with_fixture('accounts_load'), content_type='application/json') responses.add(responses.GET, with_resource('/' + API_VERSION + '/accounts/2iqph/tweet_previews'), body=with_fixture('tweet_previews'), content_type='application/json') client = Client(characters(40), characters(40), characters(40), characters(40)) account = Account.load(client, '2iqph') tweets = TweetPreview.load( account, tweet_ids=['1130942781109596160', '1101254234031370240'], tweet_type=TWEET_TYPE.PUBLISHED) assert tweets is not None assert isinstance(tweets, Cursor) assert tweets.count == 2 tweet = tweets.next() assert tweet.tweet_id == '1130942781109596160' assert '<iframe' in tweet.preview
def test_analytics_async(): responses.add(responses.GET, with_resource('/' + API_VERSION + '/accounts/2iqph'), body=with_fixture('accounts_load'), content_type='application/json') responses.add(responses.POST, with_resource('/' + API_VERSION + '/stats/jobs/accounts/2iqph'), body=with_fixture('analytics_async_post'), content_type='application/json') responses.add(responses.GET, with_resource('/' + API_VERSION + '/stats/jobs/accounts/2iqph'), body=with_fixture('analytics_async_get'), content_type='application/json') client = Client( characters(40), characters(40), characters(40), characters(40) ) account = Account.load(client, '2iqph') ids = ['aaaa'] metric_groups = [METRIC_GROUP.ENGAGEMENT] stats = Campaign.queue_async_stats_job( account, ids, metric_groups, granularity=GRANULARITY.TOTAL ) # test POST request response - queue_async_stats_job() assert 'granularity=TOTAL' in responses.calls[1].request.url assert stats is not None assert isinstance(stats, dict) assert stats['entity_ids'] == ids # call async_stats_job_result() through Campaign class (inheritance) job_id = stats['id_str'] job_result = Campaign.async_stats_job_result( account, [job_id]).first assert job_result is not None assert isinstance(job_result, dict) assert job_result['url'] == 'https://ton.twimg.com/advertiser-api-async-analytics/stats.json.gz' # call async_stats_job_result() from Analytics class directly job_result = Analytics.async_stats_job_result( account, [job_id]).first assert job_result is not None assert isinstance(job_result, dict) assert job_result['url'] == 'https://ton.twimg.com/advertiser-api-async-analytics/stats.json.gz'
def test_audience_summary(): responses.add(responses.GET, with_resource('/' + API_VERSION + '/accounts/2iqph'), body=with_fixture('accounts_load'), content_type='application/json') responses.add(responses.POST, with_resource('/' + API_VERSION + '/accounts/2iqph/audience_estimate'), body=with_fixture('audience_estimate'), content_type='application/json') client = Client( characters(40), characters(40), characters(40), characters(40) ) account = Account.load(client, '2iqph') params = { "targeting_criteria": [ { "targeting_type":"LOCATION", "targeting_value":"96683cc9126741d1" }, { "targeting_type":"BROAD_KEYWORD", "targeting_value":"cats" }, { "targeting_type":"SIMILAR_TO_FOLLOWERS_OF_USER", "targeting_value": "14230524" }, { "targeting_type":"SIMILAR_TO_FOLLOWERS_OF_USER", "targeting_value": "90420314" } ] } audience_summary = AudienceEstimate.load( account=account, params=params ) print (audience_summary) assert audience_summary is not None assert audience_summary.audience_size is not None assert audience_summary.audience_size['min'] == 41133600 assert audience_summary.audience_size['max'] == 50274400
def test_retry_count_error(monkeypatch): monkeypatch.setattr(time, 'sleep', lambda s: None) responses.add(responses.GET, with_resource('/' + API_VERSION + '/accounts/2iqph'), body=with_fixture('accounts_load'), content_type='application/json') responses.add(responses.GET, with_resource('/' + API_VERSION + '/accounts/2iqph/campaigns'), status=404, body=with_fixture('campaigns_all'), content_type='application/json', headers={ 'x-account-rate-limit-limit': '10000', 'x-account-rate-limit-remaining': '0', 'x-account-rate-limit-reset': str(int(time.time()) + 5) }) responses.add(responses.GET, with_resource('/' + API_VERSION + '/accounts/2iqph/campaigns'), status=404, body=with_fixture('campaigns_all'), content_type='application/json', headers={ 'x-account-rate-limit-limit': '10000', 'x-account-rate-limit-remaining': '9999', 'x-account-rate-limit-reset': '1546300800' }) client = Client(characters(40), characters(40), characters(40), characters(40), options={ 'retry_max': 1, 'retry_delay': 3000, 'retry_on_status': [404, 500, 503] }) account = Account.load(client, '2iqph') try: cursor = Campaign.all(account) except Exception as e: error = e print(error) assert len(responses.calls) == 3 assert isinstance(error, NotFound)
def test_rate_limit_handle_error(monkeypatch): monkeypatch.setattr(time, 'sleep', lambda s: None) responses.add(responses.GET, with_resource('/' + API_VERSION + '/accounts/2iqph'), body=with_fixture('accounts_load'), content_type='application/json') responses.add(responses.GET, with_resource('/' + API_VERSION + '/accounts/2iqph/campaigns'), status=429, body=with_fixture('campaigns_all'), content_type='application/json', headers={ 'x-account-rate-limit-limit': '10000', 'x-account-rate-limit-remaining': '0', 'x-account-rate-limit-reset': str(int(time.time()) + 5) }) responses.add(responses.GET, with_resource('/' + API_VERSION + '/accounts/2iqph/campaigns'), status=429, body=with_fixture('campaigns_all'), content_type='application/json', headers={ 'x-account-rate-limit-limit': '10000', 'x-account-rate-limit-remaining': '0', 'x-account-rate-limit-reset': '1546300800' }) client = Client(characters(40), characters(40), characters(40), characters(40), options={'handle_rate_limit': True}) account = Account.load(client, '2iqph') try: cursor = Campaign.all(account) except Exception as e: error = e print(error) assert len(responses.calls) == 3 assert isinstance(error, RateLimit) assert error.reset_at == '1546300800'
def test_campaign_load(): responses.add(responses.GET, with_resource('/' + API_VERSION + '/accounts/2iqph'), body=with_fixture('accounts_load'), content_type='application/json') responses.add(responses.GET, with_resource('/' + API_VERSION + '/accounts/2iqph/campaigns/2wap7'), body=with_fixture('campaigns_load'), content_type='application/json') client = Client(characters(40), characters(40), characters(40), characters(40)) account = Account.load(client, '2iqph') campaign = Campaign.load(account, '2wap7') assert campaign.id == '2wap7' assert campaign.entity_status == 'ACTIVE'
def test_promoted_tweets_load(): responses.add(responses.GET, with_resource('/' + API_VERSION + '/accounts/2iqph'), body=with_fixture('accounts_load'), content_type='application/json') responses.add(responses.GET, with_resource('/' + API_VERSION + '/accounts/2iqph/promoted_tweets/6thl4'), body=with_fixture('promoted_tweets_load'), content_type='application/json') client = Client(characters(40), characters(40), characters(40), characters(40)) account = Account.load(client, '2iqph') promoted_tweet = PromotedTweet.load(account, '6thl4') assert promoted_tweet.id == '6thl4' assert promoted_tweet.entity_status == 'ACTIVE'
def test_rate_limit_resource_class_access(): responses.add(responses.GET, with_resource('/' + API_VERSION + '/accounts/2iqph'), body=with_fixture('accounts_load'), content_type='application/json') responses.add(responses.GET, with_resource('/' + API_VERSION + '/accounts/2iqph/campaigns/2wap7'), body=with_fixture('campaigns_load'), content_type='application/json', headers={ 'x-account-rate-limit-limit': '10000', 'x-account-rate-limit-remaining': '9999', 'x-account-rate-limit-reset': '1546300800' }) client = Client(characters(40), characters(40), characters(40), characters(40)) account = Account.load(client, '2iqph') campaign = Campaign.load(account, '2wap7') resource = '/' + API_VERSION + '/accounts/2iqph/campaigns/2wap7' params = {} response = Request(client, 'get', resource, params=params).perform() # from_response() is a staticmethod, so passing campaign instance as dummy. # We can later change this test case to not call this manually # once we changed existing classes to pass the header argument. data = campaign.from_response(response.body['data'], response.headers) assert data is not None assert isinstance(data, Resource) assert data.id == '2wap7' assert data.entity_status == 'ACTIVE' assert data.account_rate_limit_limit == '10000' assert data.account_rate_limit_remaining == '9999' assert data.account_rate_limit_reset == '1546300800'
def test_accounts_with_no_id(): responses.add(responses.GET, with_resource('/' + API_VERSION + '/accounts'), body=with_fixture('accounts_all'), content_type='application/json') client = Client(characters(40), characters(40), characters(40), characters(40)) cursor = client.accounts() assert cursor is not None assert isinstance(cursor, Cursor) assert cursor.count == 5
def test_accounts_with_id(): responses.add(responses.GET, with_resource('/' + API_VERSION + '/accounts/2iqph'), body=with_fixture('accounts_load'), content_type='application/json') client = Client(characters(40), characters(40), characters(40), characters(40)) account = client.accounts('2iqph') assert account is not None assert isinstance(account, Account) assert account.id == '2iqph'
def test_line_item_load(): responses.add(responses.GET, with_resource('/' + API_VERSION + '/accounts/2iqph'), body=with_fixture('accounts_load'), content_type='application/json') responses.add(responses.GET, with_resource('/' + API_VERSION + '/accounts/2iqph/line_items/bw2'), body=with_fixture('line_items_load'), content_type='application/json') client = Client( characters(40), characters(40), characters(40), characters(40) ) account = Account.load(client, '2iqph') line_item = LineItem.load(account, 'bw2') assert line_item.id == 'bw2' assert line_item.entity_status == 'ACTIVE'
def test_campaign_load(): responses.add(responses.GET, with_resource('/' + API_VERSION + '/accounts/2iqph'), body=with_fixture('accounts_load'), content_type='application/json') responses.add(responses.GET, with_resource('/' + API_VERSION + '/accounts/2iqph/campaigns/2wap7'), body=with_fixture('campaigns_load'), content_type='application/json') client = Client( characters(40), characters(40), characters(40), characters(40) ) account = Account.load(client, '2iqph') campaign = Campaign.load(account, '2wap7') assert campaign.id == '2wap7' assert campaign.entity_status == 'ACTIVE'
def test_accounts_with_no_id(): responses.add(responses.GET, with_resource('/' + API_VERSION + '/accounts'), body=with_fixture('accounts_all'), content_type='application/json') client = Client( characters(40), characters(40), characters(40), characters(40) ) cursor = client.accounts() assert cursor is not None assert isinstance(cursor, Cursor) assert cursor.count == 5
def test_accounts_with_id(): responses.add(responses.GET, with_resource('/' + API_VERSION + '/accounts/2iqph'), body=with_fixture('accounts_load'), content_type='application/json') client = Client( characters(40), characters(40), characters(40), characters(40) ) account = client.accounts('2iqph') assert account is not None assert isinstance(account, Account) assert account.id == '2iqph'
def test_analytics_async(): responses.add(responses.GET, with_resource('/' + API_VERSION + '/accounts/2iqph'), body=with_fixture('accounts_load'), content_type='application/json') responses.add(responses.POST, with_resource('/' + API_VERSION + '/stats/jobs/accounts/2iqph'), body=with_fixture('analytics_async_post'), content_type='application/json', headers={ 'x-concurrent-job-limit': '100', 'x-concurrent-job-limit-remaining': '99' }) responses.add(responses.GET, with_resource('/' + API_VERSION + '/stats/jobs/accounts/2iqph'), body=with_fixture('analytics_async_get'), content_type='application/json') client = Client(characters(40), characters(40), characters(40), characters(40)) account = Account.load(client, '2iqph') ids = ['aaaa'] metric_groups = [METRIC_GROUP.ENGAGEMENT] stats = Campaign.queue_async_stats_job(account, ids, metric_groups, granularity=GRANULARITY.TOTAL) # call queue_async_stats_job() through Campaign class (inheritance) assert 'granularity=TOTAL' in responses.calls[1].request.url assert stats is not None assert isinstance(stats, Analytics) assert stats.entity_ids == ids assert stats.concurrent_job_limit == '100' stats2 = Analytics.queue_async_stats_job(account, ids, metric_groups, granularity=GRANULARITY.TOTAL, entity=ENTITY.CAMPAIGN) # call queue_async_stats_job() from Analytics class directly assert 'entity=CAMPAIGN' in responses.calls[1].request.url assert stats2 is not None assert isinstance(stats2, Analytics) assert stats2.entity_ids == ids assert stats2.concurrent_job_limit == '100' # call async_stats_job_result() through Campaign class (inheritance) job_id = stats.id_str job_result = Campaign.async_stats_job_result(account, job_ids=[job_id]).first assert job_result is not None assert isinstance(job_result, Analytics) assert job_result.url == 'https://ton.twimg.com/advertiser-api-async-analytics/stats.json.gz' # call async_stats_job_result() from Analytics class directly job_result = Analytics.async_stats_job_result(account, job_ids=[job_id]).first assert job_result is not None assert isinstance(job_result, Analytics) assert job_result.url == 'https://ton.twimg.com/advertiser-api-async-analytics/stats.json.gz'
def test_rate_limit_handle_with_retry_success_2(monkeypatch): # scenario: # - 429 (handle rate limit) -> 500 (retry) -> 200 (end) monkeypatch.setattr(time, 'sleep', lambda s: None) responses.add(responses.GET, with_resource('/' + API_VERSION + '/accounts/2iqph'), body=with_fixture('accounts_load'), content_type='application/json') responses.add(responses.GET, with_resource('/' + API_VERSION + '/accounts/2iqph/campaigns'), status=429, body=with_fixture('campaigns_all'), content_type='application/json', headers={ 'x-account-rate-limit-limit': '10000', 'x-account-rate-limit-remaining': '0', 'x-account-rate-limit-reset': '1546300800' }) responses.add(responses.GET, with_resource('/' + API_VERSION + '/accounts/2iqph/campaigns'), status=500, body=with_fixture('campaigns_all'), content_type='application/json', headers={ 'x-account-rate-limit-limit': '10000', 'x-account-rate-limit-remaining': '0', 'x-account-rate-limit-reset': str(int(time.time()) + 5) }) responses.add(responses.GET, with_resource('/' + API_VERSION + '/accounts/2iqph/campaigns'), status=200, body=with_fixture('campaigns_all'), content_type='application/json', headers={ 'x-account-rate-limit-limit': '10000', 'x-account-rate-limit-remaining': '9999', 'x-account-rate-limit-reset': '1546300800' }) client = Client(characters(40), characters(40), characters(40), characters(40), options={ 'handle_rate_limit': True, 'retry_max': 1, 'retry_delay': 3000, 'retry_on_status': [500] }) account = Account.load(client, '2iqph') cursor = Campaign.all(account) assert len(responses.calls) == 4 assert cursor is not None assert isinstance(cursor, Cursor) assert cursor.account_rate_limit_limit == '10000' assert cursor.account_rate_limit_remaining == '9999' assert cursor.account_rate_limit_reset == '1546300800'