from __future__ import absolute_import from __future__ import division from __future__ import print_function from __future__ import unicode_literals from .statements import * from django.utils import timezone nu = datetime.datetime.now(tz=timezone.utc) from django.db import transaction # set up import rowers.teams as teams import rowers.plannedsessions as plannedsessions @override_settings(TESTING=True) class PermissionsFreeCoach(TestCase): def setUp(self): self.c = Client() ## Users - Pro, Basic, Free Coach & Self Coach self.ufreecoach = UserFactory(username='coachuser') self.rfreecoach = Rower.objects.create(user=self.ufreecoach, birthdate=faker.profile()['birthdate'], gdproptin=True,gdproptindate=timezone.now(), rowerplan='freecoach',clubsize=100) self.coachinggroup = CoachingGroup.objects.create() self.rfreecoach.mycoachgroup = self.coachinggroup self.rfreecoach.save() self.factory = RequestFactory() self.password = faker.word() self.ufreecoach.set_password(self.password) self.ufreecoach.save() self.uplan = UserFactory(username='planuser') self.rplan = Rower.objects.create(user=self.uplan, birthdate=faker.profile()['birthdate'], gdproptin=True,gdproptindate=timezone.now(), rowerplan='plan') self.uplan_workouts = WorkoutFactory.create_batch(5, user=self.rplan) self.factory = RequestFactory() self.password = faker.word() self.uplan.set_password(self.password) self.uplan.save() self.upro = UserFactory(username='prouser') self.rpro = Rower.objects.create(user=self.upro, birthdate=faker.profile()['birthdate'], gdproptin=True,gdproptindate=timezone.now(), rowerplan='pro') self.upro_workouts = WorkoutFactory.create_batch(5, user=self.rpro) self.factory = RequestFactory() self.password = faker.word() self.upro.set_password(self.password) self.upro.save() self.uplan2 = UserFactory(username='planuser2') self.rplan2 = Rower.objects.create(user=self.uplan2, birthdate=faker.profile()['birthdate'], gdproptin=True,gdproptindate=timezone.now(), rowerplan='plan') self.uplan2_workouts = WorkoutFactory.create_batch(5, user=self.rplan2) self.factory = RequestFactory() self.password = faker.word() self.uplan2.set_password(self.password) self.uplan2.save() self.upro2 = UserFactory(username='prouser2') self.rpro2 = Rower.objects.create(user=self.upro2, birthdate=faker.profile()['birthdate'], gdproptin=True,gdproptindate=timezone.now(), rowerplan='pro') self.upro2_workouts = WorkoutFactory.create_batch(5, user=self.rpro2) self.factory = RequestFactory() self.password = faker.word() self.upro2.set_password(self.password) self.upro2.save() self.ubasic = UserFactory(username='basicuser') self.rbasic = Rower.objects.create(user=self.ubasic, birthdate=faker.profile()['birthdate'], gdproptin=True,gdproptindate=timezone.now(), rowerplan='basic') self.ubasic_workouts = WorkoutFactory.create_batch(5, user=self.rbasic) self.factory = RequestFactory() self.ubasicpassword = faker.word() self.ubasic.set_password(self.ubasicpassword) self.ubasic.save() ## TeamFreeCoach self.teamfreecoach = Team.objects.create( name=faker.word()+'3', notes=faker.text(), manager=self.ufreecoach) ## Coach can have any number of groups def test_coach_groupmanager(self): team1 = Team.objects.create( name = 'FirstTeam', notes = faker.text(), manager = self.ufreecoach, ) self.assertEqual(team1.manager,self.ufreecoach) team2 = Team.objects.create( name = 'SecondTeam', notes = faker.text(), manager = self.ufreecoach, ) self.assertEqual(team2.manager,self.ufreecoach) team3 = Team.objects.create( name = 'ThirdTeam', notes = faker.text(), manager = self.ufreecoach, ) self.assertEqual(team3.manager,self.ufreecoach) ## Free coach can create more than one group def test_plan_groupmanager(self): team1 = Team.objects.create( name = 'FirstTeam', notes = faker.text(), manager = self.ufreecoach, ) self.assertEqual(team1.manager,self.ufreecoach) team2 = Team.objects.create( name = 'SecondTeam', notes = faker.text(), manager = self.ufreecoach, ) self.assertEqual(team2.manager,self.ufreecoach) ## Free Coach can create planned sessions and team planned sessions ## Self Coach and higher can create planned sessions and team planned sessions def test_plan_create_session(self): ps = PlannedSession.objects.create( manager=self.ufreecoach, name=faker.word(), comment=faker.text() ) self.assertEqual(ps.manager,self.ufreecoach) def test_coach_create_session(self): ps = PlannedSession.objects.create( manager=self.ufreecoach, name=faker.word(), comment=faker.text() ) self.assertEqual(ps.manager,self.ufreecoach) ## Basic cannot join groups led by Free Coach def test_add_basic_pro_or_plan(self): with transaction.atomic(): with self.assertRaises(ValidationError): self.rbasic.team.add(self.teamfreecoach) ## Free Coach user cannot have workouts def test_add_workout_freecoach(self): result = get_random_file(filename='rowers/tests/testdata/erg1.csv') with transaction.atomic(): with self.assertRaises(ValidationError): self.werg1 = WorkoutFactory(user=self.rfreecoach, csvfilename=result['filename'], starttime=result['starttime'], startdatetime=result['startdatetime'], duration=result['duration'], distance=result['totaldist'], workouttype = 'rower', ) @override_settings(TESTING=True) class PermissionsBasicsTests(TestCase): def setUp(self): self.c = Client() ## Users - Pro, Basic, Coach & Self Coach self.ucoach = UserFactory(username='coachuser') self.rcoach = Rower.objects.create(user=self.ucoach, birthdate=faker.profile()['birthdate'], gdproptin=True,gdproptindate=timezone.now(), rowerplan='coach',clubsize=10) self.ucoach_workouts = WorkoutFactory.create_batch(5, user=self.rcoach) self.coachinggroup = CoachingGroup.objects.create() self.rcoach.mycoachgroup = self.coachinggroup self.rcoach.save() self.factory = RequestFactory() self.password = faker.word() self.ucoach.set_password(self.password) self.ucoach.save() self.uplan = UserFactory(username='planuser') self.rplan = Rower.objects.create(user=self.uplan, birthdate=faker.profile()['birthdate'], gdproptin=True,gdproptindate=timezone.now(), rowerplan='plan') self.uplan_workouts = WorkoutFactory.create_batch(5, user=self.rplan) self.factory = RequestFactory() self.password = faker.word() self.uplan.set_password(self.password) self.uplan.save() self.upro = UserFactory(username='prouser') self.rpro = Rower.objects.create(user=self.upro, birthdate=faker.profile()['birthdate'], gdproptin=True,gdproptindate=timezone.now(), rowerplan='pro') self.upro_workouts = WorkoutFactory.create_batch(5, user=self.rpro) self.factory = RequestFactory() self.password = faker.word() self.upro.set_password(self.password) self.upro.save() self.uplan2 = UserFactory(username='planuser2') self.rplan2 = Rower.objects.create(user=self.uplan2, birthdate=faker.profile()['birthdate'], gdproptin=True,gdproptindate=timezone.now(), rowerplan='plan') self.uplan2_workouts = WorkoutFactory.create_batch(5, user=self.rplan2) self.factory = RequestFactory() self.password = faker.word() self.uplan2.set_password(self.password) self.uplan2.save() self.upro2 = UserFactory(username='prouser2') self.rpro2 = Rower.objects.create(user=self.upro2, birthdate=faker.profile()['birthdate'], gdproptin=True,gdproptindate=timezone.now(), rowerplan='pro') self.upro2_workouts = WorkoutFactory.create_batch(5, user=self.rpro2) self.factory = RequestFactory() self.password = faker.word() self.upro2.set_password(self.password) self.upro2.save() self.ubasic = UserFactory(username='basicuser') self.rbasic = Rower.objects.create(user=self.ubasic, birthdate=faker.profile()['birthdate'], gdproptin=True,gdproptindate=timezone.now(), rowerplan='basic') self.ubasic_workouts = WorkoutFactory.create_batch(5, user=self.rbasic) self.factory = RequestFactory() self.ubasicpassword = faker.word() self.ubasic.set_password(self.ubasicpassword) self.ubasic.save() ## TeamPro, TeamCoach, TeamSelfCoach self.teampro = Team.objects.create( name=faker.word()+'1', notes=faker.text(), manager=self.upro2) self.teamplan = Team.objects.create( name=faker.word()+'2', notes=faker.text(), manager=self.uplan2) self.teamcoach = Team.objects.create( name=faker.word()+'3', notes=faker.text(), manager=self.ucoach) # Requirements ## Low level ## Coach can have any number of groups def test_coach_groupmanager(self): team1 = Team.objects.create( name = 'FirstTeam', notes = faker.text(), manager = self.ucoach, ) self.assertEqual(team1.manager,self.ucoach) team2 = Team.objects.create( name = 'SecondTeam', notes = faker.text(), manager = self.ucoach, ) self.assertEqual(team2.manager,self.ucoach) team3 = Team.objects.create( name = 'ThirdTeam', notes = faker.text(), manager = self.ucoach, ) self.assertEqual(team3.manager,self.ucoach) ## Basic athletes can be member of Coach led group def test_add_coach(self): self.rbasic.team.add(self.teamcoach) self.assertIn(self.teamcoach,self.rbasic.team.all()) ## Self coach can create one group ## Self coach cannot create more than one group def test_plan_groupmanager(self): team1 = Team.objects.create( name = 'FirstTeam', notes = faker.text(), manager = self.uplan, ) self.assertEqual(team1.manager,self.uplan) with self.assertRaises(ValidationError): team2 = Team.objects.create( name = 'SecondTeam', notes = faker.text(), manager = self.uplan, ) ## Pro users (and higher) can join group led by other Pro (or higher) user def test_add_proplan_pro_or_plan(self): self.rpro.team.add(self.teamplan) self.assertIn(self.teamplan,self.rpro.team.all()) self.rpro.team.add(self.teampro) self.assertIn(self.teampro,self.rpro.team.all()) self.rplan.team.add(self.teamplan) self.assertIn(self.teamplan,self.rplan.team.all()) self.rplan.team.add(self.teampro) self.assertIn(self.teampro,self.rplan.team.all()) self.rcoach.team.add(self.teamplan) self.assertIn(self.teamplan,self.rcoach.team.all()) self.rcoach.team.add(self.teampro) self.assertIn(self.teampro,self.rcoach.team.all()) ## Coach can create planned sessions and team planned sessions ## Self Coach and higher can create planned sessions and team planned sessions def test_plan_create_session(self): ps = PlannedSession.objects.create( manager=self.uplan, name=faker.word(), comment=faker.text() ) self.assertEqual(ps.manager,self.uplan) def test_coach_create_session(self): ps = PlannedSession.objects.create( manager=self.ucoach, name=faker.word(), comment=faker.text() ) self.assertEqual(ps.manager,self.ucoach) ## Pro can have one group ## Pro cannot create more than one group def test_pro_groupmanager(self): team1 = Team.objects.create( name = 'FirstTeam', notes = faker.text(), manager = self.upro, ) self.assertEqual(team1.manager,self.upro) with self.assertRaises(ValidationError): team2 = Team.objects.create( name = 'SecondTeam', notes = faker.text(), manager = self.upro, ) ## Pro or Basic cannot create planned sessions or team planned sessions def test_pro_create_plannedsession(self): with self.assertRaises(ValidationError): ps = PlannedSession.objects.create( manager=self.upro, name = faker.word(), comment = faker.text() ) def test_basic_create_plannedsession(self): with self.assertRaises(ValidationError): ps = PlannedSession.objects.create( manager=self.ubasic, name = faker.word(), comment = faker.text() ) ## Basic cannot join groups led by Pro or Self Coach def test_add_basic_pro_or_plan(self): with transaction.atomic(): with self.assertRaises(ValidationError): self.rbasic.team.add(self.teamplan) with transaction.atomic(): with self.assertRaises(ValidationError): self.rbasic.team.add(self.teampro) ## Basic cannot manage a group def test_basic_groupmanager(self): with self.assertRaises(ValidationError): team = Team.objects.create( name = 'ThisTeamShouldNotExist', notes = faker.text(), manager = self.ubasic, private = 'open', viewing = 'allmembers') ## On downgrade, Coach users lose all but their oldest team # View based @override_settings(TESTING=True) class PermissionsViewTests(TestCase): def setUp(self): self.c = Client() ## Users - Pro, Basic, Coach & Self Coach self.ucoach = UserFactory(username='coachuser') self.rcoach = Rower.objects.create(user=self.ucoach, birthdate=faker.profile()['birthdate'], gdproptin=True,gdproptindate=timezone.now(), rowerplan='coach',clubsize=10) self.ucoach_workouts = WorkoutFactory.create_batch(5, user=self.rcoach) self.coachinggroup = CoachingGroup.objects.create() self.rcoach.mycoachgroup = self.coachinggroup self.rcoach.save() self.factory = RequestFactory() self.ucoachpassword = faker.word() self.ucoach.set_password(self.ucoachpassword) self.ucoach.save() self.uplan = UserFactory(username='planuser') self.rplan = Rower.objects.create(user=self.uplan, birthdate=faker.profile()['birthdate'], gdproptin=True,gdproptindate=timezone.now(), rowerplan='plan') self.uplan_workouts = WorkoutFactory.create_batch(5, user=self.rplan) self.factory = RequestFactory() self.uplanpassword = faker.word() self.uplan.set_password(self.uplanpassword) self.uplan.save() self.upro = UserFactory(username='prouser') self.rpro = Rower.objects.create(user=self.upro, birthdate=faker.profile()['birthdate'], gdproptin=True,gdproptindate=timezone.now(), rowerplan='pro') self.upro_workouts = WorkoutFactory.create_batch(5, user=self.rpro) self.factory = RequestFactory() self.upropassword = faker.word() self.upro.set_password(self.upropassword) self.upro.save() self.uplan2 = UserFactory(username='planuser2') self.rplan2 = Rower.objects.create(user=self.uplan2, birthdate=faker.profile()['birthdate'], gdproptin=True,gdproptindate=timezone.now(), rowerplan='plan') self.uplan2_workouts = WorkoutFactory.create_batch(5, user=self.rplan2) self.factory = RequestFactory() self.uplan2password = faker.word() self.uplan2.set_password(self.uplan2password) self.uplan2.save() self.upro2 = UserFactory(username='prouser2') self.rpro2 = Rower.objects.create(user=self.upro2, birthdate=faker.profile()['birthdate'], gdproptin=True,gdproptindate=timezone.now(), rowerplan='pro') self.upro2_workouts = WorkoutFactory.create_batch(5, user=self.rpro2) self.factory = RequestFactory() self.upro2password = faker.word() self.upro2.set_password(self.upro2password) self.upro2.save() self.ubasic = UserFactory(username='basicuser') self.rbasic = Rower.objects.create(user=self.ubasic, birthdate=faker.profile()['birthdate'], gdproptin=True,gdproptindate=timezone.now(), rowerplan='basic') self.ubasic_workouts = WorkoutFactory.create_batch(5, user=self.rbasic) self.factory = RequestFactory() self.ubasicpassword = faker.word() self.ubasic.set_password(self.ubasicpassword) self.ubasic.save() ## TeamPro, TeamCoach, TeamSelfCoach self.teampro = Team.objects.create( name=faker.word(), notes=faker.text(), manager=self.upro2) self.teamplan = Team.objects.create( name=faker.word()+'2', notes=faker.text(), manager=self.uplan2) self.teamcoach = Team.objects.create( name=faker.word()+'3', notes=faker.text(), manager=self.ucoach) ## Coach can have any number of groups def test_coach_groups_create(self): login = self.c.login(username=self.ucoach.username, password=self.ucoachpassword) self.assertTrue(login) url = reverse('team_create_view') response = self.c.get(url) self.assertTrue(response.status_code,200) # Create 1st new team form_data = { 'name': faker.word(), 'notes': faker.text(), 'private': 'open', 'viewing': 'allmembers' } form = TeamForm(form_data) if not form.is_valid(): print(form.errors) self.assertTrue(form.is_valid()) expected_url = reverse('rower_teams_view') response = self.c.post(url,form_data,follow=True) self.assertRedirects(response, expected_url=expected_url, status_code=302,target_status_code=200) # Create 2nd new team form_data = { 'name': faker.word(), 'notes': faker.text(), 'private': 'open', 'viewing': 'allmembers' } form = TeamForm(form_data) if not form.is_valid(): print(form.errors) self.assertTrue(form.is_valid()) expected_url = reverse('rower_teams_view') response = self.c.post(url,form_data,follow=True) self.assertRedirects(response, expected_url=expected_url, status_code=302,target_status_code=200) ## Basic athletes can be member of Coach led group ## Coach can create planned sessions and team planned sessions def test_coach_create_session(self): login = self.c.login(username=self.ucoach.username, password=self.ucoachpassword) self.assertTrue(login) url = reverse('plannedsession_create_view') startdate = nu.date() enddate = (nu+datetime.timedelta(days=3)).date() preferreddate = startdate response = self.c.get(url) self.assertEqual(response.status_code,200) post_data = { 'comment': faker.text(), 'criterium': 'none', 'enddate': enddate.strftime("%Y-%m-%d"), 'preferreddate': preferreddate.strftime("%Y-%m-%d"), 'startdate': startdate.strftime("%Y-%m-%d"), 'sessionmode':'time', 'sessiontype':'session', 'sessionunit':'min', 'sessionvalue': '60', 'name': faker.word(), } form = PlannedSessionForm(post_data) self.assertTrue(form.is_valid()) response = self.c.post(url,post_data) self.assertEqual(response.status_code,200) ## Coach can edit on behalf of athlete if permitted def test_coach_edit_athlete_settings(self): self.rbasic.team.add(self.teamcoach) self.rbasic.coachinggroups.add(self.coachinggroup) login = self.c.login(username=self.ucoach.username, password=self.ucoachpassword) self.assertTrue(login) url = reverse('rower_prefs_view',kwargs={'userid':self.ubasic.id}) response = self.c.get(url) self.assertEqual(response.status_code,200) def test_coach_edit_athlete_settings_not(self): self.rbasic.team.add(self.teamcoach) login = self.c.login(username=self.ucoach.username, password=self.ucoachpassword) self.assertTrue(login) url = reverse('rower_prefs_view',kwargs={'userid':self.ubasic.id}) response = self.c.get(url) self.assertEqual(response.status_code,403) ## Coach can run analytics for athlete @patch('rowers.dataprep.read_cols_df_sql', side_effect = mocked_read_df_cols_sql_multistats) def test_coach_edit_athlete_analysis(self,mocked_df): self.rbasic.team.add(self.teamcoach) self.rbasic.coachinggroups.add(self.coachinggroup) login = self.c.login(username=self.ucoach.username, password=self.ucoachpassword) self.assertTrue(login) url = reverse('cumstats', kwargs={ 'theuser':self.ubasic.id, } ) response = self.c.get(url) self.assertEqual(response.status_code,200) @patch('rowers.dataprep.read_cols_df_sql', side_effect = mocked_read_df_cols_sql_multistats) def test_coach_edit_athlete_analysis_not(self,mocked_df): self.rbasic.team.add(self.teamcoach) login = self.c.login(username=self.ucoach.username, password=self.ucoachpassword) self.assertTrue(login) url = reverse('cumstats', kwargs={ 'theuser':self.ubasic.id, } ) response = self.c.get(url) self.assertEqual(response.status_code,403) ## Coach can upload on behalf of athlete - if team allows @patch('rowers.dataprep.create_engine') @patch('rowers.dataprep.getsmallrowdata_db',side_effect=mocked_getsmallrowdata_db) def test_coach_edit_athlete_upload(self,mocked_sqlalchemy,mocked_getsmallrowdata_db): self.rbasic.team.add(self.teamcoach) self.rbasic.coachinggroups.add(self.coachinggroup) login = self.c.login(username=self.ucoach.username, password=self.ucoachpassword) self.assertTrue(login) url = reverse('team_workout_upload_view') aantal = len(Workout.objects.filter(user=self.rbasic)) response = self.c.get(url) self.assertEqual(response.status_code,200) filename = 'rowers/tests/testdata/testdata.csv' f = open(filename,'rb') file_data = {'file': f} form_data = { 'title':'test', 'workouttype':'rower', 'boattype':'1x', 'notes':'aap noot mies', 'make_plot':False, 'upload_to_c2':False, 'plottype':'timeplot', 'file': f, 'user': self.ubasic.id } response = self.c.post(url, form_data, follow=True) f.close() self.assertEqual(response.status_code,200) self.assertRedirects(response, expected_url = url, status_code=302,target_status_code=200) aantal2 = len(Workout.objects.filter(user=self.rbasic)) self.assertEqual(aantal2,aantal+1) ## Coach can upload on behalf of athlete - if team allows @patch('rowers.dataprep.create_engine') @patch('rowers.dataprep.getsmallrowdata_db',side_effect=mocked_getsmallrowdata_db) def test_coach_edit_athlete_uploadnot(self,mocked_sqlalchemy,mocked_getsmallrowdata_db): self.rbasic.team.add(self.teamcoach) login = self.c.login(username=self.ucoach.username, password=self.ucoachpassword) self.assertTrue(login) url = reverse('team_workout_upload_view') aantal = len(Workout.objects.filter(user=self.rbasic)) response = self.c.get(url) self.assertEqual(response.status_code,200) filename = 'rowers/tests/testdata/testdata.csv' f = open(filename,'rb') file_data = {'file': f} form_data = { 'title':'test', 'workouttype':'rower', 'boattype':'1x', 'notes':'aap noot mies', 'make_plot':False, 'upload_to_c2':False, 'plottype':'timeplot', 'file': f, 'user': self.ubasic.id } response = self.c.post(url, form_data, follow=True) f.close() self.assertEqual(response.status_code,200) self.assertRedirects(response, expected_url = url, status_code=302,target_status_code=200) aantal2 = len(Workout.objects.filter(user=self.rbasic)) self.assertEqual(aantal2,aantal) ## Coach can edit athlete's workout def test_coach_edit_athlete_workout(self): self.rbasic.team.add(self.teamcoach) login = self.c.login(username=self.ucoach.username, password=self.ucoachpassword) self.assertTrue(login) url = reverse('workout_edit_view', kwargs={'id':encoder.encode_hex(self.ubasic_workouts[0].id)} ) response = self.c.get(url) self.assertEqual(response.status_code,403) ## Self coach can create one group ## Self coach cannot create more than one group def test_plan_groups_create(self): login = self.c.login(username=self.uplan.username, password=self.uplanpassword) self.assertTrue(login) url = reverse('team_create_view') response = self.c.get(url) self.assertTrue(response.status_code,200) # Create 1st new team form_data = { 'name': faker.word(), 'notes': faker.text(), 'private': 'open', 'viewing': 'allmembers' } form = TeamForm(form_data) if not form.is_valid(): print(form.errors) self.assertTrue(form.is_valid()) expected_url = reverse('rower_teams_view') response = self.c.post(url,form_data,follow=True) self.assertRedirects(response, expected_url=expected_url, status_code=302,target_status_code=200) # Create 2nd new team - should redirect to paid plans form_data = { 'name': faker.word(), 'notes': faker.text(), 'private': 'open', 'viewing': 'allmembers' } form = TeamForm(form_data) if not form.is_valid(): print(form.errors) self.assertTrue(form.is_valid()) expected_url = reverse('paidplans') response = self.c.post(url,form_data,follow=True) self.assertRedirects(response, expected_url=expected_url, status_code=302,target_status_code=200) ## Self Coach can create planned sessions and team planned sessions def test_plan_create_session(self): login = self.c.login(username=self.uplan2.username, password=self.uplan2password) self.assertTrue(login) url = reverse('plannedsession_create_view') startdate = nu.date() enddate = (nu+datetime.timedelta(days=3)).date() preferreddate = startdate response = self.c.get(url) self.assertEqual(response.status_code,200) post_data = { 'comment': faker.text(), 'criterium': 'none', 'enddate': enddate.strftime("%Y-%m-%d"), 'preferreddate': preferreddate.strftime("%Y-%m-%d"), 'startdate': startdate.strftime("%Y-%m-%d"), 'sessionmode':'time', 'sessiontype':'session', 'sessionunit':'min', 'sessionvalue': '60', 'name': faker.word(), } form = PlannedSessionForm(post_data) self.assertTrue(form.is_valid()) response = self.c.post(url,post_data) self.assertEqual(response.status_code,200) ## Self Coach cannot edit on behalf of athlete def test_plan_edit_athlete_settings(self): self.rpro.team.add(self.teamplan) login = self.c.login(username=self.uplan2.username, password=self.uplan2password) self.assertTrue(login) url = reverse('rower_prefs_view',kwargs={'userid':self.ubasic.id}) response = self.c.get(url) self.assertEqual(response.status_code,403) ## Self Coach cannot run analytics on behalf of athlete @patch('rowers.dataprep.read_cols_df_sql', side_effect = mocked_read_df_cols_sql_multistats) def test_plan_edit_athlete_analysis(self,mocked_df): self.rpro.team.add(self.teamplan) login = self.c.login(username=self.uplan2.username, password=self.uplan2password) self.assertTrue(login) url = reverse('cumstats', kwargs={ 'theuser':self.ubasic.id, } ) response = self.c.get(url) self.assertEqual(response.status_code,403) ## Self Coach cannot upload on behalf of athlete @patch('rowers.dataprep.create_engine') @patch('rowers.dataprep.getsmallrowdata_db',side_effect=mocked_getsmallrowdata_db) def test_plan_edit_athlete_upload(self,mocked_sqlalchemy,mocked_getsmallrowdata_db): self.rpro.team.add(self.teamplan) login = self.c.login(username=self.uplan2.username, password=self.uplan2password) self.assertTrue(login) url = reverse('team_workout_upload_view') response = self.c.get(url) self.assertEqual(response.status_code,403) ## Pro can have one group ## Pro cannot create more than one group def test_pro_groups_create(self): login = self.c.login(username=self.upro.username, password=self.upropassword) self.assertTrue(login) url = reverse('team_create_view') response = self.c.get(url) self.assertTrue(response.status_code,200) # Create 1st new team form_data = { 'name': faker.word(), 'notes': faker.text(), 'private': 'open', 'viewing': 'allmembers' } form = TeamForm(form_data) if not form.is_valid(): print(form.errors) self.assertTrue(form.is_valid()) expected_url = reverse('rower_teams_view') response = self.c.post(url,form_data,follow=True) self.assertRedirects(response, expected_url=expected_url, status_code=302,target_status_code=200) # Create 2nd new team - should redirect to paid plans form_data = { 'name': faker.word(), 'notes': faker.text(), 'private': 'open', 'viewing': 'allmembers' } form = TeamForm(form_data) if not form.is_valid(): print(form.errors) self.assertTrue(form.is_valid()) expected_url = reverse('paidplans') response = self.c.post(url,form_data,follow=True) self.assertRedirects(response, expected_url=expected_url, status_code=302,target_status_code=200) ## Pro cannot create planned sessions or team planned sessions def test_pro_create_session(self): login = self.c.login(username=self.upro2.username, password=self.upro2password) self.assertTrue(login) url = reverse('plannedsession_create_view') startdate = nu.date() enddate = (nu+datetime.timedelta(days=3)).date() preferreddate = startdate response = self.c.get(url,follow=True) self.assertEqual(response.status_code,200) expected_url = reverse('paidplans') self.assertRedirects(response, expected_url=expected_url, status_code=302,target_status_code=200) ## Pro cannot edit on behalf of athlete def test_pro_edit_athlete_settings(self): self.rpro.team.add(self.teampro) login = self.c.login(username=self.upro2.username, password=self.upro2password) self.assertTrue(login) url = reverse('rower_prefs_view',kwargs={'userid':self.ubasic.id}) response = self.c.get(url) self.assertEqual(response.status_code,403) ## Pro cannot run analytics on behalf of athlete @patch('rowers.dataprep.read_cols_df_sql', side_effect = mocked_read_df_cols_sql_multistats) def test_pro_edit_athlete_analysis(self,mocked_df): self.rpro.team.add(self.teampro) login = self.c.login(username=self.upro2.username, password=self.upro2password) self.assertTrue(login) url = reverse('cumstats', kwargs={ 'theuser':self.ubasic.id, } ) response = self.c.get(url) self.assertEqual(response.status_code,403) ## Self Coach cannot upload on behalf of athlete @patch('rowers.dataprep.create_engine') @patch('rowers.dataprep.getsmallrowdata_db',side_effect=mocked_getsmallrowdata_db) def test_plan_edit_athlete_upload(self,mocked_sqlalchemy,mocked_getsmallrowdata_db): self.rpro.team.add(self.teamplan) login = self.c.login(username=self.uplan2.username, password=self.uplan2password) self.assertTrue(login) url = reverse('team_workout_upload_view') response = self.c.get(url,follow=True) self.assertEqual(response.status_code,200) expected_url = reverse('paidplans') self.assertRedirects(response, expected_url = expected_url, status_code=302,target_status_code=200) ## Pro users can see team members' workout, but not edit def test_pro_edit_athlete_workout(self): self.rpro.team.add(self.teampro) self.rpro2.team.add(self.teampro) login = self.c.login(username=self.upro2.username, password=self.upro2password) self.assertTrue(login) url = reverse('workout_edit_view', kwargs={'id':encoder.encode_hex(self.upro_workouts[0].id)} ) response = self.c.get(url) self.assertEqual(response.status_code,403) url = reverse('workout_view', kwargs={'id':encoder.encode_hex(self.upro_workouts[0].id)} ) response = self.c.get(url) self.assertEqual(response.status_code,200) ## Self Coach users can see team members' workout, but not edit def test_plan_edit_athlete_workout(self): self.rpro.team.add(self.teamplan) login = self.c.login(username=self.uplan2.username, password=self.uplan2password) self.assertTrue(login) url = reverse('workout_edit_view', kwargs={'id':encoder.encode_hex(self.ubasic_workouts[0].id)} ) response = self.c.get(url) self.assertEqual(response.status_code,403) url = reverse('workout_view', kwargs={'id':encoder.encode_hex(self.ubasic_workouts[0].id)} ) response = self.c.get(url) self.assertEqual(response.status_code,200) ## Basic users can see team members' workout, but not edit def test_basic_edit_athlete_workout(self): self.rbasic.team.add(self.teamcoach) self.rplan2.team.add(self.teamcoach) login = self.c.login(username=self.ubasic.username, password=self.ubasicpassword) self.assertTrue(login) url = reverse('workout_edit_view', kwargs={'id':encoder.encode_hex(self.uplan2_workouts[0].id)} ) response = self.c.get(url) self.assertEqual(response.status_code,403) url = reverse('workout_view', kwargs={'id':encoder.encode_hex(self.uplan2_workouts[0].id)} ) response = self.c.get(url) self.assertEqual(response.status_code,200) # stats url = reverse('workout_view', kwargs={'id':encoder.encode_hex(self.uplan2_workouts[0].id)} ) response = self.c.get(url) self.assertEqual(response.status_code,200) # workflow url = reverse('workout_workflow_view', kwargs={'id':encoder.encode_hex(self.uplan2_workouts[0].id)} ) response = self.c.get(url) self.assertEqual(response.status_code,200) # stats url = reverse('workout_stats_view', kwargs={'id':encoder.encode_hex(self.uplan2_workouts[0].id)} ) response = self.c.get(url) self.assertEqual(response.status_code,200) ## Pro users (and higher) can join group led by other Pro (or higher) user def test_team_member_request_pro_pro(self): login = self.c.login(username=self.upro.username,password=self.upropassword) self.assertTrue(login) url = reverse('team_requestmembership_view', kwargs = { 'teamid':self.teampro.id, 'userid':self.upro.id }) response = self.c.get(url,follow=True) self.assertEqual(response.status_code,200) expected_url = reverse('team_view',kwargs={'id':self.teampro.id}) self.assertRedirects(response, expected_url = expected_url, status_code=302,target_status_code=200) ## Basic cannot join groups from Pro or Self Coach users (redirects to paid plans) def test_team_member_request_basic_pro(self): login = self.c.login(username=self.ubasic.username,password=self.ubasicpassword) self.assertTrue(login) url = reverse('team_requestmembership_view', kwargs = { 'teamid':self.teampro.id, 'userid':self.ubasic.id }) response = self.c.get(url,follow=True) self.assertEqual(response.status_code,200) expected_url = reverse('paidplans') self.assertRedirects(response, expected_url = expected_url, status_code=302,target_status_code=200) @override_settings(TESTING=True) class PermissionsCoachingTests(TestCase): def setUp(self): self.c = Client() ## Users - Pro, Basic, Coach & Self Coach self.ucoach = UserFactory(username='coachuser') self.rcoach = Rower.objects.create(user=self.ucoach, birthdate=faker.profile()['birthdate'], gdproptin=True,gdproptindate=timezone.now(), rowerplan='coach',clubsize=10) self.ucoach_workouts = WorkoutFactory.create_batch(5, user=self.rcoach) self.coachinggroup = CoachingGroup.objects.create() self.rcoach.mycoachgroup = self.coachinggroup self.rcoach.save() self.factory = RequestFactory() self.ucoachpassword = faker.word() self.ucoach.set_password(self.ucoachpassword) self.ucoach.save() self.uplan = UserFactory(username='planuser') self.rplan = Rower.objects.create(user=self.uplan, birthdate=faker.profile()['birthdate'], gdproptin=True,gdproptindate=timezone.now(), rowerplan='plan') self.uplan_workouts = WorkoutFactory.create_batch(5, user=self.rplan) self.factory = RequestFactory() self.password = faker.word() self.uplan.set_password(self.password) self.uplan.save() self.upro = UserFactory(username='prouser') self.rpro = Rower.objects.create(user=self.upro, birthdate=faker.profile()['birthdate'], gdproptin=True,gdproptindate=timezone.now(), rowerplan='pro') self.upro_workouts = WorkoutFactory.create_batch(5, user=self.rpro) self.factory = RequestFactory() self.password = faker.word() self.upro.set_password(self.password) self.upro.save() self.uplan2 = UserFactory(username='planuser2') self.rplan2 = Rower.objects.create(user=self.uplan2, birthdate=faker.profile()['birthdate'], gdproptin=True,gdproptindate=timezone.now(), rowerplan='plan') self.uplan2_workouts = WorkoutFactory.create_batch(5, user=self.rplan2) self.factory = RequestFactory() self.password = faker.word() self.uplan2.set_password(self.password) self.uplan2.save() self.upro2 = UserFactory(username='prouser2') self.rpro2 = Rower.objects.create(user=self.upro2, birthdate=faker.profile()['birthdate'], gdproptin=True,gdproptindate=timezone.now(), rowerplan='pro') self.upro2_workouts = WorkoutFactory.create_batch(5, user=self.rpro2) self.factory = RequestFactory() self.password = faker.word() self.upro2.set_password(self.password) self.upro2.save() self.ubasic = UserFactory(username='basicuser') self.rbasic = Rower.objects.create(user=self.ubasic, birthdate=faker.profile()['birthdate'], gdproptin=True,gdproptindate=timezone.now(), rowerplan='basic') self.ubasic_workouts = WorkoutFactory.create_batch(5, user=self.rbasic) self.factory = RequestFactory() self.ubasicpassword = faker.word() self.ubasic.set_password(self.ubasicpassword) self.ubasic.save() ## TeamPro, TeamCoach, TeamSelfCoach self.teampro = Team.objects.create( name=faker.word()+'1', notes=faker.text(), manager=self.upro2) self.teamplan = Team.objects.create( name=faker.word()+'2', notes=faker.text(), manager=self.uplan2) self.teamcoach = Team.objects.create( name=faker.word()+'3', notes=faker.text(), manager=self.ucoach) def test_athlete_request_athlete_revoke(self): login = self.c.login(username=self.ubasic.username,password=self.ubasicpassword) self.assertTrue(login) url = reverse('request_coaching_view',kwargs={'coachid':self.rcoach.id}) expected_url = reverse('rower_teams_view') response = self.c.get(url,follow=True) self.assertRedirects(response, expected_url=expected_url, status_code=302,target_status_code=200) coachingrequests = CoachRequest.objects.filter(user=self.ubasic) self.assertEqual(len(coachingrequests),1) rekwest = coachingrequests[0] url = reverse('reject_revoke_coach_request',kwargs={'id':rekwest.id}) response = self.c.get(url,follow=True) self.assertRedirects(response, expected_url=expected_url, status_code=302,target_status_code=200) coachingrequests = CoachRequest.objects.filter(user=self.ubasic) self.assertEqual(len(coachingrequests),0) def test_coach_offer_coach_revoke(self): login = self.c.login(username=self.ucoach.username,password=self.ucoachpassword) self.assertTrue(login) url = reverse('offer_coaching_view',kwargs={'userid':self.ubasic.id}) expected_url = reverse('rower_teams_view') response = self.c.get(url,follow=True) self.assertRedirects(response, expected_url=expected_url, status_code=302,target_status_code=200) coachingrequests = CoachOffer.objects.filter(user=self.ubasic) self.assertEqual(len(coachingrequests),1) rekwest = coachingrequests[0] url = reverse('reject_revoke_coach_offer',kwargs={'id':rekwest.id}) response = self.c.get(url,follow=True) self.assertRedirects(response, expected_url=expected_url, status_code=302,target_status_code=200) coachingrequests = CoachOffer.objects.filter(user=self.ubasic) self.assertEqual(len(coachingrequests),0) def test_athlete_request_coach_reject(self): login = self.c.login(username=self.ubasic.username,password=self.ubasicpassword) self.assertTrue(login) url = reverse('request_coaching_view',kwargs={'coachid':self.rcoach.id}) expected_url = reverse('rower_teams_view') response = self.c.get(url,follow=True) self.assertRedirects(response, expected_url=expected_url, status_code=302,target_status_code=200) coachingrequests = CoachRequest.objects.filter(user=self.ubasic) self.assertEqual(len(coachingrequests),1) rekwest = coachingrequests[0] login = self.c.login(username=self.ucoach.username,password=self.ucoachpassword) self.assertTrue(login) url = reverse('reject_revoke_coach_request',kwargs={'id':rekwest.id}) response = self.c.get(url,follow=True) self.assertRedirects(response, expected_url=expected_url, status_code=302,target_status_code=200) coachingrequests = CoachRequest.objects.filter(user=self.ubasic) self.assertEqual(len(coachingrequests),0) def test_coach_offer_athlete_reject(self): login = self.c.login(username=self.ucoach.username,password=self.ucoachpassword) self.assertTrue(login) url = reverse('offer_coaching_view',kwargs={'userid':self.ubasic.id}) expected_url = reverse('rower_teams_view') response = self.c.get(url,follow=True) self.assertRedirects(response, expected_url=expected_url, status_code=302,target_status_code=200) coachingrequests = CoachOffer.objects.filter(user=self.ubasic) self.assertEqual(len(coachingrequests),1) rekwest = coachingrequests[0] login = self.c.login(username=self.ubasic.username,password=self.ubasicpassword) self.assertTrue(login) url = reverse('reject_revoke_coach_offer',kwargs={'id':rekwest.id}) response = self.c.get(url,follow=True) self.assertRedirects(response, expected_url=expected_url, status_code=302,target_status_code=200) coachingrequests = CoachOffer.objects.filter(user=self.ubasic) self.assertEqual(len(coachingrequests),0) def test_athlete_request_coach_accept_coach_drop(self): login = self.c.login(username=self.ubasic.username,password=self.ubasicpassword) self.assertTrue(login) url = reverse('request_coaching_view',kwargs={'coachid':self.rcoach.id}) expected_url = reverse('rower_teams_view') response = self.c.get(url,follow=True) self.assertRedirects(response, expected_url=expected_url, status_code=302,target_status_code=200) coachingrequests = CoachRequest.objects.filter(user=self.ubasic) self.assertEqual(len(coachingrequests),1) rekwest = coachingrequests[0] login = self.c.login(username=self.ucoach.username,password=self.ucoachpassword) self.assertTrue(login) url = reverse('coach_accept_coachrequest_view',kwargs={'code':rekwest.code}) response = self.c.get(url,follow=True) self.assertRedirects(response, expected_url=expected_url, status_code=302,target_status_code=200) coachingrequests = CoachRequest.objects.filter(user=self.ubasic) self.assertEqual(len(coachingrequests),0) coaches = teams.rower_get_coaches(self.rbasic) self.assertEqual(coaches[0],self.rcoach) url = reverse('coach_drop_athlete_confirm_view',kwargs={'id':self.rbasic.id}) response = self.c.get(url) self.assertEqual(response.status_code,200) url = reverse('coach_drop_athlete_view',kwargs={'id':self.rbasic.id}) response = self.c.get(url,follow=True) self.assertRedirects(response, expected_url=expected_url, status_code=302,target_status_code=200) coaches = teams.rower_get_coaches(self.rbasic) self.assertEqual(len(coaches),0) def test_coach_offer_athlete_accept_athlete_drop(self): login = self.c.login(username=self.ucoach.username,password=self.ucoachpassword) self.assertTrue(login) url = reverse('offer_coaching_view',kwargs={'userid':self.ubasic.id}) expected_url = reverse('rower_teams_view') response = self.c.get(url,follow=True) self.assertRedirects(response, expected_url=expected_url, status_code=302,target_status_code=200) coachingrequests = CoachOffer.objects.filter(user=self.ubasic) self.assertEqual(len(coachingrequests),1) rekwest = coachingrequests[0] login = self.c.login(username=self.ubasic.username,password=self.ubasicpassword) self.assertTrue(login) url = reverse('rower_accept_coachoffer_view',kwargs={'code':rekwest.code}) response = self.c.get(url,follow=True) self.assertRedirects(response, expected_url=expected_url, status_code=302,target_status_code=200) coachingrequests = CoachOffer.objects.filter(user=self.ubasic) self.assertEqual(len(coachingrequests),0) coaches = teams.rower_get_coaches(self.rbasic) self.assertEqual(coaches[0],self.rcoach) url = reverse('athlete_drop_coach_view',kwargs={'id':self.rcoach.id}) response = self.c.get(url,follow=True) self.assertRedirects(response, expected_url=expected_url, status_code=302,target_status_code=200) coaches = teams.rower_get_coaches(self.rbasic) self.assertEqual(len(coaches),0) def test_coach_offer_athlete_accept_coach_drop(self): login = self.c.login(username=self.ucoach.username,password=self.ucoachpassword) self.assertTrue(login) url = reverse('offer_coaching_view',kwargs={'userid':self.ubasic.id}) expected_url = reverse('rower_teams_view') response = self.c.get(url,follow=True) self.assertRedirects(response, expected_url=expected_url, status_code=302,target_status_code=200) coachingrequests = CoachOffer.objects.filter(user=self.ubasic) self.assertEqual(len(coachingrequests),1) rekwest = coachingrequests[0] login = self.c.login(username=self.ubasic.username,password=self.ubasicpassword) self.assertTrue(login) url = reverse('rower_accept_coachoffer_view',kwargs={'code':rekwest.code}) response = self.c.get(url,follow=True) self.assertRedirects(response, expected_url=expected_url, status_code=302,target_status_code=200) coachingrequests = CoachOffer.objects.filter(user=self.ubasic) self.assertEqual(len(coachingrequests),0) coaches = teams.rower_get_coaches(self.rbasic) self.assertEqual(coaches[0],self.rcoach) login = self.c.login(username=self.ucoach.username,password=self.ucoachpassword) self.assertTrue(login) url = reverse('coach_drop_athlete_view',kwargs={'id':self.rbasic.id}) response = self.c.get(url,follow=True) self.assertRedirects(response, expected_url=expected_url, status_code=302,target_status_code=200) coaches = teams.rower_get_coaches(self.rbasic) self.assertEqual(len(coaches),0) def test_athlete_request_coach_accept_athlete_drop(self): login = self.c.login(username=self.ubasic.username,password=self.ubasicpassword) self.assertTrue(login) url = reverse('request_coaching_view',kwargs={'coachid':self.rcoach.id}) expected_url = reverse('rower_teams_view') response = self.c.get(url,follow=True) self.assertRedirects(response, expected_url=expected_url, status_code=302,target_status_code=200) coachingrequests = CoachRequest.objects.filter(user=self.ubasic) self.assertEqual(len(coachingrequests),1) rekwest = coachingrequests[0] login = self.c.login(username=self.ucoach.username,password=self.ucoachpassword) self.assertTrue(login) url = reverse('coach_accept_coachrequest_view',kwargs={'code':rekwest.code}) response = self.c.get(url,follow=True) self.assertRedirects(response, expected_url=expected_url, status_code=302,target_status_code=200) coachingrequests = CoachRequest.objects.filter(user=self.ubasic) self.assertEqual(len(coachingrequests),0) coaches = teams.rower_get_coaches(self.rbasic) self.assertEqual(coaches[0],self.rcoach) login = self.c.login(username=self.ubasic.username,password=self.ubasicpassword) self.assertTrue(login) url = reverse('athlete_drop_coach_confirm_view',kwargs={'id':self.rcoach.id}) response = self.c.get(url) self.assertEqual(response.status_code,200) url = reverse('athlete_drop_coach_view',kwargs={'id':self.rcoach.id}) response = self.c.get(url,follow=True) self.assertRedirects(response, expected_url=expected_url, status_code=302,target_status_code=200) coaches = teams.rower_get_coaches(self.rbasic) self.assertEqual(len(coaches),0) # coach related ## coach disappears from list when downgrading # Race related ## Basic and Pro users can create races ## Basic users can subscribe to any race ### ## group members can see but not edit each other's plans