Private
Public Access
1
0

going through importviews ... coverage

This commit is contained in:
Sander Roosendaal
2021-04-20 10:41:32 +02:00
parent f413af91e6
commit 9677d5166e
7 changed files with 464 additions and 239 deletions

View File

@@ -14,6 +14,9 @@ import rowers
from rowers import dataprep from rowers import dataprep
from rowers import tasks from rowers import tasks
from rowers import c2stuff from rowers import c2stuff
from rowers import stravastuff
import urllib
import json
@pytest.mark.django_db @pytest.mark.django_db
@override_settings(TESTING=True) @override_settings(TESTING=True)
@@ -461,6 +464,11 @@ class NKObjects(DjangoTestCase):
) )
self.assertTrue(res>0) self.assertTrue(res>0)
@patch('rowers.nkstuff.requests.post', side_effect=mocked_requests)
def notest_nk_callback(self, mock_post):
response = self.c.get('/nk_callback?code=absdef23&scope=read',follow=True)
self.assertEqual(response.status_code, 200)
@patch('rowers.nkstuff.requests.get', side_effect=mocked_requests) @patch('rowers.nkstuff.requests.get', side_effect=mocked_requests)
@patch('rowers.nkstuff.requests.post', side_effect=mocked_requests) @patch('rowers.nkstuff.requests.post', side_effect=mocked_requests)
@@ -609,6 +617,10 @@ class RP3Objects(DjangoTestCase):
res = tasks.handle_rp3_async_workout(userid,rp3token,rp3id,startdatetime,max_attempts) res = tasks.handle_rp3_async_workout(userid,rp3token,rp3id,startdatetime,max_attempts)
self.assertEqual(res,1) self.assertEqual(res,1)
@patch('rowers.rp3stuff.requests.post', side_effect=mocked_requests)
def notest_rp3_callback(self, mock_post):
response = self.c.get('/rp3_callback?code=absdef23&scope=read',follow=True)
self.assertEqual(response.status_code, 200)
#@pytest.mark.django_db #@pytest.mark.django_db
@@ -630,6 +642,7 @@ class StravaObjects(DjangoTestCase):
self.r.stravatoken = '12' self.r.stravatoken = '12'
self.r.stravarefreshtoken = '123' self.r.stravarefreshtoken = '123'
self.r.stravatokenexpirydate = arrow.get(datetime.datetime.now()-datetime.timedelta(days=1)).datetime self.r.stravatokenexpirydate = arrow.get(datetime.datetime.now()-datetime.timedelta(days=1)).datetime
self.r.strava_owner_id = 4
self.r.save() self.r.save()
self.c.login(username='john',password='koeinsloot') self.c.login(username='john',password='koeinsloot')
@@ -666,6 +679,79 @@ class StravaObjects(DjangoTestCase):
csvfilename=filename csvfilename=filename
) )
@patch('rowers.stravastuff.requests.post', side_effect=mocked_requests)
@patch('rowers.stravastuff.requests.get', side_effect=mocked_requests)
def test_strava_webhook(self, mock_get, mock_post):
url = reverse('strava_webhook_view')
params = {
'hub.challenge':'aap',
'hub.verify_token':stravastuff.webhookverification,
}
url2 = url+'?'+urllib.parse.urlencode(params)
response = self.c.get(url2)
self.assertEqual(response.status_code,200)
data = {
'aspect_type':'create',
'object_id': 123,
'object_type':'activity',
'strava_owner': self.r.strava_owner_id,
'starttimeunix': arrow.get(datetime.datetime.now()).timestamp(),
}
raw_data = json.dumps(data)
response = self.c.generic('POST', url, raw_data)
self.assertEqual(response.status_code,200)
data = {
'aspect_type':'update',
'updates':{
'title':faker.word(),
'type': 'Ride',
},
'object_id': 123,
'object_type':'activity',
'strava_owner': self.r.strava_owner_id,
'starttimeunix': arrow.get(datetime.datetime.now()).timestamp(),
}
raw_data = json.dumps(data)
response = self.c.generic('POST', url, raw_data)
self.assertEqual(response.status_code,200)
data = {
'aspect_type':'delete',
'object_id': 123,
'object_type':'activity',
'strava_owner': self.r.strava_owner_id,
'starttimeunix': arrow.get(datetime.datetime.now()).timestamp(),
}
raw_data = json.dumps(data)
response = self.c.generic('POST', url, raw_data)
self.assertEqual(response.status_code,200)
@patch('rowers.stravastuff.requests.post', side_effect=mocked_requests)
@patch('rowers.stravastuff.requests.get', side_effect=mocked_requests)
@patch('rowers.stravastuff.stravalib.Client',side_effect=MockStravalibClient)
def test_strava_upload(self, mock_get, mock_post,MockStravalibClient):
response = self.c.get('/rowers/workout/'+encoded1+'/stravauploadw/')
self.assertRedirects(response,
expected_url = '/rowers/workout/'+encoded1+'/edit/',
status_code=302,target_status_code=200)
self.assertEqual(response.url, '/rowers/workout/'+encoded1+'/edit/')
self.assertEqual(response.status_code, 302)
@patch('rowers.stravastuff.requests.get', side_effect=mocked_requests) @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)

View File

@@ -9,6 +9,14 @@ from .statements import *
nu = datetime.datetime.now() nu = datetime.datetime.now()
from rowers.rower_rules import is_workout_user from rowers.rower_rules import is_workout_user
from rowers.models import update_records
class MiscTests(TestCase):
def setUp(self):
pass
def test_c2records(self):
update_records(verbose=False)
#@pytest.mark.django_db #@pytest.mark.django_db
class WorkoutTests(TestCase): class WorkoutTests(TestCase):

View File

@@ -1442,6 +1442,104 @@ class PlannedSessionsView(TestCase):
added = plannedsessions.add_team_session(self.team,self.ps_trimp) added = plannedsessions.add_team_session(self.team,self.ps_trimp)
self.ps_trimp.save() self.ps_trimp.save()
s = b"""filename: britishrowing.json
name: British Rowing Training Plan Beginner Week 1
trainingDays:
- order: 1
workouts:
- workoutName: Week 1 Session 1
steps:
- stepId: 0
wkt_step_name: Warmup
durationType: Time
durationValue: 300000
intensity: Warmup
description: ""
- stepId: 1
wkt_step_name: Intervals
durationType: Time
durationValue: 60000
intensity: Active
description: ""
- stepId: 2
wkt_step_name: Interval Rest
durationType: Time
durationValue: 60000
intensity: Rest
description: ""
- stepId: 3
wkt_step_name: Rep
durationType: RepeatUntilStepsCmplt
durationValue: 1
targetValue: 5
- stepId: 4
wkt_step_name: Cooldown
durationType: Time
durationValue: 300000
intensity: Cooldown
description: ""
sport: ""
description: ""
- order: 4
workouts:
- workoutName: Week 1 Session 2
steps:
- stepId: 0
wkt_step_name: Warmup
durationType: Time
durationValue: 300000
intensity: Warmup
description: ""
- stepId: 1
wkt_step_name: Interval
durationType: Time
durationValue: 300000
intensity: Active
description: ""
- stepId: 2
wkt_step_name: Interval Rest
durationType: Time
durationValue: 180000
intensity: Rest
description: ""
- stepId: 3
wkt_step_name: Rep
durationType: RepeatUntilStepsCmplt
durationValue: 1
targetValue: 5
- stepId: 4
wkt_step_name: Cooldown
durationType: Time
durationValue: 300000
intensity: Cooldown
description: ""
sport: ""
description: ""
duration: 7
description: ""
"""
self.file_data = {'yaml': SimpleUploadedFile('britishrowing.yml', s)}
with open('media/temp.yml','wb') as f:
f.write(s)
self.instantplan = InstantPlan(
uuid = "79b0dacf-9b49-4f33-9acf-e2e6734e22dc",
url = "https://thepeteplan.wordpress.com/beginner-training/",
name = faker.word(),
goal = faker.word(),
duration = 42,
description = faker.word(),
target = faker.word(),
hoursperweek = 3,
sessionsperweek = 3,
price = 0,
yaml = 'temp.yml',
)
self.instantplan.save()
def tearDown(self): def tearDown(self):
@@ -1555,6 +1653,29 @@ class PlannedSessionsView(TestCase):
response = self.c.post(url,formdata,follow=True) response = self.c.post(url,formdata,follow=True)
self.assertEqual(response.status_code,200) self.assertEqual(response.status_code,200)
def test_deletetarget_view(self):
login = self.c.login(username=self.u.username, password=self.password)
self.assertTrue(login)
url = reverse('rower_delete_trainingtarget',kwargs={'id':self.target.id})
response = self.c.get(url)
self.assertEqual(response.status_code,302)
def test_deletetrainingplan_view(self):
login = self.c.login(username=self.u.username, password=self.password)
self.assertTrue(login)
url = reverse('trainingplan_delete_view',kwargs={'pk':self.plan.id})
response = self.c.get(url)
self.assertEqual(response.status_code,200)
form = {}
response = self.c.post(url,form)
self.assertEqual(response.status_code,302)
def test_multicreate_view(self): def test_multicreate_view(self):
login = self.c.login(username=self.u.username, password=self.password) login = self.c.login(username=self.u.username, password=self.password)
@@ -1637,6 +1758,10 @@ class PlannedSessionsView(TestCase):
response = self.c.post(url,form_data,follow=True) response = self.c.post(url,form_data,follow=True)
self.assertEqual(response.status_code,200) self.assertEqual(response.status_code,200)
url = reverse('remove_groupsession_view',kwargs={'id':self.ps_trimp.id})
response = self.c.get(url)
self.assertEqual(response.status_code,302)
def test_teamedit_view(self): def test_teamedit_view(self):
login = self.c.login(username=self.u.username, password=self.password) login = self.c.login(username=self.u.username, password=self.password)
@@ -1908,86 +2033,29 @@ class PlannedSessionsView(TestCase):
#'yaml': {'yaml': SimpleUploadedFile('britishrowing.yml', f.read())} #'yaml': {'yaml': SimpleUploadedFile('britishrowing.yml', f.read())}
} }
s = b"""filename: britishrowing.json
name: British Rowing Training Plan Beginner Week 1
trainingDays:
- order: 1
workouts:
- workoutName: Week 1 Session 1
steps:
- stepId: 0
wkt_step_name: Warmup
durationType: Time
durationValue: 300000
intensity: Warmup
description: ""
- stepId: 1
wkt_step_name: Intervals
durationType: Time
durationValue: 60000
intensity: Active
description: ""
- stepId: 2
wkt_step_name: Interval Rest
durationType: Time
durationValue: 60000
intensity: Rest
description: ""
- stepId: 3
wkt_step_name: Rep
durationType: RepeatUntilStepsCmplt
durationValue: 1
targetValue: 5
- stepId: 4
wkt_step_name: Cooldown
durationType: Time
durationValue: 300000
intensity: Cooldown
description: ""
sport: ""
description: ""
- order: 4
workouts:
- workoutName: Week 1 Session 2
steps:
- stepId: 0
wkt_step_name: Warmup
durationType: Time
durationValue: 300000
intensity: Warmup
description: ""
- stepId: 1
wkt_step_name: Interval
durationType: Time
durationValue: 300000
intensity: Active
description: ""
- stepId: 2
wkt_step_name: Interval Rest
durationType: Time
durationValue: 180000
intensity: Rest
description: ""
- stepId: 3
wkt_step_name: Rep
durationType: RepeatUntilStepsCmplt
durationValue: 1
targetValue: 5
- stepId: 4
wkt_step_name: Cooldown
durationType: Time
durationValue: 300000
intensity: Cooldown
description: ""
sport: ""
description: ""
duration: 7
description: ""
"""
file_data = {'yaml': SimpleUploadedFile('britishrowing.yml', s)} form = InstantPlanForm(form_data,self.file_data)
form = InstantPlanForm(form_data,file_data)
if not form.is_valid(): if not form.is_valid():
print(form.errors) print(form.errors)
self.assertTrue(form.is_valid()) self.assertTrue(form.is_valid())
# look at a instant plan
url = reverse('rower_view_instantplan',kwargs={'id':self.instantplan.uuid})
response = self.c.get(url)
self.assertEqual(response.status_code,200)
form_data = {
'name':faker.word(),
'target': '',
'startdate':datetime.datetime.now().strftime('%Y-%m-%d'),
'enddate':(datetime.datetime.now()+datetime.timedelta(days=self.instantplan.duration)).strftime('%Y-%m-%d'),
'notes': faker.word(),
'datechoice':'startdate',
}
form = InstantPlanSelectForm(form_data)
self.assertTrue(form.is_valid())
response = self.c.post(url,form_data,follow=True)
self.assertEqual(response.status_code,200)

