From f9dbdfefca1ba39329b0fc94c606ad782e3755ee Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Wed, 19 Jan 2022 20:11:07 +0100 Subject: [PATCH 1/3] some more tests for Polar stuff --- rowers/polarstuff.py | 28 ++++++++++++++++++------ rowers/tests/mocks.py | 30 +++++++++++++++++++++++++- rowers/tests/test_imports.py | 19 ++++++++++++++++ rowers/tests/testdata/testdata.tcx.gz | Bin 4003 -> 0 bytes 4 files changed, 69 insertions(+), 8 deletions(-) delete mode 100644 rowers/tests/testdata/testdata.tcx.gz diff --git a/rowers/polarstuff.py b/rowers/polarstuff.py index ef201d44..3ac89424 100644 --- a/rowers/polarstuff.py +++ b/rowers/polarstuff.py @@ -93,6 +93,10 @@ def get_token(code): data=post_data, headers=headers) + if response.status_code != 200: + dologging('polar.log','Getting token, got:') + dologging('polar.log',response.status_code) + dologging('polar.log',response.text) try: token_json = response.json() @@ -100,11 +104,17 @@ def get_token(code): expires_in = token_json['expires_in'] user_id = token_json['x_user_id'] dologging('polar.log',response.status_code) - dologging('polar.log',response.text) + try: + dologging('polar.log',response.text) + except AttributeError: + pass dologging('polar.log',token_json) except (KeyError,JSONDecodeError) as e: dologging('polar.log',e) - dologging('polar.log',response.text) + try: + dologging('polar.log',response.text) + except AttributeError: + pass thetoken = 0 expires_in = 0 user_id = 0 @@ -132,11 +142,12 @@ def revoke_access(user): 'Authorization': 'Bearer {token}'.format(token=user.rower.polartoken) } - response = requests.delete('https://www.polaraccesslink.com/v3/users/{user-id}', params={ - 'user-id':user.rower.polaruserid, - }, headers = headers) + response = requests.delete('https://www.polaraccesslink.com/v3/users/{userid}'.format( + userid = user.rower.polaruserid + ), headers = headers) dologging('polar.log',response.text) + dologging('polar.log',response.reason) return 1 @@ -169,9 +180,12 @@ def get_polar_notifications(): dologging('polar.log',available_data) else: dologging('polar.log',response.status_code) - dologging('polar.log',reponse.text) + dologging('polar.log',response.text) except AttributeError: - dologging('polar.log',response.text) + try: + dologging('polar.log',response.text) + except AttributeError: + pass pass return available_data diff --git a/rowers/tests/mocks.py b/rowers/tests/mocks.py index f4a31f68..35e54974 100644 --- a/rowers/tests/mocks.py +++ b/rowers/tests/mocks.py @@ -1021,6 +1021,7 @@ def mocked_requests(*args, **kwargs): polartester = re.compile(r'.*?polaraccesslink\.com') + polarremotetester = re.compile(r'.*?polarremote\.com') c2tester = re.compile(r'.*?log\.concept2\.com') stravatester = re.compile(r'.*?strava\.com') sttester = re.compile(r'.*?sporttracks\.mobi') @@ -1041,6 +1042,9 @@ def mocked_requests(*args, **kwargs): polartcxregex = r'.*?polaraccesslink\.com\/.*\/(\d+)\/tcx' polartcxtester = re.compile(polartcxregex) + polarnotificationregex = r'.*polaraccesslink\.com\/.*\/notifications' + polarnotificationtester = re.compile(polarnotificationregex) + c2importregex = r'.*?concept2.com\/api\/users\/me\/results\/\d+' c2importtester = re.compile(c2importregex) @@ -1134,8 +1138,32 @@ def mocked_requests(*args, **kwargs): json_data = stravaathletejson return MockResponse(json_data,200) + if polarremotetester.match(args[0]): + json_data = { + 'access_token':'aap', + 'expires_in':31535999, + 'x_user_id':1, + } + return MockResponse(json_data,200) + if polartester.match(args[0]): - if polartcxtester.match(args[0]): + if polarnotificationtester.match(args[0]): + json_data = { + "available-user-data": [ + { + "user-id": 475, + "data-type": "ACTIVITY_SUMMARY", + "url": "https://www.polaraccesslink.com/v3/users/475/activity-transactions" + }, + { + 'user-id': 475, + 'data-type': 'EXERCISE', + 'url': 'https://polaraccesslink.com/v3/users/40273947/exercise-transactions' + } + ] + } + return MockResponse(json_data,200) + elif polartcxtester.match(args[0]): filename = 'rowers/tests/testdata/polar_response.tcx' return MockContentResponse(filename,200) elif polarexercisetester.match(args[0]): diff --git a/rowers/tests/test_imports.py b/rowers/tests/test_imports.py index 7bee6d14..ce78fa52 100644 --- a/rowers/tests/test_imports.py +++ b/rowers/tests/test_imports.py @@ -774,6 +774,8 @@ class PolarObjects(DjangoTestCase): self.r.polartoken = '12' self.r.polarrefreshtoken = '123' + self.r.polaruserid = 475 + self.r.rowerplan = 'pro' self.r.polartokenexpirydate = arrow.get(datetime.datetime.now()+datetime.timedelta(days=100)).datetime @@ -821,6 +823,23 @@ class PolarObjects(DjangoTestCase): res = polarstuff.get_polar_workouts(self.r.user) self.assertEqual(len(res),2) + @patch('rowers.polarstuff.requests.post', side_effect=mocked_requests) + @patch('rowers.polarstuff.requests.get', side_effect=mocked_requests) + def test_polar_callback(self, mock_get, mock_post): + response = self.c.get('/polarflowcallback?code=abcdef&state=12sdss',follow=True) + + self.assertEqual(response.status_code,200) + + @patch('rowers.polarstuff.requests.post', side_effect=mocked_requests) + @patch('rowers.polarstuff.requests.get', side_effect=mocked_requests) + def test_polar_notifications(self, mock_get, mock_post): + data = polarstuff.get_polar_notifications() + + self.assertEqual(data[0]['user-id'],475) + + response = polarstuff.get_all_new_workouts(data) + self.assertEqual(response,1) + #@pytest.mark.django_db @override_settings(TESTING=True) class RP3Objects(DjangoTestCase): diff --git a/rowers/tests/testdata/testdata.tcx.gz b/rowers/tests/testdata/testdata.tcx.gz deleted file mode 100644 index 2469a2d930feeefcb7460823045cea3d97011511..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4003 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 Date: Fri, 21 Jan 2022 15:41:00 +0100 Subject: [PATCH 2/3] next step polar --- rowers/polarstuff.py | 115 +++++++++++++++++--------- rowers/tests/mocks.py | 27 +++++- rowers/tests/test_imports.py | 12 +++ rowers/tests/testdata/testdata.tcx.gz | Bin 0 -> 3999 bytes rowers/views/importviews.py | 22 +++-- 5 files changed, 131 insertions(+), 45 deletions(-) create mode 100644 rowers/tests/testdata/testdata.tcx.gz diff --git a/rowers/polarstuff.py b/rowers/polarstuff.py index 3ac89424..0cb85c95 100644 --- a/rowers/polarstuff.py +++ b/rowers/polarstuff.py @@ -93,7 +93,7 @@ def get_token(code): data=post_data, headers=headers) - if response.status_code != 200: + if response.status_code != 200: # pragma: no cover dologging('polar.log','Getting token, got:') dologging('polar.log',response.status_code) dologging('polar.log',response.text) @@ -109,7 +109,7 @@ def get_token(code): except AttributeError: pass dologging('polar.log',token_json) - except (KeyError,JSONDecodeError) as e: + except (KeyError,JSONDecodeError) as e: # pragma: no cover dologging('polar.log',e) try: dologging('polar.log',response.text) @@ -122,7 +122,7 @@ def get_token(code): return [thetoken,expires_in,user_id] # Make authorization URL including random string -def make_authorization_url(): +def make_authorization_url(): # pragma: no cover # Generate a random string for the state parameter # Save it for use later to prevent xsrf attacks state = str(uuid4()) @@ -137,7 +137,7 @@ def make_authorization_url(): return HttpResponseRedirect(url) -def revoke_access(user): +def revoke_access(user): # pragma: no cover headers = { 'Authorization': 'Bearer {token}'.format(token=user.rower.polartoken) } @@ -167,7 +167,7 @@ def get_polar_notifications(): try: response = requests.get(url, headers=headers) - except ConnectionError: + except ConnectionError: # pragma: no cover response = { 'status_code':400, } @@ -178,10 +178,10 @@ def get_polar_notifications(): if response.status_code == 200: available_data = response.json()['available-user-data'] dologging('polar.log',available_data) - else: + else: # pragma: no cover dologging('polar.log',response.status_code) dologging('polar.log',response.text) - except AttributeError: + except AttributeError: # pragma: no cover try: dologging('polar.log',response.text) except AttributeError: @@ -195,7 +195,7 @@ from rowers.rower_rules import ispromember def get_all_new_workouts(available_data,testing=False): for record in available_data: dologging('polar.log',str(record)) - if testing: + if testing: # pragma: no cover print(record) if record['data-type'] == 'EXERCISE': try: @@ -204,9 +204,9 @@ def get_all_new_workouts(available_data,testing=False): if r.polar_auto_import and ispromember(u): exercise_list = get_polar_workouts(u) dologging('polar.log',exercise_list) - if testing: + if testing: # pragma: no cover print(exercise_list) - except Rower.DoesNotExist: + except Rower.DoesNotExist: # pragma: no cover pass return 1 @@ -220,7 +220,7 @@ def get_polar_workouts(user): if (r.polartoken == '') or (r.polartoken is None): s = "Token doesn't exist. Need to authorize" return custom_exception_handler(401,s) - elif (timezone.now()>r.polartokenexpirydate): + elif (timezone.now()>r.polartokenexpirydate): # pragma: no cover s = "Token expired. Needs to refresh" dologging('polar.log',s) return custom_exception_handler(401,s) @@ -278,7 +278,7 @@ def get_polar_workouts(user): workouttype = 'other' try: workouttype = mytypes.polaraccesslink_sports[exercise_dict['detailed-sport-info']] - except KeyError: + except KeyError: # pragma: no cover dologging('polar.log',exercise_dict['detailed-sport-info']) dologging('polar.log',workouttype) try: @@ -319,7 +319,7 @@ def get_polar_workouts(user): ) dologging('polar.log',response.status_code) - if response.status_code != 200: + if response.status_code != 200: # pragma: no cover try: dologging('polar.log',response.text) except: @@ -330,7 +330,7 @@ def get_polar_workouts(user): pass exercise_dict['filename'] = filename - else: + else: # pragma: no cover exercise_dict['filename'] = '' exercise_list.append(exercise_dict) @@ -346,6 +346,39 @@ def get_polar_workouts(user): return exercise_list +def register_user(user): + r = Rower.objects.get(user=user) + if (r.polartoken == '') or (r.polartoken is None): + s = "Token doesn't exist. Need to authorize" + return custom_exception_handler(401,s) + elif (timezone.now()>r.polartokenexpirydate): + s = "Token expired. Needs to refresh" + return custom_exception_handler(401,s) + + authorizationstring = str('Bearer ' + r.polartoken) + headers = { + 'Content-Type': 'application/xml', + 'Authorization':authorizationstring, + 'Accept': 'application/json' + } + + params = { + 'member-id': str(user.id) + } + + url = baseurl+'/users' + + dologging('polar.log','Registering user') + response = requests.post(url,params=params,headers=headers) + + if response.status_code != 200: + dologging('polar.log',response.status_code) + return {} + + polar_user_data = response.json() + + return polar_user_data + def get_polar_user_info(user,physical=False): r = Rower.objects.get(user=user) if (r.polartoken == '') or (r.polartoken is None): @@ -354,34 +387,34 @@ def get_polar_user_info(user,physical=False): elif (timezone.now()>r.polartokenexpirydate): s = "Token expired. Needs to refresh" return custom_exception_handler(401,s) - else: - authorizationstring = str('Bearer ' + r.polartoken) - headers = { - 'Authorization':authorizationstring, - 'Accept': 'application/json' + + authorizationstring = str('Bearer ' + r.polartoken) + headers = { + 'Authorization':authorizationstring, + 'Accept': 'application/json' + } + + + params = { + 'user-id': r.polaruserid } - - params = { - 'user-id': r.polaruserid - } - - if not physical: - url = baseurl+'/users/{userid}'.format( - userid = r.polaruserid + if not physical: + url = baseurl+'/users/{userid}'.format( + userid = r.polaruserid + ) + else: + url = 'https://www.polaraccesslink.com/v3/users/{userid}/physical-information-transactions/'.format( + userid = r.polaruserid ) - else: - url = 'https://www.polaraccesslink.com/v3/users/{userid}/physical-information-transactions/'.format( - userid = r.polaruserid - ) - if physical: - response = requests.post(url, headers=headers) - else: - response = requests.get(url, headers=headers) + if physical: + response = requests.post(url, headers=headers) + else: + response = requests.get(url, headers=headers) - return response + return response def get_polar_workout(user,id,transactionid): @@ -429,11 +462,15 @@ def get_polar_workout(user,id,transactionid): transactionid = transactionid, exerciseid = id ) + authorizationstring = str('Bearer ' + r.polartoken) + headers2 = { + 'Authorization':authorizationstring, + } response = requests.get(url,headers = headers2) if response.status_code == 200: - result = response.text + result = response.content # commit transaction url = baseurl+'/users/{userid}/exercise-transactions/{transactionid}'.format( transactionid = transactionid, @@ -441,9 +478,9 @@ def get_polar_workout(user,id,transactionid): ) response = requests.put(url,headers=headers) dologging('polar.log','Committing transaction on {url}'.format(url=url)) - else: + else: # pragma: no cover result = None return result - return None + return None # pragma: no cover diff --git a/rowers/tests/mocks.py b/rowers/tests/mocks.py index 35e54974..a2584dc1 100644 --- a/rowers/tests/mocks.py +++ b/rowers/tests/mocks.py @@ -768,6 +768,25 @@ def mocked_requests(*args, **kwargs): ] } + polar_user_data = { + "polar-user-id": 475, + "member-id": "i09u9ujj", + "registration-date": "2011-10-14T12:50:37.000Z", + "first-name": "Eka", + "last-name": "Toka", + "birthdate": "1985-09-06", + "gender": "MALE", + "weight": 66, + "height": 170, + "field": [ + { + "value": "2", + "index": 0, + "name": "number-of-children" + } + ] + } + polar_exercise_dict = { "id": 1937529874, "upload-time": "2008-10-13T10:40:02Z", @@ -1042,6 +1061,9 @@ def mocked_requests(*args, **kwargs): polartcxregex = r'.*?polaraccesslink\.com\/.*\/(\d+)\/tcx' polartcxtester = re.compile(polartcxregex) + polaruserregex = r'.*?polaraccesslink\.com\/.*\/users$' + polarusertester = re.compile(polaruserregex) + polarnotificationregex = r'.*polaraccesslink\.com\/.*\/notifications' polarnotificationtester = re.compile(polarnotificationregex) @@ -1142,7 +1164,7 @@ def mocked_requests(*args, **kwargs): json_data = { 'access_token':'aap', 'expires_in':31535999, - 'x_user_id':1, + 'x_user_id':475, } return MockResponse(json_data,200) @@ -1163,6 +1185,9 @@ def mocked_requests(*args, **kwargs): ] } return MockResponse(json_data,200) + elif polarusertester.match(args[0]): + json_data = polar_user_data + return MockResponse(json_data,200) elif polartcxtester.match(args[0]): filename = 'rowers/tests/testdata/polar_response.tcx' return MockContentResponse(filename,200) diff --git a/rowers/tests/test_imports.py b/rowers/tests/test_imports.py index ce78fa52..8e33a456 100644 --- a/rowers/tests/test_imports.py +++ b/rowers/tests/test_imports.py @@ -776,6 +776,7 @@ class PolarObjects(DjangoTestCase): self.r.polarrefreshtoken = '123' self.r.polaruserid = 475 self.r.rowerplan = 'pro' + self.r.polar_auto_import = True self.r.polartokenexpirydate = arrow.get(datetime.datetime.now()+datetime.timedelta(days=100)).datetime @@ -840,6 +841,17 @@ class PolarObjects(DjangoTestCase): response = polarstuff.get_all_new_workouts(data) self.assertEqual(response,1) + @patch('rowers.polarstuff.requests.post', side_effect=mocked_requests) + @patch('rowers.polarstuff.requests.get', side_effect=mocked_requests) + def test_polar_get_workout(self, mock_get, mock_post): + transaction_id = 240522162 + id = 1937529874 + + response = polarstuff.get_polar_workout(self.u, id, transaction_id) + self.assertEqual(len(response),14836) + + + #@pytest.mark.django_db @override_settings(TESTING=True) class RP3Objects(DjangoTestCase): diff --git a/rowers/tests/testdata/testdata.tcx.gz b/rowers/tests/testdata/testdata.tcx.gz new file mode 100644 index 0000000000000000000000000000000000000000..8e445e010401b471bd13aa3bb60fced0b54eeed2 GIT binary patch literal 3999 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 F0RY@hEvNth literal 0 HcmV?d00001 diff --git a/rowers/views/importviews.py b/rowers/views/importviews.py index 9d8acd99..0237c833 100644 --- a/rowers/views/importviews.py +++ b/rowers/views/importviews.py @@ -200,7 +200,7 @@ def rower_strava_authorize(request): # pragma: no cover # Polar Authorization @login_required() -def rower_polar_authorize(request): +def rower_polar_authorize(request): # pragma: no cover state = str(uuid4()) @@ -413,14 +413,14 @@ def rower_process_polarcallback(request): error = request.GET.get('error','no error') dologging('polar.log','Callback: {error}'.format(error=error)) - if error != 'no error': + if error != 'no error': # pragma: no cover messages.error(request,error) url = reverse('rower_exportsettings_view') return HttpResponseRedirect(url) try: code = request.GET['code'] - except MultiValueDictKeyError: + except MultiValueDictKeyError: # pragma: no cover try: message = request.GET['error'] except MultiValueDictKeyError: @@ -432,6 +432,15 @@ def rower_process_polarcallback(request): return HttpResponseRedirect(url) access_token, expires_in, user_id = polarstuff.get_token(code) + polar_user_data = polarstuff.register_user(request.user) + + try: + user_id2 = polar_user_data['polar-user-id'] + except KeyError: + user_id2 = 0 + + if user_id2 != user_id: + messages.error(request,'Polar User ID error') expirydatetime = timezone.now()+datetime.timedelta(seconds=expires_in) @@ -442,8 +451,11 @@ def rower_process_polarcallback(request): r.save() - successmessage = "Tokens stored. Good to go. Please check your import/export settings" - messages.info(request,successmessage) + if user_id2 == user_id: + successmessage = "Tokens stored. Good to go. Please check your import/export settings" + messages.info(request,successmessage) + else: + messages.error(request,"Please contact support@rowsandall.com for help.") url = reverse('rower_exportsettings_view') return HttpResponseRedirect(url) From a88a1cc7a82d7a7079a73c7c912a96f8529a167e Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Fri, 21 Jan 2022 15:57:54 +0100 Subject: [PATCH 3/3] remove temp files --- rowers/tests/testdata/testdata.tcx.gz | Bin 3999 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 rowers/tests/testdata/testdata.tcx.gz diff --git a/rowers/tests/testdata/testdata.tcx.gz b/rowers/tests/testdata/testdata.tcx.gz deleted file mode 100644 index 8e445e010401b471bd13aa3bb60fced0b54eeed2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3999 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 F0RY@hEvNth