diff --git a/owlet_api/cli.py b/owlet_api/cli.py index 8e7f242..0c917a6 100644 --- a/owlet_api/cli.py +++ b/owlet_api/cli.py @@ -46,7 +46,7 @@ def cli(): try: api.login() except OwletPermanentCommunicationException: - print("Login failed, username or passwort might be wrong") + print("Login failed, username or password might be wrong") sys.exit(1) except OwletTemporaryCommunicationException: print("Login failed, server might be down") diff --git a/owlet_api/owlet.py b/owlet_api/owlet.py index 8393161..fe1c1d6 100644 --- a/owlet_api/owlet.py +++ b/owlet_api/owlet.py @@ -1,6 +1,7 @@ #!/usr/bin/env python """Contains Class Owlet.""" +import json from json.decoder import JSONDecodeError import requests from requests.exceptions import RequestException @@ -99,13 +100,266 @@ def update(self): 'Server Request failed - status code') try: - json = result.json() + json_data = result.json() except JSONDecodeError: raise OwletTemporaryCommunicationException( 'Update failed - JSON error') - for myproperty in json: + for myproperty in json_data: property_name = myproperty['property']['name'] + + if property_name == 'REAL_TIME_VITALS': + # Convert Dream Sock Data to Smart Sock 3 Format + vitals = json.loads(myproperty['property']['value']) + # OXYGEN_LEVEL = ox + temp_property = { + 'name': 'OXYGEN_LEVEL', + 'display_name': 'Oxygen Level', + 'key': myproperty['property']['key'], + 'value': vitals['ox'], + 'data_updated_at': myproperty['property']['data_updated_at'] + } + new_property = OwletProperty(temp_property) + self.properties[new_property.name] = new_property + #HEART_RATE = hr + temp_property = { + 'name': 'HEART_RATE', + 'display_name': 'Heart Rate', + 'key': myproperty['property']['key'], + 'value': vitals['hr'], + 'data_updated_at': myproperty['property']['data_updated_at'] + } + new_property = OwletProperty(temp_property) + self.properties[new_property.name] = new_property + #MOVEMENT = mv + temp_property = { + 'name': 'MOVEMENT', + 'display_name': 'Baby Movement', + 'key': myproperty['property']['key'], + 'value': vitals['mv'], + 'data_updated_at': myproperty['property']['data_updated_at'] + } + new_property = OwletProperty(temp_property) + self.properties[new_property.name] = new_property + # SOCK_CONNECTION = sc + temp_property = { + 'name': 'SOCK_CONNECTION', + 'display_name': 'Sock Connection', + 'key': myproperty['property']['key'], + 'value': vitals['sc'], + 'data_updated_at': myproperty['property']['data_updated_at'] + } + new_property = OwletProperty(temp_property) + self.properties[new_property.name] = new_property + """ + # ??? = st + temp_property = { + 'name': '???', + 'display_name': '???', + 'key': myproperty['property']['key'], + 'value': vitals['st'], + 'data_updated_at': myproperty['property']['data_updated_at'] + } + new_property = OwletProperty(temp_property) + self.properties[new_property.name] = new_property + """ + # BASE_STAT_ON = bso + temp_property = { + 'name': 'BASE_STAT_ON', + 'display_name': 'Base Station On', + 'key': myproperty['property']['key'], + 'value': vitals['bso'], + 'data_updated_at': myproperty['property']['data_updated_at'] + } + new_property = OwletProperty(temp_property) + self.properties[new_property.name] = new_property + #BATT_LEVEL = bat + temp_property = { + 'name': 'BATT_LEVEL', + 'display_name': 'Battery Level (%)', + 'key': myproperty['property']['key'], + 'value': vitals['bat'], + 'data_updated_at': myproperty['property']['data_updated_at'] + } + new_property = OwletProperty(temp_property) + self.properties[new_property.name] = new_property + # BAT_TIME = btt + temp_property = { + 'name': 'BAT_TIME', + 'display_name': 'Sock Battery (Minutes)', + 'key': myproperty['property']['key'], + 'value': vitals['btt'], + 'data_updated_at': myproperty['property']['data_updated_at'] + } + new_property = OwletProperty(temp_property) + self.properties[new_property.name] = new_property + # CHARGE_STATUS = chg + # 1 = Charged + # 2 = Charging + temp_property = { + 'name': 'CHARGE_STATUS', + 'display_name': 'Charge Status', + 'key': myproperty['property']['key'], + 'value': vitals['chg'], + 'data_updated_at': myproperty['property']['data_updated_at'] + } + new_property = OwletProperty(temp_property) + self.properties[new_property.name] = new_property + # ALRTS_DISABLED = aps + temp_property = { + 'name': 'ALRTS_DISABLED', + 'display_name': 'Disable Alerts', + 'key': myproperty['property']['key'], + 'value': vitals['aps'], + 'data_updated_at': myproperty['property']['data_updated_at'] + } + new_property = OwletProperty(temp_property) + self.properties[new_property.name] = new_property + # ALERT = alrt + # 16 = Disconnected + # 32 & 64 = Placement + temp_property = { + 'name': 'ALERT', + 'display_name': 'Alert Status', + 'key': myproperty['property']['key'], + 'value': vitals['alrt'], + 'data_updated_at': myproperty['property']['data_updated_at'] + } + new_property = OwletProperty(temp_property) + self.properties[new_property.name] = new_property + # OTA_STATUS = ota + # 0 = None + # 1 = Firmware being sent + # 2 = Waiting for sock to be plugged in + # 3 = Installing + # 4 = Installing Critical + # 5 = Unknown + temp_property = { + 'name': 'OTA_STATUS', + 'display_name': 'OTA Status', + 'key': myproperty['property']['key'], + 'value': vitals['ota'], + 'data_updated_at': myproperty['property']['data_updated_at'] + } + new_property = OwletProperty(temp_property) + self.properties[new_property.name] = new_property + # SOCK_STATUS = srf + # 1 = Checking On + # 2 (When sc also = 2) = Kicking + # 3 = Recently Placed + temp_property = { + 'name': 'SOCK_STATUS', + 'display_name': 'Sock Status', + 'key': myproperty['property']['key'], + 'value': vitals['srf'], + 'data_updated_at': myproperty['property']['data_updated_at'] + } + new_property = OwletProperty(temp_property) + self.properties[new_property.name] = new_property + #BLE_RSSI = rsi + temp_property = { + 'name': 'BLE_RSSI', + 'display_name': 'BLE RSSI', + 'key': myproperty['property']['key'], + 'value': vitals['rsi'], + 'data_updated_at': myproperty['property']['data_updated_at'] + } + new_property = OwletProperty(temp_property) + self.properties[new_property.name] = new_property + """ + # ??? = sb + temp_property = { + 'name': '???', + 'display_name': '???', + 'key': myproperty['property']['key'], + 'value': vitals['sb'], + 'data_updated_at': myproperty['property']['data_updated_at'] + } + new_property = OwletProperty(temp_property) + self.properties[new_property.name] = new_property + """ + """ + # ??? = ss + temp_property = { + 'name': '???', + 'display_name': '???', + 'key': myproperty['property']['key'], + 'value': vitals['ss'], + 'data_updated_at': myproperty['property']['data_updated_at'] + } + new_property = OwletProperty(temp_property) + self.properties[new_property.name] = new_property + """ + """ + # ??? = mvb + temp_property = { + 'name': '???', + 'display_name': '???', + 'key': myproperty['property']['key'], + 'value': vitals['mvb'], + 'data_updated_at': myproperty['property']['data_updated_at'] + } + new_property = OwletProperty(temp_property) + self.properties[new_property.name] = new_property + """ + """ + # ??? = mst + temp_property = { + 'name': '???', + 'display_name': '???', + 'key': myproperty['property']['key'], + 'value': vitals['mst'], + 'data_updated_at': myproperty['property']['data_updated_at'] + } + new_property = OwletProperty(temp_property) + self.properties[new_property.name] = new_property + """ + # OXYGEN_TEN_MIN = oxta + temp_property = { + 'name': 'OXYGEN_TEN_MIN', + 'display_name': 'Oxygen Ten Minute Average', + 'key': myproperty['property']['key'], + 'value': vitals['oxta'], + 'data_updated_at': myproperty['property']['data_updated_at'] + } + new_property = OwletProperty(temp_property) + self.properties[new_property.name] = new_property + """ + # ??? = onm + temp_property = { + 'name': '???', + 'display_name': '???', + 'key': myproperty['property']['key'], + 'value': vitals['onm'], + 'data_updated_at': myproperty['property']['data_updated_at'] + } + new_property = OwletProperty(temp_property) + self.properties[new_property.name] = new_property + """ + """ + # ??? = bsb + temp_property = { + 'name': '???', + 'display_name': '???', + 'key': myproperty['property']['key'], + 'value': vitals['bsb'], + 'data_updated_at': myproperty['property']['data_updated_at'] + } + new_property = OwletProperty(temp_property) + self.properties[new_property.name] = new_property + """ + """ + # ??? = hw + temp_property = { + 'name': '???', + 'display_name': '???', + 'key': myproperty['property']['key'], + 'value': vitals['hw'], + 'data_updated_at': myproperty['property']['data_updated_at'] + } + new_property = OwletProperty(temp_property) + self.properties[new_property.name] = new_property + """ if property_name in self.properties: self.properties[property_name].update(myproperty['property']) else: @@ -132,11 +386,14 @@ def download_logged_data(self): raise OwletNotInitializedException( 'Initialize first - no properties') - if 'LOGGED_DATA_CACHE' not in self.properties: + if 'LOGGED_DATA_CACHE' not in self.properties and \ + 'VITALS_LOG_FILE' not in self.properties: raise OwletNotInitializedException( 'Initialize first - missing property') - - download_url = self.properties['LOGGED_DATA_CACHE'].value + if 'LOGGED_DATA_CACHE' in self.properties: + download_url = self.properties['LOGGED_DATA_CACHE'].value + if 'VITALS_LOG_FILE' in self.properties: + download_url = self.properties['VITALS_LOG_FILE'].value download_header = self.owlet_api.get_request_headers() try: diff --git a/owlet_api/owletapi.py b/owlet_api/owletapi.py index 708a624..00b3a1d 100644 --- a/owlet_api/owletapi.py +++ b/owlet_api/owletapi.py @@ -14,19 +14,58 @@ class OwletAPI(): """Handles Owlet API stuff.""" - base_user_url = 'https://user-field.aylanetworks.com/users/' - base_properties_url = 'https://ads-field.aylanetworks.com/apiv1/' + google_API_key = 'AIzaSyCBJ_5TRcPz_cQA4Xdqpcuo9PE5lR8Cc7k' + app_id = 'owa-rg-id' + app_secret = 'owa-dx85qljgtR6hmVflyrL6LasCxA8' + owlet_login_url = 'https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=' + owlet_login_token_provider_url = 'https://ayla-sso.owletdata.com/mini/' + base_user_url = 'https://ads-owlue1.aylanetworks.com/api/v1/token_sign_in.json' + base_properties_url = 'https://ads-owlue1.aylanetworks.com/apiv1/' def __init__(self, email=None, password=None): """Initialize OwletAPI, with email and password as opt. arguments.""" self._email = email self._password = password + self._owlet_id_token = None + self._owlet_local_id = None + self._owlet_refresh_token = None + self._owlet_id_token_expiry_time = None + self._owlet_mini_token = None self._auth_token = None + self._refresh_token = None self._expiry_time = None self._devices = [] + def set_api_key(self, key): + """Set google API key.""" + self.google_API_key = key + + def set_app_id(self, app_id): + """Set app_id.""" + self.app_id = app_id + + def set_app_secret(self, app_secret): + """Set app_secret.""" + self.app_secret = app_secret + + def set_owlet_login_url(self, owlet_login_url): + """Set owlet_login_url.""" + self.owlet_login_url = owlet_login_url + + def set_owlet_login_token_provider_url(self, owlet_login_token_provider_url): + """Set owlet_login_token_provider_url.""" + self.owlet_login_token_provider_url = owlet_login_token_provider_url + + def set_base_user_url(self, base_user_url): + """Set base_user_url.""" + self.base_user_url = base_user_url + + def set_base_properties_url(self, base_properties_url): + """Set base_properties_url.""" + self.base_properties_url = base_properties_url + def set_email(self, email): - """Set Emailadress aka Username.""" + """Set Email address aka Username.""" self._email = email def set_password(self, password): @@ -34,23 +73,26 @@ def set_password(self, password): self._password = password def login(self): - """Login to Owlet Cloud Service and obtain Auth Token.""" + """Login is currently a three step process + 1. Login to Google Identity Toolkit to get owlet_authorization + 2. Use owlet_authorization to get Ayla login token + 3. Use Ayla login token to login to Ayla cloud database + """ + + """Step 1: Login to Google Identity Toolkit to get authorization.""" login_headers = { 'Content-Type': 'application/json', 'Accept': 'application/json' } - login_url = self.base_user_url + 'sign_in.json' + login_url = self.owlet_login_url + self.google_API_key + + login_payload = { - 'user': { - 'email': self._email, - 'password': self._password, - 'application': { - 'app_id': 'OWL-id', - 'app_secret': 'OWL-4163742' - } - } + 'returnSecureToken': True, + 'email': self._email, + 'password': self._password } try: @@ -65,26 +107,130 @@ def login(self): 'Login request failed - no response') # Login failed - if result.status_code == 401: + if result.status_code == 400: + if result.text.__contains__('EMAIL_NOT_FOUND'): + raise OwletPermanentCommunicationException( + 'Login failed, bad username', result) + if result.text.__contains__('INVALID_PASSWORD'): + raise OwletPermanentCommunicationException( + 'Login failed, bad password', result) + if result.text.__contains__('API_KEY_INVALID'): + raise OwletPermanentCommunicationException( + 'Login failed, bad API key.', result) raise OwletPermanentCommunicationException( - 'Login failed, check username and password') + 'Login failed, check username and password', result) if result.status_code != 200: raise OwletTemporaryCommunicationException( - 'Login request failed - status code') + 'Login request failed - status code (' + str(result.status_code) + ') - (Step 2 of 3)', result) # Login seems to be ok, extract json try: json_result = result.json() except JSONDecodeError: raise OwletTemporaryCommunicationException( - 'Server did not send valid json') + 'Server did not send valid json (Step 1 of 3)') + + if ('idToken' not in json_result) or \ + ('localId' not in json_result) or \ + ('refreshToken' not in json_result) or \ + ('expiresIn' not in json_result): + raise OwletTemporaryCommunicationException( + 'Server did not send id token (Step 1 of 3)', json_result) + + self._owlet_id_token = json_result['idToken'] + self._owlet_local_id = json_result['localId'] + self._owlet_refresh_token = json_result['refreshToken'] + self._owlet_id_token_expiry_time = time.time() + int(json_result['expiresIn']) + + """Step 2: Retrieve Ayla Login Token.""" + login_headers = { + 'Accept': 'application/json', + 'authorization': self._owlet_id_token + } + + login_url = self.owlet_login_token_provider_url + + try: + result = requests.get( + login_url, + headers=login_headers, + timeout=5 + ) + except RequestException: + raise OwletTemporaryCommunicationException( + 'Login request failed - no response (Step 2 of 3)') + + # Login failed + if result.status_code != 200: + raise OwletTemporaryCommunicationException( + 'Login request failed - status code (' + str(result.status_code) + ') - (Step 2 of 3)', result) + + # Login seems to be ok, extract json + try: + json_result = result.json() + except JSONDecodeError: + raise OwletTemporaryCommunicationException( + 'Server did not send valid json (Step 2 of 3)') + + if ('mini_token' not in json_result): + raise OwletTemporaryCommunicationException( + 'Server did not send mini token (Step 2 of 3)', json_result) + + self._owlet_mini_token = json_result['mini_token'] + + """Step 3: Login to Ayla and obtain Auth Token.""" + login_headers = { + 'Content-Type': 'application/json', + 'Accept': 'application/json' + } + + login_url = self.base_user_url + + login_payload = { + 'token': self._owlet_mini_token, + 'app_id': self.app_id, + 'app_secret': self.app_secret, + 'headers': { + 'Accept': 'application/json', + 'Content-Type': 'application/json' + } + } + + try: + result = requests.post( + login_url, + json=login_payload, + headers=login_headers, + timeout=5 + ) + except RequestException: + raise OwletTemporaryCommunicationException( + 'Login request failed - no response (Step 3 of 3)', result) + + # Login failed + if result.status_code != 200: + if result.status_code == 404 and\ + result.text.__contains__('Could not find application'): + raise OwletPermanentCommunicationException( + 'login request failed - app_id or app_secret is bad (Step 3 of 3)', result) + raise OwletTemporaryCommunicationException( + 'Login request failed - status code (' + str(result.status_code) + ') - (Step 3 of 3)', result) + + # Login seems to be ok, extract json + try: + json_result = result.json() + except JSONDecodeError: + raise OwletTemporaryCommunicationException( + 'Server did not send valid json (Step 3 of 3)') if ('access_token' not in json_result) or \ + ('refresh_token' not in json_result) or \ ('expires_in' not in json_result): raise OwletTemporaryCommunicationException( - 'Server did not send access token') + 'Server did not send access token (Step 3 of 3)', json_result) self._auth_token = json_result['access_token'] + self._refresh_token = json_result['refresh_token'] self._expiry_time = time.time() + json_result['expires_in'] def get_auth_token(self): @@ -134,7 +280,7 @@ def update_devices(self): if result.status_code != 200: raise OwletTemporaryCommunicationException( - 'Server request failed - status code') + 'Server request failed - status code', result) try: json_result = result.json() diff --git a/setup.py b/setup.py index 249241f..8e2b571 100644 --- a/setup.py +++ b/setup.py @@ -4,7 +4,7 @@ from setuptools import setup, find_packages name='owlet_api' -version='0.1.0' +version='0.2.0' setup(name = name, version = version, diff --git a/tests/test_cli.py b/tests/test_cli.py index 696c871..02fdecb 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -17,7 +17,12 @@ from owlet_api.cli import cli LOGIN_PAYLOAD = { - 'access_token': 'testtoken', + 'access_token': 'test_access_token', + 'idToken': 'test_id_token', + 'refreshToken': 'test_refresh_token', + 'refresh_token': 'test_refresh_token', + 'mini_token': 'test_min_token', + 'expiresIn': '3600', 'expires_in': 86400 } @@ -168,16 +173,20 @@ 'metadata':{ }, - 'value':'https://ads-field.aylanetworks.com/apiv1/devices/24826059/properties/LOGGED_DATA_CACHE/datapoints/76ce9810-5375-11e8-e7a5-6450803806ca.json', + 'value':OwletAPI.base_properties_url + 'devices/24826059/properties/LOGGED_DATA_CACHE/datapoints/76ce9810-5375-11e8-e7a5-6450803806ca.json', 'created_at_from_device':None, - 'file':'https://ayla-device-field-production-1a2039d9.s3.amazonaws.com/X?AWSAccessKeyId=Y&Expires=1234&Signature=Z' + 'file':'https://ayla-device-owlue1-production-1a2039d9.s3.amazonaws.com/X?AWSAccessKeyId=Y&Expires=1234&Signature=Z' } } @responses.activate def test_cli_token(): - responses.add(responses.POST, 'https://user-field.aylanetworks.com/users/sign_in.json', + responses.add(responses.POST, OwletAPI.owlet_login_url + OwletAPI.google_API_key, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.GET, OwletAPI.owlet_login_token_provider_url, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.POST, OwletAPI.base_user_url, json=LOGIN_PAYLOAD, status=200) with patch('sys.argv', ['cli.py', 'test@test.de', 'moped', 'token']): @@ -185,9 +194,8 @@ def test_cli_token(): @responses.activate def test_cli_login_fail(): - responses.add(responses.POST, 'https://user-field.aylanetworks.com/users/sign_in.json', - json=LOGIN_PAYLOAD, status=401) - + responses.add(responses.POST, OwletAPI.owlet_login_url + OwletAPI.google_API_key, + json=LOGIN_PAYLOAD, status=400) with patch('sys.argv', ['cli.py', 'test@test.de', 'moped', 'token']): with pytest.raises(SystemExit) as info: @@ -207,9 +215,13 @@ def test_cli_server_down(): @responses.activate def test_cli_devices_ok(): - responses.add(responses.POST, 'https://user-field.aylanetworks.com/users/sign_in.json', + responses.add(responses.POST, OwletAPI.owlet_login_url + OwletAPI.google_API_key, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.GET, OwletAPI.owlet_login_token_provider_url, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.POST, OwletAPI.base_user_url, json=LOGIN_PAYLOAD, status=200) - responses.add(responses.GET, 'https://ads-field.aylanetworks.com/apiv1/devices.json', + responses.add(responses.GET, OwletAPI.base_properties_url + 'devices.json', json=DEVICES_PAYLOAD, status=200) with patch('sys.argv', ['cli.py', 'test@test.de', 'moped', 'devices']): @@ -217,11 +229,15 @@ def test_cli_devices_ok(): @responses.activate def test_cli_attributes_ok(): - responses.add(responses.POST, 'https://user-field.aylanetworks.com/users/sign_in.json', + responses.add(responses.POST, OwletAPI.owlet_login_url + OwletAPI.google_API_key, json=LOGIN_PAYLOAD, status=200) - responses.add(responses.GET, 'https://ads-field.aylanetworks.com/apiv1/devices.json', + responses.add(responses.GET, OwletAPI.owlet_login_token_provider_url, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.POST, OwletAPI.base_user_url, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.GET, OwletAPI.base_properties_url + 'devices.json', json=DEVICES_PAYLOAD, status=200) - responses.add(responses.GET, 'https://ads-field.aylanetworks.com/apiv1/dsns/c/properties', + responses.add(responses.GET, OwletAPI.base_properties_url + 'dsns/c/properties', json=DEVICE_ATTRIBUTES, status=200) with patch('sys.argv', ['cli.py', 'test@test.de', 'moped', 'attributes']): @@ -229,15 +245,19 @@ def test_cli_attributes_ok(): @responses.activate def test_cli_download_ok(): - responses.add(responses.POST, 'https://user-field.aylanetworks.com/users/sign_in.json', + responses.add(responses.POST, OwletAPI.owlet_login_url + OwletAPI.google_API_key, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.GET, OwletAPI.owlet_login_token_provider_url, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.POST, OwletAPI.base_user_url, json=LOGIN_PAYLOAD, status=200) - responses.add(responses.GET, 'https://ads-field.aylanetworks.com/apiv1/devices.json', + responses.add(responses.GET, OwletAPI.base_properties_url + 'devices.json', json=DEVICES_PAYLOAD, status=200) - responses.add(responses.GET, 'https://ads-field.aylanetworks.com/apiv1/dsns/c/properties', + responses.add(responses.GET, OwletAPI.base_properties_url + 'dsns/c/properties', json=DEVICE_ATTRIBUTES, status=200) responses.add(responses.GET, 'http://de.mo/file', json=DOWNLOAD_DATA, status=200) - responses.add(responses.GET, 'https://ayla-device-field-production-1a2039d9.s3.amazonaws.com/X?AWSAccessKeyId=Y&Expires=1234&Signature=Z', + responses.add(responses.GET, 'https://ayla-device-owlue1-production-1a2039d9.s3.amazonaws.com/X?AWSAccessKeyId=Y&Expires=1234&Signature=Z', status=200) with patch('sys.argv', ['cli.py', 'test@test.de', 'moped', 'download']): @@ -247,13 +267,17 @@ def test_cli_download_ok(): @responses.activate def test_cli_stream_ok(): - responses.add(responses.POST, 'https://user-field.aylanetworks.com/users/sign_in.json', + responses.add(responses.POST, OwletAPI.owlet_login_url + OwletAPI.google_API_key, json=LOGIN_PAYLOAD, status=200) - responses.add(responses.GET, 'https://ads-field.aylanetworks.com/apiv1/devices.json', + responses.add(responses.GET, OwletAPI.owlet_login_token_provider_url, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.POST, OwletAPI.base_user_url, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.GET, OwletAPI.base_properties_url + 'devices.json', json=DEVICES_PAYLOAD, status=200) - responses.add(responses.GET, 'https://ads-field.aylanetworks.com/apiv1/dsns/c/properties', + responses.add(responses.GET, OwletAPI.base_properties_url + 'dsns/c/properties', json=DEVICE_ATTRIBUTES, status=200) - responses.add(responses.POST, 'https://ads-field.aylanetworks.com/apiv1/properties/42738119/datapoints', + responses.add(responses.POST, OwletAPI.base_properties_url + 'properties/42738119/datapoints', status=201) with patch('sys.argv', ['cli.py', 'test@test.de', 'moped', '--timeout', '10', 'stream']): @@ -261,17 +285,21 @@ def test_cli_stream_ok(): #@pytest.mark.skip(reason="no way of currently testing this") @responses.activate -def test_cli_stream_updatefail(): +def test_cli_stream_update_fail(): - responses.add(responses.POST, 'https://user-field.aylanetworks.com/users/sign_in.json', + responses.add(responses.POST, OwletAPI.owlet_login_url + OwletAPI.google_API_key, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.GET, OwletAPI.owlet_login_token_provider_url, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.POST, OwletAPI.base_user_url, json=LOGIN_PAYLOAD, status=200) - responses.add(responses.GET, 'https://ads-field.aylanetworks.com/apiv1/devices.json', + responses.add(responses.GET, OwletAPI.base_properties_url + 'devices.json', json=DEVICES_PAYLOAD, status=200) - responses.add(responses.GET, 'https://ads-field.aylanetworks.com/apiv1/dsns/c/properties', + responses.add(responses.GET, OwletAPI.base_properties_url + 'dsns/c/properties', json=DEVICE_ATTRIBUTES, status=200) - responses.add(responses.POST, 'https://ads-field.aylanetworks.com/apiv1/properties/42738119/datapoints', + responses.add(responses.POST, OwletAPI.base_properties_url + 'properties/42738119/datapoints', status=201) - responses.add(responses.GET, 'https://ads-field.aylanetworks.com/apiv1/dsns/c/properties', + responses.add(responses.GET, OwletAPI.base_properties_url + 'dsns/c/properties', json=DEVICE_ATTRIBUTES, status=400) with patch('sys.argv', ['cli.py', 'test@test.de', 'moped', '--timeout', '10', 'stream']): @@ -279,15 +307,19 @@ def test_cli_stream_updatefail(): #@pytest.mark.skip(reason="no way of currently testing this") @responses.activate -def test_cli_stream_reactivationfail(): +def test_cli_stream_reactivation_fail(): - responses.add(responses.POST, 'https://user-field.aylanetworks.com/users/sign_in.json', + responses.add(responses.POST, OwletAPI.owlet_login_url + OwletAPI.google_API_key, json=LOGIN_PAYLOAD, status=200) - responses.add(responses.GET, 'https://ads-field.aylanetworks.com/apiv1/devices.json', + responses.add(responses.GET, OwletAPI.owlet_login_token_provider_url, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.POST, OwletAPI.base_user_url, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.GET, OwletAPI.base_properties_url + 'devices.json', json=DEVICES_PAYLOAD, status=200) - responses.add(responses.GET, 'https://ads-field.aylanetworks.com/apiv1/dsns/c/properties', + responses.add(responses.GET, OwletAPI.base_properties_url + 'dsns/c/properties', json=DEVICE_ATTRIBUTES, status=200) - responses.add(responses.POST, 'https://ads-field.aylanetworks.com/apiv1/properties/42738119/datapoints', + responses.add(responses.POST, OwletAPI.base_properties_url + 'properties/42738119/datapoints', status=400) with patch('sys.argv', ['cli.py', 'test@test.de', 'moped', '--timeout', '10', 'stream']): @@ -299,13 +331,17 @@ def test_cli_stream_reactivationfail(): def test_cli_stream_ctrlc(sleep_mock): sleep_mock.side_effect = SystemExit - responses.add(responses.POST, 'https://user-field.aylanetworks.com/users/sign_in.json', + responses.add(responses.POST, OwletAPI.owlet_login_url + OwletAPI.google_API_key, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.GET, OwletAPI.owlet_login_token_provider_url, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.POST, OwletAPI.base_user_url, json=LOGIN_PAYLOAD, status=200) - responses.add(responses.GET, 'https://ads-field.aylanetworks.com/apiv1/devices.json', + responses.add(responses.GET, OwletAPI.base_properties_url + 'devices.json', json=DEVICES_PAYLOAD, status=200) - responses.add(responses.GET, 'https://ads-field.aylanetworks.com/apiv1/dsns/c/properties', + responses.add(responses.GET, OwletAPI.base_properties_url + 'dsns/c/properties', json=DEVICE_ATTRIBUTES, status=200) - responses.add(responses.POST, 'https://ads-field.aylanetworks.com/apiv1/properties/42738119/datapoints', + responses.add(responses.POST, OwletAPI.base_properties_url + 'properties/42738119/datapoints', status=201) with patch('sys.argv', ['cli.py', 'test@test.de', 'moped', '--timeout', '10', 'stream']): diff --git a/tests/test_owlet.py b/tests/test_owlet.py index 49b92a0..1e54445 100644 --- a/tests/test_owlet.py +++ b/tests/test_owlet.py @@ -15,7 +15,12 @@ from owlet_api.owletexceptions import OwletNotInitializedException LOGIN_PAYLOAD = { - 'access_token': 'testtoken', + 'access_token': 'test_access_token', + 'idToken': 'test_id_token', + 'refreshToken': 'test_refresh_token', + 'refresh_token': 'test_refresh_token', + 'mini_token': 'test_min_token', + 'expiresIn': '3600', 'expires_in': 86400 } @@ -162,7 +167,7 @@ 'metadata':{ }, - 'value':'https://ads-field.aylanetworks.com/apiv1/devices/24826059/properties/LOGGED_DATA_CACHE/datapoints/76ce9810-5375-11e8-e7a5-6450803806ca.json', + 'value':OwletAPI.base_properties_url + 'devices/24826059/properties/LOGGED_DATA_CACHE/datapoints/76ce9810-5375-11e8-e7a5-6450803806ca.json', 'created_at_from_device':None, 'file':'https://ayla-device-field-production-1a2039d9.s3.amazonaws.com/X?AWSAccessKeyId=Y&Expires=1234&Signature=Z' } @@ -194,10 +199,14 @@ def test_owlet_ok(): @responses.activate def test_update_ok(): - responses.add(responses.POST, 'https://user-field.aylanetworks.com/users/sign_in.json', + responses.add(responses.POST, OwletAPI.owlet_login_url + OwletAPI.google_API_key, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.GET, OwletAPI.owlet_login_token_provider_url, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.POST, OwletAPI.base_user_url, json=LOGIN_PAYLOAD, status=200) # Owlet will pull the properties of this particular device - responses.add(responses.GET, 'https://ads-field.aylanetworks.com/apiv1/dsns/c/properties', + responses.add(responses.GET, OwletAPI.base_properties_url + 'dsns/c/properties', json=DEVICE_ATTRIBUTES, status=200) # Initialize OwletAPI @@ -207,7 +216,7 @@ def test_update_ok(): # Instantiate the device device = Owlet(api, DEVICE_PAYLOAD) - # Update the decice + # Update the device device.update() assert device.get_property('AGE_MONTHS_OLD').value == None @@ -215,8 +224,12 @@ def test_update_ok(): assert device.get_property('APP_ACTIVE').value == 0 @responses.activate -def test_update_noresponse(): - responses.add(responses.POST, 'https://user-field.aylanetworks.com/users/sign_in.json', +def test_update_no_response(): + responses.add(responses.POST, OwletAPI.owlet_login_url + OwletAPI.google_API_key, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.GET, OwletAPI.owlet_login_token_provider_url, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.POST, OwletAPI.base_user_url, json=LOGIN_PAYLOAD, status=200) # Initialize OwletAPI @@ -226,7 +239,7 @@ def test_update_noresponse(): # Instantiate the device device = Owlet(api, DEVICE_PAYLOAD) - # Update the decice + # Update the device with pytest.raises(OwletTemporaryCommunicationException) as info: device.update() @@ -236,9 +249,13 @@ def test_update_noresponse(): @responses.activate def test_update_return_code(): # Owlet will pull the properties of this particular device - responses.add(responses.GET, 'https://ads-field.aylanetworks.com/apiv1/dsns/c/properties', + responses.add(responses.GET, OwletAPI.base_properties_url + 'dsns/c/properties', json=DEVICE_ATTRIBUTES, status=500) - responses.add(responses.POST, 'https://user-field.aylanetworks.com/users/sign_in.json', + responses.add(responses.POST, OwletAPI.owlet_login_url + OwletAPI.google_API_key, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.GET, OwletAPI.owlet_login_token_provider_url, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.POST, OwletAPI.base_user_url, json=LOGIN_PAYLOAD, status=200) # Initialize OwletAPI @@ -248,7 +265,7 @@ def test_update_return_code(): # Instantiate the device device = Owlet(api, DEVICE_PAYLOAD) - # Update the decice + # Update the device with pytest.raises(OwletTemporaryCommunicationException) as info: device.update() @@ -258,10 +275,14 @@ def test_update_return_code(): @responses.activate def test_update_invalid_json(): # Owlet will pull the properties of this particular device - responses.add(responses.GET, 'https://ads-field.aylanetworks.com/apiv1/dsns/c/properties', + responses.add(responses.GET, OwletAPI.base_properties_url + 'dsns/c/properties', body="INVALID", status=200) - responses.add(responses.POST, 'https://user-field.aylanetworks.com/users/sign_in.json', + responses.add(responses.POST, OwletAPI.owlet_login_url + OwletAPI.google_API_key, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.GET, OwletAPI.owlet_login_token_provider_url, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.POST, OwletAPI.base_user_url, json=LOGIN_PAYLOAD, status=200) # Initialize OwletAPI @@ -271,7 +292,7 @@ def test_update_invalid_json(): # Instantiate the device device = Owlet(api, DEVICE_PAYLOAD) - # Update the decice + # Update the device with pytest.raises(OwletTemporaryCommunicationException) as info: device.update() @@ -285,11 +306,15 @@ def test_update_repeat(): my_device_attributes[0]['property']['data_updated_at'] = '2018-12-30T09:43:28Z' # Owlet will pull the properties of this particular device - responses.add(responses.GET, 'https://ads-field.aylanetworks.com/apiv1/dsns/c/properties', + responses.add(responses.GET, OwletAPI.base_properties_url + 'dsns/c/properties', json=DEVICE_ATTRIBUTES, status=200) - responses.add(responses.GET, 'https://ads-field.aylanetworks.com/apiv1/dsns/c/properties', + responses.add(responses.GET, OwletAPI.base_properties_url + 'dsns/c/properties', json=my_device_attributes, status=200) - responses.add(responses.POST, 'https://user-field.aylanetworks.com/users/sign_in.json', + responses.add(responses.POST, OwletAPI.owlet_login_url + OwletAPI.google_API_key, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.GET, OwletAPI.owlet_login_token_provider_url, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.POST, OwletAPI.base_user_url, json=LOGIN_PAYLOAD, status=200) # Initialize OwletAPI @@ -299,7 +324,7 @@ def test_update_repeat(): # Instantiate the device device = Owlet(api, DEVICE_PAYLOAD) - # Update the decice + # Update the device device.update() device.update() @@ -314,11 +339,15 @@ def test_update_repeat(): @responses.activate def test_reactivate_ok(): - responses.add(responses.POST, 'https://user-field.aylanetworks.com/users/sign_in.json', + responses.add(responses.POST, OwletAPI.owlet_login_url + OwletAPI.google_API_key, json=LOGIN_PAYLOAD, status=200) - responses.add(responses.GET, 'https://ads-field.aylanetworks.com/apiv1/dsns/c/properties', + responses.add(responses.GET, OwletAPI.owlet_login_token_provider_url, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.POST, OwletAPI.base_user_url, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.GET, OwletAPI.base_properties_url + 'dsns/c/properties', json=DEVICE_ATTRIBUTES, status=200) - responses.add(responses.POST, 'https://ads-field.aylanetworks.com/apiv1/properties/42738119/datapoints', + responses.add(responses.POST, OwletAPI.base_properties_url + 'properties/42738119/datapoints', status=201) # Initialize OwletAPI @@ -328,14 +357,18 @@ def test_reactivate_ok(): # Instantiate the device device = Owlet(api, DEVICE_PAYLOAD) - # Update the decice + # Update the device device.update() device.reactivate() @responses.activate -def test_reactivate_fail_noattributes(): - responses.add(responses.POST, 'https://user-field.aylanetworks.com/users/sign_in.json', +def test_reactivate_fail_no_attributes(): + responses.add(responses.POST, OwletAPI.owlet_login_url + OwletAPI.google_API_key, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.GET, OwletAPI.owlet_login_token_provider_url, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.POST, OwletAPI.base_user_url, json=LOGIN_PAYLOAD, status=200) # Initialize OwletAPI @@ -352,15 +385,19 @@ def test_reactivate_fail_noattributes(): @responses.activate -def test_reactivate_fail_wrongattributes(): - responses.add(responses.POST, 'https://user-field.aylanetworks.com/users/sign_in.json', +def test_reactivate_fail_wrong_attributes(): + responses.add(responses.POST, OwletAPI.owlet_login_url + OwletAPI.google_API_key, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.GET, OwletAPI.owlet_login_token_provider_url, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.POST, OwletAPI.base_user_url, json=LOGIN_PAYLOAD, status=200) my_device_attributes = copy.deepcopy(DEVICE_ATTRIBUTES) my_device_attributes[0]['property']['name'] = 'DEADBEEF1' my_device_attributes[1]['property']['name'] = 'DEADBEEF2' my_device_attributes[2]['property']['name'] = 'DEADBEEF3' - responses.add(responses.GET, 'https://ads-field.aylanetworks.com/apiv1/dsns/c/properties', + responses.add(responses.GET, OwletAPI.base_properties_url + 'dsns/c/properties', json=my_device_attributes, status=200) # Initialize OwletAPI @@ -370,7 +407,7 @@ def test_reactivate_fail_wrongattributes(): # Instantiate the device device = Owlet(api, DEVICE_PAYLOAD) - # Update the decice + # Update the device device.update() with pytest.raises(OwletNotInitializedException) as info: @@ -379,10 +416,14 @@ def test_reactivate_fail_wrongattributes(): assert 'Initialize first - missing property' in str(info.value) @responses.activate -def test_reactivate_fail_noconnection(): - responses.add(responses.POST, 'https://user-field.aylanetworks.com/users/sign_in.json', +def test_reactivate_fail_no_connection(): + responses.add(responses.POST, OwletAPI.owlet_login_url + OwletAPI.google_API_key, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.GET, OwletAPI.owlet_login_token_provider_url, json=LOGIN_PAYLOAD, status=200) - responses.add(responses.GET, 'https://ads-field.aylanetworks.com/apiv1/dsns/c/properties', + responses.add(responses.POST, OwletAPI.base_user_url, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.GET, OwletAPI.base_properties_url + 'dsns/c/properties', json=DEVICE_ATTRIBUTES, status=200) # Initialize OwletAPI @@ -392,7 +433,7 @@ def test_reactivate_fail_noconnection(): # Instantiate the device device = Owlet(api, DEVICE_PAYLOAD) - # Update the decice + # Update the device device.update() with pytest.raises(OwletTemporaryCommunicationException) as info: @@ -401,12 +442,16 @@ def test_reactivate_fail_noconnection(): assert 'Server Request failed - no response' in str(info.value) @responses.activate -def test_reactivate_fail_statuscode(): - responses.add(responses.POST, 'https://user-field.aylanetworks.com/users/sign_in.json', +def test_reactivate_fail_status_code(): + responses.add(responses.POST, OwletAPI.owlet_login_url + OwletAPI.google_API_key, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.GET, OwletAPI.owlet_login_token_provider_url, json=LOGIN_PAYLOAD, status=200) - responses.add(responses.GET, 'https://ads-field.aylanetworks.com/apiv1/dsns/c/properties', + responses.add(responses.POST, OwletAPI.base_user_url, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.GET, OwletAPI.base_properties_url + 'dsns/c/properties', json=DEVICE_ATTRIBUTES, status=200) - responses.add(responses.POST, 'https://ads-field.aylanetworks.com/apiv1/properties/42738119/datapoints', + responses.add(responses.POST, OwletAPI.base_properties_url + 'properties/42738119/datapoints', status=500) # Initialize OwletAPI @@ -416,7 +461,7 @@ def test_reactivate_fail_statuscode(): # Instantiate the device device = Owlet(api, DEVICE_PAYLOAD) - # Update the decice + # Update the device device.update() with pytest.raises(OwletTemporaryCommunicationException) as info: @@ -426,9 +471,13 @@ def test_reactivate_fail_statuscode(): @responses.activate def test_download_logged_data_ok(): - responses.add(responses.POST, 'https://user-field.aylanetworks.com/users/sign_in.json', + responses.add(responses.POST, OwletAPI.owlet_login_url + OwletAPI.google_API_key, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.GET, OwletAPI.owlet_login_token_provider_url, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.POST, OwletAPI.base_user_url, json=LOGIN_PAYLOAD, status=200) - responses.add(responses.GET, 'https://ads-field.aylanetworks.com/apiv1/dsns/c/properties', + responses.add(responses.GET, OwletAPI.base_properties_url + 'dsns/c/properties', json=DEVICE_ATTRIBUTES, status=200) responses.add(responses.GET, 'http://de.mo/file', json=DOWNLOAD_DATA, status=200) @@ -442,15 +491,19 @@ def test_download_logged_data_ok(): # Instantiate the device device = Owlet(api, DEVICE_PAYLOAD) - # Update the decice + # Update the device device.update() device.download_logged_data() @responses.activate -def test_download_logged_data_fail_noinit(): - responses.add(responses.POST, 'https://user-field.aylanetworks.com/users/sign_in.json', +def test_download_logged_data_fail_no_init(): + responses.add(responses.POST, OwletAPI.owlet_login_url + OwletAPI.google_API_key, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.GET, OwletAPI.owlet_login_token_provider_url, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.POST, OwletAPI.base_user_url, json=LOGIN_PAYLOAD, status=200) # Initialize OwletAPI @@ -467,15 +520,19 @@ def test_download_logged_data_fail_noinit(): assert 'Initialize first - no properties' in str(info.value) @responses.activate -def test_download_logged_data_fail_noattribute(): - responses.add(responses.POST, 'https://user-field.aylanetworks.com/users/sign_in.json', +def test_download_logged_data_fail_no_attribute(): + responses.add(responses.POST, OwletAPI.owlet_login_url + OwletAPI.google_API_key, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.GET, OwletAPI.owlet_login_token_provider_url, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.POST, OwletAPI.base_user_url, json=LOGIN_PAYLOAD, status=200) my_device_attributes = copy.deepcopy(DEVICE_ATTRIBUTES) my_device_attributes[0]['property']['name'] = 'DEADBEEF3' my_device_attributes[1]['property']['name'] = 'DEADBEEF3' my_device_attributes[2]['property']['name'] = 'DEADBEEF3' my_device_attributes[3]['property']['name'] = 'DEADBEEF3' - responses.add(responses.GET, 'https://ads-field.aylanetworks.com/apiv1/dsns/c/properties', + responses.add(responses.GET, OwletAPI.base_properties_url + 'dsns/c/properties', json=my_device_attributes, status=200) # Initialize OwletAPI @@ -485,7 +542,7 @@ def test_download_logged_data_fail_noattribute(): # Instantiate the device device = Owlet(api, DEVICE_PAYLOAD) - # Update the decice + # Update the device device.update() with pytest.raises(OwletNotInitializedException) as info: @@ -494,10 +551,14 @@ def test_download_logged_data_fail_noattribute(): assert 'Initialize first - missing property' in str(info.value) @responses.activate -def test_download_logged_data_fail_noconnection(): - responses.add(responses.POST, 'https://user-field.aylanetworks.com/users/sign_in.json', +def test_download_logged_data_fail_no_connection(): + responses.add(responses.POST, OwletAPI.owlet_login_url + OwletAPI.google_API_key, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.GET, OwletAPI.owlet_login_token_provider_url, json=LOGIN_PAYLOAD, status=200) - responses.add(responses.GET, 'https://ads-field.aylanetworks.com/apiv1/dsns/c/properties', + responses.add(responses.POST, OwletAPI.base_user_url, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.GET, OwletAPI.base_properties_url + 'dsns/c/properties', json=DEVICE_ATTRIBUTES, status=200) # Initialize OwletAPI @@ -507,7 +568,7 @@ def test_download_logged_data_fail_noconnection(): # Instantiate the device device = Owlet(api, DEVICE_PAYLOAD) - # Update the decice + # Update the device device.update() with pytest.raises(OwletTemporaryCommunicationException) as info: @@ -517,10 +578,14 @@ def test_download_logged_data_fail_noconnection(): @responses.activate -def test_download_logged_data_fail_statuscode(): - responses.add(responses.POST, 'https://user-field.aylanetworks.com/users/sign_in.json', +def test_download_logged_data_fail_status_code(): + responses.add(responses.POST, OwletAPI.owlet_login_url + OwletAPI.google_API_key, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.GET, OwletAPI.owlet_login_token_provider_url, json=LOGIN_PAYLOAD, status=200) - responses.add(responses.GET, 'https://ads-field.aylanetworks.com/apiv1/dsns/c/properties', + responses.add(responses.POST, OwletAPI.base_user_url, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.GET, OwletAPI.base_properties_url + 'dsns/c/properties', json=DEVICE_ATTRIBUTES, status=200) responses.add(responses.GET, 'http://de.mo/file', json=DOWNLOAD_DATA, status=500) @@ -532,7 +597,7 @@ def test_download_logged_data_fail_statuscode(): # Instantiate the device device = Owlet(api, DEVICE_PAYLOAD) - # Update the decice + # Update the device device.update() with pytest.raises(OwletTemporaryCommunicationException) as info: @@ -542,10 +607,14 @@ def test_download_logged_data_fail_statuscode(): @responses.activate -def test_download_logged_data_fail_invalidjson(): - responses.add(responses.POST, 'https://user-field.aylanetworks.com/users/sign_in.json', +def test_download_logged_data_fail_invalid_json(): + responses.add(responses.POST, OwletAPI.owlet_login_url + OwletAPI.google_API_key, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.GET, OwletAPI.owlet_login_token_provider_url, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.POST, OwletAPI.base_user_url, json=LOGIN_PAYLOAD, status=200) - responses.add(responses.GET, 'https://ads-field.aylanetworks.com/apiv1/dsns/c/properties', + responses.add(responses.GET, OwletAPI.base_properties_url + 'dsns/c/properties', json=DEVICE_ATTRIBUTES, status=200) responses.add(responses.GET, 'http://de.mo/file', body="INVALID", status=200) @@ -557,7 +626,7 @@ def test_download_logged_data_fail_invalidjson(): # Instantiate the device device = Owlet(api, DEVICE_PAYLOAD) - # Update the decice + # Update the device device.update() with pytest.raises(OwletTemporaryCommunicationException) as info: @@ -567,10 +636,14 @@ def test_download_logged_data_fail_invalidjson(): @responses.activate -def test_download_logged_data_fail_incompletejson(): - responses.add(responses.POST, 'https://user-field.aylanetworks.com/users/sign_in.json', +def test_download_logged_data_fail_incomplete_json(): + responses.add(responses.POST, OwletAPI.owlet_login_url + OwletAPI.google_API_key, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.GET, OwletAPI.owlet_login_token_provider_url, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.POST, OwletAPI.base_user_url, json=LOGIN_PAYLOAD, status=200) - responses.add(responses.GET, 'https://ads-field.aylanetworks.com/apiv1/dsns/c/properties', + responses.add(responses.GET, OwletAPI.base_properties_url + 'dsns/c/properties', json=DEVICE_ATTRIBUTES, status=200) my_download_data = copy.deepcopy(DOWNLOAD_DATA) my_download_data['datapoint'] = {} @@ -584,7 +657,7 @@ def test_download_logged_data_fail_incompletejson(): # Instantiate the device device = Owlet(api, DEVICE_PAYLOAD) - # Update the decice + # Update the device device.update() with pytest.raises(OwletTemporaryCommunicationException) as info: @@ -594,10 +667,14 @@ def test_download_logged_data_fail_incompletejson(): @responses.activate -def test_download_logged_data_fail_nodownload(): - responses.add(responses.POST, 'https://user-field.aylanetworks.com/users/sign_in.json', +def test_download_logged_data_fail_no_download(): + responses.add(responses.POST, OwletAPI.owlet_login_url + OwletAPI.google_API_key, json=LOGIN_PAYLOAD, status=200) - responses.add(responses.GET, 'https://ads-field.aylanetworks.com/apiv1/dsns/c/properties', + responses.add(responses.GET, OwletAPI.owlet_login_token_provider_url, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.POST, OwletAPI.base_user_url, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.GET, OwletAPI.base_properties_url + 'dsns/c/properties', json=DEVICE_ATTRIBUTES, status=200) responses.add(responses.GET, 'http://de.mo/file', json=DOWNLOAD_DATA, status=200) @@ -609,7 +686,7 @@ def test_download_logged_data_fail_nodownload(): # Instantiate the device device = Owlet(api, DEVICE_PAYLOAD) - # Update the decice + # Update the device device.update() with pytest.raises(OwletTemporaryCommunicationException) as info: @@ -619,10 +696,14 @@ def test_download_logged_data_fail_nodownload(): @responses.activate -def test_download_logged_data_fail_nodownloadcode(): - responses.add(responses.POST, 'https://user-field.aylanetworks.com/users/sign_in.json', +def test_download_logged_data_fail_no_download_code(): + responses.add(responses.POST, OwletAPI.owlet_login_url + OwletAPI.google_API_key, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.GET, OwletAPI.owlet_login_token_provider_url, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.POST, OwletAPI.base_user_url, json=LOGIN_PAYLOAD, status=200) - responses.add(responses.GET, 'https://ads-field.aylanetworks.com/apiv1/dsns/c/properties', + responses.add(responses.GET, OwletAPI.base_properties_url + 'dsns/c/properties', json=DEVICE_ATTRIBUTES, status=200) responses.add(responses.GET, 'http://de.mo/file', json=DOWNLOAD_DATA, status=200) @@ -636,7 +717,7 @@ def test_download_logged_data_fail_nodownloadcode(): # Instantiate the device device = Owlet(api, DEVICE_PAYLOAD) - # Update the decice + # Update the device device.update() with pytest.raises(OwletTemporaryCommunicationException) as info: diff --git a/tests/test_owlet_api.py b/tests/test_owlet_api.py index 1712d2b..52b3cda 100644 --- a/tests/test_owlet_api.py +++ b/tests/test_owlet_api.py @@ -15,7 +15,12 @@ from owlet_api.owletexceptions import OwletNotInitializedException LOGIN_PAYLOAD = { - 'access_token': 'testtoken', + 'access_token': 'test_access_token', + 'idToken': 'test_id_token', + 'refreshToken': 'test_refresh_token', + 'refresh_token': 'test_refresh_token', + 'mini_token': 'test_min_token', + 'expiresIn': '3600', 'expires_in': 86400 } @@ -49,7 +54,11 @@ @responses.activate def test_login_ok(): - responses.add(responses.POST, 'https://user-field.aylanetworks.com/users/sign_in.json', + responses.add(responses.POST, OwletAPI.owlet_login_url + OwletAPI.google_API_key, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.GET, OwletAPI.owlet_login_token_provider_url, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.POST, OwletAPI.base_user_url, json=LOGIN_PAYLOAD, status=200) api = OwletAPI() @@ -60,16 +69,16 @@ def test_login_ok(): assert api._email == "test@test.de" assert api._password == "moped" - assert api._auth_token == "testtoken" + assert api._auth_token == "test_access_token" assert api._expiry_time > time.time() + 86400 - 1 assert api._expiry_time < time.time() + 86400 + 1 - assert api.get_auth_token() == "testtoken" + assert api.get_auth_token() == "test_access_token" @responses.activate def test_login_fail(): - responses.add(responses.POST, 'https://user-field.aylanetworks.com/users/sign_in.json', - json=LOGIN_PAYLOAD, status=401) + responses.add(responses.POST, OwletAPI.owlet_login_url + OwletAPI.google_API_key, + json=LOGIN_PAYLOAD, status=400) api = OwletAPI() api.set_email("test@test.de") @@ -83,11 +92,91 @@ def test_login_fail(): assert api._password == "moped" assert api._auth_token == None assert api.get_auth_token() == None + +@responses.activate +def test_login_fail_step_1_api_key_bad(): + login_payload = { + "error": { + "details": [ + { + "reason": "API_KEY_INVALID", + } + ] + } + } + responses.add(responses.POST, OwletAPI.owlet_login_url + OwletAPI.google_API_key, + json=login_payload, status=400) + + api = OwletAPI() + api.set_email("test@test.de") + api.set_password("moped") + with pytest.raises(OwletPermanentCommunicationException) as info: + api.login() + + assert 'Login failed, bad API key.' in str(info.value) + assert api._email == "test@test.de" + assert api._password == "moped" + assert api._auth_token == None + assert api.get_auth_token() == None + +@responses.activate +def test_login_fail_step_1_username_bad(): + login_payload = { + "error": { + "details": [ + { + "reason": "EMAIL_NOT_FOUND" + } + ] + } + } + responses.add(responses.POST, OwletAPI.owlet_login_url + OwletAPI.google_API_key, + json=login_payload, status=400) + + api = OwletAPI() + api.set_email("test@test.de") + api.set_password("moped") + + with pytest.raises(OwletPermanentCommunicationException) as info: + api.login() + + assert 'Login failed, bad username' in str(info.value) + assert api._email == "test@test.de" + assert api._password == "moped" + assert api._auth_token == None + assert api.get_auth_token() == None + +@responses.activate +def test_login_fail_step_1_password_bad(): + login_payload = { + "error": { + "details": [ + { + "reason": "INVALID_PASSWORD" + } + ] + } + } + responses.add(responses.POST, OwletAPI.owlet_login_url + OwletAPI.google_API_key, + json=login_payload, status=400) + + api = OwletAPI() + api.set_email("test@test.de") + api.set_password("moped") + + with pytest.raises(OwletPermanentCommunicationException) as info: + api.login() + + assert 'Login failed, bad password' in str(info.value) + assert api._email == "test@test.de" + assert api._password == "moped" + assert api._auth_token == None + assert api.get_auth_token() == None @responses.activate -def test_login_fail_temporary(): - responses.add(responses.POST, 'https://user-field.aylanetworks.com/users/sign_in.json', +def test_login_fail_step_1_temporary(): + responses.add(responses.POST, OwletAPI.owlet_login_url + OwletAPI.google_API_key, json=LOGIN_PAYLOAD, status=500) api = OwletAPI() @@ -103,10 +192,9 @@ def test_login_fail_temporary(): assert api._auth_token == None assert api.get_auth_token() == None - @responses.activate -def test_login_fail_invalidjson(): - responses.add(responses.POST, 'https://user-field.aylanetworks.com/users/sign_in.json', +def test_login_fail_step_1_invalid_json(): + responses.add(responses.POST, OwletAPI.owlet_login_url + OwletAPI.google_API_key, body="broken", status=200) api = OwletAPI() @@ -116,19 +204,18 @@ def test_login_fail_invalidjson(): with pytest.raises(OwletTemporaryCommunicationException) as info: api.login() - assert 'Server did not send valid json' in str(info.value) + assert 'Server did not send valid json (Step 1 of 3)' in str(info.value) assert api._email == "test@test.de" assert api._password == "moped" assert api._auth_token == None assert api.get_auth_token() == None - @responses.activate -def test_login_fail_incompletejson(): +def test_login_fail_step_1_incomplete_json(): login_payload = { 'access_token': 'testtoken' } - responses.add(responses.POST, 'https://user-field.aylanetworks.com/users/sign_in.json', + responses.add(responses.POST, OwletAPI.owlet_login_url + OwletAPI.google_API_key, json=login_payload, status=200) api = OwletAPI() @@ -138,15 +225,14 @@ def test_login_fail_incompletejson(): with pytest.raises(OwletTemporaryCommunicationException) as info: api.login() - assert 'Server did not send access token' in str(info.value) + assert 'Server did not send id token (Step 1 of 3)' in str(info.value) assert api._email == "test@test.de" assert api._password == "moped" assert api._auth_token == None assert api.get_auth_token() == None - @responses.activate -def test_login_fail_noconnection(): +def test_login_fail_step_1_no_connection(): api = OwletAPI() api.set_email("test@test.de") api.set_password("moped") @@ -160,10 +246,207 @@ def test_login_fail_noconnection(): assert api._auth_token == None assert api.get_auth_token() == None +@responses.activate +def test_login_fail_step_2_temporary(): + responses.add(responses.POST, OwletAPI.owlet_login_url + OwletAPI.google_API_key, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.GET, OwletAPI.owlet_login_token_provider_url, + json=LOGIN_PAYLOAD, status=500) + + api = OwletAPI() + api.set_email("test@test.de") + api.set_password("moped") + + with pytest.raises(OwletTemporaryCommunicationException) as info: + api.login() + + assert 'Login request failed - status code (500) - (Step 2 of 3)' in str(info.value) + assert api._email == "test@test.de" + assert api._password == "moped" + assert api._auth_token == None + assert api.get_auth_token() == None + +@responses.activate +def test_login_fail_step_2_invalid_json(): + responses.add(responses.POST, OwletAPI.owlet_login_url + OwletAPI.google_API_key, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.GET, OwletAPI.owlet_login_token_provider_url, + body="broken", status=200) + + api = OwletAPI() + api.set_email("test@test.de") + api.set_password("moped") + + with pytest.raises(OwletTemporaryCommunicationException) as info: + api.login() + + assert 'Server did not send valid json (Step 2 of 3)' in str(info.value) + assert api._email == "test@test.de" + assert api._password == "moped" + assert api._auth_token == None + assert api.get_auth_token() == None + +@responses.activate +def test_login_fail_step_2_incomplete_json(): + login_payload = { + } + responses.add(responses.POST, OwletAPI.owlet_login_url + OwletAPI.google_API_key, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.GET, OwletAPI.owlet_login_token_provider_url, + json=login_payload, status=200) + + api = OwletAPI() + api.set_email("test@test.de") + api.set_password("moped") + + with pytest.raises(OwletTemporaryCommunicationException) as info: + api.login() + + assert 'Server did not send mini token (Step 2 of 3)' in str(info.value) + assert api._email == "test@test.de" + assert api._password == "moped" + assert api._auth_token == None + assert api.get_auth_token() == None + +@responses.activate +def test_login_fail_step_2_no_connection(): + responses.add(responses.POST, OwletAPI.owlet_login_url + OwletAPI.google_API_key, + json=LOGIN_PAYLOAD, status=200) + + api = OwletAPI() + api.set_email("test@test.de") + api.set_password("moped") + + with pytest.raises(OwletTemporaryCommunicationException) as info: + api.login() + + assert 'Login request failed - no response (Step 2 of 3)' in str(info.value) + assert api._email == "test@test.de" + assert api._password == "moped" + assert api._auth_token == None + assert api.get_auth_token() == None + +@responses.activate +def test_login_fail_step_3_temporary(): + responses.add(responses.POST, OwletAPI.owlet_login_url + OwletAPI.google_API_key, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.GET, OwletAPI.owlet_login_token_provider_url, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.POST, OwletAPI.base_user_url, + json=LOGIN_PAYLOAD, status=500) + + api = OwletAPI() + api.set_email("test@test.de") + api.set_password("moped") + + with pytest.raises(OwletTemporaryCommunicationException) as info: + api.login() + + assert 'Login request failed - status code (500) - (Step 3 of 3)' in str(info.value) + assert api._email == "test@test.de" + assert api._password == "moped" + assert api._auth_token == None + assert api.get_auth_token() == None + +@responses.activate +def test_login_fail_step_3_app_id_or_app_secret_bad(): + login_payload = { + 'error': 'Could not find application' + } + responses.add(responses.POST, OwletAPI.owlet_login_url + OwletAPI.google_API_key, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.GET, OwletAPI.owlet_login_token_provider_url, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.POST, OwletAPI.base_user_url, + json=login_payload, status=404) + + api = OwletAPI() + api.set_email("test@test.de") + api.set_password("moped") + + with pytest.raises(OwletPermanentCommunicationException) as info: + api.login() + + assert 'login request failed - app_id or app_secret is bad (Step 3 of 3)' in str(info.value) + assert api._email == "test@test.de" + assert api._password == "moped" + assert api._auth_token == None + assert api.get_auth_token() == None + +@responses.activate +def test_login_fail_step_3_invalid_json(): + responses.add(responses.POST, OwletAPI.owlet_login_url + OwletAPI.google_API_key, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.GET, OwletAPI.owlet_login_token_provider_url, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.POST, OwletAPI.base_user_url, + body="broken", status=200) + + api = OwletAPI() + api.set_email("test@test.de") + api.set_password("moped") + + with pytest.raises(OwletTemporaryCommunicationException) as info: + api.login() + + assert 'Server did not send valid json (Step 3 of 3)' in str(info.value) + assert api._email == "test@test.de" + assert api._password == "moped" + assert api._auth_token == None + assert api.get_auth_token() == None + +@responses.activate +def test_login_fail_step_3_incomplete_json(): + login_payload = { + 'access_token': 'testtoken' + } + responses.add(responses.POST, OwletAPI.owlet_login_url + OwletAPI.google_API_key, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.GET, OwletAPI.owlet_login_token_provider_url, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.POST, OwletAPI.base_user_url, + json=login_payload, status=200) + + api = OwletAPI() + api.set_email("test@test.de") + api.set_password("moped") + + with pytest.raises(OwletTemporaryCommunicationException) as info: + api.login() + + assert 'Server did not send access token (Step 3 of 3)' in str(info.value) + assert api._email == "test@test.de" + assert api._password == "moped" + assert api._auth_token == None + assert api.get_auth_token() == None + +@responses.activate +def test_login_fail_step_3_no_connection(): + responses.add(responses.POST, OwletAPI.owlet_login_url + OwletAPI.google_API_key, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.GET, OwletAPI.owlet_login_token_provider_url, + json=LOGIN_PAYLOAD, status=200) + + api = OwletAPI() + api.set_email("test@test.de") + api.set_password("moped") + + with pytest.raises(OwletTemporaryCommunicationException) as info: + api.login() + + assert 'Login request failed - no response (Step 3 of 3)' in str(info.value) + assert api._email == "test@test.de" + assert api._password == "moped" + assert api._auth_token == None + assert api.get_auth_token() == None @responses.activate def test_get_auth_token_ok(): - responses.add(responses.POST, 'https://user-field.aylanetworks.com/users/sign_in.json', + responses.add(responses.POST, OwletAPI.owlet_login_url + OwletAPI.google_API_key, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.GET, OwletAPI.owlet_login_token_provider_url, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.POST, OwletAPI.base_user_url, json=LOGIN_PAYLOAD, status=200) api = OwletAPI() @@ -172,17 +455,25 @@ def test_get_auth_token_ok(): api.login() # If no exception occurred, everything seems to be fine - assert api.get_auth_token() == "testtoken" + assert api.get_auth_token() == "test_access_token" @responses.activate def test_get_auth_token_relogin(): - responses.add(responses.POST, 'https://user-field.aylanetworks.com/users/sign_in.json', + responses.add(responses.POST, OwletAPI.owlet_login_url + OwletAPI.google_API_key, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.GET, OwletAPI.owlet_login_token_provider_url, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.POST, OwletAPI.base_user_url, json=LOGIN_PAYLOAD, status=200) login_payload2 = copy.deepcopy(LOGIN_PAYLOAD) login_payload2['access_token'] = 'newtoken' - responses.add(responses.POST, 'https://user-field.aylanetworks.com/users/sign_in.json', + responses.add(responses.POST, OwletAPI.owlet_login_url + OwletAPI.google_API_key, + json=login_payload2, status=200) + responses.add(responses.GET, OwletAPI.owlet_login_token_provider_url, + json=login_payload2, status=200) + responses.add(responses.POST, OwletAPI.base_user_url, json=login_payload2, status=200) api = OwletAPI() @@ -192,7 +483,7 @@ def test_get_auth_token_relogin(): # Login happens at 2018-12-30 and lasts 1 day with freeze_time("2018-12-30"): api.login() - assert api.get_auth_token() == "testtoken" + assert api.get_auth_token() == "test_access_token" with freeze_time("2019-12-30"): @@ -206,7 +497,11 @@ def test_get_auth_token_fail(): @responses.activate def test_get_request_headers_ok(): - responses.add(responses.POST, 'https://user-field.aylanetworks.com/users/sign_in.json', + responses.add(responses.POST, OwletAPI.owlet_login_url + OwletAPI.google_API_key, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.GET, OwletAPI.owlet_login_token_provider_url, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.POST, OwletAPI.base_user_url, json=LOGIN_PAYLOAD, status=200) api = OwletAPI() @@ -216,7 +511,7 @@ def test_get_request_headers_ok(): assert api.get_request_headers()['Content-Type'] == "application/json" assert api.get_request_headers()['Accept'] == "application/json" - assert api.get_request_headers()['Authorization'] == "testtoken" + assert api.get_request_headers()['Authorization'] == "test_access_token" def test_get_request_headers_fail(): @@ -224,10 +519,14 @@ def test_get_request_headers_fail(): assert api.get_request_headers() == None -@patch('owlet_api.owletapi.Owlet.__init__', Mock(return_value=None)) +@patch('OwletAPI.owletapi.Owlet.__init__', Mock(return_value=None)) @responses.activate def test_get_devices_ok(): - responses.add(responses.POST, 'https://user-field.aylanetworks.com/users/sign_in.json', + responses.add(responses.POST, OwletAPI.owlet_login_url + OwletAPI.google_API_key, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.GET, OwletAPI.owlet_login_token_provider_url, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.POST, OwletAPI.base_user_url, json=LOGIN_PAYLOAD, status=200) api = OwletAPI() @@ -235,7 +534,7 @@ def test_get_devices_ok(): api.set_password("moped") api.login() - responses.add(responses.GET, 'https://ads-field.aylanetworks.com/apiv1/devices.json', json=DEVICES_PAYLOAD, status=200) + responses.add(responses.GET, OwletAPI.base_properties_url + 'devices.json', json=DEVICES_PAYLOAD, status=200) api.get_devices() assert Owlet.__init__.called_once @@ -244,15 +543,19 @@ def test_get_devices_ok(): args, kwargs = Owlet.__init__.call_args instance, arguments = args assert instance is api - assert arguments == devices_payload[0]['device'] + assert arguments == DEVICES_PAYLOAD[0]['device'] # When calling get_devices again, no new instances of Owlet should be created api.get_devices() assert Owlet.__init__.called_once @responses.activate -def test_update_devices_fail_servererror(): - responses.add(responses.POST, 'https://user-field.aylanetworks.com/users/sign_in.json', +def test_update_devices_fail_server_error(): + responses.add(responses.POST, OwletAPI.owlet_login_url + OwletAPI.google_API_key, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.GET, OwletAPI.owlet_login_token_provider_url, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.POST, OwletAPI.base_user_url, json=LOGIN_PAYLOAD, status=200) api = OwletAPI() @@ -260,7 +563,7 @@ def test_update_devices_fail_servererror(): api.set_password("moped") api.login() - responses.add(responses.GET, 'https://ads-field.aylanetworks.com/apiv1/devices.json', json=DEVICES_PAYLOAD, status=500) + responses.add(responses.GET, OwletAPI.base_properties_url + 'devices.json', json=DEVICES_PAYLOAD, status=500) with pytest.raises(OwletTemporaryCommunicationException) as info: api.update_devices() @@ -268,8 +571,12 @@ def test_update_devices_fail_servererror(): assert 'Server request failed - status code' in str(info.value) @responses.activate -def test_update_devices_fail_noresponse(): - responses.add(responses.POST, 'https://user-field.aylanetworks.com/users/sign_in.json', +def test_update_devices_fail_no_response(): + responses.add(responses.POST, OwletAPI.owlet_login_url + OwletAPI.google_API_key, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.GET, OwletAPI.owlet_login_token_provider_url, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.POST, OwletAPI.base_user_url, json=LOGIN_PAYLOAD, status=200) api = OwletAPI() @@ -283,8 +590,12 @@ def test_update_devices_fail_noresponse(): assert 'Server request failed - no response' in str(info.value) @responses.activate -def test_update_devices_fail_invalidjson(): - responses.add(responses.POST, 'https://user-field.aylanetworks.com/users/sign_in.json', +def test_update_devices_fail_invalid_json(): + responses.add(responses.POST, OwletAPI.owlet_login_url + OwletAPI.google_API_key, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.GET, OwletAPI.owlet_login_token_provider_url, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.POST, OwletAPI.base_user_url, json=LOGIN_PAYLOAD, status=200) api = OwletAPI() @@ -292,14 +603,14 @@ def test_update_devices_fail_invalidjson(): api.set_password("moped") api.login() - responses.add(responses.GET, 'https://ads-field.aylanetworks.com/apiv1/devices.json', body="invalid", status=200) + responses.add(responses.GET, OwletAPI.base_properties_url + 'devices.json', body="invalid", status=200) with pytest.raises(OwletTemporaryCommunicationException) as info: api.update_devices() assert 'Server did not send valid json' in str(info.value) -def test_update_devices_fail_noinit(): +def test_update_devices_fail_no_init(): api = OwletAPI() with pytest.raises(OwletNotInitializedException) as info: @@ -311,7 +622,11 @@ def test_update_devices_fail_noinit(): @patch('owlet_api.owlet.Owlet.get_update_interval', Mock(return_value=177)) @responses.activate def test_get_devices_ok(): - responses.add(responses.POST, 'https://user-field.aylanetworks.com/users/sign_in.json', + responses.add(responses.POST, OwletAPI.owlet_login_url + OwletAPI.google_API_key, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.GET, OwletAPI.owlet_login_token_provider_url, + json=LOGIN_PAYLOAD, status=200) + responses.add(responses.POST, OwletAPI.base_user_url, json=LOGIN_PAYLOAD, status=200) api = OwletAPI() @@ -319,7 +634,7 @@ def test_get_devices_ok(): api.set_password("moped") api.login() - responses.add(responses.GET, 'https://ads-field.aylanetworks.com/apiv1/devices.json', json=DEVICES_PAYLOAD, status=200) + responses.add(responses.GET, OwletAPI.base_properties_url + 'devices.json', json=DEVICES_PAYLOAD, status=200) api.get_devices() assert api.get_update_interval() == 177