75
rowers/tests/testdata/temp.yml vendored Normal file
View File

@@ -0,0 +1,75 @@
filename: britishrowing.json
name: British Rowing Training Plan Beginner Week 1
trainingDays:
- order: 1
workouts:
- workoutName: Week 1 Session 1
steps:
- stepId: 0
wkt_step_name: Warmup
durationType: Time
durationValue: 300000
intensity: Warmup
description: ""
- stepId: 1
wkt_step_name: Intervals
durationType: Time
durationValue: 60000
intensity: Active
description: ""
- stepId: 2
wkt_step_name: Interval Rest
durationType: Time
durationValue: 60000
intensity: Rest
description: ""
- stepId: 3
wkt_step_name: Rep
durationType: RepeatUntilStepsCmplt
durationValue: 1
targetValue: 5
- stepId: 4
wkt_step_name: Cooldown
durationType: Time
durationValue: 300000
intensity: Cooldown
description: ""
sport: ""
description: ""
- order: 4
workouts:
- workoutName: Week 1 Session 2
steps:
- stepId: 0
wkt_step_name: Warmup
durationType: Time
durationValue: 300000
intensity: Warmup
description: ""
- stepId: 1
wkt_step_name: Interval
durationType: Time
durationValue: 300000
intensity: Active
description: ""
- stepId: 2
wkt_step_name: Interval Rest
durationType: Time
durationValue: 180000
intensity: Rest
description: ""
- stepId: 3
wkt_step_name: Rep
durationType: RepeatUntilStepsCmplt
durationValue: 1
targetValue: 5
- stepId: 4
wkt_step_name: Cooldown
durationType: Time
durationValue: 300000
intensity: Cooldown
description: ""
sport: ""
description: ""
duration: 7
description: ""

Binary file not shown.

View File

