diff --git a/rest_auth/runtests.py b/rest_auth/runtests.py index cec36c6..dc9b53d 100644 --- a/rest_auth/runtests.py +++ b/rest_auth/runtests.py @@ -11,6 +11,7 @@ from django.contrib.sites.models import RequestSite from django.contrib.sites.models import Site from django.db import models +from rest_framework.serializers import _resolve_model from registration.models import RegistrationProfile from registration.backends.default.views import RegistrationView as BaseRegistrationView from registration import signals @@ -43,6 +44,12 @@ class RegistrationView(BaseRegistrationView): signals.user_registered.send(sender=self.__class__, user=new_user, request=request) + + # create user profile + user_profile_model = _resolve_model( + getattr(settings, 'REST_PROFILE_MODULE', None)) + user_profile_model.objects.create(user=new_user) + return new_user settings.REST_REGISTRATION_BACKEND = 'rest_auth.runtests.RegistrationView' diff --git a/rest_auth/test_settings.py b/rest_auth/test_settings.py index dcf30b4..1b6f82e 100644 --- a/rest_auth/test_settings.py +++ b/rest_auth/test_settings.py @@ -15,7 +15,7 @@ MEDIA_ROOT = os.path.join(PROJECT_ROOT, '%s' % UPLOADS_DIR_NAME) IS_DEV = False IS_STAGING = False IS_PROD = False -IS_TEST = 'test' in sys.argv +IS_TEST = 'test' in sys.argv or 'test_coverage' in sys.argv if django.VERSION[:2] >= (1, 3): DATABASES = { diff --git a/rest_auth/tests.py b/rest_auth/tests.py index 26e11cf..43abde6 100644 --- a/rest_auth/tests.py +++ b/rest_auth/tests.py @@ -2,6 +2,7 @@ import json import os import sys from datetime import datetime, date, time +from urlparse import urlparse os.environ['DJANGO_SETTINGS_MODULE'] = 'test_settings' test_dir = os.path.dirname(__file__) @@ -13,6 +14,8 @@ from django.test.client import Client, MULTIPART_CONTENT from django.test import TestCase from django.contrib.auth.models import User from django.contrib.auth import get_user_model +from django.core import mail +from django.core.urlresolvers import resolve from registration.models import RegistrationProfile from rest_framework.serializers import _resolve_model @@ -128,13 +131,15 @@ class LoginAPITestCase(TestCase, BaseAPITestCase): USERNAME = 'person' PASS = 'person' - + EMAIL = "person1@world.com" + NEW_PASS = 'new-test-pass' def setUp(self): self.init() self.login_url = reverse('rest_login') self.password_change_url = reverse('rest_password_change') self.register_url = reverse('rest_register') + self.password_reset_url = reverse('rest_password_reset') def test_login(self): payload = { @@ -230,15 +235,15 @@ class LoginAPITestCase(TestCase, BaseAPITestCase): self.get(verify_url) new_user = get_user_model().objects.latest('id') self.assertEqual(new_user.is_active, True) - #user_profile = user_profile_model.objects.get(user=new_user) - #self.assertIsNotNone(user_profile) + user_profile = user_profile_model.objects.get(user=new_user) + self.assertIsNotNone(user_profile) def test_registration_user_without_profile(self): payload = { "username": self.USERNAME, "password": self.PASS, - "email": "person1@world.com" + "email": self.EMAIL, } self.post(self.register_url, data=payload, status_code=201) @@ -256,5 +261,45 @@ class LoginAPITestCase(TestCase, BaseAPITestCase): new_user = get_user_model().objects.latest('id') self.assertEqual(new_user.is_active, True) - # user_profile = user_profile_model.objects.get(user=new_user) - # self.assertIsNotNone(user_profile) + user_profile = user_profile_model.objects.get(user=new_user) + self.assertIsNotNone(user_profile) + + def test_password_reset(self): + user = User.objects.create_user(self.USERNAME, self.EMAIL, self.PASS) + + # call password reset + mail_count = len(mail.outbox) + payload = {'email': self.EMAIL} + self.post(self.password_reset_url, data=payload) + self.assertEqual(len(mail.outbox), mail_count+1) + + url_kwargs = self.generate_uid_and_token(user) + + data = { + 'new_password1': self.NEW_PASS, + 'new_password2': self.NEW_PASS + } + url = reverse('rest_password_reset_confirm', kwargs=url_kwargs) + self.post(url, data=data, status_code=200) + + payload = { + "username": self.USERNAME, + "password": self.NEW_PASS + } + self.post(self.login_url, data=payload, status_code=200) + + + def generate_uid_and_token(self, user): + result = {} + from django.utils.encoding import force_bytes + from django.contrib.auth.tokens import default_token_generator + from django import VERSION + if VERSION[1] == 6: + from django.utils.http import urlsafe_base64_encode + result['uid'] = urlsafe_base64_encode(force_bytes(user.pk)) + elif VERSION[1] == 5: + from django.utils.http import int_to_base36 + result['uid'] = int_to_base36(user.pk) + result['token'] = default_token_generator.make_token(user) + return result + diff --git a/rest_auth/urls.py b/rest_auth/urls.py index 766d09f..c83cd72 100644 --- a/rest_auth/urls.py +++ b/rest_auth/urls.py @@ -11,7 +11,7 @@ urlpatterns = patterns('rest_auth.views', name='rest_register'), url(r'^password/reset/$', PasswordReset.as_view(), name='rest_password_reset'), - url(r'^password/reset/confirm/(?P[0-9A-Za-z_\-]+)/(?P[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$', + url(r'^password/reset/confirm/(?P[0-9A-Za-z_\-]+)/(?P[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$', PasswordResetConfirm.as_view( ), name='rest_password_reset_confirm'), url(r'^login/$', Login.as_view(), name='rest_login'), @@ -33,3 +33,7 @@ if settings.DEBUG and not settings.IS_TEST: url(r'^docs/', include('rest_framework_swagger.urls')), ) + +if settings.IS_TEST: + from django.contrib.auth.tests import urls + urlpatterns += patterns('', url(r'^test-admin/', include(urls))) diff --git a/rest_auth/views.py b/rest_auth/views.py index 7e2292b..7f01f5f 100644 --- a/rest_auth/views.py +++ b/rest_auth/views.py @@ -133,11 +133,12 @@ class Register(LoggedOutRESTAPIView, GenericAPIView): """ serializer_class = UserRegistrationSerializer + profile_serializer_class = UserRegistrationProfileSerializer def post(self, request): # Create serializers with request.DATA serializer = self.serializer_class(data=request.DATA) - profile_serializer = UserRegistrationProfileSerializer( + profile_serializer = self.profile_serializer_class( data=request.DATA) if serializer.is_valid() and profile_serializer.is_valid(): @@ -256,19 +257,19 @@ class PasswordResetConfirm(LoggedOutRESTAPIView, GenericAPIView): Password reset e-mail link is confirmed, therefore this resets the user's password. Accepts the following POST parameters: new_password1, new_password2 - Accepts the following Django URL arguments: token, uidb64 + Accepts the following Django URL arguments: token, uid Returns the success/fail message. """ serializer_class = SetPasswordSerializer - def post(self, request, uidb64=None, token=None): + def post(self, request, uid=None, token=None): # Get the UserModel UserModel = get_user_model() # Decode the uidb64 to uid to get User object try: - uid = uid_decoder(uidb64) + uid = uid_decoder(uid) user = UserModel._default_manager.get(pk=uid) except (TypeError, ValueError, OverflowError, UserModel.DoesNotExist): user = None @@ -302,7 +303,7 @@ class PasswordResetConfirm(LoggedOutRESTAPIView, GenericAPIView): status=status.HTTP_400_BAD_REQUEST) else: - return Response({"errors": "Couldn\'t find the user from uidb64."}, status=status.HTTP_400_BAD_REQUEST) + return Response({"errors": "Couldn\'t find the user from uid."}, status=status.HTTP_400_BAD_REQUEST) class VerifyEmail(LoggedOutRESTAPIView, GenericAPIView):