Add new testing suite with working fixture
This commit is contained in:
@@ -11,14 +11,20 @@ modules: dict[str, Any] = {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
TORTOISE_ORM = {
|
TEST_TORTOISE_ORM = {
|
||||||
"connections": {
|
"connections": {
|
||||||
"testing": {
|
"default": "sqlite://:memory:"
|
||||||
"engine": "tortoise.backends.sqlite",
|
},
|
||||||
"credentials": {
|
"apps": {
|
||||||
"file_path": "stoneedge.sqlite"
|
"models": {
|
||||||
}
|
"models": modules.get("models", []) + ["aerich.models"],
|
||||||
|
"default_connection": "default",
|
||||||
},
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
PROD_TORTOISE_ORM = {
|
||||||
|
"connections": {
|
||||||
"default": {
|
"default": {
|
||||||
"engine": "tortoise.backends.asyncpg",
|
"engine": "tortoise.backends.asyncpg",
|
||||||
"credentials": {
|
"credentials": {
|
||||||
@@ -28,23 +34,26 @@ TORTOISE_ORM = {
|
|||||||
"password": settings.PSQL_PASSWORD,
|
"password": settings.PSQL_PASSWORD,
|
||||||
"port": settings.PSQL_PORT,
|
"port": settings.PSQL_PORT,
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
"apps": {
|
"apps": {
|
||||||
"models": {
|
"models": {
|
||||||
"models": modules.get("models", []) + ["aerich.models"],
|
"models": modules.get("models", []) + ["aerich.models"],
|
||||||
"default_connection": "testing" if settings.IS_TESTING else "default",
|
"default_connection": "default",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async def migrate_db(tortoise_config=TORTOISE_ORM):
|
async def migrate_db(tortoise_config=PROD_TORTOISE_ORM):
|
||||||
|
if settings.IS_TESTING:
|
||||||
|
tortoise_config=TEST_TORTOISE_ORM
|
||||||
aerich = Command(tortoise_config)
|
aerich = Command(tortoise_config)
|
||||||
await aerich.init()
|
await aerich.init()
|
||||||
await aerich.upgrade(run_in_transaction=True)
|
await aerich.upgrade()
|
||||||
await Tortoise.init(tortoise_config)
|
await Tortoise.init(tortoise_config)
|
||||||
await Tortoise.generate_schemas(safe=True)
|
await Tortoise.generate_schemas(safe=True)
|
||||||
|
|
||||||
|
|
||||||
async def end_connections_to_db():
|
async def end_connections_to_db():
|
||||||
await Tortoise.close_connections()
|
await Tortoise.close_connections()
|
||||||
|
|||||||
@@ -31,7 +31,9 @@ async def login(form: Annotated[OAuth2PasswordRequestForm, Depends()]):
|
|||||||
|
|
||||||
Logs the user into our API, creates tokens and passes them back to User.
|
Logs the user into our API, creates tokens and passes them back to User.
|
||||||
"""
|
"""
|
||||||
user: User | None = await User.filter(email=form.username).first()
|
user: User | None = await User.filter(Q(email=form.username) | Q(username=form.username)).first()
|
||||||
|
|
||||||
|
print(user)
|
||||||
|
|
||||||
if user is None:
|
if user is None:
|
||||||
raise HTTPException(status_code=401, detail=account_error)
|
raise HTTPException(status_code=401, detail=account_error)
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import pytest
|
|
||||||
|
|
||||||
@pytest.mark.usefixtures("use_database_during_testing")
|
|
||||||
class Test():
|
class Test():
|
||||||
pass
|
pass
|
||||||
@@ -1,11 +1,8 @@
|
|||||||
import asyncio
|
import asyncio, httpx, pytest
|
||||||
from contextlib import asynccontextmanager
|
from contextlib import asynccontextmanager
|
||||||
from typing import AsyncGenerator
|
from typing import AsyncGenerator
|
||||||
import httpx, pytest
|
|
||||||
from tortoise import Tortoise
|
|
||||||
from asgi_lifespan import LifespanManager
|
from asgi_lifespan import LifespanManager
|
||||||
|
|
||||||
from database import migrate_db
|
|
||||||
from tests.fixtures.account import *
|
from tests.fixtures.account import *
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -32,13 +29,6 @@ def event_loop():
|
|||||||
loop.close()
|
loop.close()
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
async def use_database_during_testing():
|
|
||||||
await migrate_db()
|
|
||||||
yield
|
|
||||||
await Tortoise._drop_databases()
|
|
||||||
|
|
||||||
|
|
||||||
@asynccontextmanager
|
@asynccontextmanager
|
||||||
async def client_manager(app, base_url="https://localhost", **kw) -> ClientManagerType:
|
async def client_manager(app, base_url="https://localhost", **kw) -> ClientManagerType:
|
||||||
app.state.testing = True
|
app.state.testing = True
|
||||||
|
|||||||
+33
-23
@@ -5,6 +5,7 @@ from modules.auth.utils import create_jwt_tokens
|
|||||||
from modules.organizations.models import Organization, OrganizationType
|
from modules.organizations.models import Organization, OrganizationType
|
||||||
from modules.users.models import ACL, Membership, User
|
from modules.users.models import ACL, Membership, User
|
||||||
from modules.auth.models import Token
|
from modules.auth.models import Token
|
||||||
|
from tortoise.expressions import Q
|
||||||
|
|
||||||
from config import settings
|
from config import settings
|
||||||
|
|
||||||
@@ -27,32 +28,41 @@ async def create_user_with_org():
|
|||||||
organization_name="simple organization",
|
organization_name="simple organization",
|
||||||
organization_type=OrganizationType.HOME,
|
organization_type=OrganizationType.HOME,
|
||||||
is_admin=False) -> user_creation_return_type:
|
is_admin=False) -> user_creation_return_type:
|
||||||
org: Organization = await Organization.create(
|
org: Organization | None = await Organization.filter(Q(name=organization_name) & Q(name=organization_type)).first()
|
||||||
name=organization_name,
|
if not org:
|
||||||
type=organization_type
|
org: Organization = await Organization.create(
|
||||||
)
|
name=organization_name,
|
||||||
|
type=organization_type
|
||||||
|
)
|
||||||
|
|
||||||
acl: ACL = await ACL.create(
|
user: User | None = await User.filter(Q(email=email)).first()
|
||||||
READ=True,
|
if not user:
|
||||||
WRITE=True,
|
user: User = await User.create(
|
||||||
REPORT=True,
|
email=email,
|
||||||
MANAGE=True if is_admin else False,
|
username=username,
|
||||||
ADMIN=True if is_admin else False,
|
name=name,
|
||||||
)
|
surname=surname,
|
||||||
|
password=crypt.hash(password),
|
||||||
|
)
|
||||||
|
|
||||||
user: User = await User.create(
|
acl: ACL | None = await ACL.filter(Q(id="5f33facd-08dd-48a1-8f15-3b24f2a727f5")).first()
|
||||||
email=email,
|
if not acl:
|
||||||
username=username,
|
acl: ACL = await ACL.create(
|
||||||
name=name,
|
id="5f33facd-08dd-48a1-8f15-3b24f2a727f5",
|
||||||
surname=surname,
|
READ=True,
|
||||||
password=crypt.hash(password),
|
WRITE=True,
|
||||||
)
|
REPORT=True,
|
||||||
|
MANAGE=True if is_admin else False,
|
||||||
|
ADMIN=True if is_admin else False,
|
||||||
|
)
|
||||||
|
|
||||||
await Membership.create(
|
membership: Membership | None = await Membership.filter(Q(user=user, organization=org, acl=acl)).first()
|
||||||
organization=org,
|
if not membership:
|
||||||
user=user,
|
await Membership.get_or_create(
|
||||||
acl=acl
|
organization=org,
|
||||||
)
|
user=user,
|
||||||
|
acl=acl
|
||||||
|
)
|
||||||
|
|
||||||
tokens: Token = await create_jwt_tokens(user=user)
|
tokens: Token = await create_jwt_tokens(user=user)
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ crypt = settings.CRYPT
|
|||||||
|
|
||||||
|
|
||||||
class TestAuthentication(Test):
|
class TestAuthentication(Test):
|
||||||
@pytest.mark.asyncio
|
|
||||||
async def test_authentication_with_non_existing_user_and_password(
|
async def test_authentication_with_non_existing_user_and_password(
|
||||||
self, client: AsyncClient
|
self, client: AsyncClient
|
||||||
):
|
):
|
||||||
@@ -25,7 +24,6 @@ class TestAuthentication(Test):
|
|||||||
assert response.status_code == 401
|
assert response.status_code == 401
|
||||||
assert response.json() == {"detail": "E-Mail Address or password is incorrect"}
|
assert response.json() == {"detail": "E-Mail Address or password is incorrect"}
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
|
||||||
async def test_authentication_with_existing_user_and_wrong_password(
|
async def test_authentication_with_existing_user_and_wrong_password(
|
||||||
self, client: AsyncClient, create_user_with_org
|
self, client: AsyncClient, create_user_with_org
|
||||||
):
|
):
|
||||||
@@ -41,7 +39,6 @@ class TestAuthentication(Test):
|
|||||||
assert response.status_code == 401
|
assert response.status_code == 401
|
||||||
assert response.json() == {"detail": "E-Mail Address or password is incorrect"}
|
assert response.json() == {"detail": "E-Mail Address or password is incorrect"}
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
|
||||||
async def test_authentication_with_existing_user_and_password(
|
async def test_authentication_with_existing_user_and_password(
|
||||||
self, client: AsyncClient, create_user_with_org
|
self, client: AsyncClient, create_user_with_org
|
||||||
):
|
):
|
||||||
@@ -69,19 +66,19 @@ class TestAuthentication(Test):
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
|
||||||
async def test_logging_out_destroys_tokens(
|
async def test_logging_out_destroys_tokens(
|
||||||
self, client: AsyncClient, create_user_with_org
|
self, client: AsyncClient, create_user_with_org
|
||||||
):
|
):
|
||||||
user, _, _, _ = await create_user_with_org(email="user@localhost.com", password="userpassword")
|
user, _, _, _ = await create_user_with_org(email="superuser@localhost.com", password="superuser")
|
||||||
response = await client.post(
|
response = await client.post(
|
||||||
"https://localhost/api/v1/auth/login",
|
"https://localhost/api/v1/auth/login",
|
||||||
data={
|
data={
|
||||||
"username": "user@localhost.com",
|
"username": "superuser@localhost.com",
|
||||||
"password": "userpassword",
|
"password": "superuser",
|
||||||
"grant_type": "password",
|
"grant_type": "password",
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
print(response.json())
|
||||||
assert response.status_code == 200
|
assert response.status_code == 200
|
||||||
assert response.json() == {
|
assert response.json() == {
|
||||||
"jwt": {
|
"jwt": {
|
||||||
@@ -116,7 +113,6 @@ class TestAuthentication(Test):
|
|||||||
"detail": "Refresh token not found or something went wrong."
|
"detail": "Refresh token not found or something went wrong."
|
||||||
}
|
}
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
|
||||||
async def test_create_new_tokens_upon_refresh(
|
async def test_create_new_tokens_upon_refresh(
|
||||||
self, client: AsyncClient, create_user_with_org
|
self, client: AsyncClient, create_user_with_org
|
||||||
):
|
):
|
||||||
@@ -166,7 +162,6 @@ class TestAuthentication(Test):
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
|
||||||
async def test_setup_new_account(self, client: AsyncClient):
|
async def test_setup_new_account(self, client: AsyncClient):
|
||||||
# Ensure account is never available. Prevents account already being available.
|
# Ensure account is never available. Prevents account already being available.
|
||||||
check_if_account_exists: User | None = await User.filter(
|
check_if_account_exists: User | None = await User.filter(
|
||||||
|
|||||||
Reference in New Issue
Block a user