from django.test import TestCase, RequestFactory
from graphene.test import Client
from graphql_relay import to_global_id

from api.schema import schema
from api.utils import get_graphql_mutation

from books.factories import BookFactory, ContentBlockFactory
from users.models import User
from users.services import create_users


class ModuleSolutionVisibilityTest(TestCase):
    def setUp(self):
        create_users()
        _, _, self.module, chapter, _ = BookFactory.create_default_structure()
        content = {
            'type': 'solution',
            'value': {
                'text': '<p>Das ist eine Lösung.</p>'
            }
        }

        content_block = ContentBlockFactory.create(
            parent=chapter,
            module=self.module,
            title="Another content block",
            type="task",
            contents=[content]
        )

        self.teacher = User.objects.get(username="teacher")
        self.selected_class = self.teacher.selected_class
        self.student = User.objects.get(username="student1")
        student_request = RequestFactory().get('/')
        student_request.user = self.student
        self.student_client = Client(schema=schema, context_value=student_request)

        teacher_request = RequestFactory().get('/')
        teacher_request.user = self.teacher
        self.teacher_client = Client(schema=schema, context_value=teacher_request)

        self.content_block_id = to_global_id('ContentBlockNode', content_block.pk)

        self.update_mutation = get_graphql_mutation('updateSolutionVisibility.gql')

        self.query = """
        query ContentBlockQuery($id: ID!) {
          contentBlock(id: $id) {
              contents
              title
          }
        }
        """

    def test_hide_solutions_for_students_and_then_show_them(self):
        self.assertEqual(self.student.selected_class, self.teacher.selected_class)

        student_result = self.student_client.execute(self.query, variables={
            'id': self.content_block_id
        })

        self.assertIsNone(student_result.get('errors'))
        self.assertEqual(len(student_result.get('data').get('contentBlock').get('contents')), 0)

        teacher_result = self.teacher_client.execute(self.query, variables={
            'id': self.content_block_id
        })
        self.assertIsNone(teacher_result.get('errors'))
        self.assertEqual(len(teacher_result.get('data').get('contentBlock').get('contents')), 1)

        teacher_result = self.teacher_client.execute(self.update_mutation, variables={
            'input': {
                'slug': self.module.slug,
                'enabled': True
            }
        })

        self.assertEqual(teacher_result.get('data').get('updateSolutionVisibility').get('success'), True)

        self.assertEqual(self.module.solutions_enabled_for.filter(pk=self.selected_class.pk).count(), 1)

        student_result = self.student_client.execute(self.query, variables={
            'id': self.content_block_id
        })

        self.assertIsNone(student_result.get('errors'))
        self.assertEqual(len(student_result.get('data').get('contentBlock').get('contents')), 1)

        teacher_result = self.teacher_client.execute(self.query, variables={
            'id': self.content_block_id
        })
        self.assertIsNone(teacher_result.get('errors'))
        self.assertEqual(len(teacher_result.get('data').get('contentBlock').get('contents')), 1)

    def test_try_to_show_solutions_as_student_and_fail(self):
        result = self.student_client.execute(self.query, variables={
            'id': self.content_block_id
        })

        self.assertEqual(len(result.get('data').get('contentBlock').get('contents')), 0)

        result = self.student_client.execute(self.update_mutation, variables={
            'input': {
                'slug': self.module.slug,
                'enabled': True
            }
        })

        self.assertIsNone(result.get('errors'))
        self.assertFalse(result.get('data').get('success'))

        result = self.student_client.execute(self.query, variables={
            'id': self.content_block_id
        })

        self.assertEqual(len(result.get('data').get('contentBlock').get('contents')), 0)
