81 lines
2.3 KiB
Python
81 lines
2.3 KiB
Python
import os
|
|
from unittest import mock
|
|
|
|
import pytest
|
|
from fastapi.testclient import TestClient
|
|
from sqlalchemy import StaticPool, create_engine, event
|
|
from sqlalchemy.orm import sessionmaker
|
|
|
|
from allmende_payment_system.api.dependencies import get_session
|
|
from allmende_payment_system.app import app
|
|
from allmende_payment_system.models import Base
|
|
|
|
engine = create_engine(
|
|
"sqlite:///:memory:",
|
|
connect_args={"check_same_thread": False},
|
|
poolclass=StaticPool,
|
|
)
|
|
|
|
# Create a single connection and an outer transaction which we can rollback
|
|
# at the end of the test run. Individual tests will use nested transactions
|
|
# (SAVEPOINTs) for isolation. This ensures the TestClient (app) and the
|
|
# test fixture sessions see the same in-memory database state.
|
|
connection = engine.connect()
|
|
transaction = connection.begin()
|
|
|
|
Base.metadata.create_all(bind=connection)
|
|
|
|
# Bind sessions to the single connection so all sessions share the same DB
|
|
TestSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=connection)
|
|
|
|
test_session = None
|
|
|
|
|
|
def get_test_session():
|
|
"""Dependency override for get_session"""
|
|
assert test_session is not None, "test_session is not set"
|
|
yield test_session
|
|
test_session.flush()
|
|
|
|
|
|
app.dependency_overrides[get_session] = get_test_session
|
|
|
|
|
|
class APSTestClient(TestClient):
|
|
def __init__(self, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
|
|
def post(self, *args, user: str = "test", **kwargs):
|
|
with mock.patch.dict(os.environ, {"APS_username": user}, clear=False):
|
|
return super().post(*args, **kwargs)
|
|
|
|
def get(self, *args, user: str = "test", **kwargs):
|
|
with mock.patch.dict(os.environ, {"APS_username": user}, clear=False):
|
|
return super().get(*args, **kwargs)
|
|
|
|
|
|
@pytest.fixture(scope="session")
|
|
def client():
|
|
os.environ["APS_username"] = "test"
|
|
return APSTestClient(app)
|
|
|
|
|
|
@pytest.fixture(scope="session")
|
|
def unauthorized_client():
|
|
os.environ.pop("APS_username", None)
|
|
return TestClient(app)
|
|
|
|
|
|
@pytest.fixture(scope="function")
|
|
def test_db():
|
|
"""Provides a database session for direct test usage"""
|
|
db = TestSessionLocal()
|
|
global test_session
|
|
test_session = db
|
|
try:
|
|
yield db
|
|
finally:
|
|
test_session = None
|
|
db.rollback()
|
|
db.close()
|