from django.test import TestCase
from graphene import Context
from graphene.test import Client

from core.factories import UserFactory
from users.factories import SchoolClassFactory
from users.models import SchoolClass, SchoolClassMember
from api.schema import schema


class JoinSchoolClassTest(TestCase):
    def setUp(self):
        self.client = Client(schema=schema)
        self.user = UserFactory(username='ueli')
        SchoolClassFactory(users=[self.user], name='Klasse 1A', code='XXXX')
        SchoolClassFactory(name='Klasse 2B', code='YYYY')
        self.mutation = """
        mutation JoinClass($input: JoinClassInput!) {
          joinClass(input: $input) {
            success
            schoolClass {
              id
              name
            }
          }
        }
        """
        self.variables = {
            'input': {
                'code': 'YYYY'
            }
        }
        self.context = Context(user=self.user)

    def test_join_class(self):
        self.assertEqual(self.user.school_classes.count(), 1)

        executed = self.client.execute(self.mutation, variables=self.variables, context=self.context)
        self.assertIsNone(executed.get('errors', None))
        result = executed['data']['joinClass']
        self.assertEqual(result['success'], True)
        self.assertEqual(result['schoolClass']['name'], 'Klasse 2B')
        self.assertEqual(self.user.school_classes.count(), 2)
        self.assertEqual(self.user.selected_class.code, 'YYYY')

    def test_class_already_joined(self):
        code = 'YYYY'
        school_class = SchoolClass.objects.get(code=code)
        SchoolClassMember.objects.create(
            user=self.user,
            school_class=school_class
        )

        self.assertEqual(self.user.school_classes.count(), 2)

        executed = self.client.execute(self.mutation, variables=self.variables, context=self.context)
        self.assertIsNotNone(executed['errors'])
        self.assertEqual(executed['errors'][0]['message'], '[CAJ] Schüler ist bereits in Klasse')
        self.assertEqual(self.user.school_classes.count(), 2)

    def test_code_not_valid(self):
        code = '1234'
        self.assertEqual(self.user.school_classes.count(), 1)

        executed = self.client.execute(self.mutation, variables={
            'input': {
                'code': code
            }
        }, context=self.context)
        self.assertIsNotNone(executed['errors'])
        self.assertEqual(executed['errors'][0]['message'], '[CNV] Code ist nicht gültig')
        self.assertEqual(self.user.school_classes.count(), 1)
