from __future__ import absolute_import from __future__ import division from __future__ import print_function from __future__ import unicode_literals from .statements import * from rowers.mytypes import rowtypes from rowers.utils import allmonths,allsundays, totaltime_sec_to_string from rowers.models import update_records from django.db import transaction nu = datetime.datetime.now() import datetime import pytz import polars as pl # interactive plots from rowers import interactiveplots from rowers import dataprep from rowers import tasks from rowers import plannedsessions from rowers.views.workoutviews import get_video_id import rowingdata from rowers.c2stuff import getagegrouprecord class OtherUnitTests(TestCase): def setUp(self): self.u = UserFactory() self.r = Rower.objects.create(user=self.u, birthdate=faker.profile()['birthdate'], gdproptin=True, ftpset=True,surveydone=True, gdproptindate=timezone.now(), defaulttimezone='US/Pacific', rowerplan='pro') # Test get_dates_timeperiod def test_get_dates_timeperiod(self): rq = RequestFactory().get('/rowers/plannedsessions/') get_response = MagicMock() middleware = SessionMiddleware(get_response) middleware.process_request(rq) # blanco should just run startdate,enddate = get_dates_timeperiod(rq,rower=self.r) # time should be midnight self.assertEqual(startdate.strftime('%H:%M:%S'),'00:00:00') # tzinfo should be present self.assertTrue(startdate.tzinfo is not None) # time zone should be US/Pacific self.assertTrue('US/Pacific' in str(startdate.tzinfo)) # now with dates startdatestring = '2021-09-26' enddatestring = '2021-10-02' startdate,enddate = get_dates_timeperiod(rq,startdatestring=startdatestring, enddatestring=enddatestring) # time should be midnight self.assertEqual(startdate.strftime('%H:%M:%S'),'00:00:00') # startdate and enddate should match self.assertEqual(startdate.strftime('%m-%d'),'09-26') self.assertEqual(enddate.strftime('%m-%d'),'10-02') # tzinfo should be present self.assertTrue(startdate.tzinfo is not None) # time zone should be US/Pacific self.assertTrue('UTC' in str(startdate.tzinfo)) # now with dates and rower startdatestring = '2021-09-26' enddatestring = '2021-10-02' startdate,enddate = get_dates_timeperiod(rq,startdatestring=startdatestring, enddatestring=enddatestring,rower=self.r) # time should be midnight self.assertEqual(startdate.strftime('%H:%M:%S'),'00:00:00') # startdate and enddate should match self.assertEqual(startdate.strftime('%m-%d'),'09-26') self.assertEqual(enddate.strftime('%m-%d'),'10-02') # tzinfo should be present self.assertTrue(startdate.tzinfo is not None) # time zone should be US/Pacific self.assertTrue('US/Pacific' in str(startdate.tzinfo)) def test_totaltime_sec_to_string(self): results = ( (0,"0:00"), (120,"2:00"), (3634.2,"1:00:34"), ) for duration, expected in results: self.assertEqual(totaltime_sec_to_string(duration, shorten=True), expected) results = ( (0,"00:00:00.0"), (120,"00:02:00.0"), (3634.2,"01:00:34.2"), ) for duration, expected in results: self.assertEqual(totaltime_sec_to_string(duration, shorten=False), expected) def test_summaryfromsplitdata(self): with open('rowers/tests/testdata/c2splits.json','r') as f: s = f.read() data = json.loads(s) splitdata = data['workout']['intervals'] summary = tasks.summaryfromsplitdata(splitdata,data,'aap.txt') self.assertEqual(len(summary),3) sums = summary[0] self.assertEqual(len(sums),631) def test_get_video_id(self): url1 = 'http://youtu.be/_lOT2p_FCvA' url2 = 'www.youtube.com/watch?v=_lOT2p_FCvA&feature=feedu' url3 = 'http://www.youtube.com/embed/_lOT2p_FCvA' url4 = 'http://www.youtube.com/v/_lOT2p_FCvA?version=3&hl=en_US' url5 = 'https://www.youtube.com/watch?v=rTHlyTphWP0&index=6&list=PLjeDyYvG6-40qawYNR4juzvSOg-ezZ2a6' url6 = 'youtube.com/watch?v=_lOT2p_FCvA' expected = '_lOT2p_FCvA' expected2 = 'rTHlyTphWP0' result = get_video_id(url1) self.assertEqual(result,expected) result = get_video_id(url2) self.assertEqual(result,expected) result = get_video_id(url3) self.assertEqual(result,expected) result = get_video_id(url4) self.assertEqual(result,expected) result = get_video_id(url5) self.assertEqual(result,expected2) result = get_video_id(url6) self.assertEqual(result,expected) class PlannedSessionTests(TestCase): def setUp(self): self.u = UserFactory() self.r = Rower.objects.create(user=self.u, birthdate=faker.profile()['birthdate'], gdproptin=True, ftpset=True,surveydone=True, gdproptindate=timezone.now(), rowerplan='pro') 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() self.u2 = UserFactory(username='testbasicuser') self.r2 = Rower.objects.create(user=self.u2, birthdate=faker.profile()['birthdate'], gdproptin=True, ftpset=True,surveydone=True, gdproptindate=timezone.now(), rowerplan='basic') self.password2 = faker.word() self.u2.set_password(self.password2) self.u2.save() self.team = Team.objects.create( name = faker.word(), notes = faker.text(), manager = self.u, ) self.team.save() self.r.team.add(self.team) self.r2.team.add(self.team) self.r.save() self.r2.save() result = get_random_file(filename='rowers/tests/testdata/2019-01-13_session.csv',name='sprintervals') self.factory = RequestFactory() self.password = faker.word() self.u.set_password(self.password) self.u.save() self.w1 = Workout.objects.create( name='sprintervals', notes=faker.text(), startdatetime = result['startdatetime'], starttime = result['starttime'], workouttype='rower', date=result['date'], duration=result['duration'], distance=result['totaldist'], csvfilename=result['filename'], trimp = 77, rscore = 69, hrtss = 43, normp = 236, user=self.r, ) # plan self.target = TrainingTarget.objects.create( name = faker.word(), manager = self.u.rower, notes = faker.text() ) self.target.rowers.add(self.u.rower) self.target.save() thismonthbegin = datetime.date(timezone.now().year,timezone.now().month,1) self.plan = TrainingPlan.objects.create( manager = self.u.rower, name = faker.word(), status=True, target = self.target, startdate=thismonthbegin, enddate = self.target.date, ) self.plan.rowers.add(self.u.rower) self.plan.save() # cycles self.macro = TrainingMacroCycle.objects.create( plan=self.plan, name=faker.word(), type='userdefined', notes = faker.text(), startdate = self.plan.startdate, enddate = self.plan.enddate, ) mesos = TrainingMesoCycle.objects.filter(plan=self.macro) for m in mesos: m.delete() monthstarts = [d for d in allmonths(self.macro.startdate,self.macro.enddate)] monthstarts.append(self.macro.enddate) for i in range(len(monthstarts)-1): firstday = monthstarts[i] lastday = monthstarts[i+1]-datetime.timedelta(days=1) if lastday < self.macro.enddate and i == len(monthstarts)-2: lastday = self.macro.enddate meso = TrainingMesoCycle(startdate=firstday, enddate=lastday, plan=self.macro, name = '%s' % firstday.strftime("%B"), type = 'userdefined') meso.save() mesos = TrainingMesoCycle.objects.filter(plan=self.macro) for cycle in mesos: micros = TrainingMicroCycle.objects.filter(plan=cycle) for m in micros: m.delete() sundays = [s for s in allsundays(cycle.startdate,cycle.enddate)] if sundays and sundays[-1] < cycle.enddate: sundays = sundays+[cycle.enddate] elif not sundays: sundays = [cycle.enddate] for i in range(len(sundays)): if i==0: monday = cycle.startdate else: monday = sundays[i]-datetime.timedelta(days=6) if monday < cycle.startdate: monday = cycle.startdate nextsunday = sundays[i] micro = TrainingMicroCycle(startdate=monday, enddate=nextsunday, plan=cycle, name = 'Week %s' % monday.isocalendar()[1], type='userdefined') micro.save() # sessions startdatetime = self.w1.startdatetime startdate = (startdatetime-datetime.timedelta(days=1)).date() enddate = (startdatetime+datetime.timedelta(days=1)).date() preferreddate = startdatetime.date() self.startdate = startdate self.enddate = enddate self.ps_rscore = SessionFactory( startdate=startdate,enddate=enddate, sessiontype='test', sessionmode = 'rScore', criterium = 'none', sessionvalue = 69, sessionunit='None', preferreddate=preferreddate, manager=self.u, ) self.ps_rscore.save() added = plannedsessions.add_rower_session(self.u.rower,self.ps_rscore) self.ps_dist = SessionFactory( startdate=startdate,enddate=enddate, sessiontype='test', sessionmode = 'distance', criterium = 'none', sessionvalue = result['totaldist'], sessionunit='m', preferreddate=preferreddate, manager=self.u, ) self.ps_dist.save() added = plannedsessions.add_rower_session(self.u.rower,self.ps_dist) self.ps_time = SessionFactory( startdate=startdate,enddate=enddate, sessiontype='test', sessionmode = 'time', criterium = 'none', sessionvalue = 38, sessionunit='min', preferreddate=preferreddate, manager=self.u, ) self.ps_time.save() added = plannedsessions.add_rower_session(self.u.rower,self.ps_time) self.ps_trimp = SessionFactory( startdate=startdate,enddate=enddate, sessiontype='test', sessionmode = 'TRIMP', criterium = 'none', sessionvalue = 77, sessionunit='none', preferreddate=preferreddate, manager=self.u, ) self.ps_trimp.save() added = plannedsessions.add_rower_session(self.u.rower,self.ps_trimp) added = plannedsessions.add_team_session(self.team,self.ps_trimp) self.ps_trimp.save() def tearDown(self): pass def test_to_time(self): calculatedTime = plannedsessions.to_time(8100000) expectedTime = datetime.time(2,15,0,0) def test_checkscores(self): macrocycles = TrainingMacroCycle.objects.filter(plan=self.plan) plannedsessions.checkscores(self.r,macrocycles) def test_executionreport(self): data, ok = plannedsessions.get_execution_report(self.r,self.plan.startdate,self.plan.enddate) self.assertEqual(ok,'ok') def test_todays_micro(self): micro1 = plannedsessions.get_todays_micro(self.plan) micro2 = plannedsessions.get_todays_micro(self.plan,thedate=datetime.date.today()) self.assertFalse(micro1 is None) self.assertFalse(micro2 is None) self.assertEqual(micro1.id,micro2.id) def test_get_session_ids(self): ids = plannedsessions.get_my_session_ids(self.r) pss = PlannedSession.objects.filter(rower__in=[self.r]) self.assertEqual(len(ids),len(pss)) class DataPrepTests(TestCase): def setUp(self): self.u = UserFactory() self.r = Rower.objects.create(user=self.u, birthdate=faker.profile()['birthdate'], gdproptin=True, ftpset=True,surveydone=True, sex='male', gdproptindate=timezone.now(), rowerplan='pro') self.r.birthdate = timezone.now()-datetime.timedelta(days=25*365) self.r.defaulttimezone = 'Europe/Amsterdam' self.r.save() 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() result = get_random_file(filename='rowers/tests/testdata/uherskehradiste_otw.csv') self.wuh_otw = WorkoutFactory(user=self.r, csvfilename=result['filename'], starttime=result['starttime'], startdatetime=result['startdatetime'], duration=result['duration'], distance=result['totaldist'], workouttype = 'water', ) with open('rowers/tests/testdata/c2records.json','r') as f: s = f.read() data = json.loads(s) for obj in data: m = obj['fields'] record = C2WorldClassAgePerformance(**m) record.save() with open('rowers/tests/testdata/calcageperformance.json','r') as f: s = f.read() data = json.loads(s) for obj in data: m = obj['fields'] record = CalcAgePerformance(**m) record.save() def tearDown(self): pass def test_timezones(self): #row = rowingdata.rowingdata(csvfile='rowers.tests/testdata/testdata_210616_075409.csv') row = rowingdata.rowingdata(csvfile='rowers/tests/testdata/testdata_210616_075409.csv') aware = datetime.datetime(2021,6,16,7,54,9,999000,tzinfo=pytz.timezone('Europe/Amsterdam')) row.rowdatetime = aware startdatetime, startdate, starttime, timezone_str,partofday = dataprep.get_startdate_time_zone(self.r,row) self.assertEqual(partofday,'Morning') want = arrow.get('2021-06-16T07:54:09.999000+02:00').isoformat() got = arrow.get(startdatetime).isoformat() self.assertEqual(got, want) self.assertEqual(timezone_str,'Europe/Amsterdam') self.assertEqual(starttime,'07:54:09') self.assertEqual(startdate,'2021-06-16') def test_timezones2(self): #row = rowingdata.rowingdata(csvfile='rowers.tests/testdata/testdata_210616_075409.csv') row = rowingdata.rowingdata(csvfile='rowers/tests/testdata/testdata_210616_075409.csv') naive = datetime.datetime(2021,6,16,7,54,9,999000) timezone = pytz.timezone('Europe/Prague') aware = timezone.localize(naive) row.rowdatetime = aware startdatetime, startdate, starttime, timezone_str,partofday = dataprep.get_startdate_time_zone(self.r,row, startdatetime=aware) self.assertEqual(partofday,'Morning') want = arrow.get('2021-06-16T07:54:09.999000+02:00').isoformat() got = arrow.get(startdatetime).isoformat() self.assertEqual(got, want) self.assertEqual(timezone_str,'Europe/Prague') self.assertEqual(starttime,'07:54:09') self.assertEqual(startdate,'2021-06-16') def test_timezones3(self): #row = rowingdata.rowingdata(csvfile='rowers.tests/testdata/testdata_210616_075409.csv') row = rowingdata.rowingdata(csvfile='rowers/tests/testdata/testdata_210616_075409.csv') naive = datetime.datetime(2021,6,16,7,54,9,999000) row.rowdatetime = naive startdatetime, startdate, starttime, timezone_str,partofday = dataprep.get_startdate_time_zone(self.r,row) self.assertEqual(timezone_str,'Europe/Amsterdam') def test_timezones4(self): #row = rowingdata.rowingdata(csvfile='rowers.tests/testdata/testdata_210616_075409.csv') row = rowingdata.rowingdata(csvfile='rowers/tests/testdata/testdata_210616_075409.csv') naive = datetime.datetime(2021,6,15,19,55,13,400000) timezone = pytz.timezone('America/Los_Angeles') aware = timezone.localize(naive) row.rowdatetime = aware ( startdatetime, startdate, starttime, timezone_str, partofday ) = dataprep.get_startdate_time_zone(self.r,row,startdatetime=aware) self.assertEqual(timezone_str,'America/Los_Angeles') self.assertEqual(partofday,'Evening') want = arrow.get('2021-06-15 19:55:13.400000-07:00').isoformat() got = arrow.get(startdatetime).isoformat() self.assertEqual(got, want) self.assertEqual(starttime,'19:55:13') self.assertEqual(startdate,'2021-06-15') def test_timezones5(self): #row = rowingdata.rowingdata(csvfile='rowers.tests/testdata/testdata_210616_075409.csv') row = rowingdata.rowingdata(csvfile='rowers/tests/testdata/testdata_210616_075409.csv') naive = datetime.datetime(2021,6,15,19,55,13,400000) timezone = pytz.timezone('America/Los_Angeles') aware = timezone.localize(naive) row.rowdatetime = aware ( startdatetime, startdate, starttime, timezone_str, partofday ) = dataprep.get_startdate_time_zone(self.r,row) self.assertEqual(timezone_str,'America/Los_Angeles') self.assertEqual(partofday,'Evening') want = arrow.get('2021-06-15 19:55:13.400000-07:00').isoformat() got = arrow.get(startdatetime).isoformat() self.assertEqual(got, want) self.assertEqual(starttime,'19:55:13') self.assertEqual(startdate,'2021-06-15') def test_calculate_age(self): today = timezone.now() born = today-datetime.timedelta(days=45+49*365.2425) age = dataprep.calculate_age(born,today=today) self.assertEqual(age,49) @patch('rowers.dataprep.read_data',side_effect=mocked_getsmallrowdata_uh) def test_goldmedalstandard(self,mocked_getsmallrowdata_uh): maxvalue, delta = dataprep.calculate_goldmedalstandard(self.r,self.wuh_otw) records = CalcAgePerformance.objects.filter( age=dataprep.calculate_age(self.r.birthdate), weightcategory=self.r.weightcategory, sex=self.r.sex) self.assertTrue(maxvalue > 0) self.assertTrue(delta > 0) def test_getagegrouprecord(self): records = C2WorldClassAgePerformance.objects.filter(distance=2000,sex=self.r.sex,weightcategory=self.r.weightcategory) result = getagegrouprecord(25) self.assertEqual(int(result),590) @patch('rowers.dataprep.getsmallrowdata_pd',side_effect=mocked_getsmallrowdata_uh_pd) def test_get_videodata(self,mocked_getsmallrowdata_uh_pd): data, metrics, maxtime = dataprep.get_video_data(self.wuh_otw) self.assertEqual(len(data),9) self.assertEqual(len(metrics),6) self.assertEqual(int(maxtime),1737) def test_polarization_index(self): df = pd.read_csv('rowers/tests/testdata/uhfull.csv') index = dataprep.polarization_index(df,self.r) self.assertEqual(int(100*index),-67) def test_get_latlon(self): data = dataprep.get_latlon(self.wuh_otw.id) self.assertEqual(len(data),2) def test_workout_summary_to_df(self): df = dataprep.workout_summary_to_df(self.r) self.assertEqual(len(df),6) @patch('rowers.dataprep.create_engine') def test_update_c2id(self,mocked_sqlalchemy): res = dataprep.update_c2id_sql(1,1) self.assertEqual(res,1) def test_checkmarker(self): workouts = Workout.objects.all().order_by("-date") wmax = dataprep.check_marker(workouts[0]) self.assertTrue(wmax.rankingpiece) def test_workouttype_fromfit(self): filename = 'rowers/tests/testdata/3x250m.fit' res = dataprep.get_workouttype_from_fit(filename) self.assertEqual(res,'Workout') def test_workouttype_fromtcx(self): filename = 'rowers/tests/testdata/crewnerddata.tcx' res = dataprep.get_workouttype_from_tcx(filename) self.assertEqual(res,'water') class InteractivePlotTests(TestCase): def setUp(self): self.u = UserFactory() self.r = Rower.objects.create(user=self.u, birthdate=faker.profile()['birthdate'], gdproptin=True, ftpset=True,surveydone=True, gdproptindate=timezone.now(), rowerplan='pro') 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): pass def test_interactive_hr_piechart(self): df = pl.read_csv('rowers/tests/testdata/getrowdata_mock.csv') script, div = interactiveplots.interactive_hr_piechart(df, self.r,'') self.assertFalse(len(script)==0) self.assertFalse(len(div)==0) def test_interactive_workouttype_piechart(self): workouts = Workout.objects.filter(user=self.r) script, div = interactiveplots.interactive_workouttype_piechart(workouts) self.assertFalse(len(script)==0) self.assertFalse(len(div)==0) def test_interactive_boxchart(self): df = pl.read_csv('rowers/tests/testdata/boxplotdata.csv') df = df.with_columns(pl.col("date").str.to_datetime("%Y-%m-%d")) script, div = interactiveplots.interactive_boxchart(df, 'spm') self.assertFalse(len(script)==0) self.assertFalse(len(div)==0) def test_interactive_activitychart(self): workouts = Workout.objects.filter(user=self.r).order_by('date') workouts2 = Workout.objects.filter(user=self.r).order_by('-date') startdate = workouts[0].date-datetime.timedelta(days=5) enddate = workouts2[0].date+datetime.timedelta(days=5) script, div = interactiveplots.interactive_activitychart2(workouts,startdate,enddate) self.assertFalse(len(script)==0) self.assertFalse(len(div)==0) def test_interactive_otwcpchart(self): df = pl.read_csv('rowers/tests/testdata/otwcp.csv') script, div, p1, ratio, message = interactiveplots.interactive_otwcpchart(df,r=self.r,cpfit='data') self.assertFalse(len(script)==0) self.assertFalse(len(div)==0) script, div, p1, ratio, message = interactiveplots.interactive_otwcpchart(df,r=self.r,cpfit='automatic') self.assertFalse(len(script)==0) self.assertFalse(len(div)==0) @patch('rowers.dataprep.create_engine') @patch('rowers.dataprep.read_data', side_effect=mocked_read_data) def test_interactive_chart(self, mocked_sqlalchemy, mocked_read_data): workout = Workout.objects.filter(user=self.r,workouttype__in=mytypes.rowtypes)[0] id = workout.id script, div = interactiveplots.interactive_chart(id=id) self.assertFalse(len(script)==0) self.assertFalse(len(div)==0) intervaldata = { 'itime': [0.0, 234.0, 61.2, 59.7, 60.5, 61.0, 44.2, 74.7, 44.8, 75.1, 43.4, 78.0, 40.1, 79.4, 42.4, 76.1, 45.4, 75.2, 43.2, 255.0, 60.0, 60.6, 60.7, 60.7, 55.3, 65.4, 58.2, 60.2, 59.7, 62.0, 44.7, 72.5, 43.2, 78.5, 56.4, 889.5], 'idist': [0, 700, 257, 179, 254, 197, 185, 246, 190, 240, 181, 240, 169, 241, 179, 215, 180, 223, 179, 302, 247, 190, 246, 180, 229, 197, 242, 179, 245, 189, 175, 208, 166, 218, 224, 2399], 'itype': [4, 3, 4.0, 3, 4.0, 3, 4.0, 3, 4.0, 3, 4.0, 3, 4.0, 3, 4.0, 3, 4.0, 3, 4.0, 3, 4.0, 3, 4.0, 3, 4.0, 3, 4.0, 3, 4.0, 3, 4.0, 3, 4.0, 3, 4.0, 3], 'selector': 'power', 'normp': 203, 'normv': 3.557050625695544 } script, div = interactiveplots.interactive_chart(id=id,intervaldata=intervaldata) self.assertFalse(len(script)==0) self.assertFalse(len(div)==0) def test_interactive_chart_video(self): datadf = pd.read_csv('rowers/tests/testdata/videodata.csv') data = datadf.to_dict() script, div = interactiveplots.interactive_chart_video(data) self.assertFalse(len(script)==0) self.assertFalse(len(div)==0) @patch('rowers.dataprep.create_engine') @patch('rowers.dataprep.read_data', side_effect=mocked_read_data) def test_interactive_flexchart_stacked(self, mocked_sqlalchemy, mocked_read_data): workout = Workout.objects.filter(user=self.r,workouttype__in=mytypes.rowtypes)[0] id = workout.id script, div = interactiveplots.interactive_flexchart_stacked(id,self.r) self.assertFalse(len(script)==0) self.assertFalse(len(div)==0)