@@ -7,7 +7,7 @@ from rowers.views.statements import *
import numpy import numpy
def default(o): def default(o): # pragma: no cover
if isinstance(o, numpy.int64): return int(o) if isinstance(o, numpy.int64): return int(o)
raise TypeError raise TypeError
@@ -21,7 +21,7 @@ def workout_tp_upload_view(request,id=0):
res = -1 res = -1
try: try:
thetoken = tp_open(r.user) thetoken = tp_open(r.user)
except NoTokenError: except NoTokenError: # pragma: no cover
return HttpResponseRedirect("/rowers/me/tpauthorize/") return HttpResponseRedirect("/rowers/me/tpauthorize/")
# ready to upload. Hurray # ready to upload. Hurray
@@ -35,7 +35,7 @@ def workout_tp_upload_view(request,id=0):
r.tptoken,tcxfile, r.tptoken,tcxfile,
name=w.name name=w.name
) )
if res == 0: if res == 0: # pragma: no cover
message = "Upload to TrainingPeaks failed with status code "+str(status_code)+": "+reason message = "Upload to TrainingPeaks failed with status code "+str(status_code)+": "+reason
try: try:
os.remove(tcxfile) os.remove(tcxfile)
@@ -50,7 +50,7 @@ def workout_tp_upload_view(request,id=0):
os.remove(tcxfile) os.remove(tcxfile)
messages.info(request,'Uploaded to TrainingPeaks') messages.info(request,'Uploaded to TrainingPeaks')
else: # no tcxfile else: # pragma: no cover # no tcxfile
message = "Upload to TrainingPeaks failed" message = "Upload to TrainingPeaks failed"
w.uploadedtotp = -1 w.uploadedtotp = -1
w.save() w.save()
@@ -74,10 +74,10 @@ def workout_strava_upload_view(request,id=0):
try: try:
thetoken = strava_open(request.user) thetoken = strava_open(request.user)
except NoTokenError: except NoTokenError: # pragma: no cover
return HttpResponseRedirect("/rowers/me/stravaauthorize/") return HttpResponseRedirect("/rowers/me/stravaauthorize/")
if (r.stravatoken == '') or (r.stravatoken is None): if (r.stravatoken == '') or (r.stravatoken is None): # pragma: no cover
s = "Token doesn't exist. Need to authorize" s = "Token doesn't exist. Need to authorize"
return HttpResponseRedirect("/rowers/me/stravaauthorize/") return HttpResponseRedirect("/rowers/me/stravaauthorize/")
else: else:
@@ -99,9 +99,9 @@ def workout_strava_upload_view(request,id=0):
if activity_type == 'match': if activity_type == 'match':
try: try:
activity_type = mytypes.stravamapping[w.workouttype] activity_type = mytypes.stravamapping[w.workouttype]
except KeyError: except KeyError: # pragma: no cover
activity_type = 'Ride' activity_type = 'Ride'
else: else: # pragma: no cover
try: try:
activity_type = mytypes.stravamapping[w.workouttype] activity_type = mytypes.stravamapping[w.workouttype]
except KeyError: except KeyError:
@@ -112,7 +112,7 @@ def workout_strava_upload_view(request,id=0):
r.stravatoken, r.stravatoken,
description=newnotes, description=newnotes,
activity_type=activity_type,quick=False) activity_type=activity_type,quick=False)
if res==0: if res==0: # pragma: no cover
messages.error(request,mes) messages.error(request,mes)
w.uploadedtostrava = -1 w.uploadedtostrava = -1
w.save() w.save()
@@ -132,13 +132,13 @@ def workout_strava_upload_view(request,id=0):
w.save() w.save()
try: try:
os.remove(tcxfile) os.remove(tcxfile)
except WindowsError: except WindowsError: # pragma: no cover
pass pass
url = reverse('workout_edit_view',kwargs={'id':w.id}) url = reverse('workout_edit_view',kwargs={'id':w.id})
messages.info(request,mes) messages.info(request,mes)
except: except: # pragma: no cover
with open("media/stravaerrors.log","a") as errorlog: with open("media/stravaerrors.log","a") as errorlog:
errorstring = str(sys.exc_info()[0]) errorstring = str(sys.exc_info()[0])
timestr = strftime("%Y%m%d-%H%M%S") timestr = strftime("%Y%m%d-%H%M%S")
@@ -146,7 +146,7 @@ def workout_strava_upload_view(request,id=0):
errorlog.write("views.py line 826\r\n") errorlog.write("views.py line 826\r\n")
message = 'Error: '+errorstring message = 'Error: '+errorstring
messages.error(request,message) messages.error(request,message)
else: # No tcxfile else: # pragma: no cover # No tcxfile
message = "Strava Data error "+tcxmessg message = "Strava Data error "+tcxmessg
messages.error(request,message) messages.error(request,message)
w.uploadedtostrava = -1 w.uploadedtostrava = -1
@@ -164,7 +164,7 @@ def workout_strava_upload_view(request,id=0):
} }
) )
response = HttpResponseRedirect(url) response = HttpResponseRedirect(url)
except ActivityUploadFailed as e: except ActivityUploadFailed as e: # pragma: no cover
message = "Strava Upload error: %s" % e message = "Strava Upload error: %s" % e
messages.error(request,message) messages.error(request,message)
w.uploadedtostrava = -1 w.uploadedtostrava = -1
@@ -188,10 +188,10 @@ def workout_c2_upload_view(request,id=0):
try: try:
message,c2id = c2stuff.workout_c2_upload(request.user,w) message,c2id = c2stuff.workout_c2_upload(request.user,w)
except NoTokenError: except NoTokenError: # pragma: no cover
return HttpResponseRedirect("/rowers/me/c2authorize/") return HttpResponseRedirect("/rowers/me/c2authorize/")
if message and c2id <=0: if message and c2id <=0: # pragma: no cover
messages.error(request,message) messages.error(request,message)
elif message: elif message:
messages.info(request,message) messages.info(request,message)
@@ -216,14 +216,14 @@ def workout_runkeeper_upload_view(request,id=0):
try: try:
thetoken = runkeeper_open(r.user) thetoken = runkeeper_open(r.user)
except NoTokenError: except NoTokenError: # pragma: no cover
return HttpResponseRedirect("/rowers/me/runkeeperauthorize/") return HttpResponseRedirect("/rowers/me/runkeeperauthorize/")
# ready to upload. Hurray # ready to upload. Hurray
data = runkeeperstuff.createrunkeeperworkoutdata(w) data = runkeeperstuff.createrunkeeperworkoutdata(w)
if not data: if not data: # pragma: no cover
message = "Data error" message = "Data error"
messages.error(request,message) messages.error(request,message)
url = reverse(r.defaultlandingpage, url = reverse(r.defaultlandingpage,
@@ -242,7 +242,7 @@ def workout_runkeeper_upload_view(request,id=0):
response = requests.post(url,headers=headers,data=json.dumps(data,default=default)) response = requests.post(url,headers=headers,data=json.dumps(data,default=default))
# check for duplicate error first # check for duplicate error first
if (response.status_code == 409 ): if (response.status_code == 409 ): # pragma: no cover # pragma: no cover
message = "Duplicate error" message = "Duplicate error"
messages.error(request,message) messages.error(request,message)
w.uploadedtorunkeeper = -1 w.uploadedtorunkeeper = -1
@@ -255,7 +255,7 @@ def workout_runkeeper_upload_view(request,id=0):
kwargs={'id':encoder.encode_hex(w.id)}) kwargs={'id':encoder.encode_hex(w.id)})
return HttpResponseRedirect(url) return HttpResponseRedirect(url)
else: else: # pragma: no cover
s = response s = response
message = "Something went wrong in workout_runkeeper_upload_view: %s - %s" % (s.reason,s.text) message = "Something went wrong in workout_runkeeper_upload_view: %s - %s" % (s.reason,s.text)
messages.error(request,message) messages.error(request,message)
@@ -264,9 +264,9 @@ def workout_runkeeper_upload_view(request,id=0):
url = reverse(r.defaultlandingpage, url = reverse(r.defaultlandingpage,
kwargs = { kwargs = {
'id':encoder.encode_hex(w.id), 'id':encoder.encode_hex(w.id),
}) }) # pragma: no cover
return HttpResponseRedirect(url) return HttpResponseRedirect(url) # pragma: no cover
# Upload workout to Underarmour # Upload workout to Underarmour
@permission_required('workout.change_workout',fn=get_workout_by_opaqueid,raise_exception=True) @permission_required('workout.change_workout',fn=get_workout_by_opaqueid,raise_exception=True)
@@ -277,14 +277,14 @@ def workout_underarmour_upload_view(request,id=0):
try: try:
thetoken = underarmour_open(r.user) thetoken = underarmour_open(r.user)
except NoTokenError: except NoTokenError: # pragma: no cover
return HttpResponseRedirect("/rowers/me/underarmourauthorize/") return HttpResponseRedirect("/rowers/me/underarmourauthorize/")
# ready to upload. Hurray # ready to upload. Hurray
data = underarmourstuff.createunderarmourworkoutdata(w) data = underarmourstuff.createunderarmourworkoutdata(w)
if not data: if not data: # pragma: no cover
message = "Data error" message = "Data error"
messages.error(request,message) messages.error(request,message)
url = reverse(r.defaultlandingpage, url = reverse(r.defaultlandingpage,
@@ -305,7 +305,7 @@ def workout_underarmour_upload_view(request,id=0):
# check for duplicate error first # check for duplicate error first
if (response.status_code == 409 ): if (response.status_code == 409 ): # pragma: no cover # pragma: no cover
message = "Duplicate error" message = "Duplicate error"
messages.error(request,message) messages.error(request,message)
w.uploadedtounderarmour = -1 w.uploadedtounderarmour = -1
@@ -317,7 +317,7 @@ def workout_underarmour_upload_view(request,id=0):
url = reverse('workout_edit_view',kwargs={'id':encoder.encode_hex(w.id)}) url = reverse('workout_edit_view',kwargs={'id':encoder.encode_hex(w.id)})
return HttpResponseRedirect(url) return HttpResponseRedirect(url)
else: else: # pragma: no cover
s = response s = response
message = "Something went wrong in workout_underarmour_upload_view: %s " % s.reason message = "Something went wrong in workout_underarmour_upload_view: %s " % s.reason
messages.error(request,message) messages.error(request,message)
@@ -325,9 +325,9 @@ def workout_underarmour_upload_view(request,id=0):
url = reverse(r.defaultlandingpage, url = reverse(r.defaultlandingpage,
kwargs = { kwargs = {
'id':encoder.encode_hex(w.id), 'id':encoder.encode_hex(w.id),
}) }) # pragma: no cover
return HttpResponseRedirect(url) return HttpResponseRedirect(url) # pragma: no cover
# Upload workout to SportTracks # Upload workout to SportTracks
@permission_required('workout.change_workout',fn=get_workout_by_opaqueid) @permission_required('workout.change_workout',fn=get_workout_by_opaqueid)
@@ -339,14 +339,14 @@ def workout_sporttracks_upload_view(request,id=0):
try: try:
thetoken = sporttracks_open(r.user) thetoken = sporttracks_open(r.user)
except NoTokenError: except NoTokenError: # pragma: no cover
return HttpResponseRedirect("/rowers/me/sporttracksauthorize/") return HttpResponseRedirect("/rowers/me/sporttracksauthorize/")
data = sporttracksstuff.createsporttracksworkoutdata(w) data = sporttracksstuff.createsporttracksworkoutdata(w)
if not data: if not data: # pragma: no cover
message = "Data error" message = "Data error"
messages.error(request,message) messages.error(request,message)
url = reverse(r.defaultlandingpage, url = reverse(r.defaultlandingpage,
@@ -365,7 +365,7 @@ def workout_sporttracks_upload_view(request,id=0):
# check for duplicate error first # check for duplicate error first
if (response.status_code == 409 ): if (response.status_code == 409 ): # pragma: no cover
message = "Duplicate error" message = "Duplicate error"
messages.error(request,message) messages.error(request,message)
w.uploadedtosporttracks = -1 w.uploadedtosporttracks = -1
@@ -380,7 +380,7 @@ def workout_sporttracks_upload_view(request,id=0):
url = reverse('workout_edit_view',kwargs={'id':encoder.encode_hex(w.id)}) url = reverse('workout_edit_view',kwargs={'id':encoder.encode_hex(w.id)})
return HttpResponseRedirect(url) return HttpResponseRedirect(url)
else: else: # pragma: no cover
s = response s = response
message = "Something went wrong in workout_sporttracks_upload_view: %s" % s.reason message = "Something went wrong in workout_sporttracks_upload_view: %s" % s.reason
messages.error(request,message) messages.error(request,message)
@@ -388,14 +388,14 @@ def workout_sporttracks_upload_view(request,id=0):
url = reverse(r.defaultlandingpage, url = reverse(r.defaultlandingpage,
kwargs = { kwargs = {
'id':encoder.encode_hex(w.id), 'id':encoder.encode_hex(w.id),
}) }) # pragma: no cover
return HttpResponseRedirect(url) return HttpResponseRedirect(url) # pragma: no cover
# NK LiNK authorization # NK LiNK authorization
@login_required() @login_required()
def rower_nk_authorize(request): def rower_nk_authorize(request): # pragma: no cover
state = str(uuid4()) state = str(uuid4())
scope = "read" scope = "read"
params = { params = {
@@ -415,7 +415,7 @@ def rower_nk_authorize(request):
# Concept2 authorization # Concept2 authorization
@login_required() @login_required()
def rower_c2_authorize(request): def rower_c2_authorize(request): # pragma: no cover
# Generate a random string for the state parameter # Generate a random string for the state parameter
# Save it for use later to prevent xsrf attacks # Save it for use later to prevent xsrf attacks
@@ -430,7 +430,7 @@ def rower_c2_authorize(request):
# Garmin authorization # Garmin authorization
@login_required() @login_required()
def rower_garmin_authorize(request): def rower_garmin_authorize(request): # pragma: no cover
authorization_url,token,secret = garmin_stuff.garmin_authorize() authorization_url,token,secret = garmin_stuff.garmin_authorize()
request.session['garmin_owner_key'] = token request.session['garmin_owner_key'] = token
request.session['garmin_owner_secret'] = secret request.session['garmin_owner_secret'] = secret
@@ -438,7 +438,7 @@ def rower_garmin_authorize(request):
# Strava Authorization # Strava Authorization
@login_required() @login_required()
def rower_strava_authorize(request): def rower_strava_authorize(request): # pragma: no cover
# Generate a random string for the state parameter # Generate a random string for the state parameter
# Save it for use later to prevent xsrf attacks # Save it for use later to prevent xsrf attacks
@@ -455,7 +455,7 @@ def rower_strava_authorize(request):
# Polar Authorization # Polar Authorization
@login_required() @login_required()
def rower_polar_authorize(request): def rower_polar_authorize(request): # pragma: no cover
state = str(uuid4()) state = str(uuid4())
@@ -473,7 +473,7 @@ def rower_polar_authorize(request):
# Runkeeper authorization # Runkeeper authorization
@login_required() @login_required()
def rower_runkeeper_authorize(request): def rower_runkeeper_authorize(request): # pragma: no cover
# Generate a random string for the state parameter # Generate a random string for the state parameter
# Save it for use later to prevent xsrf attacks # Save it for use later to prevent xsrf attacks
@@ -491,7 +491,7 @@ def rower_runkeeper_authorize(request):
# SportTracks Authorization # SportTracks Authorization
@login_required() @login_required()
def rower_sporttracks_authorize(request): def rower_sporttracks_authorize(request): # pragma: no cover
# Generate a random string for the state parameter # Generate a random string for the state parameter
# Save it for use later to prevent xsrf attacks # Save it for use later to prevent xsrf attacks
@@ -509,7 +509,7 @@ def rower_sporttracks_authorize(request):
# Underarmour Authorization # Underarmour Authorization
@login_required() @login_required()
def rower_underarmour_authorize(request): def rower_underarmour_authorize(request): # pragma: no cover
# Generate a random string for the state parameter # Generate a random string for the state parameter
# Save it for use later to prevent xsrf attacks # Save it for use later to prevent xsrf attacks
@@ -526,7 +526,7 @@ def rower_underarmour_authorize(request):
# Underarmour Authorization # Underarmour Authorization
@login_required() @login_required()
def rower_rp3_authorize(request): def rower_rp3_authorize(request): # pragma: no cover
# Generate a random string for the state parameter # Generate a random string for the state parameter
# Save it for use later to prevent xsrf attacks # Save it for use later to prevent xsrf attacks
@@ -541,7 +541,7 @@ def rower_rp3_authorize(request):
# Underarmour Authorization # Underarmour Authorization
@login_required() @login_required()
def rower_tp_authorize(request): def rower_tp_authorize(request): # pragma: no cover
# Generate a random string for the state parameter # Generate a random string for the state parameter
# Save it for use later to prevent xsrf attacks # Save it for use later to prevent xsrf attacks
@@ -576,7 +576,7 @@ def rower_c2_token_refresh(request):
successmessage = "Tokens refreshed. Good to go" successmessage = "Tokens refreshed. Good to go"
messages.info(request,successmessage) messages.info(request,successmessage)
else: else: # pragma: no cover
message = "Something went wrong (refreshing tokens). Please reauthorize:" message = "Something went wrong (refreshing tokens). Please reauthorize:"
messages.error(request,message) messages.error(request,message)
@@ -677,7 +677,7 @@ def rower_process_callback(request):
try: try:
code = request.GET['code'] code = request.GET['code']
res = c2stuff.get_token(code) res = c2stuff.get_token(code)
except MultiValueDictKeyError: except MultiValueDictKeyError: # pragma: no cover
message = "The resource owner or authorization server denied the request" message = "The resource owner or authorization server denied the request"
messages.error(request,message) messages.error(request,message)
@@ -686,7 +686,7 @@ def rower_process_callback(request):
return HttpResponseRedirect(url) return HttpResponseRedirect(url)
access_token = res[0] access_token = res[0]
if access_token == 0: if access_token == 0: # pragma: no cover
message = res[1] message = res[1]
message += ' Contact info@rowsandall.com if this behavior persists.' message += ' Contact info@rowsandall.com if this behavior persists.'
messages.error(request,message) messages.error(request,message)
@@ -716,12 +716,12 @@ def rower_process_callback(request):
# dummy # dummy
@login_required() @login_required()
def rower_process_twittercallback(request): def rower_process_twittercallback(request): # pragma: no cover
return "dummy" return "dummy"
# Process Polar Callback # Process Polar Callback
@login_required() @login_required()
def rower_process_polarcallback(request): def rower_process_polarcallback(request): # pragma: no cover
try: try:
code = request.GET['code'] code = request.GET['code']
except MultiValueDictKeyError: except MultiValueDictKeyError:
@@ -754,7 +754,7 @@ def rower_process_polarcallback(request):
# process Garmin callback # process Garmin callback
@login_required() @login_required()
def rower_process_garmincallback(request): def rower_process_garmincallback(request): # pragma: no cover
r = getrower(request.user) r = getrower(request.user)
absoluteurl = request.build_absolute_uri() absoluteurl = request.build_absolute_uri()
@@ -775,7 +775,7 @@ def rower_process_garmincallback(request):
# Process NK Callback # Process NK Callback
@login_required() @login_required()
def rower_process_nkcallback(request): def rower_process_nkcallback(request): # pragma: no cover
# do stuff # do stuff
try: try:
code = request.GET.get('code',None) code = request.GET.get('code',None)
@@ -819,7 +819,7 @@ def rower_process_nkcallback(request):
def workout_getnkworkout_all(request): def workout_getnkworkout_all(request):
try: try:
thetoken = nk_open(request.user) thetoken = nk_open(request.user)
except NoTokenError: except NoTokenError: # pragma: no cover
return HttpResponseRedirect("rower_nk_authorize") return HttpResponseRedirect("rower_nk_authorize")
r = getrequestrower(request) r = getrequestrower(request)
@@ -828,7 +828,7 @@ def workout_getnkworkout_all(request):
if result: if result:
messages.info(request,"Your NK workouts will be imported in the coming few minutes") messages.info(request,"Your NK workouts will be imported in the coming few minutes")
else: else: # pragma: no cover
messages.error(request,"Your NK workouts import failed") messages.error(request,"Your NK workouts import failed")
url = reverse('workouts_view') url = reverse('workouts_view')
@@ -840,12 +840,12 @@ def workout_nkimport_view(request,userid=0,after=0,before=0):
r = getrequestrower(request,userid=userid) r = getrequestrower(request,userid=userid)
try: try:
thetoken = nk_open(request.user) thetoken = nk_open(request.user)
except NoTokenError: except NoTokenError: # pragma: no cover
return HttpResponseRedirect("/rowers/me/nkauthorize/") return HttpResponseRedirect("/rowers/me/nkauthorize/")
res = nkstuff.get_nk_workout_list(request.user,before=before,after=after) res = nkstuff.get_nk_workout_list(request.user,before=before,after=after)
if (res.status_code != 200): if (res.status_code != 200): # pragma: no cover
if (res.status_code == 401): if (res.status_code == 401):
r = getrower(request.user) r = getrower(request.user)
if (r.stravatoken == '') or (r.stravatoken is None): if (r.stravatoken == '') or (r.stravatoken is None):
@@ -869,7 +869,7 @@ def workout_nkimport_view(request,userid=0,after=0,before=0):
with open('nkblocked.json','r') as nkblocked: with open('nkblocked.json','r') as nkblocked:
jsondata = json.load(nkblocked) jsondata = json.load(nkblocked)
parkedids = jsondata['ids'] parkedids = jsondata['ids']
except FileNotFoundError: except FileNotFoundError: # pragma: no cover
pass pass
knownnkids = uniqify(knownnkids+tombstones+parkedids) knownnkids = uniqify(knownnkids+tombstones+parkedids)
@@ -893,7 +893,7 @@ def workout_nkimport_view(request,userid=0,after=0,before=0):
n = item['name'] n = item['name']
if i in knownnkids: if i in knownnkids:
nnn = '' nnn = ''
else: else: # pragma: no cover
nnn = 'NEW' nnn = 'NEW'
ttot = str(datetime.timedelta(seconds=int(float(item['elapsedTime'])/1000.))) ttot = str(datetime.timedelta(seconds=int(float(item['elapsedTime'])/1000.)))
s = arrow.get(item['startTime'],tzinfo=r.defaulttimezone).format(arrow.FORMAT_RFC850) s = arrow.get(item['startTime'],tzinfo=r.defaulttimezone).format(arrow.FORMAT_RFC850)
@@ -931,10 +931,10 @@ def rower_process_stravacallback(request):
try: try:
code = request.GET['code'] code = request.GET['code']
scope = request.GET['scope'] scope = request.GET['scope']
except MultiValueDictKeyError: except MultiValueDictKeyError:# pragma: no cover
try: try:
message = request.GET['error'] message = request.GET['error']
except MultiValueDictKeyError: except MultiValueDictKeyError:# pragma: no cover
message = "access error" message = "access error"
messages.error(request,message) messages.error(request,message)
@@ -964,7 +964,7 @@ def rower_process_stravacallback(request):
messages.info(request,successmessage) messages.info(request,successmessage)
url = reverse('rower_exportsettings_view') url = reverse('rower_exportsettings_view')
return HttpResponseRedirect(url) return HttpResponseRedirect(url)
else: else:# pragma: no cover
message = "Something went wrong with the Strava authorization" message = "Something went wrong with the Strava authorization"
messages.error(request,message) messages.error(request,message)
url = reverse('rower_exportsettings_view') url = reverse('rower_exportsettings_view')
@@ -979,7 +979,7 @@ def rower_process_runkeepercallback(request):
res = runkeeperstuff.get_token(code) res = runkeeperstuff.get_token(code)
access_token = res[0] access_token = res[0]
if access_token == 0: if access_token == 0:# pragma: no cover
messages.error(request,"Something went wrong importing the token") messages.error(request,"Something went wrong importing the token")
url = reverse('workouts_view') url = reverse('workouts_view')
@@ -1004,7 +1004,7 @@ def rower_process_runkeepercallback(request):
def rower_process_sporttrackscallback(request): def rower_process_sporttrackscallback(request):
try: try:
code = request.GET['code'] code = request.GET['code']
except: except:# pragma: no cover
messages.error(request,"Sorry, something went wrong.") messages.error(request,"Sorry, something went wrong.")
url = reverse('rower_exportsettings_view') url = reverse('rower_exportsettings_view')
return HttpResponseRedirect(url) return HttpResponseRedirect(url)
@@ -1058,7 +1058,7 @@ def rower_process_underarmourcallback(request):
# Process RP3 callback # Process RP3 callback
@login_required() @login_required()
def rower_process_rp3callback(request): def rower_process_rp3callback(request): # pragma: no cover
try: try:
code = request.GET['code'] code = request.GET['code']
except MultiValueDictKeyError: except MultiValueDictKeyError:
@@ -1095,7 +1095,7 @@ def rower_process_rp3callback(request):
def rower_process_tpcallback(request): def rower_process_tpcallback(request):
try: try:
code = request.GET['code'] code = request.GET['code']
except MultiValueDictKeyError: except MultiValueDictKeyError: # pragma: no cover
messages.error(request,"There was an error with the callback") messages.error(request,"There was an error with the callback")
try: try:
errormessage = request.GET['error'] errormessage = request.GET['error']
@@ -1128,7 +1128,7 @@ def rower_process_tpcallback(request):
# Process Own API callback - for API testing purposes # Process Own API callback - for API testing purposes
@login_required() @login_required()
def rower_process_testcallback(request): def rower_process_testcallback(request): # pragma: no cover
code = request.GET['code'] code = request.GET['code']
res = ownapistuff.get_token(code) res = ownapistuff.get_token(code)
@@ -1153,13 +1153,13 @@ def workout_rp3import_view(request,userid=0):
try: try:
thetoken = rp3stuff.rp3_open(request.user) thetoken = rp3stuff.rp3_open(request.user)
except NoTokenError: except NoTokenError: # pragma: no cover
url = reverse('rower_rp3_authorize') url = reverse('rower_rp3_authorize')
return HttpResponseRedirect(url) return HttpResponseRedirect(url)
res = rp3stuff.get_rp3_workout_list(request.user) res = rp3stuff.get_rp3_workout_list(request.user)
if (res.status_code != 200): if (res.status_code != 200): # pragma: no cover
if (res.status_code == 401): if (res.status_code == 401):
r = getrower(request.user) r = getrower(request.user)
if (r.stravatoken == '') or (r.stravatoken is None): if (r.stravatoken == '') or (r.stravatoken is None):
@@ -1185,7 +1185,7 @@ def workout_rp3import_view(request,userid=0):
for key,data in workouts_list.iterrows(): for key,data in workouts_list.iterrows():
i = data['id'] i = data['id']
if i in knownrp3ids: if i in knownrp3ids: # pragma: no cover
nnn = '' nnn = ''
else: else:
nnn = 'NEW' nnn = 'NEW'
@@ -1229,14 +1229,14 @@ def workout_stravaimport_view(request,message="",userid=0):
# messages.info(request,"You cannot import other people's workouts from Strava") # 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: # pragma: no cover
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)
if (res.status_code != 200): if (res.status_code != 200): # pragma: no cover
if (res.status_code == 401): if (res.status_code == 401):
r = getrower(request.user) r = getrower(request.user)
if (r.stravatoken == '') or (r.stravatoken is None): if (r.stravatoken == '') or (r.stravatoken is None):
@@ -1258,7 +1258,7 @@ def workout_stravaimport_view(request,message="",userid=0):
wfailed = Workout.objects.filter(user=r,uploadedtostrava=-1) wfailed = Workout.objects.filter(user=r,uploadedtostrava=-1)
for w in wfailed: for w in wfailed: # pragma: no cover
for item in stravadata: for item in stravadata:
elapsed_time = item['elapsed_time'] elapsed_time = item['elapsed_time']
start_date = item['start_date'] start_date = item['start_date']
@@ -1282,7 +1282,7 @@ def workout_stravaimport_view(request,message="",userid=0):
for item in res.json(): for item in res.json():
d = int(float(item['distance'])) d = int(float(item['distance']))
i = item['id'] i = item['id']
if i in knownstravaids: if i in knownstravaids: # pragma: no cover
nnn = '' nnn = ''
else: else:
nnn = 'NEW' nnn = 'NEW'
@@ -1317,7 +1317,7 @@ def workout_stravaimport_view(request,message="",userid=0):
'teams':get_my_teams(request.user), 'teams':get_my_teams(request.user),
}) })
return HttpResponse(res) return HttpResponse(res) # pragma: no cover
# for Strava webhook request validation # for Strava webhook request validation
@csrf_exempt @csrf_exempt
@@ -1481,7 +1481,7 @@ def strava_webhook_view(request):
# For push notifications from Garmin # For push notifications from Garmin
@csrf_exempt @csrf_exempt
def garmin_summaries_view(request): def garmin_summaries_view(request): # pragma: no cover
if request.method != 'POST': if request.method != 'POST':
return HttpResponse(status=200) return HttpResponse(status=200)
@@ -1504,7 +1504,7 @@ def garmin_summaries_view(request):
return HttpResponse(status=200) return HttpResponse(status=200)
@csrf_exempt @csrf_exempt
def garmin_newfiles_ping(request): def garmin_newfiles_ping(request): # pragma: no cover
t = time.localtime() t = time.localtime()
timestamp = time.strftime('%b-%d-%Y_%H%M', t) timestamp = time.strftime('%b-%d-%Y_%H%M', t)
@@ -1528,7 +1528,7 @@ def garmin_newfiles_ping(request):
except KeyError: except KeyError:
pass pass
return HttpResponse(status=200) return HttpResponse(status=200) # pragma: no cover
@csrf_exempt @csrf_exempt
def garmin_deregistration_view(request): def garmin_deregistration_view(request):
@@ -1544,16 +1544,16 @@ def garmin_deregistration_view(request):
r = Rower.objects.get(garmintoken=garmintoken) r = Rower.objects.get(garmintoken=garmintoken)
r.garmintoken = '' r.garmintoken = ''
r.save() r.save()
except Rower.DoesNotExist: except Rower.DoesNotExist: # pragma: no cover
pass pass
except KeyError: except KeyError: # pragma: no cover
pass pass
return HttpResponse(status=200) return HttpResponse(status=200)
@csrf_exempt @csrf_exempt
def garmin_details_view(request): def garmin_details_view(request):
if request.method != 'POST': if request.method != 'POST': # pragma: no cover
return HttpResponse(status=200) return HttpResponse(status=200)
t = time.localtime() t = time.localtime()
@@ -1577,12 +1577,12 @@ def workout_runkeeperimport_view(request,message="",userid=0):
if (r.runkeepertoken == '') or (r.runkeepertoken is None): if (r.runkeepertoken == '') or (r.runkeepertoken is None):
s = "Token doesn't exist. Need to authorize" s = "Token doesn't exist. Need to authorize"
return HttpResponseRedirect("/rowers/me/runkeeperauthorize/") return HttpResponseRedirect("/rowers/me/runkeeperauthorize/")
message = "Something went wrong in workout_runkeeperimport_view" message = "Something went wrong in workout_runkeeperimport_view" # pragma: no cover
messages.error(request,message) messages.error(request,message) # pragma: no cover
if settings.DEBUG: if settings.DEBUG: # pragma: no cover
return HttpResponse(res) return HttpResponse(res)
else: else: # pragma: no cover
url = reverse('workouts_view') url = reverse('workouts_view')
return HttpResponseRedirect(url) return HttpResponseRedirect(url)
@@ -1620,7 +1620,7 @@ def workout_runkeeperimport_view(request,message="",userid=0):
'teams':get_my_teams(request.user), 'teams':get_my_teams(request.user),
}) })
return HttpResponse(res) return HttpResponse(res) # pragma: no cover
# The page where you select which RunKeeper workout to import # The page where you select which RunKeeper workout to import
@login_required() @login_required()
@@ -1638,7 +1638,7 @@ def workout_underarmourimport_view(request,message="",userid=0):
n = item['name'] n = item['name']
try: try:
d = item['aggregates']['distance_total'] d = item['aggregates']['distance_total']
except KeyError: except KeyError: # pragma: no cover
d = 0 d = 0
try: try:
ttot = item['aggregates']['active_time_total'] ttot = item['aggregates']['active_time_total']
@@ -1671,12 +1671,12 @@ def workout_underarmourimport_view(request,message="",userid=0):
'teams':get_my_teams(request.user), 'teams':get_my_teams(request.user),
}) })
return HttpResponse(res) return HttpResponse(res) # pragma: no cover
# the page where you select which Polar workout to Import # the page where you select which Polar workout to Import
@login_required() @login_required()
@permission_required('rower.is_coach',fn=get_user_by_userid,raise_exception=True) @permission_required('rower.is_coach',fn=get_user_by_userid,raise_exception=True)
def workout_polarimport_view(request,userid=0): def workout_polarimport_view(request,userid=0): # pragma: no cover
exercises = polarstuff.get_polar_workouts(request.user) exercises = polarstuff.get_polar_workouts(request.user)
workouts = [] workouts = []
@@ -1686,7 +1686,7 @@ def workout_polarimport_view(request,userid=0):
messages.error(request,'Not authorized. You need to connect to Polar first') messages.error(request,'Not authorized. You need to connect to Polar first')
url = reverse('workouts_view') url = reverse('workouts_view')
return HttpResponseRedirect(url) return HttpResponseRedirect(url)
except: except: # pragma: no cover
pass pass
for exercise in exercises: for exercise in exercises:
@@ -1744,11 +1744,11 @@ def workout_sporttracksimport_view(request,message="",userid=0):
if (r.sporttrackstoken == '') or (r.sporttrackstoken is None): if (r.sporttrackstoken == '') or (r.sporttrackstoken is None):
s = "Token doesn't exist. Need to authorize" s = "Token doesn't exist. Need to authorize"
return HttpResponseRedirect("/rowers/me/sporttracksauthorize/") return HttpResponseRedirect("/rowers/me/sporttracksauthorize/")
else: else: # pragma: no cover
return HttpResponseRedirect("/rowers/me/sporttracksrefresh/") return HttpResponseRedirect("/rowers/me/sporttracksrefresh/")
message = "Something went wrong in workout_sporttracksimport_view" message = "Something went wrong in workout_sporttracksimport_view" # pragma: no cover
messages.error(request,message) messages.error(request,message) # pragma: no cover
if settings.DEBUG: if settings.DEBUG: # pragma: no cover
return HttpResponse(res) return HttpResponse(res)
else: else:
url = reverse('workouts_view') url = reverse('workouts_view')
@@ -1764,7 +1764,7 @@ def workout_sporttracksimport_view(request,message="",userid=0):
for item in res.json()['items']: for item in res.json()['items']:
d = int(float(item['total_distance'])) d = int(float(item['total_distance']))
i = int(getidfromuri(item['uri'])) i = int(getidfromuri(item['uri']))
if i in knownstids: if i in knownstids: # pragma: no cover
nnn = '' nnn = ''
else: else:
nnn = 'NEW' nnn = 'NEW'
@@ -1802,10 +1802,10 @@ def workout_sporttracksimport_view(request,message="",userid=0):
# List of workouts on Concept2 logbook. This view only used for debugging # List of workouts on Concept2 logbook. This view only used for debugging
@login_required() @login_required()
def c2listdebug_view(request,page=1,message=""): def c2listdebug_view(request,page=1,message=""): # pragma: no cover
try: try:
thetoken = c2_open(request.user) thetoken = c2_open(request.user)
except NoTokenError: except NoTokenError: # pragma: no cover
return HttpResponseRedirect("/rowers/me/c2authorize/") return HttpResponseRedirect("/rowers/me/c2authorize/")
r = getrower(request.user) r = getrower(request.user)
@@ -1845,10 +1845,10 @@ def c2listdebug_view(request,page=1,message=""):
# Import all unknown workouts available on Concept2 logbook # Import all unknown workouts available on Concept2 logbook
@login_required() @login_required()
def workout_getc2workout_all(request,page=1,message=""): def workout_getc2workout_all(request,page=1,message=""): # pragma: no cover
try: try:
thetoken = c2_open(request.user) thetoken = c2_open(request.user)
except NoTokenError: except NoTokenError: # pragma: no cover
return HttpResponseRedirect("/rowers/me/c2authorize/") return HttpResponseRedirect("/rowers/me/c2authorize/")
r = getrequestrower(request) r = getrequestrower(request)
@@ -1864,10 +1864,10 @@ def workout_getc2workout_all(request,page=1,message=""):
return HttpResponseRedirect(url) return HttpResponseRedirect(url)
@login_required() @login_required()
def workout_getrp3workout_all(request): def workout_getrp3workout_all(request): # pragma: no cover
try: try:
thetoken = rp3_open(request.user) thetoken = rp3_open(request.user)
except NoTokenError: except NoTokenError: # pragma: no cover
return HttpResponseRedirect("/rowers/me/rp3authorize/") return HttpResponseRedirect("/rowers/me/rp3authorize/")
r = getrequestrower(request) r = getrequestrower(request)
@@ -1891,12 +1891,12 @@ def workout_c2import_view(request,page=1,userid=0,message=""):
try: try:
thetoken = c2_open(request.user) thetoken = c2_open(request.user)
except NoTokenError: except NoTokenError: # pragma: no cover
return HttpResponseRedirect("/rowers/me/c2authorize/") return HttpResponseRedirect("/rowers/me/c2authorize/")
res = c2stuff.get_c2_workout_list(request.user,page=page) res = c2stuff.get_c2_workout_list(request.user,page=page)
if (res.status_code != 200): if (res.status_code != 200): # pragma: no cover
message = "Something went wrong in workout_c2import_view (C2 token refresh)" message = "Something went wrong in workout_c2import_view (C2 token refresh)"
messages.error(request,message) messages.error(request,message)
url = reverse('workouts_view') url = reverse('workouts_view')
@@ -1915,7 +1915,7 @@ def workout_c2import_view(request,page=1,userid=0,message=""):
with open('c2blocked.json','r') as c2blocked: with open('c2blocked.json','r') as c2blocked:
jsondata = json.load(c2blocked) jsondata = json.load(c2blocked)
parkedids = jsondata['ids'] parkedids = jsondata['ids']
except FileNotFoundError: except FileNotFoundError: # pragma: no cover
pass pass
knownc2ids = uniqify(knownc2ids+tombstones+parkedids) knownc2ids = uniqify(knownc2ids+tombstones+parkedids)
@@ -1931,7 +1931,7 @@ def workout_c2import_view(request,page=1,userid=0,message=""):
c = item['comments'] c = item['comments']
if i in knownc2ids: if i in knownc2ids:
nnn = '' nnn = ''
else: else: # pragma: no cover
nnn = 'NEW' nnn = 'NEW'
keys = ['id','distance','duration','starttime','rowtype','source','comment','new'] keys = ['id','distance','duration','starttime','rowtype','source','comment','new']
values = [i,d,ttot,s,r,s2,c,nnn] values = [i,d,ttot,s,r,s2,c,nnn]
@@ -2005,12 +2005,12 @@ def workout_getimportview(request,externalid,source = 'c2',do_async=False):
data,strokedata = importsources[source].get_workout(request.user,externalid, data,strokedata = importsources[source].get_workout(request.user,externalid,
do_async=do_async) do_async=do_async)
if do_async: if do_async: # pragma: no cover
messages.info(request,"Your workout will be imported in the background") messages.info(request,"Your workout will be imported in the background")
url = reverse('workouts_view') url = reverse('workouts_view')
return HttpResponseRedirect(url) return HttpResponseRedirect(url)
if not data: if not data: # pragma: no cover
messages.error(request,"No strokedata received") messages.error(request,"No strokedata received")
url = reverse('workouts_view') url = reverse('workouts_view')
@@ -2033,7 +2033,7 @@ def workout_getimportview(request,externalid,source = 'c2',do_async=False):
pass pass
if strokedata.empty: if strokedata.empty: # pragma: no cover
distance = data['distance'] distance = data['distance']
c2id = data['id'] c2id = data['id']
workouttype = mytypes.c2mappinginv[data['type']] workouttype = mytypes.c2mappinginv[data['type']]
@@ -2106,7 +2106,7 @@ def workout_getimportview(request,externalid,source = 'c2',do_async=False):
w = get_workout(encoder.encode_hex(id)) w = get_workout(encoder.encode_hex(id))
if 'workout' in data: if 'workout' in data: # pragma: no cover
if 'splits' in data['workout']: if 'splits' in data['workout']:
splitdata = data['workout']['splits'] splitdata = data['workout']['splits']
elif 'intervals' in data['workout']: elif 'intervals' in data['workout']:
@@ -2117,7 +2117,7 @@ def workout_getimportview(request,externalid,source = 'c2',do_async=False):
splitdata = False splitdata = False
# splitdata (only for C2) # splitdata (only for C2)
if splitdata: if splitdata: # pragma: no cover
w.summary,sa,results = c2stuff.summaryfromsplitdata(splitdata,data,w.csvfilename,workouttype=workouttype) w.summary,sa,results = c2stuff.summaryfromsplitdata(splitdata,data,w.csvfilename,workouttype=workouttype)
w.save() w.save()
@@ -2142,20 +2142,20 @@ def workout_getimportview(request,externalid,source = 'c2',do_async=False):
w.uploadedtostrava = externalid w.uploadedtostrava = externalid
elif source == 'c2': elif source == 'c2':
w.uploadedtoc2 = externalid w.uploadedtoc2 = externalid
elif source == 'polar': elif source == 'polar': # pragma: no cover
w.uploadedtopolar = externalid w.uploadedtopolar = externalid
elif source == 'runkeeper': elif source == 'runkeeper':
w.uploadedtorunkeeper = externalid w.uploadedtorunkeeper = externalid
elif source == 'sporttracks': elif source == 'sporttracks':
w.uploadedtosporttracks = externalid w.uploadedtosporttracks = externalid
elif source == 'trainingpeaks': elif source == 'trainingpeaks': # pragma: no cover
w.uploadedtotp = externalid w.uploadedtotp = externalid
elif source == 'underarmour': elif source == 'underarmour':
w.uploadedtounderarmour = externalid w.uploadedtounderarmour = externalid
w.save() w.save()
if message: if message: # pragma: no cover
messages.error(request,message) messages.error(request,message)
r = getrower(request.user) r = getrower(request.user)
@@ -2206,7 +2206,7 @@ def workout_getsporttracksworkout_all(request):
def workout_getstravaworkout_all(request): def workout_getstravaworkout_all(request):
r = getrower(request.user) r = getrower(request.user)
res = stravastuff.get_strava_workouts(r) res = stravastuff.get_strava_workouts(r)
if res == 1: if res == 1: # pragma: no cover
messages.info(request,"Your workouts are being imported and should appear on the site in the next 15 minutes") messages.info(request,"Your workouts are being imported and should appear on the site in the next 15 minutes")
else: else:
messages.error(request,"Couldn't import Strava workouts ") messages.error(request,"Couldn't import Strava workouts ")
@@ -2217,7 +2217,7 @@ def workout_getstravaworkout_all(request):
# Imports all new workouts from SportTracks # Imports all new workouts from SportTracks
@login_required() @login_required()
def workout_getstravaworkout_next(request): def workout_getstravaworkout_next(request): # pragma: no cover
r = Rower.objects.get(user=request.user) r = Rower.objects.get(user=request.user)

