diff --git a/app/config.py b/app/config.py index af30156..00c419c 100644 --- a/app/config.py +++ b/app/config.py @@ -2,14 +2,11 @@ from pathlib import Path import tomli import pydantic +import os DEBUG = True MAIN_VERSION = "0.1.1" -ROOT_DIR = Path().parent.resolve() -DB_PATH = ROOT_DIR / "data" / "database.db" -SQLALCHEMY_DATABASE_URL = f"sqlite:///{DB_PATH}" -_CONFIG_FILE = "config.toml" class Config(pydantic.BaseModel): domain: str @@ -32,6 +29,12 @@ class Config(pydantic.BaseModel): inbox_retention_days: int = 15 post_token: str | None = None + sqlalchemy_database: str | None = None + + +ROOT_DIR = Path().parent.resolve() +_CONFIG_FILE = os.getenv("FOXHOLE_CONFIG_FILE", "config.toml") + def load_config() -> Config: try: return Config.parse_obj( @@ -56,6 +59,10 @@ def get_version_commit() -> str: CONFIG = load_config() DOMAIN = CONFIG.domain + +DB_PATH = CONFIG.sqlalchemy_database or ROOT_DIR / "data" / "database.db" +SQLALCHEMY_DATABASE_URL = f"sqlite:///{DB_PATH}" + _SCHEME = "https" if CONFIG.https else "http" ID = f"{_SCHEME}://{DOMAIN}" BASE_URL = ID diff --git a/data/tests.toml b/data/tests.toml new file mode 100644 index 0000000..aed5e8e --- /dev/null +++ b/data/tests.toml @@ -0,0 +1,12 @@ +domain = "localhost:8000" +username = "test" +name = "test" + +summary = "

Hello World!

" +https = false +icon_url = "https://localhost:8000/static/nopic.png" +secret = "0d0645798d20af6bd77a9303658f62d8" +debug = true + +# In-mem DB +sqlalchemy_database = "file:pytest?mode=memory&cache=shared&uri=true" diff --git a/tasks.py b/tasks.py index f6c3419..d0c182b 100644 --- a/tasks.py +++ b/tasks.py @@ -168,3 +168,12 @@ def send_note(ctx): print("Done!") asyncio.run(_dodo()) + + +@task +def tests(ctx): + run( + f"FOXHOLE_CONFIG_FILE=tests.toml pytest -vvv", + pty=True, + echo=True, + ) diff --git a/tests/conftest.py b/tests/conftest.py index bd2b38a..bd5ff70 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -14,10 +14,20 @@ from app.database import SessionLocal from sqlalchemy import orm -_Session = orm.scoped_session(SessionLocal) + +@pytest_asyncio.fixture +async def async_db_session(): + async with async_session() as session: # type: ignore + async with async_engine.begin() as conn: + await conn.run_sync(Base.metadata.create_all) + yield session + async with async_engine.begin() as conn: + await conn.run_sync(Base.metadata.drop_all) + @pytest.fixture def db(): + _Session = orm.scoped_session(SessionLocal) Base.metadata.create_all(bind=engine) with _Session() as db_session: try: diff --git a/tests/test_outbox.py b/tests/test_outbox.py index 51f094e..2371d10 100644 --- a/tests/test_outbox.py +++ b/tests/test_outbox.py @@ -21,6 +21,7 @@ from sqlalchemy import select @pytest.mark.asyncio async def test_outbox_send_follow_request( db: Session, + async_db_session, client: TestClient, respx_mock: respx.MockRouter, ) -> None: @@ -34,10 +35,9 @@ async def test_outbox_send_follow_request( respx_mock.post(remote_ap_id + "/inbox").mock( return_value=httpx.Response(202)) - from app.database import async_session from app.boxes import send_follow - async with async_session() as db_session: #type: ignore + async with async_db_session as db_session: #type: ignore await send_follow(db_session, remote_ap_id) # And the Follow activity was created in the outbox @@ -49,6 +49,7 @@ async def test_outbox_send_follow_request( @pytest.mark.asyncio async def test_outbox_send_create_activity( db: Session, + async_db_session, client: TestClient, respx_mock: respx.MockRouter, ) -> None: @@ -62,12 +63,11 @@ async def test_outbox_send_create_activity( respx_mock.post(remote_ap_id + "/inbox").mock( return_value=httpx.Response(202)) - from app.database import async_session from app.boxes import _send_create from app.activitypub import VisibilityEnum from app.orgpython import to_html - async with async_session() as db_session: #type: ignore + async with async_db_session as db_session: #type: ignore content = "*Blod Text* =code Text= \n" content = to_html(content)