Skip to content

Commit

Permalink
fully test the authentication and authorization system of the app
Browse files Browse the repository at this point in the history
  • Loading branch information
mahdihaghverdi committed Mar 28, 2024
1 parent 795a5f1 commit d675db7
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 28 deletions.
4 changes: 2 additions & 2 deletions tests/auth/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@
- Repeat successful
6. /logout
- Unsuccessful due to not passing the Refresh-Token (`ForbiddenError`)
- Unsuccessful due to invalid Refresh-Token passing (`CredentialsError`)
- Unsuccessful due to not providing the Access-Token (`ForbiddenError`)
- Unsuccessful due to wrong Access-Token (`CredentialsError`)
- Successful
test refresh is deleted from redis
test sha256_username is deleted from redis
Expand Down
14 changes: 14 additions & 0 deletions tests/auth/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,20 @@

base_url = base_url + f"{APIPrefixesEnum.AUTH.value}"

username = "mahdi"
password = "12345678"
simple_signup_data = {"username": username, "password": password}
signup_data = {
"username": "Mahdi",
"password": "12345678",
"name": "Mahdi Haghverdi",
"bio": "Hi I am a writer",
"email": "[email protected]",
"telegram": "@pyeafp",
"instagram": "mah.dihaghverdi",
"twitter": "@mliewpl",
}
login_data = {"username": username, "password": password}
data = {"username": "mahdi", "password": "12345678"}

LoginData = namedtuple("LoginData", "refresh_token, csrf_token")
Expand Down
47 changes: 28 additions & 19 deletions tests/auth/test_auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,9 @@
from src.core.schemas import UserOutSchema
from src.core.security import decode_refresh_token, decode_csrf_token, decode_access_token
from src.core.utils import sha256_username
from .conftest import base_url
from .conftest import base_url, simple_signup_data, username, signup_data, login_data
from ..redis_db import get_redis_client_mock

username = "mahdi"
password = "12345678"
simple_signup_data = {"username": username, "password": password}
signup_data = {
"username": "Mahdi",
"password": "12345678",
"name": "Mahdi Haghverdi",
"bio": "Hi I am a writer",
"email": "[email protected]",
"telegram": "@pyeafp",
"instagram": "mah.dihaghverdi",
"twitter": "@mliewpl",
}


class BaseTest:
url: str
Expand Down Expand Up @@ -110,9 +96,6 @@ def test_signup_duplicate(self, client):
assert message == f"username: {username!r} already exists!"


login_data = {"username": username, "password": password}


class TestLogin(BaseTest):
url = base_url + "/login"

Expand Down Expand Up @@ -285,9 +268,35 @@ def test_twice(self, client, verified_mahdi):
assert csrf_token.access_token == access_token


class TestLogout(BaseTest, RefreshTokenMixin):
class TestLogout(BaseTest):
url = base_url + "/logout"

def test_not_pass_access_token(self, client, login_mahdi):
response = client.post(
self.url,
headers=self.make_auth_headers(login_mahdi.csrf_token),
)
assert response.status_code == HTTPStatus.FORBIDDEN.value, response.text

code_message, message = self.extract_error_message(response.json())
assert code_message == HTTPStatus.FORBIDDEN.description
assert message == "Access-Token is not provided"

def test_not_invalid_access_token(self, client, refreshed_mahdi):
invalid_access_token = refreshed_mahdi.access_token.translate(
str.maketrans({"a": "b"})
)
response = client.post(
self.url,
headers=self.make_auth_headers(refreshed_mahdi.csrf_token),
cookies={"Access-Token": invalid_access_token},
)
assert response.status_code == HTTPStatus.UNAUTHORIZED.value, response.text

code_message, message = self.extract_error_message(response.json())
assert code_message == HTTPStatus.UNAUTHORIZED.description
assert message == "Could not validate credentials"

def test_logout(self, client, refreshed_mahdi):
response = client.post(
self.url,
Expand Down
4 changes: 3 additions & 1 deletion tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from src.core.security import hash_password
from src.repository.models import UserModel, Base
from tests.database import get_db_mock, ASessionMock, AEngineMock
from tests.redis_db import get_redis_client_mock
from tests.redis_db import get_redis_client_mock, clear_database

app.dependency_overrides[get_db_session] = get_db_mock
app.dependency_overrides[get_redis_client] = get_redis_client_mock
Expand All @@ -33,7 +33,9 @@ async def drop_all():
@pytest.fixture(scope="function")
def client():
asyncio.run(create_all())
clear_database()
yield TestClient(app=app)
clear_database()
asyncio.run(drop_all())


Expand Down
15 changes: 9 additions & 6 deletions tests/redis_db.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,28 @@
from src.core.utils import asingleton

database = {}

class RedisClientMock:
def __init__(self):
self.database = {}

class RedisClientMock:
async def get(self, name: str, default=None):
return self.database.get(name, default)
return database.get(name, default)

async def set(self, name, value, timeout):
self.database[name] = value
database[name] = value
return True

async def delete(self, *names):
for name in names:
self.database.pop(name)
database.pop(name)

async def ttl(self, name) -> int:
return 100


def clear_database():
database.clear()


@asingleton
async def get_redis_client_mock():
return RedisClientMock()

0 comments on commit d675db7

Please sign in to comment.