-
Notifications
You must be signed in to change notification settings - Fork 448
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: user registration request data validation
- Loading branch information
1 parent
144826b
commit aedba66
Showing
8 changed files
with
312 additions
and
46 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
from app.utils.validation_utils import is_email_valid, is_username_valid | ||
|
||
# Field character limit | ||
|
||
NAME_MAX_LENGTH = 30 | ||
NAME_MIN_LENGTH = 2 | ||
USERNAME_MAX_LENGTH = 25 | ||
USERNAME_MIN_LENGTH = 5 | ||
PASSWORD_MAX_LENGTH = 25 | ||
PASSWORD_MIN_LENGTH = 8 | ||
|
||
|
||
def validate_user_registration_request_data(data): | ||
# Verify if request body has required fields | ||
if 'name' not in data: | ||
return {"message": "Name field is missing."} | ||
if 'username' not in data: | ||
return {"message": "Username field is missing."} | ||
if 'password' not in data: | ||
return {"message": "Password field is missing."} | ||
if 'email' not in data: | ||
return {"message": "Email field is missing."} | ||
if 'terms_and_conditions_checked' not in data: | ||
return {"message": "Terms and conditions field is missing."} | ||
|
||
name = data['name'] | ||
username = data['username'] | ||
password = data['password'] | ||
email = data['email'] | ||
terms_and_conditions_checked = data['terms_and_conditions_checked'] | ||
|
||
if not (isinstance(name, str) and isinstance(username, str) and isinstance(password, str)): | ||
return {"message": "Name, username and password must be in string format."} | ||
|
||
if not (NAME_MIN_LENGTH <= len(name) <= NAME_MAX_LENGTH): | ||
return {"message": "The name field has to longer than {min_limit} " | ||
"characters and shorter than {max_limit} characters.".format(min_limit=NAME_MIN_LENGTH-1, | ||
max_limit=NAME_MAX_LENGTH+1)} | ||
|
||
if not (USERNAME_MIN_LENGTH <= len(username) <= USERNAME_MAX_LENGTH): | ||
return {"message": "The username field has to longer than {min_limit} " | ||
"characters and shorter than {max_limit} characters.".format(min_limit=USERNAME_MIN_LENGTH-1, | ||
max_limit=USERNAME_MAX_LENGTH+1)} | ||
|
||
if not (PASSWORD_MIN_LENGTH <= len(password) <= PASSWORD_MAX_LENGTH): | ||
return {"message": "The password field has to longer than {min_limit} " | ||
"characters and shorter than {max_limit} characters.".format(min_limit=PASSWORD_MIN_LENGTH-1, | ||
max_limit=PASSWORD_MAX_LENGTH+1)} | ||
|
||
# Verify business logic of request body | ||
if terms_and_conditions_checked is False: | ||
return {"message": "Terms and conditions are not checked."} | ||
|
||
if not is_email_valid(email): | ||
return {"message": "Your email is invalid."} | ||
|
||
if not is_username_valid(username): | ||
return {"message": "Your username is invalid."} | ||
|
||
return {} | ||
|
||
|
||
def validate_resend_email_request_data(data): | ||
|
||
# Verify if request body has required fields | ||
if 'email' not in data: | ||
return {"message": "Email field is missing."} | ||
|
||
email = data['email'] | ||
if not is_email_valid(email): | ||
return {"message": "Your email is invalid."} | ||
|
||
return {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,12 @@ | ||
import re | ||
|
||
email_regex = r"(^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$)" | ||
username_regex = r"(^[a-zA-Z0-9]+$)" | ||
|
||
|
||
def is_email_valid(email): | ||
return re.match(email_regex, email) | ||
|
||
|
||
def is_username_valid(username): | ||
return re.match(username_regex, username) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,189 @@ | ||
import unittest | ||
from random import SystemRandom | ||
from string import ascii_lowercase | ||
|
||
from app.api.validations.user import validate_user_registration_request_data, NAME_MIN_LENGTH, NAME_MAX_LENGTH, \ | ||
USERNAME_MIN_LENGTH, USERNAME_MAX_LENGTH, PASSWORD_MAX_LENGTH, PASSWORD_MIN_LENGTH | ||
from tests.test_data import user1 | ||
|
||
|
||
class TestUserApiRequestDataValidation(unittest.TestCase): | ||
|
||
def test_user_registration_valid_request_data(self): | ||
expected_result = {} | ||
request_body = dict( | ||
name=user1['name'], | ||
username=user1['username'], | ||
password=user1['password'], | ||
email=user1['email'], | ||
terms_and_conditions_checked=user1['terms_and_conditions_checked']) | ||
actual_result = validate_user_registration_request_data(request_body) | ||
|
||
self.assertEqual(expected_result, actual_result) | ||
|
||
def test_user_registration_request_data_missing_name_field(self): | ||
expected_result = {"message": "Name field is missing."} | ||
request_body = dict( | ||
username=user1['username'], | ||
password=user1['password'], | ||
email=user1['email'], | ||
terms_and_conditions_checked=user1['terms_and_conditions_checked']) | ||
actual_result = validate_user_registration_request_data(request_body) | ||
|
||
self.assertEqual(expected_result, actual_result) | ||
|
||
def test_user_registration_request_data_missing_username_field(self): | ||
expected_result = {"message": "Username field is missing."} | ||
request_body = dict( | ||
name=user1['name'], | ||
password=user1['password'], | ||
email=user1['email'], | ||
terms_and_conditions_checked=user1['terms_and_conditions_checked']) | ||
actual_result = validate_user_registration_request_data(request_body) | ||
|
||
self.assertEqual(expected_result, actual_result) | ||
|
||
def test_user_registration_request_data_missing_password_field(self): | ||
expected_result = {"message": "Password field is missing."} | ||
request_body = dict( | ||
name=user1['name'], | ||
username=user1['username'], | ||
email=user1['email'], | ||
terms_and_conditions_checked=user1['terms_and_conditions_checked']) | ||
actual_result = validate_user_registration_request_data(request_body) | ||
|
||
self.assertEqual(expected_result, actual_result) | ||
|
||
def test_user_registration_request_data_missing_email_field(self): | ||
expected_result = {"message": "Email field is missing."} | ||
request_body = dict( | ||
name=user1['name'], | ||
username=user1['username'], | ||
password=user1['password'], | ||
terms_and_conditions_checked=user1['terms_and_conditions_checked']) | ||
actual_result = validate_user_registration_request_data(request_body) | ||
|
||
self.assertEqual(expected_result, actual_result) | ||
|
||
def test_user_registration_request_data_missing_terms_and_conditions_field(self): | ||
expected_result = {"message": "Terms and conditions field is missing."} | ||
request_body = dict( | ||
name=user1['name'], | ||
username=user1['username'], | ||
password=user1['password'], | ||
email=user1['email']) | ||
actual_result = validate_user_registration_request_data(request_body) | ||
|
||
self.assertEqual(expected_result, actual_result) | ||
|
||
def test_user_registration_request_data_with_terms_unchecked(self): | ||
expected_result = {"message": "Terms and conditions are not checked."} | ||
request_body = dict( | ||
name=user1['name'], | ||
username=user1['username'], | ||
password=user1['password'], | ||
email=user1['email'], | ||
terms_and_conditions_checked=False) | ||
actual_result = validate_user_registration_request_data(request_body) | ||
|
||
self.assertEqual(expected_result, actual_result) | ||
|
||
def test_user_registration_request_data_name_inferior_to_limit(self): | ||
secure_random = SystemRandom() | ||
expected_result = {"message": "The name field has to longer than {min_limit} " | ||
"characters and shorter than {max_limit} characters.".format(min_limit=NAME_MIN_LENGTH-1, | ||
max_limit=NAME_MAX_LENGTH+1)} | ||
random_generated_name = "".join(secure_random.choice(ascii_lowercase) for x in range(NAME_MIN_LENGTH-1)) | ||
request_body = dict( | ||
name=random_generated_name, | ||
username=user1['username'], | ||
password=user1['password'], | ||
email=user1['email'], | ||
terms_and_conditions_checked=user1['terms_and_conditions_checked']) | ||
actual_result = validate_user_registration_request_data(request_body) | ||
|
||
self.assertEqual(expected_result, actual_result) | ||
|
||
def test_user_registration_request_data_name_superior_to_limit(self): | ||
secure_random = SystemRandom() | ||
expected_result = {"message": "The name field has to longer than {min_limit} " | ||
"characters and shorter than {max_limit} characters.".format(min_limit=NAME_MIN_LENGTH-1, | ||
max_limit=NAME_MAX_LENGTH+1)} | ||
random_generated_name = "".join(secure_random.choice(ascii_lowercase) for x in range(NAME_MAX_LENGTH+1)) | ||
request_body = dict( | ||
name=random_generated_name, | ||
username=user1['username'], | ||
password=user1['password'], | ||
email=user1['email'], | ||
terms_and_conditions_checked=user1['terms_and_conditions_checked']) | ||
actual_result = validate_user_registration_request_data(request_body) | ||
|
||
self.assertEqual(expected_result, actual_result) | ||
|
||
def test_user_registration_request_data_username_inferior_to_limit(self): | ||
secure_random = SystemRandom() | ||
expected_result = {"message": "The username field has to longer than {min_limit} " | ||
"characters and shorter than {max_limit} characters.".format(min_limit=USERNAME_MIN_LENGTH-1, | ||
max_limit=USERNAME_MAX_LENGTH+1)} | ||
random_generated_username = "".join(secure_random.choice(ascii_lowercase) for x in range(USERNAME_MIN_LENGTH-1)) | ||
request_body = dict( | ||
name=user1['name'], | ||
username=random_generated_username, | ||
password=user1['password'], | ||
email=user1['email'], | ||
terms_and_conditions_checked=user1['terms_and_conditions_checked']) | ||
actual_result = validate_user_registration_request_data(request_body) | ||
|
||
self.assertEqual(expected_result, actual_result) | ||
|
||
def test_user_registration_request_data_username_superior_to_limit(self): | ||
secure_random = SystemRandom() | ||
expected_result = {"message": "The username field has to longer than {min_limit} " | ||
"characters and shorter than {max_limit} characters.".format(min_limit=USERNAME_MIN_LENGTH-1, | ||
max_limit=USERNAME_MAX_LENGTH+1)} | ||
random_generated_username = "".join(secure_random.choice(ascii_lowercase) for x in range(USERNAME_MAX_LENGTH+1)) | ||
request_body = dict( | ||
name=user1['name'], | ||
username=random_generated_username, | ||
password=user1['password'], | ||
email=user1['email'], | ||
terms_and_conditions_checked=user1['terms_and_conditions_checked']) | ||
actual_result = validate_user_registration_request_data(request_body) | ||
|
||
self.assertEqual(expected_result, actual_result) | ||
|
||
def test_user_registration_request_data_password_inferior_to_limit(self): | ||
secure_random = SystemRandom() | ||
expected_result = {"message": "The password field has to longer than {min_limit} " | ||
"characters and shorter than {max_limit} characters.".format(min_limit=PASSWORD_MIN_LENGTH-1, | ||
max_limit=PASSWORD_MAX_LENGTH+1)} | ||
random_generated_password = "".join(secure_random.choice(ascii_lowercase) for x in range(PASSWORD_MIN_LENGTH-1)) | ||
request_body = dict( | ||
name=user1['name'], | ||
username=user1['username'], | ||
password=random_generated_password, | ||
email=user1['email'], | ||
terms_and_conditions_checked=user1['terms_and_conditions_checked']) | ||
actual_result = validate_user_registration_request_data(request_body) | ||
|
||
self.assertEqual(expected_result, actual_result) | ||
|
||
def test_user_registration_request_data_password_superior_to_limit(self): | ||
secure_random = SystemRandom() | ||
expected_result = {"message": "The password field has to longer than {min_limit} " | ||
"characters and shorter than {max_limit} characters.".format(min_limit=PASSWORD_MIN_LENGTH-1, | ||
max_limit=PASSWORD_MAX_LENGTH+1)} | ||
random_generated_password = "".join(secure_random.choice(ascii_lowercase) for x in range(PASSWORD_MAX_LENGTH+1)) | ||
request_body = dict( | ||
name=user1['name'], | ||
username=user1['username'], | ||
password=random_generated_password, | ||
email=user1['email'], | ||
terms_and_conditions_checked=user1['terms_and_conditions_checked']) | ||
actual_result = validate_user_registration_request_data(request_body) | ||
|
||
self.assertEqual(expected_result, actual_result) | ||
|
||
|
||
if __name__ == '__main__': | ||
unittest.main() |
4 changes: 2 additions & 2 deletions
4
tests/utils/test_email_utils.py → tests/utils/test_email_validation.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.