96 lines
3.1 KiB
Python
96 lines
3.1 KiB
Python
"""Tests for the alembic migration history.
|
|
|
|
The 0005 migration adds `script` and `last_build_status` columns to `overlays`,
|
|
drops the global_overlay_* tables, and wipes legacy l4d2center_maps/cedapug_maps
|
|
overlay rows. This module pins those behaviors.
|
|
"""
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
from alembic import command
|
|
from alembic.config import Config
|
|
from sqlalchemy import create_engine, inspect, text
|
|
|
|
|
|
_ALEMBIC_DIR = Path(__file__).resolve().parents[1] / "alembic"
|
|
|
|
|
|
def _alembic_config(db_url: str) -> Config:
|
|
cfg = Config()
|
|
cfg.set_main_option("script_location", str(_ALEMBIC_DIR))
|
|
cfg.set_main_option("sqlalchemy.url", db_url)
|
|
return cfg
|
|
|
|
|
|
@pytest.fixture
|
|
def db_url(tmp_path, monkeypatch):
|
|
path = tmp_path / "alembic.db"
|
|
url = f"sqlite:///{path}"
|
|
monkeypatch.setenv("DATABASE_URL", url)
|
|
yield url
|
|
|
|
|
|
def test_upgrade_0005_adds_script_columns(db_url) -> None:
|
|
cfg = _alembic_config(db_url)
|
|
|
|
command.upgrade(cfg, "0004_drop_legacy_external_overlay_type")
|
|
|
|
engine = create_engine(db_url)
|
|
with engine.begin() as conn:
|
|
# Seed legacy global-type overlay rows that the migration must wipe.
|
|
conn.execute(
|
|
text(
|
|
"INSERT INTO overlays (name, path, type, created_at, updated_at) "
|
|
"VALUES ('legacy-l4d2center', '1', 'l4d2center_maps', "
|
|
"'2026-01-01', '2026-01-01')"
|
|
)
|
|
)
|
|
conn.execute(
|
|
text(
|
|
"INSERT INTO overlays (name, path, type, created_at, updated_at) "
|
|
"VALUES ('legacy-cedapug', '2', 'cedapug_maps', "
|
|
"'2026-01-01', '2026-01-01')"
|
|
)
|
|
)
|
|
conn.execute(
|
|
text(
|
|
"INSERT INTO overlays (name, path, type, created_at, updated_at) "
|
|
"VALUES ('keep-workshop', '3', 'workshop', "
|
|
"'2026-01-01', '2026-01-01')"
|
|
)
|
|
)
|
|
|
|
command.upgrade(cfg, "0005_script_overlays")
|
|
|
|
inspector = inspect(engine)
|
|
|
|
overlay_cols = {c["name"]: c for c in inspector.get_columns("overlays")}
|
|
assert "script" in overlay_cols
|
|
assert "last_build_status" in overlay_cols
|
|
assert overlay_cols["script"]["nullable"] is False
|
|
assert overlay_cols["last_build_status"]["nullable"] is False
|
|
|
|
table_names = set(inspector.get_table_names())
|
|
assert "global_overlay_sources" not in table_names
|
|
assert "global_overlay_items" not in table_names
|
|
assert "global_overlay_item_files" not in table_names
|
|
|
|
with engine.connect() as conn:
|
|
rows = conn.execute(
|
|
text("SELECT name, type FROM overlays ORDER BY name")
|
|
).all()
|
|
assert rows == [("keep-workshop", "workshop")]
|
|
|
|
defaults = conn.execute(
|
|
text(
|
|
"SELECT script, last_build_status FROM overlays "
|
|
"WHERE name = 'keep-workshop'"
|
|
)
|
|
).one()
|
|
assert defaults == ("", "")
|
|
|
|
|
|
def test_downgrade_0005_skipped() -> None:
|
|
"""Per the project convention (see 0004) destructive migrations are
|
|
intentionally one-way; do not test or maintain a downgrade."""
|
|
pytest.skip("0005 is one-way: globals data is gone after upgrade")
|