API - handle user username and email case on login/register

This commit is contained in:
Sam 2021-11-03 10:23:28 +01:00
parent c683401daa
commit 3a1245a2e0
3 changed files with 80 additions and 8 deletions

View File

@ -14,6 +14,14 @@ def user_1() -> User:
return user return user
@pytest.fixture()
def user_1_upper() -> User:
user = User(username='TEST', email='TEST@TEST.COM', password='12345678')
db.session.add(user)
db.session.commit()
return user
@pytest.fixture() @pytest.fixture()
def user_1_admin() -> User: def user_1_admin() -> User:
admin = User( admin = User(

View File

@ -3,6 +3,7 @@ from datetime import datetime, timedelta
from io import BytesIO from io import BytesIO
from unittest.mock import Mock, patch from unittest.mock import Mock, patch
import pytest
from flask import Flask from flask import Flask
from freezegun import freeze_time from freezegun import freeze_time
@ -37,8 +38,38 @@ class TestUserRegistration:
assert response.content_type == 'application/json' assert response.content_type == 'application/json'
assert response.status_code == 201 assert response.status_code == 201
def test_it_returns_error_if_user_already_exists( @pytest.mark.parametrize(
self, app: Flask, user_1: User 'input_username',
['test', 'TEST'],
)
def test_it_returns_error_if_user_already_exists_with_same_username(
self, app: Flask, user_1: User, input_username: str
) -> None:
client = app.test_client()
response = client.post(
'/api/auth/register',
data=json.dumps(
dict(
username=input_username,
email='another_email@test.com',
password='12345678',
password_conf='12345678',
)
),
content_type='application/json',
)
data = json.loads(response.data.decode())
assert data['status'] == 'error'
assert data['message'] == 'sorry, that user already exists'
assert response.content_type == 'application/json'
assert response.status_code == 400
@pytest.mark.parametrize(
'input_email',
['test@test.com', 'TEST@TEST.COM'],
)
def test_it_returns_error_if_user_already_exists_with_same_email(
self, app: Flask, user_1: User, input_email: str
) -> None: ) -> None:
client = app.test_client() client = app.test_client()
response = client.post( response = client.post(
@ -292,12 +323,40 @@ class TestUserRegistration:
class TestUserLogin: class TestUserLogin:
def test_user_can_register(self, app: Flask, user_1: User) -> None: @pytest.mark.parametrize(
'input_email',
['test@test.com', 'TEST@TEST.COM'],
)
def test_user_can_login(
self, app: Flask, user_1: User, input_email: str
) -> None:
client = app.test_client() client = app.test_client()
response = client.post( response = client.post(
'/api/auth/login', '/api/auth/login',
data=json.dumps(dict(email='test@test.com', password='12345678')), data=json.dumps(dict(email=input_email, password='12345678')),
content_type='application/json',
)
assert response.content_type == 'application/json'
assert response.status_code == 200
data = json.loads(response.data.decode())
assert data['status'] == 'success'
assert data['message'] == 'successfully logged in'
assert data['auth_token']
@pytest.mark.parametrize(
'input_email',
['test@test.com', 'TEST@TEST.COM'],
)
def test_user_can_login_when_user_email_is_uppercase(
self, app: Flask, user_1_upper: User, input_email: str
) -> None:
client = app.test_client()
response = client.post(
'/api/auth/login',
data=json.dumps(dict(email=input_email, password='12345678')),
content_type='application/json', content_type='application/json',
) )

View File

@ -4,7 +4,7 @@ from typing import Dict, Tuple, Union
import jwt import jwt
from flask import Blueprint, current_app, request from flask import Blueprint, current_app, request
from sqlalchemy import exc, or_ from sqlalchemy import exc, func, or_
from werkzeug.exceptions import RequestEntityTooLarge from werkzeug.exceptions import RequestEntityTooLarge
from werkzeug.utils import secure_filename from werkzeug.utils import secure_filename
@ -117,7 +117,10 @@ def register_user() -> Union[Tuple[Dict, int], HttpResponse]:
try: try:
# check for existing user # check for existing user
user = User.query.filter( user = User.query.filter(
or_(User.username == username, User.email == email) or_(
func.lower(User.username) == func.lower(username),
func.lower(User.email) == func.lower(email),
)
).first() ).first()
if user: if user:
return InvalidPayloadErrorResponse( return InvalidPayloadErrorResponse(
@ -193,11 +196,13 @@ def login_user() -> Union[Dict, HttpResponse]:
post_data = request.get_json() post_data = request.get_json()
if not post_data: if not post_data:
return InvalidPayloadErrorResponse() return InvalidPayloadErrorResponse()
email = post_data.get('email') email = post_data.get('email', '')
password = post_data.get('password') password = post_data.get('password')
try: try:
# check for existing user # check for existing user
user = User.query.filter(User.email == email).first() user = User.query.filter(
func.lower(User.email) == func.lower(email)
).first()
if user and bcrypt.check_password_hash(user.password, password): if user and bcrypt.check_password_hash(user.password, password):
# generate auth token # generate auth token
auth_token = user.encode_auth_token(user.id) auth_token = user.encode_auth_token(user.id)