- Add SQLITE_DB_PATH env var to db_engine.py for test isolation - Create tests/conftest.py with in-memory SQLite fixture and sample data helpers - Add tests/test_dependencies.py: unit tests for valid_token, mround, param_char, get_req_url - Add tests/test_card_pricing.py: tests for Player.change_on_sell/buy and get_all_pos - Add tests/test_api_packs.py: integration tests for GET/POST/DELETE /api/v2/packs - Add requirements-test.txt with pytest and httpx - Add test job to CI workflow (build now requires tests to pass first) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
203 lines
4.3 KiB
Python
203 lines
4.3 KiB
Python
"""
|
|
Test configuration for Paper Dynasty Database.
|
|
|
|
Sets up an isolated SQLite test database before any app modules are imported.
|
|
Uses a temporary file (not :memory:) because db_engine.py closes the connection
|
|
at module load time, which would destroy an in-memory database.
|
|
"""
|
|
|
|
import logging
|
|
import os
|
|
import tempfile
|
|
|
|
import pytest
|
|
|
|
# --- Must be set BEFORE any app imports ---
|
|
_db_fd, _db_path = tempfile.mkstemp(suffix=".db")
|
|
os.close(_db_fd)
|
|
os.environ["SQLITE_DB_PATH"] = _db_path
|
|
os.environ.setdefault("API_TOKEN", "test_token_12345")
|
|
|
|
# Suppress file-based logging during tests
|
|
logging.disable(logging.CRITICAL)
|
|
|
|
# --- App imports (after env vars are set) ---
|
|
from app.db_engine import ( # noqa: E402
|
|
db,
|
|
Rarity,
|
|
Cardset,
|
|
Event,
|
|
MlbPlayer,
|
|
Player,
|
|
Team,
|
|
PackType,
|
|
Pack,
|
|
Card,
|
|
Roster,
|
|
Current,
|
|
BattingCard,
|
|
BattingCardRatings,
|
|
PitchingCard,
|
|
PitchingCardRatings,
|
|
CardPosition,
|
|
Result,
|
|
BattingStat,
|
|
PitchingStat,
|
|
Award,
|
|
Paperdex,
|
|
Reward,
|
|
GameRewards,
|
|
Notification,
|
|
GauntletReward,
|
|
GauntletRun,
|
|
StratGame,
|
|
StratPlay,
|
|
Decision,
|
|
)
|
|
|
|
ALL_MODELS = [
|
|
Current,
|
|
Rarity,
|
|
Event,
|
|
Cardset,
|
|
MlbPlayer,
|
|
Player,
|
|
Team,
|
|
PackType,
|
|
Pack,
|
|
Card,
|
|
Roster,
|
|
Result,
|
|
BattingStat,
|
|
PitchingStat,
|
|
Award,
|
|
Paperdex,
|
|
Reward,
|
|
GameRewards,
|
|
Notification,
|
|
GauntletReward,
|
|
GauntletRun,
|
|
BattingCard,
|
|
BattingCardRatings,
|
|
PitchingCard,
|
|
PitchingCardRatings,
|
|
CardPosition,
|
|
StratGame,
|
|
StratPlay,
|
|
Decision,
|
|
]
|
|
|
|
|
|
@pytest.fixture(autouse=True)
|
|
def db_transaction():
|
|
"""
|
|
Wrap each test in a transaction that rolls back afterwards.
|
|
|
|
This ensures tests are isolated — no data bleeds between tests.
|
|
The fixture reconnects if the db was closed by the middleware.
|
|
"""
|
|
db.connect(reuse_if_open=True)
|
|
with db.atomic() as txn:
|
|
yield
|
|
txn.rollback()
|
|
if not db.is_closed():
|
|
db.close()
|
|
|
|
|
|
@pytest.fixture
|
|
def sample_rarity(db_transaction):
|
|
"""A saved Rarity row for use in tests."""
|
|
return Rarity.create(value=1, name="Common", color="#ffffff")
|
|
|
|
|
|
@pytest.fixture
|
|
def sample_cardset(db_transaction, sample_event):
|
|
"""A saved Cardset row for use in tests."""
|
|
return Cardset.create(
|
|
name="Test Set 2025",
|
|
description="Test cardset",
|
|
event=None,
|
|
for_purchase=True,
|
|
total_cards=100,
|
|
in_packs=True,
|
|
ranked_legal=True,
|
|
)
|
|
|
|
|
|
@pytest.fixture
|
|
def sample_event(db_transaction):
|
|
"""A saved Event row for use in tests."""
|
|
return Event.create(name="Test Event", active=False)
|
|
|
|
|
|
@pytest.fixture
|
|
def sample_player(db_transaction, sample_rarity, sample_cardset):
|
|
"""A saved Player row for use in tests."""
|
|
return Player.create(
|
|
player_id=99001,
|
|
p_name="Test Player",
|
|
cost=100,
|
|
image="test.png",
|
|
mlbclub="TST",
|
|
franchise="Test Franchise",
|
|
cardset=sample_cardset,
|
|
set_num=1,
|
|
rarity=sample_rarity,
|
|
pos_1="1B",
|
|
description="A test player",
|
|
)
|
|
|
|
|
|
@pytest.fixture
|
|
def sample_pack_type(db_transaction):
|
|
"""A saved PackType row for use in tests."""
|
|
return PackType.create(
|
|
name="Standard Pack",
|
|
card_count=5,
|
|
description="A standard pack",
|
|
cost=500,
|
|
available=True,
|
|
)
|
|
|
|
|
|
@pytest.fixture
|
|
def sample_current(db_transaction):
|
|
"""A saved Current row for use in tests."""
|
|
return Current.create(
|
|
season=1,
|
|
week=1,
|
|
gsheet_template="template",
|
|
gsheet_version="1.0",
|
|
live_scoreboard=123456789,
|
|
)
|
|
|
|
|
|
@pytest.fixture
|
|
def sample_team(db_transaction, sample_current, sample_event):
|
|
"""A saved Team row for use in tests."""
|
|
return Team.create(
|
|
abbrev="TST",
|
|
sname="Testers",
|
|
lname="The Test Team",
|
|
gmid=111222333,
|
|
gmname="testgm",
|
|
gsheet="https://example.com",
|
|
wallet=5000,
|
|
team_value=10000,
|
|
collection_value=8000,
|
|
season=1,
|
|
event=None,
|
|
)
|
|
|
|
|
|
@pytest.fixture
|
|
def sample_pack(db_transaction, sample_team, sample_pack_type):
|
|
"""A saved Pack row for use in tests."""
|
|
return Pack.create(
|
|
team=sample_team,
|
|
pack_type=sample_pack_type,
|
|
pack_team=None,
|
|
pack_cardset=None,
|
|
open_time=None,
|
|
)
|