Skip to content

Commit 3cb1ea5

Browse files
nanotaboadaclaude
andcommitted
test(migrations): add downgrade tests; add codecov.yaml (#2)
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 3b645ab commit 3cb1ea5

File tree

3 files changed

+79
-0
lines changed

3 files changed

+79
-0
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@ This project uses famous football coaches as release codenames, following an A-Z
5151
deterministic UUID v5 values); `alembic upgrade head` runs automatically on
5252
app startup via the lifespan handler (#2)
5353
- `alembic==1.18.4`, `asyncpg==0.31.0` added to dependencies (#2)
54+
- `tests/test_migrations.py`: integration tests for migration downgrade paths —
55+
verifies each step removes only its seeded rows and restores correctly (#2)
56+
- `codecov.yaml`: excludes `alembic/env.py` from coverage (offline mode is
57+
tooling infrastructure, not application logic) (#2)
5458
- `.sonarcloud.properties`: SonarCloud Automatic Analysis configuration —
5559
sources, tests, coverage exclusions aligned with `codecov.yml` (#554)
5660
- `.dockerignore`: added `.claude/`, `CLAUDE.md`, `.coderabbit.yaml`,

codecov.yaml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
coverage:
2+
status:
3+
patch:
4+
default:
5+
target: 80%
6+
project:
7+
default:
8+
target: 80%
9+
10+
ignore:
11+
- "alembic/env.py"

tests/test_migrations.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
"""
2+
Integration tests for Alembic migration downgrade paths.
3+
4+
These tests exercise the downgrade() functions in each migration version,
5+
verifying that each step removes exactly the rows it seeded and leaves the
6+
rest of the database intact.
7+
8+
Tests run after test_main.py (alphabetical order). Each test downgrades one
9+
or more steps, asserts the expected state, then restores to head before the
10+
next test, ensuring the shared SQLite database remains consistent for any
11+
subsequent test runs.
12+
"""
13+
14+
import os
15+
import sqlite3
16+
17+
from alembic import command
18+
from alembic.config import Config
19+
20+
_DB_PATH = os.getenv("STORAGE_PATH", "./players-sqlite3.db")
21+
_ALEMBIC_CFG = Config("alembic.ini")
22+
23+
24+
def test_migration_downgrade_003_removes_substitutes_only():
25+
"""Downgrade 003→002 removes the 15 seeded substitutes, leaves Starting XI."""
26+
command.downgrade(_ALEMBIC_CFG, "-1")
27+
28+
conn = sqlite3.connect(_DB_PATH)
29+
total = conn.execute("SELECT COUNT(*) FROM players").fetchone()[0]
30+
subs = conn.execute("SELECT COUNT(*) FROM players WHERE starting11=0").fetchone()[0]
31+
conn.close()
32+
33+
command.upgrade(_ALEMBIC_CFG, "head")
34+
35+
assert total == 11
36+
assert subs == 0
37+
38+
39+
def test_migration_downgrade_002_removes_starting11_only():
40+
"""Downgrade 002→001 removes the 11 seeded Starting XI, leaves table empty."""
41+
command.downgrade(_ALEMBIC_CFG, "-2")
42+
43+
conn = sqlite3.connect(_DB_PATH)
44+
total = conn.execute("SELECT COUNT(*) FROM players").fetchone()[0]
45+
conn.close()
46+
47+
command.upgrade(_ALEMBIC_CFG, "head")
48+
49+
assert total == 0
50+
51+
52+
def test_migration_downgrade_001_drops_players_table():
53+
"""Downgrade 001→base drops the players table entirely."""
54+
command.downgrade(_ALEMBIC_CFG, "base")
55+
56+
conn = sqlite3.connect(_DB_PATH)
57+
table = conn.execute(
58+
"SELECT name FROM sqlite_master WHERE type='table' AND name='players'"
59+
).fetchone()
60+
conn.close()
61+
62+
command.upgrade(_ALEMBIC_CFG, "head")
63+
64+
assert table is None

0 commit comments

Comments
 (0)