Skip to content

Commit

Permalink
Merge 29f03c2 into ec92350
Browse files Browse the repository at this point in the history
  • Loading branch information
3Nakajugo committed Apr 30, 2019
2 parents ec92350 + 29f03c2 commit 01d6c9f
Show file tree
Hide file tree
Showing 5 changed files with 162 additions and 17 deletions.
Binary file added authors/apps/authentication/.DS_Store
Binary file not shown.
66 changes: 60 additions & 6 deletions authors/apps/authentication/serializers.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,75 @@
from django.contrib.auth import authenticate

from django.core.validators import RegexValidator
from rest_framework import serializers

from .models import User
import re


class RegistrationSerializer(serializers.ModelSerializer):
"""Serializers registration requests and creates a new user."""

# Ensure passwords are at least 8 characters long, no longer than 128
# characters, and can not be read by the client.
# ensures that password is required and not blank
#username should not contain trailing and leading white spaces
email = serializers.EmailField()
username = serializers.CharField(
trim_whitespace = True
)
password = serializers.CharField(
max_length=128,
min_length=8,
write_only=True
max_length=16,
write_only=True,
required=True,
error_messages={
"required": "Password field is required",
"blank": "Password field cannot be empty",
}
)

def validate_password(self, password):
"""
validates that password is longer than 8 characters
password is alphanumeric
"""
if len(password) < 8:
raise serializers.ValidationError(
"Password should atleast be 8 characters.")
if not re.search(r'[0-9]', password) or not re.search(r'[a-zA-Z]', password) or not re.search(r'[!?@#$%^&*.]', password):
raise serializers.ValidationError(
"Password should include numbers and alphabets and one special character")
if re.search(r'[\s]', password):
raise serializers.ValidationError(
"Password should not include white spaces")
return password


def validate_username(self, username):
""" validates username"""
exist_username = User.objects.filter(username=username)
if exist_username.exists():
raise serializers.ValidationError(
"username provided already exists")
if len(username) <= 4:
raise serializers.ValidationError(
"username should be longer than 4 characters")
if re.search(r'[\s]', username):
raise serializers.ValidationError(
"username should not contain spaces")
if not re.search(r'[a-zA-Z]', username):
raise serializers.ValidationError(
"username should contain characters")
return username

def validate_email(self, email):
""" validates email"""

exist_email = User.objects.filter(email=email)
if exist_email.exists():
raise serializers.ValidationError(
"email provided already exists")
return email


# The client should not be able to send a token along with a registration
# request. Making `token` read-only handles that for us.

Expand Down Expand Up @@ -101,7 +155,7 @@ def validate(self, data):
class UserSerializer(serializers.ModelSerializer):
"""Handles serialization and deserialization of User objects."""

# Passwords must be at least 8 characters, but no more than 128
# Passwords must be at least 8 characters, but no more than 128
# characters. These values are the default provided by Django. We could
# change them, but that would create extra work while introducing no real
# benefit, so let's just stick with the defaults.
Expand Down
55 changes: 55 additions & 0 deletions authors/apps/authentication/tests/test_authentication.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ def test_user_login(self):
user.save()
response = self.client.post(login_url, self.user_test_data.user_login,
format="json")
print(response)
self.assertEqual(response.status_code, status.HTTP_200_OK)

def test_activation_link(self):
Expand Down Expand Up @@ -144,3 +145,57 @@ def test_activation_link_user_not_found(self):
kwargs=kwargs)
response = self.client.get(activation_url, format="json")
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)

def test_signup(self):
"""test succesfull signup"""
url = reverse('authentication:user_signup')
response = self.client.post(url, self.user_test_data.user_registration, format="json")
self.assertEqual(response.status_code, status.HTTP_201_CREATED)

def test_register_invalid_username(self):
"""test fail when username is invalid"""
url = reverse('authentication:user_signup')
response = self.client.post(url, self.user_test_data.invalid_username, format="json")
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
self.assertEqual(response.data['errors']['username'][0], 'username should be longer than 4 characters')

def test_register_username_with_spaces(self):
"""test fail when username has spaces is invalid"""
url = reverse('authentication:user_signup')
response = self.client.post(url, self.user_test_data.username_with_space, format="json")
print(response)
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
self.assertEqual(response.data['errors']['username']
[0], 'username should not contain spaces')

def test_register_invalid_password(self):
"""test fail when password is invalid"""
url = reverse('authentication:user_signup')
response = self.client.post(url, self.user_test_data.invalid_password, format="json")
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
self.assertEqual(response.data['errors']['password']
[0], 'Password should atleast be 8 characters.')

def test_register_non_alphanumeric_password(self):
"""test fail when password is not alphanumeric"""
url = reverse('authentication:user_signup')
response = self.client.post(url, self.user_test_data.non_numeric_password, format="json")
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
self.assertEqual(response.data['errors']['password'][0],
'Password should include numbers and alphabets and one special character')

def test_register_password_with_whitespace(self):
"""test fail when password is not alphanumeric"""
url = reverse('authentication:user_signup')
response = self.client.post(url, self.user_test_data.password_with_space, format="json")
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
self.assertEqual(response.data['errors']['password'][0],
'Password should not include white spaces')

def test_user_exists(self):
"""Test register with email that exists """
url = reverse('authentication:user_signup')
response = self.client.post(url, self.user_test_data.user_registration, format="json")
response = self.client.post(url, self.user_test_data.user_registration ,format="json")
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)

56 changes: 46 additions & 10 deletions authors/apps/authentication/tests/user_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,62 @@ class UserTestData:
"""User Test Data."""

def __init__(self):
self.user_registration = {
"user": {
"username": "mwinel",
"email": "mwinel@live.com",
"password": "12345678"
}
}


self.user_login = {
"user": {
"email": "mwinel@live.com",
"password": "12345678"
"password": "1234$qwe"
}
}

self.activated_user = {
"user": {
"username": "mwinel",
"email": "mwinel@live.com",
"password": "12345678",
"password": "1234$qwe",
"email_verified": True
}
}

self.user_registration = {
"user": {
"username": "mwinel",
"email": "mwinel@live.com",
"password": "1234$qwe",
}
}
self.invalid_username = {
"user": {
"username": "edn",
"email": "edna@example.com",
"password": "edna@1234"
}
}
self.username_with_space = {
"user": {
"username": "ed na",
"email": "edna@example.com",
"password": "edna@1234"
}
}
self.invalid_password = {
"user": {
"username": "edina",
"email": "edna@example.com",
"password": "edna@23"
}
}
self.non_numeric_password = {
"user": {
"username": "edina",
"email": "edna@example.com",
"password": "@nakajugo"
}
}
self.password_with_space = {
"user": {
"username": "edina",
"email": "edna@example.com",
"password": "@naka1 jugo"
}
}
2 changes: 1 addition & 1 deletion authors/apps/authentication/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ class RegistrationAPIView(APIView):

def post(self, request):
user = request.data.get('user', {})

# The create serializer, validate serializer, save serializer pattern
# below is common and you will see it a lot throughout this course and
# your own work later on. Get familiar with it.

serializer = self.serializer_class(data=user)
serializer.is_valid(raise_exception=True)
serializer.save()
Expand Down

0 comments on commit 01d6c9f

Please sign in to comment.