mirror of
https://github.com/furyhawk/listen.git
synced 2026-07-21 08:55:34 +00:00
migrate tests to pytest-asyncio
This commit is contained in:
@@ -19,11 +19,16 @@ from app.main import app as fastapi_app
|
||||
from app.models import Base, User
|
||||
|
||||
default_user_id = "b75365d9-7bf9-4f54-add5-aeab333a087b"
|
||||
default_user_email = "geralt@wiedzmin.lol"
|
||||
default_user_email = "geralt@wiedzmin.pl"
|
||||
default_user_password = "geralt"
|
||||
default_user_access_token = create_jwt_token(default_user_id).access_token
|
||||
|
||||
|
||||
# @pytest.fixture(scope="session")
|
||||
# def event_loop_policy():
|
||||
# return uvloop.EventLoopPolicy()
|
||||
|
||||
|
||||
# @pytest.fixture(scope="session")
|
||||
# def event_loop() -> Generator[asyncio.AbstractEventLoop, None, None]:
|
||||
# loop = asyncio.new_event_loop()
|
||||
@@ -126,6 +131,7 @@ async def fixture_default_user(
|
||||
hashed_password=default_hashed_password,
|
||||
)
|
||||
session.add(default_user)
|
||||
|
||||
await session.commit()
|
||||
await session.refresh(default_user)
|
||||
|
||||
@@ -134,4 +140,4 @@ async def fixture_default_user(
|
||||
|
||||
@pytest_asyncio.fixture(name="default_user_headers", scope="function")
|
||||
def fixture_default_user_headers(default_user: User) -> dict[str, str]:
|
||||
return {"Authorization": f"Bearer {default_user_access_token}"}
|
||||
return {"Authorization": f"Bearer {default_user_access_token}"}
|
||||
@@ -11,15 +11,12 @@ from app.core.security.jwt import create_jwt_token
|
||||
from app.models import User
|
||||
|
||||
|
||||
@pytest.mark.asyncio(loop_scope="session")
|
||||
@pytest.mark.parametrize("api_route", api_router.routes)
|
||||
async def test_api_routes_raise_401_on_jwt_decode_errors(
|
||||
client: AsyncClient,
|
||||
api_route: routing.APIRoute,
|
||||
) -> None:
|
||||
if not api_route.path.startswith("/users") or not api_route.path.startswith(
|
||||
"/pets"
|
||||
):
|
||||
pytest.skip("This test is only for routes that require authentication")
|
||||
for method in api_route.methods:
|
||||
response = await client.request(
|
||||
method=method,
|
||||
@@ -30,16 +27,13 @@ async def test_api_routes_raise_401_on_jwt_decode_errors(
|
||||
assert response.json() == {"detail": "Token invalid: Not enough segments"}
|
||||
|
||||
|
||||
@pytest.mark.asyncio(loop_scope="session")
|
||||
@pytest.mark.parametrize("api_route", api_router.routes)
|
||||
async def test_api_routes_raise_401_on_jwt_expired_token(
|
||||
client: AsyncClient,
|
||||
default_user: User,
|
||||
api_route: routing.APIRoute,
|
||||
) -> None:
|
||||
if not api_route.path.startswith("/users") or not api_route.path.startswith(
|
||||
"/pets"
|
||||
):
|
||||
pytest.skip("This test is only for routes that require authentication")
|
||||
with freeze_time("2023-01-01"):
|
||||
jwt = create_jwt_token(default_user.user_id)
|
||||
with freeze_time("2023-02-01"):
|
||||
@@ -53,6 +47,7 @@ async def test_api_routes_raise_401_on_jwt_expired_token(
|
||||
assert response.json() == {"detail": "Token invalid: Signature has expired"}
|
||||
|
||||
|
||||
@pytest.mark.asyncio(loop_scope="session")
|
||||
@pytest.mark.parametrize("api_route", api_router.routes)
|
||||
async def test_api_routes_raise_401_on_jwt_user_deleted(
|
||||
client: AsyncClient,
|
||||
@@ -61,10 +56,6 @@ async def test_api_routes_raise_401_on_jwt_user_deleted(
|
||||
api_route: routing.APIRoute,
|
||||
session: AsyncSession,
|
||||
) -> None:
|
||||
if not api_route.path.startswith("/users") or not api_route.path.startswith(
|
||||
"/pets"
|
||||
):
|
||||
pytest.skip("This test is only for routes that require authentication")
|
||||
await session.execute(delete(User).where(User.user_id == default_user.user_id))
|
||||
await session.commit()
|
||||
|
||||
@@ -75,4 +66,4 @@ async def test_api_routes_raise_401_on_jwt_user_deleted(
|
||||
headers=default_user_headers,
|
||||
)
|
||||
assert response.status_code == status.HTTP_401_UNAUTHORIZED
|
||||
assert response.json() == {"detail": api_messages.JWT_ERROR_USER_REMOVED}
|
||||
assert response.json() == {"detail": api_messages.JWT_ERROR_USER_REMOVED}
|
||||
@@ -1,5 +1,6 @@
|
||||
import time
|
||||
|
||||
import pytest
|
||||
from fastapi import status
|
||||
from freezegun import freeze_time
|
||||
from httpx import AsyncClient
|
||||
@@ -14,6 +15,7 @@ from app.models import RefreshToken, User
|
||||
from app.tests.conftest import default_user_password
|
||||
|
||||
|
||||
@pytest.mark.asyncio(loop_scope="session")
|
||||
async def test_login_access_token_has_response_status_code(
|
||||
client: AsyncClient,
|
||||
default_user: User,
|
||||
@@ -30,6 +32,7 @@ async def test_login_access_token_has_response_status_code(
|
||||
assert response.status_code == status.HTTP_200_OK
|
||||
|
||||
|
||||
@pytest.mark.asyncio(loop_scope="session")
|
||||
async def test_login_access_token_jwt_has_valid_token_type(
|
||||
client: AsyncClient,
|
||||
default_user: User,
|
||||
@@ -47,6 +50,7 @@ async def test_login_access_token_jwt_has_valid_token_type(
|
||||
assert token["token_type"] == "Bearer"
|
||||
|
||||
|
||||
@pytest.mark.asyncio(loop_scope="session")
|
||||
@freeze_time("2023-01-01")
|
||||
async def test_login_access_token_jwt_has_valid_expire_time(
|
||||
client: AsyncClient,
|
||||
@@ -69,6 +73,7 @@ async def test_login_access_token_jwt_has_valid_expire_time(
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.asyncio(loop_scope="session")
|
||||
@freeze_time("2023-01-01")
|
||||
async def test_login_access_token_returns_valid_jwt_access_token(
|
||||
client: AsyncClient,
|
||||
@@ -92,6 +97,7 @@ async def test_login_access_token_returns_valid_jwt_access_token(
|
||||
assert token_payload.exp == token["expires_at"]
|
||||
|
||||
|
||||
@pytest.mark.asyncio(loop_scope="session")
|
||||
async def test_login_access_token_refresh_token_has_valid_expire_time(
|
||||
client: AsyncClient,
|
||||
default_user: User,
|
||||
@@ -113,6 +119,7 @@ async def test_login_access_token_refresh_token_has_valid_expire_time(
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.asyncio(loop_scope="session")
|
||||
async def test_login_access_token_refresh_token_exists_in_db(
|
||||
client: AsyncClient,
|
||||
default_user: User,
|
||||
@@ -135,6 +142,7 @@ async def test_login_access_token_refresh_token_exists_in_db(
|
||||
assert token_db_count == 1
|
||||
|
||||
|
||||
@pytest.mark.asyncio(loop_scope="session")
|
||||
async def test_login_access_token_refresh_token_in_db_has_valid_fields(
|
||||
client: AsyncClient,
|
||||
default_user: User,
|
||||
@@ -160,6 +168,7 @@ async def test_login_access_token_refresh_token_in_db_has_valid_fields(
|
||||
assert not refresh_token.used
|
||||
|
||||
|
||||
@pytest.mark.asyncio(loop_scope="session")
|
||||
async def test_auth_access_token_fail_for_not_existing_user_with_message(
|
||||
client: AsyncClient,
|
||||
) -> None:
|
||||
@@ -176,6 +185,7 @@ async def test_auth_access_token_fail_for_not_existing_user_with_message(
|
||||
assert response.json() == {"detail": api_messages.PASSWORD_INVALID}
|
||||
|
||||
|
||||
@pytest.mark.asyncio(loop_scope="session")
|
||||
async def test_auth_access_token_fail_for_invalid_password_with_message(
|
||||
client: AsyncClient,
|
||||
default_user: User,
|
||||
@@ -190,4 +200,4 @@ async def test_auth_access_token_fail_for_invalid_password_with_message(
|
||||
)
|
||||
|
||||
assert response.status_code == status.HTTP_400_BAD_REQUEST
|
||||
assert response.json() == {"detail": api_messages.PASSWORD_INVALID}
|
||||
assert response.json() == {"detail": api_messages.PASSWORD_INVALID}
|
||||
@@ -1,5 +1,6 @@
|
||||
import time
|
||||
|
||||
import pytest
|
||||
from fastapi import status
|
||||
from freezegun import freeze_time
|
||||
from httpx import AsyncClient
|
||||
@@ -13,6 +14,7 @@ from app.main import app
|
||||
from app.models import RefreshToken, User
|
||||
|
||||
|
||||
@pytest.mark.asyncio(loop_scope="session")
|
||||
async def test_refresh_token_fails_with_message_when_token_does_not_exist(
|
||||
client: AsyncClient,
|
||||
) -> None:
|
||||
@@ -27,6 +29,7 @@ async def test_refresh_token_fails_with_message_when_token_does_not_exist(
|
||||
assert response.json() == {"detail": api_messages.REFRESH_TOKEN_NOT_FOUND}
|
||||
|
||||
|
||||
@pytest.mark.asyncio(loop_scope="session")
|
||||
async def test_refresh_token_fails_with_message_when_token_is_expired(
|
||||
client: AsyncClient,
|
||||
default_user: User,
|
||||
@@ -51,6 +54,7 @@ async def test_refresh_token_fails_with_message_when_token_is_expired(
|
||||
assert response.json() == {"detail": api_messages.REFRESH_TOKEN_EXPIRED}
|
||||
|
||||
|
||||
@pytest.mark.asyncio(loop_scope="session")
|
||||
async def test_refresh_token_fails_with_message_when_token_is_used(
|
||||
client: AsyncClient,
|
||||
default_user: User,
|
||||
@@ -76,6 +80,7 @@ async def test_refresh_token_fails_with_message_when_token_is_used(
|
||||
assert response.json() == {"detail": api_messages.REFRESH_TOKEN_ALREADY_USED}
|
||||
|
||||
|
||||
@pytest.mark.asyncio(loop_scope="session")
|
||||
async def test_refresh_token_success_response_status_code(
|
||||
client: AsyncClient,
|
||||
default_user: User,
|
||||
@@ -100,6 +105,7 @@ async def test_refresh_token_success_response_status_code(
|
||||
assert response.status_code == status.HTTP_200_OK
|
||||
|
||||
|
||||
@pytest.mark.asyncio(loop_scope="session")
|
||||
async def test_refresh_token_success_old_token_is_used(
|
||||
client: AsyncClient,
|
||||
default_user: User,
|
||||
@@ -128,6 +134,7 @@ async def test_refresh_token_success_old_token_is_used(
|
||||
assert used_test_refresh_token.used
|
||||
|
||||
|
||||
@pytest.mark.asyncio(loop_scope="session")
|
||||
async def test_refresh_token_success_jwt_has_valid_token_type(
|
||||
client: AsyncClient,
|
||||
default_user: User,
|
||||
@@ -153,6 +160,7 @@ async def test_refresh_token_success_jwt_has_valid_token_type(
|
||||
assert token["token_type"] == "Bearer"
|
||||
|
||||
|
||||
@pytest.mark.asyncio(loop_scope="session")
|
||||
@freeze_time("2023-01-01")
|
||||
async def test_refresh_token_success_jwt_has_valid_expire_time(
|
||||
client: AsyncClient,
|
||||
@@ -183,6 +191,7 @@ async def test_refresh_token_success_jwt_has_valid_expire_time(
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.asyncio(loop_scope="session")
|
||||
@freeze_time("2023-01-01")
|
||||
async def test_refresh_token_success_jwt_has_valid_access_token(
|
||||
client: AsyncClient,
|
||||
@@ -214,6 +223,7 @@ async def test_refresh_token_success_jwt_has_valid_access_token(
|
||||
assert token_payload.exp == token["expires_at"]
|
||||
|
||||
|
||||
@pytest.mark.asyncio(loop_scope="session")
|
||||
@freeze_time("2023-01-01")
|
||||
async def test_refresh_token_success_refresh_token_has_valid_expire_time(
|
||||
client: AsyncClient,
|
||||
@@ -229,7 +239,6 @@ async def test_refresh_token_success_refresh_token_has_valid_expire_time(
|
||||
session.add(test_refresh_token)
|
||||
await session.commit()
|
||||
|
||||
current_time = int(time.time())
|
||||
response = await client.post(
|
||||
app.url_path_for("refresh_token"),
|
||||
json={
|
||||
@@ -238,12 +247,14 @@ async def test_refresh_token_success_refresh_token_has_valid_expire_time(
|
||||
)
|
||||
|
||||
token = response.json()
|
||||
current_time = int(time.time())
|
||||
assert (
|
||||
token["refresh_token_expires_at"]
|
||||
== current_time + get_settings().security.refresh_token_expire_secs
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.asyncio(loop_scope="session")
|
||||
async def test_refresh_token_success_new_refresh_token_is_in_db(
|
||||
client: AsyncClient,
|
||||
default_user: User,
|
||||
@@ -269,4 +280,4 @@ async def test_refresh_token_success_new_refresh_token_is_in_db(
|
||||
token_db_count = await session.scalar(
|
||||
select(func.count()).where(RefreshToken.refresh_token == token["refresh_token"])
|
||||
)
|
||||
assert token_db_count == 1
|
||||
assert token_db_count == 1
|
||||
@@ -1,3 +1,4 @@
|
||||
import pytest
|
||||
from fastapi import status
|
||||
from httpx import AsyncClient
|
||||
from sqlalchemy import func, select
|
||||
@@ -8,6 +9,7 @@ from app.main import app
|
||||
from app.models import User
|
||||
|
||||
|
||||
@pytest.mark.asyncio(loop_scope="session")
|
||||
async def test_register_new_user_status_code(
|
||||
client: AsyncClient,
|
||||
) -> None:
|
||||
@@ -22,6 +24,7 @@ async def test_register_new_user_status_code(
|
||||
assert response.status_code == status.HTTP_201_CREATED
|
||||
|
||||
|
||||
@pytest.mark.asyncio(loop_scope="session")
|
||||
async def test_register_new_user_creates_record_in_db(
|
||||
client: AsyncClient,
|
||||
session: AsyncSession,
|
||||
@@ -40,6 +43,7 @@ async def test_register_new_user_creates_record_in_db(
|
||||
assert user_count == 1
|
||||
|
||||
|
||||
@pytest.mark.asyncio(loop_scope="session")
|
||||
async def test_register_new_user_cannot_create_already_created_user(
|
||||
client: AsyncClient,
|
||||
session: AsyncSession,
|
||||
@@ -60,4 +64,4 @@ async def test_register_new_user_cannot_create_already_created_user(
|
||||
)
|
||||
|
||||
assert response.status_code == status.HTTP_400_BAD_REQUEST
|
||||
assert response.json() == {"detail": api_messages.EMAIL_ADDRESS_ALREADY_USED}
|
||||
assert response.json() == {"detail": api_messages.EMAIL_ADDRESS_ALREADY_USED}
|
||||
@@ -81,4 +81,4 @@ def test_jwt_error_with_invalid_secret_key() -> None:
|
||||
with pytest.raises(HTTPException) as e:
|
||||
jwt.verify_jwt_token(token=token.access_token)
|
||||
|
||||
assert e.value.detail == "Token invalid: Signature verification failed"
|
||||
assert e.value.detail == "Token invalid: Signature verification failed"
|
||||
@@ -1,3 +1,4 @@
|
||||
import pytest
|
||||
from fastapi import status
|
||||
from httpx import AsyncClient
|
||||
from sqlalchemy import select
|
||||
@@ -7,6 +8,7 @@ from app.main import app
|
||||
from app.models import User
|
||||
|
||||
|
||||
@pytest.mark.asyncio(loop_scope="session")
|
||||
async def test_delete_current_user_status_code(
|
||||
client: AsyncClient,
|
||||
default_user_headers: dict[str, str],
|
||||
@@ -19,6 +21,7 @@ async def test_delete_current_user_status_code(
|
||||
assert response.status_code == status.HTTP_204_NO_CONTENT
|
||||
|
||||
|
||||
@pytest.mark.asyncio(loop_scope="session")
|
||||
async def test_delete_current_user_is_deleted_in_db(
|
||||
client: AsyncClient,
|
||||
default_user_headers: dict[str, str],
|
||||
@@ -33,4 +36,4 @@ async def test_delete_current_user_is_deleted_in_db(
|
||||
user = await session.scalar(
|
||||
select(User).where(User.user_id == default_user.user_id)
|
||||
)
|
||||
assert user is None
|
||||
assert user is None
|
||||
@@ -1,3 +1,4 @@
|
||||
import pytest
|
||||
from fastapi import status
|
||||
from httpx import AsyncClient
|
||||
|
||||
@@ -8,6 +9,7 @@ from app.tests.conftest import (
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.asyncio(loop_scope="session")
|
||||
async def test_read_current_user_status_code(
|
||||
client: AsyncClient, default_user_headers: dict[str, str]
|
||||
) -> None:
|
||||
@@ -19,6 +21,7 @@ async def test_read_current_user_status_code(
|
||||
assert response.status_code == status.HTTP_200_OK
|
||||
|
||||
|
||||
@pytest.mark.asyncio(loop_scope="session")
|
||||
async def test_read_current_user_response(
|
||||
client: AsyncClient, default_user_headers: dict[str, str]
|
||||
) -> None:
|
||||
@@ -30,4 +33,4 @@ async def test_read_current_user_response(
|
||||
assert response.json() == {
|
||||
"user_id": default_user_id,
|
||||
"email": default_user_email,
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
import pytest
|
||||
from fastapi import status
|
||||
from httpx import AsyncClient
|
||||
from sqlalchemy import select
|
||||
@@ -8,6 +9,7 @@ from app.main import app
|
||||
from app.models import User
|
||||
|
||||
|
||||
@pytest.mark.asyncio(loop_scope="session")
|
||||
async def test_reset_current_user_password_status_code(
|
||||
client: AsyncClient,
|
||||
default_user_headers: dict[str, str],
|
||||
@@ -21,6 +23,7 @@ async def test_reset_current_user_password_status_code(
|
||||
assert response.status_code == status.HTTP_204_NO_CONTENT
|
||||
|
||||
|
||||
@pytest.mark.asyncio(loop_scope="session")
|
||||
async def test_reset_current_user_password_is_changed_in_db(
|
||||
client: AsyncClient,
|
||||
default_user_headers: dict[str, str],
|
||||
@@ -37,4 +40,4 @@ async def test_reset_current_user_password_is_changed_in_db(
|
||||
select(User).where(User.user_id == default_user.user_id)
|
||||
)
|
||||
assert user is not None
|
||||
assert verify_password("test_pwd", user.hashed_password)
|
||||
assert verify_password("test_pwd", user.hashed_password)
|
||||
@@ -39,6 +39,7 @@ requires = ["poetry-core>=1.0.0"]
|
||||
|
||||
[tool.pytest.ini_options]
|
||||
addopts = "-vv -n auto --cov --cov-report xml --cov-report term-missing --cov-fail-under=95"
|
||||
asyncio_default_fixture_loop_scope = "session"
|
||||
asyncio_mode = "auto"
|
||||
testpaths = ["app/tests"]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user