Private
Public Access
1
0

fixing strava tests

This commit is contained in:
Sander Roosendaal
2019-01-16 17:33:04 +01:00
parent ba4d4ced8d
commit 081ef1b11a
12 changed files with 462424 additions and 395 deletions

View File

@@ -103,6 +103,7 @@ def imports_open(user,oauth_data):
oauth_data, oauth_data,
) )
elif tokenexpirydate is None and expirydatename is not None and 'strava' in expirydatename: elif tokenexpirydate is None and expirydatename is not None and 'strava' in expirydatename:
print 'noot'
token = imports_token_refresh( token = imports_token_refresh(
user, user,
tokenname, tokenname,
@@ -152,6 +153,8 @@ def imports_do_refresh_token(refreshtoken,oauth_data,access_token=''):
data=post_data, data=post_data,
headers=headers) headers=headers)
if response.status_code == 200 or response.status_code == 201: if response.status_code == 200 or response.status_code == 201:
token_json = response.json() token_json = response.json()
else: else:

View File

@@ -265,6 +265,12 @@ from utils import get_strava_stream
# Get a Strava workout summary data and stroke data by ID # Get a Strava workout summary data and stroke data by ID
def get_workout(user,stravaid): def get_workout(user,stravaid):
try:
thetoken = strava_open(user)
except NoTokenError:
s = "Token error"
return custom_exception_handler(401,s)
r = Rower.objects.get(user=user) r = Rower.objects.get(user=user)
if (r.stravatoken == '') or (r.stravatoken is None): if (r.stravatoken == '') or (r.stravatoken is None):
s = "Token doesn't exist. Need to authorize" s = "Token doesn't exist. Need to authorize"

View File

@@ -1 +0,0 @@
E408191@CZ27LT9RCGN72.11684:1547623002

View File

@@ -31,6 +31,7 @@ from mock import Mock, patch
from minimocktest import MockTestCase from minimocktest import MockTestCase
import pandas as pd import pandas as pd
import rowers.c2stuff as c2stuff import rowers.c2stuff as c2stuff
import arrow
import json import json
import numpy as np import numpy as np
@@ -136,6 +137,12 @@ def mocked_getempowerdata_db(*args, **kwargs):
return df return df
def mocked_read_df_cols_sql_multistats(ids,columns,convertnewtons=True):
df = pd.read_csv('rowers/tests/testdata/cumstats.csv')
extracols = []
return df, extracols
def mocked_read_df_cols_sql(ids, columns, convertnewtons=True): def mocked_read_df_cols_sql(ids, columns, convertnewtons=True):
df = pd.read_csv('rowers/tests/testdata/fake_strokedata.csv') df = pd.read_csv('rowers/tests/testdata/fake_strokedata.csv')
extracols = [] extracols = []
@@ -704,7 +711,7 @@ def mocked_requests(*args, **kwargs):
"token_type": "Bearer", "token_type": "Bearer",
"access_token": "987654321234567898765432123456789", "access_token": "987654321234567898765432123456789",
"refresh_token": "1234567898765432112345678987654321", "refresh_token": "1234567898765432112345678987654321",
"expires_at": 1531385304 "expires_at": arrow.now().timestamp+3600
} }
return MockResponse(json_data,200) return MockResponse(json_data,200)

View File

