feat: add alembic migrations, integration tests, and CI support
- Add alembic dependency and initialize migration framework - Configure async alembic env.py for SQLAlchemy 2.0 - Create initial migration for PostORM table - Gate init_db() with SKIP_INIT_DB env var for CI/production - Add PostgreSQL service to Woodpecker CI pipeline - Create integration tests for migrations (TC-INT-001..002) - Create integration tests for SQLAlchemyPostRepository (TC-INT-003..009) - Add unit test for init_db skip behavior (TC-UNIT-901) - All 176 tests pass, coverage 72.59%
This commit is contained in:
44
tests/integration/test_migrations.py
Normal file
44
tests/integration/test_migrations.py
Normal file
@@ -0,0 +1,44 @@
|
||||
from typing import cast
|
||||
|
||||
import pytest
|
||||
from sqlalchemy import inspect
|
||||
from sqlalchemy.ext.asyncio import AsyncEngine, AsyncSession
|
||||
|
||||
|
||||
class TestMigrations:
|
||||
@pytest.mark.asyncio
|
||||
async def test_initial_migration_creates_post_table(self, db_session: AsyncSession) -> None:
|
||||
engine = cast(AsyncEngine, db_session.bind)
|
||||
async with engine.connect() as conn:
|
||||
tables = await conn.run_sync(lambda sync_conn: inspect(sync_conn).get_table_names())
|
||||
assert "posts" in tables
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_posts_table_has_expected_columns(self, db_session: AsyncSession) -> None:
|
||||
engine = cast(AsyncEngine, db_session.bind)
|
||||
async with engine.connect() as conn:
|
||||
columns = await conn.run_sync(lambda sync_conn: inspect(sync_conn).get_columns("posts"))
|
||||
column_names = [col["name"] for col in columns]
|
||||
expected = [
|
||||
"id",
|
||||
"title",
|
||||
"content",
|
||||
"slug",
|
||||
"author_id",
|
||||
"published",
|
||||
"tags",
|
||||
"created_at",
|
||||
"updated_at",
|
||||
]
|
||||
for col in expected:
|
||||
assert col in column_names
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_posts_table_has_indexes(self, db_session: AsyncSession) -> None:
|
||||
engine = cast(AsyncEngine, db_session.bind)
|
||||
async with engine.connect() as conn:
|
||||
indexes = await conn.run_sync(lambda sync_conn: inspect(sync_conn).get_indexes("posts"))
|
||||
index_names = [idx["name"] for idx in indexes]
|
||||
assert "ix_posts_slug" in index_names
|
||||
assert "ix_posts_author_id" in index_names
|
||||
assert "ix_posts_published" in index_names
|
||||
Reference in New Issue
Block a user