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

from api.schema import schema
from core.tests.base_test import SkillboxTestCase
from portfolio.factories import ProjectFactory
from users.factories import SchoolClassFactory
from users.models import User
from users.services import create_users
from api.test_utils import create_client, DefaultUserTestCase
from portfolio.models import Project

class ProjectQuery(SkillboxTestCase):
    def setUp(self):
        create_users()
        self.teacher = User.objects.get(username='teacher')
        self.teacher2 = User.objects.get(username='teacher2')
        self.student = User.objects.get(username='student1')
        self.student2 = User.objects.get(username='student2')
        school_class1 = SchoolClassFactory(users=[self.teacher, self.student])
        school_class2 = SchoolClassFactory(users=[self.teacher2, self.student2])
        self.project1 = ProjectFactory(student=self.student)

        self.mutation = '''
        mutation DeleteProject($input: DeleteProjectInput!) {
          deleteProject(input: $input) {
            success
            errors
          }
        }
        '''

        self.variables = {
            'input': {
                'slug': self.project1.slug
            }
        }

    def test_should_be_able_to_delete_own_projects(self):

        self.assertEqual(Project.objects.count(), 1)
        request = RequestFactory().get('/')
        request.user = self.student
        self.client = Client(schema=schema, context_value=request)

        result = self.client.execute(self.mutation, variables=self.variables)

        self.assertIsNone(result.get('errors'))
        self.assertEqual(Project.objects.count(), 0)

    def test_should_not_be_able_to_delete_other_projects(self):
        self.assertEqual(Project.objects.count(), 1)
        request = RequestFactory().get('/')
        request.user = self.student2
        self.client = Client(schema=schema, context_value=request)

        result = self.client.execute(self.mutation, variables=self.variables)
        self.assertEqual(result.get('errors')[0]['message'], 'Permission denied: Incorrect project')

    def test_should_not_be_able_to_edit_other_projects(self):
        self.assertEqual(Project.objects.count(), 1)
        request = RequestFactory().get('/')
        request.user = self.student2
        self.client = Client(schema=schema, context_value=request)
        mutation = '''
mutation UpdateProjectMutation($input: UpdateProjectInput!){
  updateProject(input: $input) {
    project {
      id
    }
  }
}
'''
        # project:
            #  {
            #   title: String
            #   description: String
            #   objectives: String
            #   appearance: String
            #   id: ID!
            #   final: Boolean
            # }
        input = {
            'project': {
                'slug': self.project1.slug,
                'title': 'BAD! THIS IS BAD!'
            }
        }
        result = self.get_client(self.student2).execute(mutation, variables={
            'input': input
        })
        self.assertIsNotNone(result.errors)
        self.assertTrue('message' in result.errors[0])
        self.assertEqual(result.errors[0]['message'], 'not allowed')

    def test_owner_can_edit(self):
        self.assertEqual(Project.objects.count(), 1)
        request = RequestFactory().get('/')
        request.user = self.student
        self.client = Client(schema=schema, context_value=request)
        mutation = '''
mutation UpdateProjectMutation($input: UpdateProjectInput!){
  updateProject(input: $input) {
    project {
      id
    }
  }
}
'''

        input = {
            'project': {
                'slug': self.project1.slug,
                'title': 'Good! THIS IS good!'
            }
        }
        result = self.get_client(self.student).execute(mutation, variables={
            'input': input
        })
        self.assertIsNone(result.errors)


class ProjectMutationsTestCase(DefaultUserTestCase):
    def test_add_project(self):
        client = create_client(self.student1)
        mutation = """
        mutation AddProjectMutation($input: AddProjectInput!){
          addProject(input: $input){
            project {
              id
            }
            errors
          }
        }
        """

        result = client.execute(mutation, variables={
            'input': {
                "project": {
                    "title": "Rick Astley",
                    "description": "She wants to dance with me",
                    "objectives": "Dance with me",
                    "appearance": "green"
                }
            }
        })
        self.assertIsNone(result.get('errors'))
        self.assertEqual(Project.objects.count(), 1)