@@ -51,6 +51,9 @@ class CoursesTest(TestCase):
response = self.c.get('/rowers/courses/1/') response = self.c.get('/rowers/courses/1/')
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
response = self.c.get('/rowers/courses/1/map/')
self.assertEqual(response.status_code, 200)
form_data = { form_data = {
'name':'apekoers', 'name':'apekoers',
'country':'United States of Atlantis', 'country':'United States of Atlantis',

View File

@@ -233,6 +233,7 @@ class StravaObjects(DjangoTestCase):
self.r.stravatoken = '12' self.r.stravatoken = '12'
self.r.stravarefreshtoken = '123' self.r.stravarefreshtoken = '123'
self.r.stravatokenexpirydate = datetime.datetime.now()-datetime.timedelta(days=1)
self.r.save() self.r.save()
self.c.login(username='john',password='koeinsloot') self.c.login(username='john',password='koeinsloot')
@@ -285,15 +286,19 @@ class StravaObjects(DjangoTestCase):
# self.assertEqual(response.url, '/rowers/workout/1/edit/') # self.assertEqual(response.url, '/rowers/workout/1/edit/')
# self.assertEqual(response.status_code, 302) # self.assertEqual(response.status_code, 302)
@patch('rowers.stravastuff.requests.get', side_effect=mocked_requests)
@patch('rowers.stravastuff.requests.post', side_effect=mocked_requests) @patch('rowers.stravastuff.requests.post', side_effect=mocked_requests)
def test_strava_list(self, mock_get): def test_strava_list(self, mock_get, mockpost):
response = self.c.get('/rowers/workout/stravaimport/',follow=True) result = rowers.stravastuff.rower_strava_token_refresh(self.u)
self.assertEqual(result,"987654321234567898765432123456789")
response = self.c.get('/rowers/workout/stravaimport/')
self.assertEqual(response.status_code,200) self.assertEqual(response.status_code,200)
@patch('rowers.utils.requests.get', side_effect=mocked_requests) @patch('rowers.utils.requests.get', side_effect=mocked_requests)
@patch('rowers.stravastuff.requests.post', side_effect=mocked_requests)
@patch('rowers.dataprep.getsmallrowdata_db') @patch('rowers.dataprep.getsmallrowdata_db')
def test_strava_import(self, mock_get, def test_strava_import(self, mock_get, mock_post,
mocked_getsmallrowdata_db): mocked_getsmallrowdata_db):
response = self.c.get('/rowers/workout/stravaimport/12',follow=True) response = self.c.get('/rowers/workout/stravaimport/12',follow=True)

View File

@@ -300,6 +300,43 @@ class ForcecurveTest(TestCase):
response = self.c.get(url) response = self.c.get(url)
self.assertEqual(response.status_code,200) self.assertEqual(response.status_code,200)
class CumStatsTest(TestCase):
def setUp(self):
self.u = UserFactory()
self.r = Rower.objects.create(user=self.u,
birthdate=faker.profile()['birthdate'],
gdproptin=True,
gdproptindate=timezone.now(),
rowerplan='coach')
self.c = Client()
self.user_workouts = WorkoutFactory.create_batch(5, user=self.r)
self.factory = RequestFactory()
self.password = faker.word()
self.u.set_password(self.password)
self.u.save()
def tearDown(self):
for workout in self.user_workouts:
try:
os.remove(workout.csvfilename)
except (IOError, WindowsError):
pass
@patch('rowers.dataprep.read_cols_df_sql', side_effect = mocked_read_df_cols_sql_multistats)
def test_cumflex(self, mocked_df):
login = self.c.login(username=self.u.username, password=self.password)
self.assertTrue(login)
startdate = (self.user_workouts[0].startdatetime-datetime.timedelta(days=3)).date()
enddate = (self.user_workouts[0].startdatetime+datetime.timedelta(days=3)).date()
url = '/rowers/cumstats/'
response = self.c.get(url)
self.assertEqual(response.status_code,200)
class CumFlexTest(TestCase): class CumFlexTest(TestCase):
def setUp(self): def setUp(self):
self.u = UserFactory() self.u = UserFactory()

View File

@@ -31,6 +31,7 @@ class SimpleViewTest(TestCase):
except (IOError, WindowsError): except (IOError, WindowsError):
pass pass
def test_getrequestrower(self): def test_getrequestrower(self):
user_no_rower = UserFactory(username='norower') user_no_rower = UserFactory(username='norower')
user_no_rower.set_password(faker.word()) user_no_rower.set_password(faker.word())

462350
rowers/tests/testdata/cumstats.csv vendored Normal file

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@@ -2502,7 +2502,7 @@
</Trackpoint> </Trackpoint>
</Track> </Track>
</Lap> </Lap>
<Notes>&lt;Element 'Notes' at 0x146d99e8&gt;</Notes> <Notes>&lt;Element 'Notes' at 0x15654160&gt;</Notes>
</Activity> </Activity>
</Activities> </Activities>
<Creator> <Creator>

View File

@@ -8887,11 +8887,6 @@ def cumstats(request,theuser=0,
cordict[field1] = thedict cordict[field1] = thedict
# interactive box plot
datadf['workoutid'].replace(datemapping,inplace=True)
datadf.rename(columns={"workoutid":"date"},inplace=True)
datadf = datadf.sort_values(['date'])
# set options form correctly # set options form correctly
initial = {} initial = {}
initial['includereststrokes'] = includereststrokes initial['includereststrokes'] = includereststrokes
@@ -9188,157 +9183,7 @@ def workout_stats_view(request,id=0,message="",successmessage=""):
'otherstats':otherstats, 'otherstats':otherstats,
}) })
# The Advanced edit page
@login_required()
def workout_advanced_view(request,id=0,message="",successmessage=""):
row = get_workout(id)
# form = WorkoutForm(instance=row)
g = GraphImage.objects.filter(workout=row).order_by("-creationdatetime")
for i in g:
try:
width,height = Image.open(i.filename).size
i.width = width
i.height = height
i.save()
except:
pass
# check if user is owner of this workout
if (checkworkoutuser(request.user,row)==False):
message = "You are not allowed to edit this workout"
messages.error(request,message)
url = reverse(workouts_view)
return HttpResponseRedirect(url)
# create interactive plot
f1 = row.csvfilename
u = row.user.user
r = getrower(u)
# create interactive plot
try:
res = interactive_chart(id,promember=1)
script = res[0]
div = res[1]
except ValueError:
pass
messages.error(request,message)
messages.info(request,successmessage)
if row.workouttype in mytypes.otwtypes:
return render(request,
'advancedotw.html',
{'workout':row,
'teams':get_my_teams(request.user),
'interactiveplot':script,
'the_div':div})
else:
return render(request,
'advancededit.html',
{'workout':row,
'teams':get_my_teams(request.user),
'interactiveplot':script,
'the_div':div})
# The interactive plot comparing two workouts (obsolete version)
def workout_comparison_view(request,id1=0,id2=0,xparam='distance',yparam='spm'):
promember=0
if not request.user.is_anonymous():
r = getrower(request.user)
result = request.user.is_authenticated() and ispromember(request.user)
if result:
promember=1
# create interactive plot
res = interactive_comparison_chart(id1,id2,xparam=xparam,yparam=yparam,
promember=promember)
script = res[0]
div = res[1]
axchoicesbasic = {ax[0]:ax[1] for ax in axes if ax[4]=='basic'}
axchoicespro = {ax[0]:ax[1] for ax in axes if ax[4]=='pro'}
noylist = ["time","distance"]
axchoicesbasic.pop("cumdist")
return render(request,
'comparisonchart.html',
{'interactiveplot':script,
'the_div':div,
'teams':get_my_teams(request.user),
'id1':id1,
'id2':id2,
'axchoicesbasic':axchoicesbasic,
'axchoicespro':axchoicespro,
'noylist':noylist,
'xparam':xparam,
'yparam':yparam,
})
# Updated version of comparison plot
def workout_comparison_view2(request,id1=0,id2=0,xparam='distance',
yparam='spm',plottype='line'):
promember=0
if not request.user.is_anonymous():
r = getrower(request.user)
result = request.user.is_authenticated() and ispromember(request.user)
if result:
promember=1
if not Workout.objects.filter(id=id1).exists() or not Workout.objects.filter(id=id2).exists():
raise Http404("Workout doesn't exist")
# create interactive plot
res = interactive_comparison_chart(id1,id2,xparam=xparam,yparam=yparam,
promember=promember,plottype=plottype)
script = res[0]
div = res[1]
axchoicesbasic = {ax[0]:ax[1] for ax in axes if ax[4]=='basic'}
axchoicespro = {ax[0]:ax[1] for ax in axes if ax[4]=='pro'}
noylist = ["time","distance"]
axchoicesbasic.pop("cumdist")
row1 = Workout.objects.get(id=id1)
row2 = Workout.objects.get(id=id2)
mayedit = 0
if request.user == row1.user.user:
mayedit=1
if checkworkoutuser(request.user,row1):
mayedit=1
if row1.workouttype != 'water' or row2.workouttype != 'water':
axchoicespro.pop('slip')
axchoicespro.pop('wash')
axchoicespro.pop('catch')
axchoicespro.pop('finish')
axchoicespro.pop('totalangle')
axchoicespro.pop('effectiveangle')
axchoicespro.pop('peakforceangle')
return render(request,
'comparisonchart2.html',
{'interactiveplot':script,
'the_div':div,
'teams':get_my_teams(request.user),
'id1':id1,
'id2':id2,
'mayedit':mayedit,
'axchoicesbasic':axchoicesbasic,
'axchoicespro':axchoicespro,
'noylist':noylist,
'xparam':xparam,
'yparam':yparam,
'plottype':plottype,
'promember':promember,
})
# Change default landing page # Change default landing page
@login_required() @login_required()
@@ -9365,47 +9210,7 @@ def get_workout_default_page(request,id):
else: else:
return reverse(workout_workflow_view,kwargs={'id':str(id)}) return reverse(workout_workflow_view,kwargs={'id':str(id)})
# Workflow Configuration # Workflow configuration
@login_required()
def workout_workflow_config_view(request):
request.session['referer'] = absolute(request)['PATH']
request.session[translation.LANGUAGE_SESSION_KEY] = USER_LANGUAGE
try:
workoutid = request.session['lastworkout']
except KeyError:
workoutid = 0
r = getrower(request.user)
if request.method == 'POST' and 'leftpanel' in request.POST:
formleft = WorkFlowLeftPanelForm(request.POST)
if formleft.is_valid():
leftpanel = formleft.cleaned_data['leftpanel']
r.workflowleftpanel = leftpanel
r.save()
if request.method == 'POST' and 'middlepanel' in request.POST:
formmiddle = WorkFlowMiddlePanelForm(request.POST)
if formmiddle.is_valid():
middlepanel = formmiddle.cleaned_data['middlepanel']
r.workflowmiddlepanel = middlepanel
r.save()
formleft = WorkFlowLeftPanelForm(instance=r)
formmiddle = WorkFlowMiddlePanelForm(instance=r)
tmplt = 'workflowconfig.html'
return render(request,tmplt,
{
'rower':r,
'formleft':formleft,
'formmiddle':formmiddle,
'workoutid': workoutid,
})
@login_required() @login_required()
def workout_workflow_config2_view(request,userid=0): def workout_workflow_config2_view(request,userid=0):
request.session['referer'] = absolute(request)['PATH'] request.session['referer'] = absolute(request)['PATH']
@@ -9902,46 +9707,6 @@ def workout_flexchart3_view(request,*args,**kwargs):
}) })
# The interactive plot with the colored Heart rate zones
def workout_biginteractive_view(request,id=0,message="",successmessage=""):
row = get_workout(id)
# check if user is owner of this workout
# create interactive plot
f1 = row.csvfilename
u = row.user.user
# r = getrower(u)
promember=0
mayedit=0
if not request.user.is_anonymous():
r = getrower(request.user)
result = request.user.is_authenticated() and ispromember(request.user)
if result:
promember=1
if request.user == row.user.user:
mayedit=1
# create interactive plot
res = interactive_bar_chart(id,promember=promember)
script = res[0]
div = res[1]
messages.error(request,message)
messages.info(request,successmessage)
return render(request,
'biginteractive1.html',
{'workout':row,
'teams':get_my_teams(request.user),
'interactiveplot':script,
'the_div':div,
'promember':promember,
'mayedit':mayedit})
# The interactive plot with wind corrected pace for OTW outings # The interactive plot with wind corrected pace for OTW outings
def workout_otwpowerplot_view(request,id=0,message="",successmessage=""): def workout_otwpowerplot_view(request,id=0,message="",successmessage=""):
@@ -10001,63 +9766,6 @@ def workout_otwpowerplot_view(request,id=0,message="",successmessage=""):
'the_div':div, 'the_div':div,
'mayedit':mayedit}) 'mayedit':mayedit})
# the page where you can choose where to export this workout
@login_required()
def workout_export_view(request,id=0, message="", successmessage=""):
request.session[translation.LANGUAGE_SESSION_KEY] = USER_LANGUAGE
row = get_workout(id)
try:
thetoken = c2_open(request.user)
except NoTokenError:
thetoken = 0
if (checkworkoutuser(request.user,row)) and thetoken:
c2userid = c2stuff.get_userid(thetoken)
else:
c2userid = 0
try:
rktoken = runkeeper_open(request.user)
except NoTokenError:
rktoken = 0
if (checkworkoutuser(request.user,row)) and rktoken:
rkuserid = runkeeperstuff.get_userid(rktoken)
else:
rkuserid = 0
# form = WorkoutForm(instance=row)
g = GraphImage.objects.filter(workout=row).order_by("-creationdatetime")
for i in g:
try:
width,height = Image.open(i.filename).size
i.width = width
i.height = height
i.save()
except:
pass
# check if user is owner of this workout
if (checkworkoutuser(request.user,row)==False):
message = "You are not allowed to edit this workout"
messages.error(request,message)
url = reverse(workouts_view)
return HttpResponseRedirect(url)
messages.error(request,message)
messages.info(request,successmessage)
return render(request,
'export.html',
{'workout':row,
'teams':get_my_teams(request.user),
'c2userid':c2userid,
'rkuserid':rkuserid,
})
# #
@login_required() @login_required()
@@ -11081,20 +10789,18 @@ def workout_add_chart_view(request,id,plotnr=1):
# The page where you select which Strava workout to import # The page where you select which Strava workout to import
@login_required() @login_required()
def workout_stravaimport_view(request,message="",userid=0): def workout_stravaimport_view(request,message="",userid=0):
r = getrequestrower(request,userid=userid)
if r.user != request.user:
messages.info(request,"You cannot import other people's workouts from Strava")
try: try:
thetoken = strava_open(request.user) thetoken = strava_open(request.user)
except NoTokenError: except NoTokenError:
return HttpResponseRedirect("/rowers/me/stravaauthorize/") return HttpResponseRedirect("/rowers/me/stravaauthorize/")
res = stravastuff.get_strava_workout_list(request.user) res = stravastuff.get_strava_workout_list(request.user)
r = getrequestrower(request,userid=userid)
if r.user != request.user:
messages.info(request,"You cannot import other people's workouts from Concept2")
r = getrower(request.user)
if (res.status_code != 200): if (res.status_code != 200):
if (res.status_code == 401): if (res.status_code == 401):
@@ -12429,95 +12135,7 @@ def team_workout_upload_view(request,message="",
# Ask the user if he really wants to delete the workout
@login_required()
def workout_delete_confirm_view(request, id=0):
try:
row = Workout.objects.get(id=id)
if (checkworkoutuser(request.user,row)==False):
raise PermissionDenied("You are not allowed to delete this workout")
else:
url = request.META.get('HTTP_REFERER','/')
return render(request,'workout_delete_confirm.html',
{'id':int(id),
'teams':get_my_teams(request.user),
'workout':row,
'url':url})
except Workout.DoesNotExist:
raise Http404("Workout doesn't exist")
# Really deleting the workout
@login_required()
def workout_delete_view(request,id=0):
try:
row = Workout.objects.get(id=id)
if (checkworkoutuser(request.user,row)==False):
raise PermissionDenied("You are not allowed to delete this workout")
else:
# files are removed by pre-delete in models.py
row.delete()
messages.info(request,'Workout deleted')
try:
url = request.session['referer']
if 'rowers/workout/' in url:
url = reverse(workouts_view)
except KeyError:
url = reverse(workouts_view)
return HttpResponseRedirect(url)
except Workout.DoesNotExist:
raise Http404("Workout doesn't exist")
# Ask the user to confirm that he wants to delete a chart
@login_required()
def graph_delete_confirm_view(request, id=0):
try:
img = GraphImage.objects.get(id=id)
row = Workout.objects.get(id=img.workout.id)
if (checkworkoutuser(request.user,row)==False):
raise PermissionDenied("You are not allowed to delete this workout")
else:
try:
url = request.session['referer']
except KeyError:
url = '/rowers/list-graphs'
request.session['referer'] = url
return render(request,'graphimage_delete_confirm.html',
{'id':int(id),
'teams':get_my_teams(request.user),
'graph':img,
'url':url})
except Workout.DoesNotExist:
raise Http404("Workout doesn't exist")
except GraphImage.DoesNotExist:
raise Http404("The image doesn't exist")
# Really deleting the chart
@login_required()
def graph_delete_view(request,id=0):
try:
img = GraphImage.objects.get(id=id)
row = Workout.objects.get(id=img.workout.id)
if (checkworkoutuser(request.user,row)==False):
raise PermissionDenied("You are not allowed to delete this graph")
else:
img.delete()
messages.info(request,'Graph deleted')
try:
url = request.session['referer']
except KeyError:
url = reverse(graphs_view)
return HttpResponseRedirect(url)
except GraphImage.DoesNotExist:
raise Http404("Graph Image doesn't exist")
except Workout.DoesNotExist:
raise Http404("Workout doesn't exist")
# A page with all the recent graphs (searchable on workout name) # A page with all the recent graphs (searchable on workout name)
@login_required() @login_required()