"""This module holds the test cases for the ``validators`` of the ``api`` app"""

import json

from django.core.urlresolvers import reverse
from django.test import RequestFactory

from mtp.apps.common.tests.test_cases import MTPTestCase, DEFAULT_PASSWORD

from ..oauth2_validators import MTPOAuth2Validator

from .test_cases import MTPOAuthClientTestCaseMixin


class MTPOAuth2ValidatorTestCase(MTPOAuthClientTestCaseMixin, MTPTestCase):
    """Test case for the ``MTPOAuth2Validator`` class"""

    def test_validate_user_should_return_false_if_user_is_soft_deleted(self):
        """Test that the ``validate_user`` method should return False if soft deleted user"""

        # The user is no soft-deleted
        self.assertTrue(
            MTPOAuth2Validator().validate_user(
                username=self.trainee.username,
                password=DEFAULT_PASSWORD,
                client={},
                request=RequestFactory()
            )
        )

        # the user is soft-deleted
        self.trainee.is_deleted = True
        self.trainee.save()

        self.assertFalse(
            MTPOAuth2Validator().validate_user(
                username=self.trainee.username,
                password=DEFAULT_PASSWORD,
                client={},
                request=RequestFactory()
            )
        )

    def test_authenticate_with_validator_return_401_if_user_is_soft_deleted(self):
        """Test that authenticate with a soft-deleted user should return an error"""

        token_url = reverse('oauth2_provider:token')

        # The user is not soft-deleted
        response = self.client.post(
            token_url,
            {
                'client_id': self.oauth_application.client_id,
                'client_secret': self.oauth_application.client_secret,
                'grant_type': 'password',
                'username': self.trainee.username,
                'password': DEFAULT_PASSWORD
            }
        )

        self.assertEqual(response.status_code, 200)

        # the user is soft-deleted
        self.trainee.is_deleted = True
        self.trainee.save()

        response = self.client.post(
            token_url,
            {
                'client_id': self.oauth_application.client_id,
                'client_secret': self.oauth_application.client_secret,
                'grant_type': 'password',
                'username': self.trainee.username,
                'password': DEFAULT_PASSWORD
            }
        )

        self.assertEqual(response.status_code, 401)
        self.assertEqual(
            json.loads(response.content.decode('utf-8')),
            {
                'error_description': 'Invalid credentials given.',
                'error': 'invalid_grant'
            }
        )
