test for password reset process

This commit is contained in:
Mateusz Sikora 2014-05-06 00:53:06 +02:00
parent d33bbc8021
commit 6993e98282
5 changed files with 70 additions and 13 deletions

View File

@ -11,6 +11,7 @@ from django.contrib.sites.models import RequestSite
from django.contrib.sites.models import Site from django.contrib.sites.models import Site
from django.db import models from django.db import models
from rest_framework.serializers import _resolve_model
from registration.models import RegistrationProfile from registration.models import RegistrationProfile
from registration.backends.default.views import RegistrationView as BaseRegistrationView from registration.backends.default.views import RegistrationView as BaseRegistrationView
from registration import signals from registration import signals
@ -43,6 +44,12 @@ class RegistrationView(BaseRegistrationView):
signals.user_registered.send(sender=self.__class__, signals.user_registered.send(sender=self.__class__,
user=new_user, user=new_user,
request=request) 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 return new_user
settings.REST_REGISTRATION_BACKEND = 'rest_auth.runtests.RegistrationView' settings.REST_REGISTRATION_BACKEND = 'rest_auth.runtests.RegistrationView'

View File

@ -15,7 +15,7 @@ MEDIA_ROOT = os.path.join(PROJECT_ROOT, '%s' % UPLOADS_DIR_NAME)
IS_DEV = False IS_DEV = False
IS_STAGING = False IS_STAGING = False
IS_PROD = 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): if django.VERSION[:2] >= (1, 3):
DATABASES = { DATABASES = {

View File

@ -2,6 +2,7 @@ import json
import os import os
import sys import sys
from datetime import datetime, date, time from datetime import datetime, date, time
from urlparse import urlparse
os.environ['DJANGO_SETTINGS_MODULE'] = 'test_settings' os.environ['DJANGO_SETTINGS_MODULE'] = 'test_settings'
test_dir = os.path.dirname(__file__) 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.test import TestCase
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.contrib.auth import get_user_model 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 registration.models import RegistrationProfile
from rest_framework.serializers import _resolve_model from rest_framework.serializers import _resolve_model
@ -128,13 +131,15 @@ class LoginAPITestCase(TestCase, BaseAPITestCase):
USERNAME = 'person' USERNAME = 'person'
PASS = 'person' PASS = 'person'
EMAIL = "person1@world.com"
NEW_PASS = 'new-test-pass'
def setUp(self): def setUp(self):
self.init() self.init()
self.login_url = reverse('rest_login') self.login_url = reverse('rest_login')
self.password_change_url = reverse('rest_password_change') self.password_change_url = reverse('rest_password_change')
self.register_url = reverse('rest_register') self.register_url = reverse('rest_register')
self.password_reset_url = reverse('rest_password_reset')
def test_login(self): def test_login(self):
payload = { payload = {
@ -230,15 +235,15 @@ class LoginAPITestCase(TestCase, BaseAPITestCase):
self.get(verify_url) self.get(verify_url)
new_user = get_user_model().objects.latest('id') new_user = get_user_model().objects.latest('id')
self.assertEqual(new_user.is_active, True) self.assertEqual(new_user.is_active, True)
#user_profile = user_profile_model.objects.get(user=new_user) user_profile = user_profile_model.objects.get(user=new_user)
#self.assertIsNotNone(user_profile) self.assertIsNotNone(user_profile)
def test_registration_user_without_profile(self): def test_registration_user_without_profile(self):
payload = { payload = {
"username": self.USERNAME, "username": self.USERNAME,
"password": self.PASS, "password": self.PASS,
"email": "person1@world.com" "email": self.EMAIL,
} }
self.post(self.register_url, data=payload, status_code=201) 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') new_user = get_user_model().objects.latest('id')
self.assertEqual(new_user.is_active, True) self.assertEqual(new_user.is_active, True)
# user_profile = user_profile_model.objects.get(user=new_user) user_profile = user_profile_model.objects.get(user=new_user)
# self.assertIsNotNone(user_profile) 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

View File

@ -11,7 +11,7 @@ urlpatterns = patterns('rest_auth.views',
name='rest_register'), name='rest_register'),
url(r'^password/reset/$', PasswordReset.as_view(), url(r'^password/reset/$', PasswordReset.as_view(),
name='rest_password_reset'), name='rest_password_reset'),
url(r'^password/reset/confirm/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$', url(r'^password/reset/confirm/(?P<uid>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$',
PasswordResetConfirm.as_view( PasswordResetConfirm.as_view(
), name='rest_password_reset_confirm'), ), name='rest_password_reset_confirm'),
url(r'^login/$', Login.as_view(), name='rest_login'), url(r'^login/$', Login.as_view(), name='rest_login'),
@ -33,3 +33,7 @@ if settings.DEBUG and not settings.IS_TEST:
url(r'^docs/', url(r'^docs/',
include('rest_framework_swagger.urls')), include('rest_framework_swagger.urls')),
) )
if settings.IS_TEST:
from django.contrib.auth.tests import urls
urlpatterns += patterns('', url(r'^test-admin/', include(urls)))

View File

@ -133,11 +133,12 @@ class Register(LoggedOutRESTAPIView, GenericAPIView):
""" """
serializer_class = UserRegistrationSerializer serializer_class = UserRegistrationSerializer
profile_serializer_class = UserRegistrationProfileSerializer
def post(self, request): def post(self, request):
# Create serializers with request.DATA # Create serializers with request.DATA
serializer = self.serializer_class(data=request.DATA) serializer = self.serializer_class(data=request.DATA)
profile_serializer = UserRegistrationProfileSerializer( profile_serializer = self.profile_serializer_class(
data=request.DATA) data=request.DATA)
if serializer.is_valid() and profile_serializer.is_valid(): 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. 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 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. Returns the success/fail message.
""" """
serializer_class = SetPasswordSerializer serializer_class = SetPasswordSerializer
def post(self, request, uidb64=None, token=None): def post(self, request, uid=None, token=None):
# Get the UserModel # Get the UserModel
UserModel = get_user_model() UserModel = get_user_model()
# Decode the uidb64 to uid to get User object # Decode the uidb64 to uid to get User object
try: try:
uid = uid_decoder(uidb64) uid = uid_decoder(uid)
user = UserModel._default_manager.get(pk=uid) user = UserModel._default_manager.get(pk=uid)
except (TypeError, ValueError, OverflowError, UserModel.DoesNotExist): except (TypeError, ValueError, OverflowError, UserModel.DoesNotExist):
user = None user = None
@ -302,7 +303,7 @@ class PasswordResetConfirm(LoggedOutRESTAPIView, GenericAPIView):
status=status.HTTP_400_BAD_REQUEST) status=status.HTTP_400_BAD_REQUEST)
else: 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): class VerifyEmail(LoggedOutRESTAPIView, GenericAPIView):