View File

@@ -1192,7 +1192,7 @@ def plannedsession_teamedit_view(request,
url = reverse('plannedsessions_view') url = reverse('plannedsessions_view')
if "_continue" in request.POST: if "_continue" in request.POST: # pragma: no cover
url = reverse(plannedsession_edit_view, url = reverse(plannedsession_edit_view,
kwargs={ kwargs={
'id':int(ps.id), 'id':int(ps.id),
@@ -1648,10 +1648,10 @@ def plannedsessions_manage_view(request,userid=0,
ps = PlannedSession.objects.get(id=ps_form.cleaned_data['plannedsession']) ps = PlannedSession.objects.get(id=ps_form.cleaned_data['plannedsession'])
if w_form.is_valid(): if w_form.is_valid():
selectedworkouts = w_form.cleaned_data['workouts'] selectedworkouts = w_form.cleaned_data['workouts']
else: else: # pragma: no cover
selectedworkouts = [] selectedworkouts = []
if len(selectedworkouts)==0: if len(selectedworkouts)==0: # pragma: no cover
for w in ws: for w in ws:
remove_workout_plannedsession(w,ps) remove_workout_plannedsession(w,ps)
@@ -1664,7 +1664,7 @@ def plannedsessions_manage_view(request,userid=0,
result,comments,errors = add_workouts_plannedsession(workouts,ps,r) result,comments,errors = add_workouts_plannedsession(workouts,ps,r)
for c in comments: for c in comments:
messages.info(request,c) messages.info(request,c)
for er in errors: for er in errors: # pragma: no cover
messages.error(request,er) messages.error(request,er)
@@ -2477,7 +2477,7 @@ class PlannedSessionDelete(DeleteView):
def rower_view_instantplan(request,id='',userid=0): def rower_view_instantplan(request,id='',userid=0):
r = getrequestrower(request,userid=userid) r = getrequestrower(request,userid=userid)
if not id: if not id: # pragma: no cover
raise Http404("Plan does not exist") raise Http404("Plan does not exist")
plan = InstantPlan.objects.get(uuid=id) plan = InstantPlan.objects.get(uuid=id)
@@ -2488,7 +2488,7 @@ def rower_view_instantplan(request,id='',userid=0):
headers = {'Authorization':authorizationstring} headers = {'Authorization':authorizationstring}
response = requests.get(url=url,headers=headers) response = requests.get(url=url,headers=headers)
if response.status_code != 200: if response.status_code != 200: # pragma: no cover
messages.error(request,"Could not connect to the training plan server") messages.error(request,"Could not connect to the training plan server")
return HttpResponseRedirect(reverse('rower_select_instantplan')) return HttpResponseRedirect(reverse('rower_select_instantplan'))
@@ -2520,7 +2520,7 @@ def rower_view_instantplan(request,id='',userid=0):
).order_by("-date") ).order_by("-date")
if request.method == 'POST' and not request.user.is_anonymous: if request.method == 'POST' and not request.user.is_anonymous:
if not can_plan(request.user): if not can_plan(request.user): # pragma: no cover
messages.error(request,'You must be on a <a href="/rowers/paidplans">paid plan</a> to use this functionality') messages.error(request,'You must be on a <a href="/rowers/paidplans">paid plan</a> to use this functionality')
url = reverse('rower_view_instantplan',kwargs={ url = reverse('rower_view_instantplan',kwargs={
'id':id, 'id':id,
@@ -2534,11 +2534,11 @@ def rower_view_instantplan(request,id='',userid=0):
name = form.cleaned_data['name'] name = form.cleaned_data['name']
try: try:
targetid = form.cleaned_data['target'] targetid = form.cleaned_data['target']
if targetid != '': if targetid != '': # pragma: no cover
target = TrainingTarget.objects.get(id=int(targetid)) target = TrainingTarget.objects.get(id=int(targetid))
else: else:
target = None target = None
except KeyError: except KeyError: # pragma: no cover
try: try:
targetid = request.POST['target'] targetid = request.POST['target']
if targetid != '': if targetid != '':
@@ -2553,12 +2553,12 @@ def rower_view_instantplan(request,id='',userid=0):
datechoice = form.cleaned_data['datechoice'] datechoice = form.cleaned_data['datechoice']
status = True status = True
if target and datechoice == 'target': if target and datechoice == 'target': # pragma: no cover
enddate = target.date enddate = target.date
startdate = enddate-datetime.timedelta(days=plan.duration) startdate = enddate-datetime.timedelta(days=plan.duration)
elif datechoice == 'startdate': elif datechoice == 'startdate':
enddate = startdate+datetime.timedelta(days=plan.duration) enddate = startdate+datetime.timedelta(days=plan.duration)
else: else: # pragma: no cover
startdate = enddate-datetime.timedelta(days=plan.duration) startdate = enddate-datetime.timedelta(days=plan.duration)
@@ -2585,7 +2585,7 @@ def rower_view_instantplan(request,id='',userid=0):
elif not request.user.is_anonymous: elif not request.user.is_anonymous:
form = InstantPlanSelectForm(targets=targets,instantplan=plan,initial={'datechoice':'startdate'}) form = InstantPlanSelectForm(targets=targets,instantplan=plan,initial={'datechoice':'startdate'})
else: else: # pragma: no cover
form = None form = None
breadcrumbs = [ breadcrumbs = [
@@ -2632,7 +2632,7 @@ def remove_groupsession_view(request,id=0):
if res: if res:
messages.info(request,"We have removed you from this group session") messages.info(request,"We have removed you from this group session")
else: else: # pragma: no cover
messages.error(request,"For some reason we could not remove you from this group session") messages.error(request,"For some reason we could not remove you from this group session")
url = reverse('plannedsessions_view') url = reverse('plannedsessions_view')
@@ -2641,12 +2641,12 @@ def remove_groupsession_view(request,id=0):
@login_required() @login_required()
def add_instantplan_view(request): def add_instantplan_view(request):
if not request.user.is_staff: if not request.user.is_staff: # pragma: no cover
raise PermissionDenied("Not Allowed") raise PermissionDenied("Not Allowed")
r = getrequestrower(request) r = getrequestrower(request)
if request.method == 'POST': if request.method == 'POST': # pragma: no cover
form = InstantPlanForm(request.POST,request.FILES) form = InstantPlanForm(request.POST,request.FILES)
if form.is_valid(): if form.is_valid():
ip = form.save(commit=False) ip = form.save(commit=False)
@@ -2764,9 +2764,9 @@ def rower_create_trainingplan(request,id=0):
targetid = request.POST['target'] targetid = request.POST['target']
if targetid != '': if targetid != '':
target = TrainingTarget.objects.get(id=int(targetid)) target = TrainingTarget.objects.get(id=int(targetid))
else: else: # pragma: no cover
target = None target = None
except KeyError: except KeyError: # pragma: no cover
target = None target = None
startdate = form.cleaned_data['startdate'] startdate = form.cleaned_data['startdate']
status = form.cleaned_data['status'] status = form.cleaned_data['status']
@@ -2814,7 +2814,7 @@ def rower_create_trainingplan(request,id=0):
status=True, status=True,
).order_by("-startdate") ).order_by("-startdate")
for p in plans_to_deactivate: for p in plans_to_deactivate: # pragma: no cover
p.status = False p.status = False
p.save() p.save()
@@ -2863,18 +2863,6 @@ def rower_delete_trainingtarget(request,id=0):
return HttpResponseRedirect(url) return HttpResponseRedirect(url)
@user_passes_test(can_plan,login_url="/rowers/paidplans",
message="This functionality requires a Coach or Self-Coach plan",
redirect_field_name=None)
@permission_required('target.delete_plan',fn=get_plan_by_pk,raise_exception=True)
def rower_delete_trainingplan(request,id=0):
plan = get_object_or_404(TrainingPlan,pk=id)
plan.delete()
url = reverse(rower_create_trainingplan)
return HttpResponseRedirect(url)
class TrainingPlanDelete(DeleteView): class TrainingPlanDelete(DeleteView):
model = TrainingPlan model = TrainingPlan
template_name = 'trainingplan_delete.html' template_name = 'trainingplan_delete.html'
@@ -2882,12 +2870,12 @@ class TrainingPlanDelete(DeleteView):
def get_object(self, *args, **kwargs): def get_object(self, *args, **kwargs):
obj = super(TrainingPlanDelete, self).get_object(*args, **kwargs) obj = super(TrainingPlanDelete, self).get_object(*args, **kwargs)
if not can_delete_plan(self.request.user,obj): if not can_delete_plan(self.request.user,obj): # pragma: no cover
raise PermissionDenied('You are not allowed to delete this training plan') raise PermissionDenied('You are not allowed to delete this training plan')
return obj return obj
class MicroCycleDelete(DeleteView): class MicroCycleDelete(DeleteView): # pragma: no cover
model = TrainingMicroCycle model = TrainingMicroCycle
template_name = 'trainingplan_delete.html' template_name = 'trainingplan_delete.html'
@@ -2953,7 +2941,7 @@ class MicroCycleDelete(DeleteView):
return obj return obj
class MesoCycleDelete(DeleteView): class MesoCycleDelete(DeleteView): # pragma: no cover
model = TrainingMesoCycle model = TrainingMesoCycle
template_name = 'trainingplan_delete.html' template_name = 'trainingplan_delete.html'
@@ -3016,7 +3004,7 @@ class MesoCycleDelete(DeleteView):
return obj return obj
class MacroCycleDelete(DeleteView): class MacroCycleDelete(DeleteView): # pragma: no cover
model = TrainingMacroCycle model = TrainingMacroCycle
template_name = 'trainingplan_delete.html' template_name = 'trainingplan_delete.html'
@@ -3085,13 +3073,13 @@ def rower_trainingplan_execution_view(request,
if int(id)>0: if int(id)>0:
try: try:
plan = TrainingPlan.objects.get(id=id) plan = TrainingPlan.objects.get(id=id)
except TrainingPlan.DoesNotExist: except TrainingPlan.DoesNotExist: # pragma: no cover
raise Http404("Training Plan Does Not Exist") raise Http404("Training Plan Does Not Exist")
if not is_coach_user(request.user,plan.manager.user): if not is_coach_user(request.user,plan.manager.user): # pragma: no cover
if request.user.rower not in plan.rowers.all(): if request.user.rower not in plan.rowers.all():
raise PermissionDenied("Access denied") raise PermissionDenied("Access denied")
if not startdate or not enddate: if not startdate or not enddate: # pragma: no cover
if int(id)>0: if int(id)>0:
startdate = plan.startdate startdate = plan.startdate
enddate = plan.enddate enddate = plan.enddate
@@ -3103,12 +3091,12 @@ def rower_trainingplan_execution_view(request,
if int(id)>0: if int(id)>0:
data,message = get_execution_report(r,startdate,enddate,plan=plan) data,message = get_execution_report(r,startdate,enddate,plan=plan)
else: else: # pragma: no cover
data,message = get_execution_report(r,startdate,enddate) data,message = get_execution_report(r,startdate,enddate)
if not data.empty: if not data.empty:
script, div = interactive_planchart(data,startdate,enddate) script, div = interactive_planchart(data,startdate,enddate)
else: else: # pragma: no cover
script = '' script = ''
div = '' div = ''
messages.error(request,'The plan does not cover this time range') messages.error(request,'The plan does not cover this time range')
@@ -3133,7 +3121,7 @@ def rower_trainingplan_execution_view(request,
'name': 'Execution' 'name': 'Execution'
} }
] ]
else: else: # pragma: no cover
breadcrumbs = [ breadcrumbs = [
{ {
'url':reverse(plannedsessions_view, 'url':reverse(plannedsessions_view,
@@ -3224,7 +3212,7 @@ def rower_trainingplan_view(request,
try: try:
thismicro = get_todays_micro(plan,thedate=startdate) thismicro = get_todays_micro(plan,thedate=startdate)
thismicroid = thismicro.pk thismicroid = thismicro.pk
except AttributeError: except AttributeError: # pragma: no cover
thismicroid = None thismicroid = None
@@ -3242,7 +3230,7 @@ def rower_trainingplan_view(request,
} }
) )
class TrainingMacroCycleUpdate(UpdateView): class TrainingMacroCycleUpdate(UpdateView): # pragma: no cover
model = TrainingMacroCycle model = TrainingMacroCycle
template_name = 'trainingplan_edit.html' template_name = 'trainingplan_edit.html'
form_class = TrainingMacroCycleForm form_class = TrainingMacroCycleForm
@@ -3307,7 +3295,7 @@ class TrainingMacroCycleUpdate(UpdateView):
obj.save() obj.save()
return obj return obj
class TrainingMesoCycleUpdate(UpdateView): class TrainingMesoCycleUpdate(UpdateView): # pragma: no cover
model = TrainingMesoCycle model = TrainingMesoCycle
template_name = 'trainingplan_edit.html' template_name = 'trainingplan_edit.html'
form_class = TrainingMesoCycleForm form_class = TrainingMesoCycleForm
@@ -3381,7 +3369,7 @@ class TrainingMesoCycleUpdate(UpdateView):
obj.plan.save() obj.plan.save()
return obj return obj
class TrainingMicroCycleUpdate(UpdateView): class TrainingMicroCycleUpdate(UpdateView): # pragma: no cover
model = TrainingMicroCycle model = TrainingMicroCycle
template_name = 'trainingplan_edit.html' template_name = 'trainingplan_edit.html'
form_class = TrainingMicroCycleForm form_class = TrainingMicroCycleForm
@@ -3460,7 +3448,7 @@ class TrainingMicroCycleUpdate(UpdateView):
obj.plan.save() obj.plan.save()
return obj return obj
class TrainingPlanUpdate(UpdateView): class TrainingPlanUpdate(UpdateView): # pragma: no cover
model = TrainingPlan model = TrainingPlan
template_name = 'trainingplan_edit.html' template_name = 'trainingplan_edit.html'
form_class = TrainingPlanForm form_class = TrainingPlanForm
@@ -3519,7 +3507,7 @@ class TrainingPlanUpdate(UpdateView):
return obj return obj
class TrainingTargetUpdate(UpdateView): class TrainingTargetUpdate(UpdateView): # pragma: no cover
model = TrainingTarget model = TrainingTarget
template_name = 'trainingplan_edit.html' template_name = 'trainingplan_edit.html'
form_class = TrainingTargetForm form_class = TrainingTargetForm
@@ -3575,7 +3563,7 @@ from rowers.utils import allsundays
message="This functionality requires a Coach or Self-Coach plan", message="This functionality requires a Coach or Self-Coach plan",
redirect_field_name=None) redirect_field_name=None)
@permission_required('cycle.change_cycle',fn=get_meso_by_pk,raise_exception=True) @permission_required('cycle.change_cycle',fn=get_meso_by_pk,raise_exception=True)
def planmesocyclebyweek(request,id=0,userid=0): def planmesocyclebyweek(request,id=0,userid=0): # pragma: no cover
cycle = get_object_or_404(TrainingMesoCycle,pk=id) cycle = get_object_or_404(TrainingMesoCycle,pk=id)
micros = TrainingMicroCycle.objects.filter(plan=cycle) micros = TrainingMicroCycle.objects.filter(plan=cycle)
@@ -3625,7 +3613,7 @@ from rowers.utils import allmonths
message="This functionality requires a Coach or Self-Coach plan", message="This functionality requires a Coach or Self-Coach plan",
redirect_field_name=None) redirect_field_name=None)
@permission_required('cycle.change_cycle',fn=get_macro_by_pk,raise_exception=True) @permission_required('cycle.change_cycle',fn=get_macro_by_pk,raise_exception=True)
def planmacrocyclebymonth(request,id=0,userid=0): def planmacrocyclebymonth(request,id=0,userid=0): # pragma: no cover
cycle = get_object_or_404(TrainingMacroCycle,pk=id) cycle = get_object_or_404(TrainingMacroCycle,pk=id)
mesos = TrainingMesoCycle.objects.filter(plan=cycle) mesos = TrainingMesoCycle.objects.filter(plan=cycle)