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
from rowers.rower_rules import is_coach_user

@override_settings(TESTING=True)
class PlanningPermissionsCoach(TestCase):
    def setUp(self):
        self.c = Client()

        self.ucoach = UserFactory()
        self.rcoach = Rower.objects.create(
            user=self.ucoach,
            birthdate=faker.profile()['birthdate'],
            gdproptin=True,surveydone=True,
            gdproptindate=timezone.now(),
            rowerplan='coach',
            clubsize=10,
        )
        self.ucoachpassword = faker.word()
        self.ucoach.set_password(self.ucoachpassword)
        self.ucoach.save()

        self.ucoachee = UserFactory()
        self.rcoachee = Rower.objects.create(
            user=self.ucoachee,
            birthdate=faker.profile()['birthdate'],
            gdproptin=True,surveydone=True,
            gdproptindate=timezone.now(),
            rowerplan='basic'
        )

        self.coachgroup = CoachingGroup.objects.create(name=self.ucoach.first_name)
        self.rcoach.mycoachgroup = self.coachgroup
        self.rcoach.save()

        self.team = Team.objects.create(
            name=faker.word()+'3',
            notes=faker.text(),
            manager=self.ucoach)

        # coachee is in coach's team
        self.rcoachee.team.add(self.team)

        # coachee is coached by coach
        self.rcoachee.coachinggroups.add(self.rcoach.mycoachgroup)
        self.rcoachee.save()

        self.ugroupmember = UserFactory()
        self.rgroupmember = Rower.objects.create(
            user=self.ugroupmember,
            birthdate=faker.profile()['birthdate'],
            gdproptin=True,surveydone=True,
            gdproptindate=timezone.now(),
            rowerplan='basic'
        )

        # groupmember is in coach's team (but not coached)
        self.rgroupmember.team.add(self.team)


    # def test_target(self):

    def test_trainingplan(self):
        plan = TrainingPlan(
            name='test plan',
            manager=self.ucoach.rower,
        )
        plan.save()

        # can add self and coachee
        plan.rowers.add(self.ucoach.rower)
        plan.rowers.add(self.ucoachee.rower)

        # test 1
        athletes = plan.rowers.all()
        self.assertTrue(self.ucoach.rower in athletes)
        self.assertTrue(self.ucoachee.rower in athletes)

        # can add groupmember if not basic
        plan.rowers.add(self.rgroupmember)
        athletes = plan.rowers.all()
        self.assertTrue(self.rgroupmember in athletes)


@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,surveydone=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,surveydone=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,surveydone=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,surveydone=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,surveydone=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,surveydone=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,surveydone=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,surveydone=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,surveydone=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,surveydone=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,surveydone=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,surveydone=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,surveydone=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,surveydone=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,surveydone=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,surveydone=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,surveydone=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,surveydone=True,gdproptindate=timezone.now(),
                                      rowerplan='basic')

        self.ubasic_workouts = WorkoutFactory.create_batch(5, user=self.rbasic)
        self.ubasic_workouts[0].privacy == 'private'

        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)


    ## only ubasic can view ubasic_workouts[0] which is private
    def test_view_workout(self):
        login = self.c.login(username=self.ucoach.username, password=self.ucoachpassword)
        self.assertTrue(login)

        url = reverse('workout_view',
                      kwargs={'id':self.ubasic_workouts[0].id})
        response = self.c.get(url)
        self.assertTrue(response.status_code,403)

        login = self.c.login(username=self.ubasic.username, password=self.ubasicpassword)
        self.assertTrue(login)

        url = reverse('workout_view',
                      kwargs={'id':self.ubasic_workouts[0].id})
        response = self.c.get(url)
        self.assertTrue(response.status_code,200)

    ## 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
    # 1, Preferences
    def test_coach_edit_athlete_prefs(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_prefs_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)

    # 2, Favorite Charts
    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_favoritecharts_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_favoritecharts_view',kwargs={'userid':self.ubasic.id})

        response = self.c.get(url)
        self.assertEqual(response.status_code,403)

    # 3, Export Settings
    def test_coach_edit_athlete_exportsettings(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_exportsettings_view',kwargs={'userid':self.ubasic.id})

        response = self.c.get(url)
        self.assertEqual(response.status_code,200)

    def test_coach_edit_athlete_exportsettings_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_exportsettings_view',kwargs={'userid':self.ubasic.id})

        response = self.c.get(url)
        self.assertEqual(response.status_code,403)

    # 4, Account settings
    def test_coach_edit_athlete_account(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_edit_view',kwargs={'userid':self.ubasic.id})

        response = self.c.get(url)
        self.assertEqual(response.status_code,200)

    def test_coach_edit_athlete_account_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_edit_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={
                          'userid':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={
                          'userid':self.ubasic.id,
                      }
        )

        response = self.c.get(url)

        self.assertEqual(response.status_code,403)

    @patch('rowers.dataprep.read_cols_df_sql', side_effect = mocked_read_df_cols_sql_multistats)
    def test_coach_edit_athlete_analysis_not2(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('analysis_new',
                  kwargs={
                      'userid':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)

    ## Coach can see list of workouts of athlete
    def test_coach_athlete_workout_list(self):
        self.rbasic.team.add(self.teamcoach)

        login = self.c.login(username=self.ucoach.username, password=self.ucoachpassword)
        self.assertTrue(login)

        url = reverse('workouts_view',
                      kwargs={'rowerid':self.rbasic.id})



        response = self.c.get(url)
        self.assertEqual(response.status_code,200)

        url = reverse('workouts_view',
                      kwargs={'userid':self.ubasic.id})

        response = self.c.get(url)
        self.assertEqual(response.status_code,200)

        url = reverse('workouts_view')

        response = self.c.get(url)
        self.assertEqual(response.status_code,200)

    ## 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_view')

        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={
                          'userid':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_view')

        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_view')

        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):
        with transaction.atomic():
            self.rpro.team.add(self.teampro)

            login = self.c.login(username=self.upro2.username, password=self.upro2password)
            self.assertTrue(login)


            url = reverse('cumstats',
                        kwargs={
                            'userid':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_view')
        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={'team_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_view')
        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,surveydone=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,surveydone=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,surveydone=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,surveydone=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,surveydone=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,surveydone=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
