mirror of
https://github.com/bckelley/tconnectsync.git
synced 2026-08-24 03:34:12 -05:00
api/android: add tests for last_event_uploaded and retry behavior
This commit is contained in:
@@ -5,6 +5,7 @@ import datetime
|
||||
import csv
|
||||
import base64
|
||||
import arrow
|
||||
import time
|
||||
|
||||
from bs4 import BeautifulSoup
|
||||
|
||||
@@ -34,6 +35,8 @@ class AndroidApi:
|
||||
|
||||
def __init__(self, email, password):
|
||||
self.login(email, password)
|
||||
self._email = email
|
||||
self._password = password
|
||||
|
||||
def login(self, email, password):
|
||||
r = requests.post(
|
||||
@@ -73,12 +76,33 @@ class AndroidApi:
|
||||
raise Exception('No access token')
|
||||
return {'Authorization': 'Bearer %s' % self.accessToken}
|
||||
|
||||
def get(self, endpoint, query={}, **kwargs):
|
||||
def _get(self, endpoint, query={}, **kwargs):
|
||||
r = requests.get(self.BASE_URL + endpoint, query, headers=self.api_headers(), **kwargs)
|
||||
|
||||
if r.status_code != 200:
|
||||
raise ApiException(r.status_code, "Internal API HTTP %s response: %s" % (str(r.status_code), r.text))
|
||||
raise ApiException(r.status_code, "Android API HTTP %s response: %s" % (str(r.status_code), r.text))
|
||||
return r.json()
|
||||
|
||||
def get(self, endpoint, query={}, tries=0, **kwargs):
|
||||
try:
|
||||
return self._get(endpoint, query, **kwargs)
|
||||
except ApiException as e:
|
||||
if tries > 0:
|
||||
raise ApiException(e.status_code, "Android API HTTP %s on retry #%d: %s" % (e.status_code, tries, e))
|
||||
|
||||
# Trigger automatic re-login, and try again once
|
||||
if e.status_code == 401:
|
||||
self.accessTokenExpiresAt = time.time()
|
||||
self.login(self._email, self._password)
|
||||
|
||||
return self.get(endpoint, query, tries=tries+1, **kwargs)
|
||||
|
||||
if e.status_code == 500:
|
||||
return self.get(endpoint, query, tries=tries+1, **kwargs)
|
||||
|
||||
raise e
|
||||
|
||||
|
||||
def post(self, endpoint, query={}, **kwargs):
|
||||
r = requests.post(self.BASE_URL + endpoint, query, headers=self.api_headers(), **kwargs)
|
||||
if r.status_code != 200:
|
||||
|
||||
+1
-1
@@ -34,7 +34,7 @@ class AndroidApi(tconnectsync.api.android.AndroidApi):
|
||||
def needs_relogin(self):
|
||||
return False
|
||||
|
||||
def get(self, endpoint, query={}, **kwargs):
|
||||
def _get(self, endpoint, query={}, **kwargs):
|
||||
raise NotImplementedError
|
||||
|
||||
class TConnectApi(tconnectsync.api.TConnectApi):
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import unittest
|
||||
import itertools
|
||||
import datetime
|
||||
|
||||
from .fake import AndroidApi
|
||||
|
||||
from tconnectsync.api.common import ApiException
|
||||
|
||||
class TestAndroidApi(unittest.TestCase):
|
||||
def fake_get_with_http_code(self, http_code, expected_endpoint, num_times):
|
||||
tries = 0
|
||||
def fake_get(endpoint, query):
|
||||
nonlocal http_code, expected_endpoint, num_times, tries
|
||||
if endpoint.endswith(expected_endpoint):
|
||||
if tries < num_times:
|
||||
tries += 1
|
||||
raise ApiException(http_code, "fake HTTP %d" % http_code)
|
||||
|
||||
return {"faked_json": True}
|
||||
|
||||
raise NotImplementedError
|
||||
|
||||
return fake_get
|
||||
|
||||
def test_last_event_uploaded_works_after_single_http_500(self):
|
||||
android = AndroidApi()
|
||||
|
||||
android._get = self.fake_get_with_http_code(500, "cloud/upload/getlasteventuploaded?sn=1111111", 1)
|
||||
|
||||
self.assertEqual(
|
||||
android.last_event_uploaded(1111111),
|
||||
{
|
||||
"faked_json": True
|
||||
})
|
||||
|
||||
def test_last_event_uploaded_fails_after_two_http_500s(self):
|
||||
android = AndroidApi()
|
||||
|
||||
android._get = self.fake_get_with_http_code(500, "cloud/upload/getlasteventuploaded?sn=1111111", 2)
|
||||
|
||||
self.assertRaises(ApiException, android.last_event_uploaded, 1111111)
|
||||
|
||||
def test_last_event_uploaded_triggers_relogin_after_single_http_401(self):
|
||||
android = AndroidApi()
|
||||
android._email = 'email'
|
||||
android._password = 'password'
|
||||
|
||||
hit_login = []
|
||||
def stub_login(email, password):
|
||||
nonlocal hit_login
|
||||
hit_login.append((email, password))
|
||||
|
||||
android.login = stub_login
|
||||
|
||||
android._get = self.fake_get_with_http_code(401, "cloud/upload/getlasteventuploaded?sn=1111111", 1)
|
||||
|
||||
self.assertEqual(
|
||||
android.last_event_uploaded(1111111),
|
||||
{
|
||||
"faked_json": True
|
||||
})
|
||||
|
||||
self.assertListEqual(hit_login, [
|
||||
('email', 'password')
|
||||
])
|
||||
|
||||
def test_last_event_uploaded_fails_after_two_http_401s(self):
|
||||
android = AndroidApi()
|
||||
android._email = 'email'
|
||||
android._password = 'password'
|
||||
|
||||
hit_login = []
|
||||
def stub_login(email, password):
|
||||
nonlocal hit_login
|
||||
hit_login.append((email, password))
|
||||
|
||||
android.login = stub_login
|
||||
|
||||
android._get = self.fake_get_with_http_code(401, "cloud/upload/getlasteventuploaded?sn=1111111", 2)
|
||||
|
||||
self.assertRaises(ApiException, android.last_event_uploaded, 1111111)
|
||||
|
||||
self.assertListEqual(hit_login, [
|
||||
('email', 'password')
|
||||
])
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user