# Path: user_management/models/tests/factories.py
# class AuthTokenFactory(factory.DjangoModelFactory):
#     key = factory.Sequence('key{}'.format)
#     user = factory.SubFactory(UserFactory)
# 
#     class Meta:
#         model = AuthToken
# 
# class UserFactory(factory.DjangoModelFactory):
#     name = factory.Sequence('Test User {}'.format)
#     email = factory.Sequence('email{}@example.com'.format)
#     is_active = True
# 
#     class Meta:
#         model = get_user_model()
# 
#     @factory.post_generation
#     def password(self, create, extracted='default password', **kwargs):
#         self.raw_password = extracted
#         self.set_password(self.raw_password)
#         if create:
#             self.save()
# 
# Path: user_management/api/authentication.py
# class FormTokenAuthentication(authentication.BaseAuthentication):
#     def authenticate(self, request):
#         """
#         Authenticate a user from a token form field
# 
#         Errors thrown here will be swallowed by django-rest-framework, and it
#         expects us to return None if authentication fails.
#         """
#         try:
#             key = request.data['token']
#         except KeyError:
#             return
# 
#         try:
#             token = AuthToken.objects.get(key=key)
#         except AuthToken.DoesNotExist:
#             return
# 
#         return (token.user, token)
# 
# class TokenAuthentication(DRFTokenAuthentication):
#     model = AuthToken
# 
#     def authenticate_credentials(self, key):
#         """Custom authentication to check if auth token has expired."""
#         user, token = super(TokenAuthentication, self).authenticate_credentials(key)
# 
#         if token.expires < timezone.now():
#             msg = _('Token has expired.')
#             raise exceptions.AuthenticationFailed(msg)
# 
#         # Update the token's expiration date
#         token.update_expiry()
# 
#         return (user, token)


import datetime
import mock
from django.http import QueryDict
from django.test import TestCase
from django.utils import timezone
from rest_framework import exceptions
from user_management.models.tests.factories import AuthTokenFactory, UserFactory
from ..authentication import FormTokenAuthentication, TokenAuthentication


class TestFormTokenAuthentication(TestCase):
    def test_no_token(self):
        request = mock.Mock(data=QueryDict(''))
        response = FormTokenAuthentication().authenticate(request)
        self.assertIsNone(response)

    def test_invalid_token(self):
        data = QueryDict('', mutable=True)
        data.update({'token': 'WOOT'})
        request = mock.Mock(data=data)
        response = FormTokenAuthentication().authenticate(request)
        self.assertIsNone(response)

    def test_valid_token(self):
        token = AuthTokenFactory.create()
        data = QueryDict('', mutable=True)
        data.update({'token': token.key})
        request = mock.Mock(data=data)
        response = FormTokenAuthentication().authenticate(request)
        expected = (token.user, token)
        self.assertEqual(response, expected)


class TestTokenAuthentication(TestCase):
    def setUp(self):
        self.now = timezone.now()
        self.days = 1
        self.key = 'k$y'

# Path: user_management/models/tests/factories.py
# class AuthTokenFactory(factory.DjangoModelFactory):
#     key = factory.Sequence('key{}'.format)
#     user = factory.SubFactory(UserFactory)
# 
#     class Meta:
#         model = AuthToken
# 
# class UserFactory(factory.DjangoModelFactory):
#     name = factory.Sequence('Test User {}'.format)
#     email = factory.Sequence('email{}@example.com'.format)
#     is_active = True
# 
#     class Meta:
#         model = get_user_model()
# 
#     @factory.post_generation
#     def password(self, create, extracted='default password', **kwargs):
#         self.raw_password = extracted
#         self.set_password(self.raw_password)
#         if create:
#             self.save()
# 
# Path: user_management/api/authentication.py
# class FormTokenAuthentication(authentication.BaseAuthentication):
#     def authenticate(self, request):
#         """
#         Authenticate a user from a token form field
# 
#         Errors thrown here will be swallowed by django-rest-framework, and it
#         expects us to return None if authentication fails.
#         """
#         try:
#             key = request.data['token']
#         except KeyError:
#             return
# 
#         try:
#             token = AuthToken.objects.get(key=key)
#         except AuthToken.DoesNotExist:
#             return
# 
#         return (token.user, token)
# 
# class TokenAuthentication(DRFTokenAuthentication):
#     model = AuthToken
# 
#     def authenticate_credentials(self, key):
#         """Custom authentication to check if auth token has expired."""
#         user, token = super(TokenAuthentication, self).authenticate_credentials(key)
# 
#         if token.expires < timezone.now():
#             msg = _('Token has expired.')
#             raise exceptions.AuthenticationFailed(msg)
# 
#         # Update the token's expiration date
#         token.update_expiry()
# 
#         return (user, token)


# Path: user_management/api/tests/test_authentication.py
import datetime
import mock
from django.http import QueryDict
from django.test import TestCase
from django.utils import timezone
from rest_framework import exceptions
from user_management.models.tests.factories import AuthTokenFactory, UserFactory
from ..authentication import FormTokenAuthentication, TokenAuthentication



class TestFormTokenAuthentication(TestCase):
    def test_no_token(self):
        request = mock.Mock(data=QueryDict(''))
        response = FormTokenAuthentication().authenticate(request)
        self.assertIsNone(response)

    def test_invalid_token(self):
        data = QueryDict('', mutable=True)
        data.update({'token': 'WOOT'})
        request = mock.Mock(data=data)
        response = FormTokenAuthentication().authenticate(request)
        self.assertIsNone(response)

    def test_valid_token(self):
        token = AuthTokenFactory.create()
        data = QueryDict('', mutable=True)
        data.update({'token': token.key})
        request = mock.Mock(data=data)
        response = FormTokenAuthentication().authenticate(request)
        expected = (token.user, token)
        self.assertEqual(response, expected)


class TestTokenAuthentication(TestCase):
    def setUp(self):
        self.now = timezone.now()
        self.days = 1
        self.key = 'k$y'

        self.user = UserFactory.create()