from datetime import date from pathlib import Path from alembic.config import Config from sqlalchemy import create_engine from sqlalchemy.orm import Session from alembic import command from app.config import get_settings from app.identity.models import User from app.ledger.models import Account, Category from app.spaces.models import FinancialSpace, Membership def test_upgrade_backfills_one_pair_without_claiming_same_named_rows( tmp_path: Path, monkeypatch, ) -> None: database_url = f"sqlite:///{tmp_path / 'migration.db'}" monkeypatch.setenv("DATABASE_URL", database_url) get_settings.cache_clear() config = Config(str(Path(__file__).parents[1] / "alembic.ini")) config.set_main_option("script_location", str(Path(__file__).parents[1] / "alembic")) try: command.upgrade(config, "0002") engine = create_engine(database_url) with Session(engine) as db: user = User(email="migration@example.com", password_hash="unused") space = FinancialSpace(name="Legacy") db.add_all([user, space]) db.flush() db.add(Membership(space_id=space.id, user_id=user.id, role="owner")) db.add( Account( space_id=space.id, name="Savings", kind="debit", opened_on=date(2026, 1, 1), ) ) db.add( Category( space_id=space.id, name_override="Savings", kind="monthly", ) ) db.commit() space_id = space.id command.upgrade(config, "head") command.upgrade(config, "head") with Session(engine) as db: accounts = db.query(Account).filter_by(space_id=space_id).all() categories = db.query(Category).filter_by(space_id=space_id).all() system_account = [item for item in accounts if item.system_key == "savings"] system_category = [item for item in categories if item.system_key == "savings"] assert len(system_account) == 1 assert len(system_category) == 1 assert system_category[0].linked_account_id == system_account[0].id assert any(item.name == "Savings" and item.system_key is None for item in accounts) assert any( item.name_override == "Savings" and item.system_key is None for item in categories ) finally: get_settings.cache_clear()