aboutsummaryrefslogtreecommitdiffstats
path: root/thallium-backend
diff options
context:
space:
mode:
authorGravatar Chris Lovering <[email protected]>2024-08-19 20:55:14 +0100
committerGravatar Chris Lovering <[email protected]>2024-08-19 20:55:14 +0100
commit1a65b54c77d53ae755c5cb3fa6a8241667813f07 (patch)
treecef6c1ded5b6010976e34916d9032dbf0ca5995c /thallium-backend
parentDrop static file mount (diff)
Add conftest for access to database
Diffstat (limited to 'thallium-backend')
-rw-r--r--thallium-backend/tests/conftest.py60
-rw-r--r--thallium-backend/tests/test_app.py12
-rw-r--r--thallium-backend/tests/test_login.py19
3 files changed, 85 insertions, 6 deletions
diff --git a/thallium-backend/tests/conftest.py b/thallium-backend/tests/conftest.py
new file mode 100644
index 0000000..3e3c8cf
--- /dev/null
+++ b/thallium-backend/tests/conftest.py
@@ -0,0 +1,60 @@
+from collections.abc import AsyncGenerator, Callable
+
+import pytest
+from fastapi import FastAPI
+from httpx import AsyncClient
+from sqlalchemy import text
+from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker, create_async_engine
+
+from src.app import fastapi_app
+from src.orm import Base
+from src.settings import CONFIG, Connections, _get_db_session
+
+db_url = CONFIG.database_url.get_secret_value()
+test_db_url = db_url + "_test"
+DB_ENGINE = create_async_engine(test_db_url, isolation_level="REPEATABLE READ", echo=False)
+DB_SESSION_MAKER = async_sessionmaker(DB_ENGINE)
+
+
[email protected](scope="session")
+async def _create_test_database_engine() -> AsyncGenerator:
+ """Yield back a Database engine object."""
+ create_engine = Connections.DB_ENGINE.execution_options(isolation_level="AUTOCOMMIT", echo=False)
+ async with create_engine.connect() as conn:
+ await conn.execute(text(f"DROP DATABASE IF EXISTS {DB_ENGINE.url.database}"))
+ await conn.execute(text(f"CREATE DATABASE {DB_ENGINE.url.database}"))
+
+
+async def db_session(_create_test_database_engine: None) -> AsyncGenerator[AsyncSession]:
+ """Yield an Asynchronous database session."""
+ async with DB_ENGINE.begin() as conn:
+ await conn.run_sync(Base.metadata.drop_all)
+ await conn.run_sync(Base.metadata.create_all)
+ async with AsyncSession(bind=conn, expire_on_commit=False) as session:
+ yield session
+ await session.close()
+
+
+def override_db_session(db_session: AsyncSession) -> AsyncSession:
+ """Yield the modified Database session that uses the correspondent Database."""
+
+ async def _override_db_session() -> AsyncGenerator[AsyncSession]:
+ yield db_session
+
+ return _override_db_session
+
+
+def app(override_db_session: Callable) -> FastAPI:
+ """Override the default FastAPI app to use the overridden DB session."""
+ fastapi_app.dependency_overrides[_get_db_session] = override_db_session
+ return fastapi_app
+
+
+async def http_client(app: FastAPI) -> AsyncGenerator[AsyncClient]:
+ """Yield a client for testing the app."""
+ async with AsyncClient(app=app, base_url="http://testserver", follow_redirects=True) as ac:
+ yield ac
diff --git a/thallium-backend/tests/test_app.py b/thallium-backend/tests/test_app.py
index c7c4937..254bb18 100644
--- a/thallium-backend/tests/test_app.py
+++ b/thallium-backend/tests/test_app.py
@@ -1,9 +1,9 @@
-from fastapi.testclient import TestClient
+import pytest
+from httpx import AsyncClient
-from src.app import fastapi_app
-
-def test_heartbeat() -> None:
+async def test_heartbeat(http_client: AsyncClient) -> None:
"""Ensure the heartbeat works."""
- with TestClient(app=fastapi_app) as client:
- assert client.get("/heartbeat").json() == {"detail": "I am alive!"}
+ resp = await http_client.get("/heartbeat")
+ assert resp.json() == {"detail": "I am alive!"}
diff --git a/thallium-backend/tests/test_login.py b/thallium-backend/tests/test_login.py
new file mode 100644
index 0000000..c742d01
--- /dev/null
+++ b/thallium-backend/tests/test_login.py
@@ -0,0 +1,19 @@
+from http import HTTPStatus
+
+import pytest
+from httpx import AsyncClient
+from sqlalchemy.ext.asyncio import AsyncSession
+
+from src.orm import Voucher
+
+
+async def test_successful_voucher_login(http_client: AsyncClient, db_session: AsyncSession) -> None:
+ """Test that a valid voucher can login to the system and receive a JWT."""
+ db_session.add(Voucher(voucher_code="k1p", balance="13.37"))
+ await db_session.flush()
+
+ resp = await http_client.post("/voucher-login", json={"voucher_code": "k1p"})
+ resp_data: dict[str, str] = resp.json()
+ assert resp.status_code == HTTPStatus.OK
+ assert {"voucher_code", "jwt"} <= resp_data.keys()