Skip to content

Commit

Permalink
Merge pull request #95 from fga-eps-mds/feature/43-user-signup
Browse files Browse the repository at this point in the history
#43 Cadastro de usuário
  • Loading branch information
shayanealcantara authored Oct 3, 2019
2 parents f31e145 + 6528028 commit be6d274
Show file tree
Hide file tree
Showing 6 changed files with 189 additions and 18 deletions.
7 changes: 6 additions & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ services:

db:
image: postgres
volumes:
- postgres_data:/var/lib/postgresql/data

acacia-back:
container_name: acacia_backend
Expand All @@ -25,4 +27,7 @@ services:
volumes:
- .:/code
depends_on:
- db
- db

volumes:
postgres_data:
6 changes: 3 additions & 3 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
Django==2.2
Django==2.2.4
djangorestframework==3.10
django-phonenumber-field==3.0
phonenumbers==8.10
djangorestframework_simplejwt
django-cors-headers
psycopg2==2.8.3
django-cors-headers==3.1.0
djangorestframework-simplejwt
coverage
6 changes: 6 additions & 0 deletions src/acacia/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
from scripts.wait_for_db import start_services
from django.utils.translation import ugettext_lazy as _

from .wait_db import start_services

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

Expand Down Expand Up @@ -41,6 +43,7 @@
'django.contrib.staticfiles',

# libs
'phonenumber_field',
'rest_framework',
'rest_framework.authtoken',
'corsheaders',
Expand Down Expand Up @@ -92,6 +95,7 @@
}
}

# STARTS SERVICES THAT DJANGO DEPENDS E.G. postgres
start_services()

LANGUAGES = (
Expand Down Expand Up @@ -146,6 +150,8 @@
]
}

# CORS headers to responses

CORS_ORIGIN_WHITELIST = [
"http://localhost:8080",
"http://localhost:8000",
Expand Down
56 changes: 56 additions & 0 deletions src/acacia/wait_db.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import importlib
import os
import time

import logging

SERVICES_STARTED = False

log = logging.getLogger('ej')


def start_services():
global SERVICES_STARTED

if SERVICES_STARTED:
return

start_postgres()

SERVICES_STARTED = True


def start_postgres():
# settings_path = os.environ['DJANGO_SETTINGS_MODULE']
# settings = importlib.import_module(settings_path)

# db = settings.DATABASES['default']
dbname = 'postgres' # db['NAME']
user = 'postgres' # db['USER']
password = '' # db['PASSWORD']
host = 'db' # db['HOST']

for _ in range(100):
if can_connect(dbname, user, password, host):
log.info("Postgres is available. Continuing...")
return
log.warning('Postgres is unavailable. Retrying in 0.5 seconds')
time.sleep(0.5)

log.critical('Maximum number of attempts connecting to postgres database')
raise RuntimeError('could not connect to database')


def can_connect(dbname, user, password, host):
import psycopg2

try:
psycopg2.connect(
dbname=dbname,
user=user,
password=password,
host=host
)
except psycopg2.OperationalError:
return False
return True
31 changes: 17 additions & 14 deletions src/users/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ class UserSignUpSerializer(serializers.Serializer):

email = serializers.EmailField(
required=True,
validators=[UniqueValidator(queryset=User.objects.all())],
#unique=True,
label="Email Address",
)

Expand All @@ -32,39 +34,40 @@ class UserSignUpSerializer(serializers.Serializer):
confirm_password = serializers.CharField(
write_only=True,
required=True,
label="Confirm Password",
style={'input_type': 'password'}
label="Confirm Password",
style={'input_type': 'password'}
)

class Meta:
model = User
fields = ['username', 'email', 'password', 'confirm_password']

#def validate_email(self, email):
# if User.objects.filter(email=email).exists():
# raise serializers.ValidationError('Email já cadastrado')
# return email


def validate_password(self, password):
min_length = getattr(settings, 'PASSWORD_MIN_LENGTH', 8)
if len(password) < min_length:
raise serializers.ValidationError(
'Password should be atleast %s characters long.' % (min_length)
'A senha deve ter no mínimo %s caracteres' % (min_length)
)
return password

def validate_email(self, email):
if User.objects.filter(email=email).exists():
raise serializers.ValidationError('Email already exists.')
return email

def validate_username(self, username):
if User.objects.filter(username=username).exists():
raise serializers.ValidationError('Username already exists.')
return username

def validate_confirm_password(self, password_confirmation):
data = self.get_initial()
password = data.get('password')
if password != password_confirmation:
raise serializers.ValidationError('Passwords must match.')
raise serializers.ValidationError('As senhas devem corresponder')
return password_confirmation

def validate_username(self, username):
if User.objects.filter(username=username).exists():
raise serializers.ValidationError('Usuário com este nome já cadastrado')
return username

def create(self, validated_data):

# this fields dont belongs to this class
Expand Down
101 changes: 101 additions & 0 deletions src/users/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,109 @@

from rest_framework.test import APITestCase
from django.urls import reverse
from django.db import IntegrityError


class UserRegistrationAPIViewTestCase(APITestCase):
url = reverse('users:register')

def test_different_password_on_password_confirmation(self):
"""
Test to try to create a user with a wrong verification password
"""

user_data = {
"username": "vitas",
"email": "[email protected]",
"password": "VitasIsNice",
"confirm_password": "VitasIsAwesome"
}

response = self.client.post(self.url, user_data)
self.assertEqual(400, response.status_code)


def test_password_less_than_8_characters(self):
"""
Test to try to create a user with a password less than 8 characters
"""

user_data = {
"username": "vitas",
"email": "[email protected]",
"password": "HiVitas",
"confirm_password": "HiVitas"
}

response = self.client.post(self.url, user_data)
self.assertEqual(400, response.status_code)


def test_unique_email_validation(self):
"""
Test to try to create a user with a registered email
"""

user1_data = {
"username": "vitas",
"email": "[email protected]",
"password": "VitasIsAwesome",
"confirm_password": "VitasIsAwesome"
}
user2_data = {
"username": "Reanu_Reves",
"email": "[email protected]",
"password": "cyberpunk2077",
"confirm_password": "cyberpunk2077"
}
response = self.client.post(self.url, user1_data)
self.assertEqual(201, response.status_code)
with self.assertRaises(IntegrityError):
response = self.client.post(self.url, user2_data)


def test_unique_username_validation(self):
"""
Test to try to create a user with a registered username
"""

user_data = {
"username": "vitas",
"email": "[email protected]",
"password": "VitasIsAwesome",
"confirm_password": "VitasIsAwesome"
}

response = self.client.post(self.url, user_data)
self.assertEqual(201, response.status_code)

user_data = {
"username": "vitas",
"email": "[email protected]",
"password": "cyberpunk2077",
"confirm_password": "cyberpunk2077"
}

response = self.client.post(self.url, user_data)
self.assertEqual(400, response.status_code)


def test_user_registration(self):
"""
Test to create a user with valid data
"""

user_data = {
"username": "keanu_reeves",
"email": "[email protected]",
"password": "cyberpunk2077",
"confirm_password": "cyberpunk2077"
}

response = self.client.post(self.url, user_data)
self.assertEqual(201, response.status_code)


class UserAuthenticationAPIViewTestCase(APITestCase):

# SETUP
Expand Down

0 comments on commit be6d274

Please sign in to comment.