diff --git a/.beans/nuzlocke-tracker-9xac--fix-stale-postgresql-enum-causing-test-failures.md b/.beans/nuzlocke-tracker-9xac--fix-stale-postgresql-enum-causing-test-failures.md new file mode 100644 index 0000000..860b9a7 --- /dev/null +++ b/.beans/nuzlocke-tracker-9xac--fix-stale-postgresql-enum-causing-test-failures.md @@ -0,0 +1,50 @@ +--- +# nuzlocke-tracker-9xac +title: Fix stale PostgreSQL enum causing test failures +status: completed +type: bug +priority: normal +created_at: 2026-03-21T10:27:53Z +updated_at: 2026-03-21T10:29:14Z +--- + +## Problem + +The backend smoke tests fail with: +``` +sqlalchemy.exc.DBAPIError: invalid input value for enum run_visibility: "public" +``` + +This happens during `Base.metadata.create_all` in the `engine` fixture (`backend/tests/conftest.py:27`). + +## Root Cause + +The `engine` fixture only calls `create_all` during setup and `drop_all` during teardown. If a previous test run was interrupted before teardown, the `run_visibility` PostgreSQL enum type persists in the test database with stale/incorrect values. On the next run, `create_all` (with `checkfirst=True` default) sees the enum exists and skips recreating it, but the existing enum lacks valid values, causing the `DEFAULT 'public'` to fail. + +PostgreSQL native enum types are not automatically dropped with `DROP TABLE` — they require explicit `DROP TYPE`. + +## Fix + +In the `engine` fixture at `backend/tests/conftest.py:23-31`, add `Base.metadata.drop_all` before `create_all` to ensure a clean slate: + +```python +@pytest.fixture(scope="session") +async def engine(): + eng = create_async_engine(TEST_DATABASE_URL, echo=False) + async with eng.begin() as conn: + await conn.run_sync(Base.metadata.drop_all) # <-- add this + await conn.run_sync(Base.metadata.create_all) + yield eng + async with eng.begin() as conn: + await conn.run_sync(Base.metadata.drop_all) + await eng.dispose() +``` + +## Checklist + +- [x] Add `drop_all` before `create_all` in the `engine` fixture (`backend/tests/conftest.py`) +- [x] Verify tests pass with `pytest backend/tests/test_smoke.py` + +## Summary of Changes + +Added `drop_all` before `create_all` in the test engine fixture to ensure stale PostgreSQL enum types are cleared before recreating the schema. This prevents test failures when a previous test run was interrupted before cleanup. diff --git a/backend/tests/conftest.py b/backend/tests/conftest.py index 01010e4..52bed36 100644 --- a/backend/tests/conftest.py +++ b/backend/tests/conftest.py @@ -24,6 +24,7 @@ async def engine(): """Create the test engine and schema once for the entire session.""" eng = create_async_engine(TEST_DATABASE_URL, echo=False) async with eng.begin() as conn: + await conn.run_sync(Base.metadata.drop_all) await conn.run_sync(Base.metadata.create_all) yield eng async with eng.begin() as conn: