fix: complete remaining evolution→refractor renames from review
- Rename route /{team_id}/evolutions → /{team_id}/refractors
- Rename function initialize_card_evolution → initialize_card_refractor
- Rename index names in migration SQL
- Update all test references
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
b7dec3f231
commit
500a8f3848
@ -16,7 +16,7 @@ from ..db_engine import (
|
||||
DoesNotExist,
|
||||
)
|
||||
from ..dependencies import oauth2_scheme, valid_token
|
||||
from ..services.refractor_init import _determine_card_type, initialize_card_evolution
|
||||
from ..services.refractor_init import _determine_card_type, initialize_card_refractor
|
||||
|
||||
router = APIRouter(prefix="/api/v2/cards", tags=["cards"])
|
||||
|
||||
@ -227,7 +227,7 @@ async def v1_cards_post(cards: CardModel, token: str = Depends(oauth2_scheme)):
|
||||
try:
|
||||
this_player = Player.get_by_id(x.player_id)
|
||||
card_type = _determine_card_type(this_player)
|
||||
initialize_card_evolution(x.player_id, x.team_id, card_type)
|
||||
initialize_card_refractor(x.player_id, x.team_id, card_type)
|
||||
except Exception:
|
||||
logging.exception(
|
||||
"refractor hook: unexpected error for player_id=%s team_id=%s",
|
||||
|
||||
@ -1530,8 +1530,8 @@ async def delete_team(team_id, token: str = Depends(oauth2_scheme)):
|
||||
raise HTTPException(status_code=500, detail=f"Team {team_id} was not deleted")
|
||||
|
||||
|
||||
@router.get("/{team_id}/evolutions")
|
||||
async def list_team_evolutions(
|
||||
@router.get("/{team_id}/refractors")
|
||||
async def list_team_refractors(
|
||||
team_id: int,
|
||||
card_type: Optional[str] = Query(default=None),
|
||||
tier: Optional[int] = Query(default=None),
|
||||
|
||||
@ -3,7 +3,7 @@ WP-10: Pack opening hook — refractor_card_state initialization.
|
||||
|
||||
Public API
|
||||
----------
|
||||
initialize_card_evolution(player_id, team_id, card_type)
|
||||
initialize_card_refractor(player_id, team_id, card_type)
|
||||
Get-or-create a RefractorCardState for the (player_id, team_id) pair.
|
||||
Returns the state instance on success, or None if initialization fails
|
||||
(missing track, integrity error, etc.). Never raises.
|
||||
@ -53,7 +53,7 @@ def _determine_card_type(player) -> str:
|
||||
return "batter"
|
||||
|
||||
|
||||
def initialize_card_evolution(
|
||||
def initialize_card_refractor(
|
||||
player_id: int,
|
||||
team_id: int,
|
||||
card_type: str,
|
||||
|
||||
@ -13,3 +13,7 @@ ALTER TABLE evolution_track RENAME TO refractor_track;
|
||||
ALTER TABLE evolution_card_state RENAME TO refractor_card_state;
|
||||
ALTER TABLE evolution_tier_boost RENAME TO refractor_tier_boost;
|
||||
ALTER TABLE evolution_cosmetic RENAME TO refractor_cosmetic;
|
||||
|
||||
-- Rename indexes to match new table names
|
||||
ALTER INDEX IF EXISTS evolution_card_state_player_team_uniq RENAME TO refractor_card_state_player_team_uniq;
|
||||
ALTER INDEX IF EXISTS evolution_tier_boost_track_tier_type_target_uniq RENAME TO refractor_tier_boost_track_tier_type_target_uniq;
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
"""
|
||||
Tests for WP-10: refractor_card_state initialization on pack opening.
|
||||
|
||||
Covers `app/services/refractor_init.py` — the `initialize_card_evolution`
|
||||
Covers `app/services/refractor_init.py` — the `initialize_card_refractor`
|
||||
function that creates an RefractorCardState row when a card is first acquired.
|
||||
|
||||
Test strategy:
|
||||
@ -30,7 +30,7 @@ from app.db_engine import (
|
||||
RefractorTrack,
|
||||
Player,
|
||||
)
|
||||
from app.services.refractor_init import _determine_card_type, initialize_card_evolution
|
||||
from app.services.refractor_init import _determine_card_type, initialize_card_refractor
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
@ -154,12 +154,12 @@ class TestDetermineCardType:
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Integration tests — initialize_card_evolution
|
||||
# Integration tests — initialize_card_refractor
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
class TestInitializeCardEvolution:
|
||||
"""Integration tests for initialize_card_evolution against in-memory SQLite.
|
||||
"""Integration tests for initialize_card_refractor against in-memory SQLite.
|
||||
|
||||
Each test relies on the conftest autouse fixture to get a clean database.
|
||||
We create tracks for all three card types so the function can always find
|
||||
@ -170,7 +170,7 @@ class TestInitializeCardEvolution:
|
||||
def seed_tracks(self):
|
||||
"""Create one RefractorTrack per card_type before each test.
|
||||
|
||||
initialize_card_evolution does a DB lookup for a track matching the
|
||||
initialize_card_refractor does a DB lookup for a track matching the
|
||||
card_type. If no track exists the function must not crash (it should
|
||||
log and return None), but having tracks present lets us verify the
|
||||
happy path for all three types without repeating setup in every test.
|
||||
@ -189,7 +189,7 @@ class TestInitializeCardEvolution:
|
||||
- track matches the player's card_type (batter here)
|
||||
"""
|
||||
player = _make_player(rarity, "2B")
|
||||
state = initialize_card_evolution(player.player_id, team.id, "batter")
|
||||
state = initialize_card_refractor(player.player_id, team.id, "batter")
|
||||
|
||||
assert state is not None
|
||||
assert state.player_id == player.player_id
|
||||
@ -208,7 +208,7 @@ class TestInitializeCardEvolution:
|
||||
"""
|
||||
player = _make_player(rarity, "SS")
|
||||
# First call creates the state
|
||||
state1 = initialize_card_evolution(player.player_id, team.id, "batter")
|
||||
state1 = initialize_card_refractor(player.player_id, team.id, "batter")
|
||||
assert state1 is not None
|
||||
|
||||
# Simulate partial evolution progress
|
||||
@ -217,7 +217,7 @@ class TestInitializeCardEvolution:
|
||||
state1.save()
|
||||
|
||||
# Second call (duplicate card) must not reset progress
|
||||
state2 = initialize_card_evolution(player.player_id, team.id, "batter")
|
||||
state2 = initialize_card_refractor(player.player_id, team.id, "batter")
|
||||
assert state2 is not None
|
||||
|
||||
# Exactly one row in the database
|
||||
@ -246,8 +246,8 @@ class TestInitializeCardEvolution:
|
||||
player_a = _make_player(rarity, "LF")
|
||||
player_b = _make_player(rarity, "RF")
|
||||
|
||||
state_a = initialize_card_evolution(player_a.player_id, team.id, "batter")
|
||||
state_b = initialize_card_evolution(player_b.player_id, team.id, "batter")
|
||||
state_a = initialize_card_refractor(player_a.player_id, team.id, "batter")
|
||||
state_b = initialize_card_refractor(player_b.player_id, team.id, "batter")
|
||||
|
||||
assert state_a is not None
|
||||
assert state_b is not None
|
||||
@ -264,7 +264,7 @@ class TestInitializeCardEvolution:
|
||||
state links to the sp track, not the batter track.
|
||||
"""
|
||||
player = _make_player(rarity, "SP")
|
||||
state = initialize_card_evolution(player.player_id, team.id, "sp")
|
||||
state = initialize_card_refractor(player.player_id, team.id, "sp")
|
||||
|
||||
assert state is not None
|
||||
assert state.track_id == self.sp_track.id
|
||||
@ -272,7 +272,7 @@ class TestInitializeCardEvolution:
|
||||
def test_rp_card_gets_rp_track(self, rarity, team):
|
||||
"""A relief pitcher (RP or CP) is assigned the 'rp' RefractorTrack."""
|
||||
player = _make_player(rarity, "RP")
|
||||
state = initialize_card_evolution(player.player_id, team.id, "rp")
|
||||
state = initialize_card_refractor(player.player_id, team.id, "rp")
|
||||
|
||||
assert state is not None
|
||||
assert state.track_id == self.rp_track.id
|
||||
@ -291,7 +291,7 @@ class TestInitializeCardEvolution:
|
||||
# Delete the sp track to simulate missing seed data
|
||||
self.sp_track.delete_instance()
|
||||
|
||||
result = initialize_card_evolution(player.player_id, team.id, "sp")
|
||||
result = initialize_card_refractor(player.player_id, team.id, "sp")
|
||||
assert result is None
|
||||
|
||||
def test_card_type_from_pos1_batter(self, rarity, team):
|
||||
@ -302,7 +302,7 @@ class TestInitializeCardEvolution:
|
||||
"""
|
||||
player = _make_player(rarity, "3B")
|
||||
card_type = _determine_card_type(player)
|
||||
state = initialize_card_evolution(player.player_id, team.id, card_type)
|
||||
state = initialize_card_refractor(player.player_id, team.id, card_type)
|
||||
|
||||
assert state is not None
|
||||
assert state.track_id == self.batter_track.id
|
||||
@ -311,7 +311,7 @@ class TestInitializeCardEvolution:
|
||||
"""_determine_card_type is wired correctly for a starting pitcher."""
|
||||
player = _make_player(rarity, "SP")
|
||||
card_type = _determine_card_type(player)
|
||||
state = initialize_card_evolution(player.player_id, team.id, card_type)
|
||||
state = initialize_card_refractor(player.player_id, team.id, card_type)
|
||||
|
||||
assert state is not None
|
||||
assert state.track_id == self.sp_track.id
|
||||
@ -320,7 +320,7 @@ class TestInitializeCardEvolution:
|
||||
"""_determine_card_type correctly routes CP to the rp track."""
|
||||
player = _make_player(rarity, "CP")
|
||||
card_type = _determine_card_type(player)
|
||||
state = initialize_card_evolution(player.player_id, team.id, card_type)
|
||||
state = initialize_card_refractor(player.player_id, team.id, card_type)
|
||||
|
||||
assert state is not None
|
||||
assert state.track_id == self.rp_track.id
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
"""Integration tests for the refractor card state API endpoints (WP-07).
|
||||
|
||||
Tests cover:
|
||||
GET /api/v2/teams/{team_id}/evolutions
|
||||
GET /api/v2/teams/{team_id}/refractors
|
||||
GET /api/v2/refractor/cards/{card_id}
|
||||
|
||||
All tests require a live PostgreSQL connection (POSTGRES_HOST env var) and
|
||||
@ -24,7 +24,7 @@ Object graph built by fixtures
|
||||
|
||||
Test matrix
|
||||
-----------
|
||||
test_list_team_evolutions -- baseline: returns count + items for a team
|
||||
test_list_team_refractors -- baseline: returns count + items for a team
|
||||
test_list_filter_by_card_type -- card_type query param filters by track.card_type
|
||||
test_list_filter_by_tier -- tier query param filters by current_tier
|
||||
test_list_pagination -- page/per_page params slice results correctly
|
||||
@ -288,19 +288,19 @@ def client():
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Tests: GET /api/v2/teams/{team_id}/evolutions
|
||||
# Tests: GET /api/v2/teams/{team_id}/refractors
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
@_skip_no_pg
|
||||
def test_list_team_evolutions(client, seeded_data):
|
||||
"""GET /teams/{id}/evolutions returns count=1 and one item for the seeded state.
|
||||
def test_list_team_refractors(client, seeded_data):
|
||||
"""GET /teams/{id}/refractors returns count=1 and one item for the seeded state.
|
||||
|
||||
Verifies the basic list response shape: a dict with 'count' and 'items',
|
||||
and that the single item contains player_id, team_id, and current_tier.
|
||||
"""
|
||||
team_id = seeded_data["team_id"]
|
||||
resp = client.get(f"/api/v2/teams/{team_id}/evolutions", headers=AUTH_HEADER)
|
||||
resp = client.get(f"/api/v2/teams/{team_id}/refractors", headers=AUTH_HEADER)
|
||||
assert resp.status_code == 200
|
||||
data = resp.json()
|
||||
assert data["count"] == 1
|
||||
@ -337,7 +337,7 @@ def test_list_filter_by_card_type(client, seeded_data, pg_conn):
|
||||
team_id = seeded_data["team_id"]
|
||||
|
||||
resp_batter = client.get(
|
||||
f"/api/v2/teams/{team_id}/evolutions?card_type=batter", headers=AUTH_HEADER
|
||||
f"/api/v2/teams/{team_id}/refractors?card_type=batter", headers=AUTH_HEADER
|
||||
)
|
||||
assert resp_batter.status_code == 200
|
||||
batter_data = resp_batter.json()
|
||||
@ -345,7 +345,7 @@ def test_list_filter_by_card_type(client, seeded_data, pg_conn):
|
||||
assert batter_data["items"][0]["player_id"] == seeded_data["player_id"]
|
||||
|
||||
resp_sp = client.get(
|
||||
f"/api/v2/teams/{team_id}/evolutions?card_type=sp", headers=AUTH_HEADER
|
||||
f"/api/v2/teams/{team_id}/refractors?card_type=sp", headers=AUTH_HEADER
|
||||
)
|
||||
assert resp_sp.status_code == 200
|
||||
sp_data = resp_sp.json()
|
||||
@ -377,13 +377,13 @@ def test_list_filter_by_tier(client, seeded_data, pg_conn):
|
||||
team_id = seeded_data["team_id"]
|
||||
|
||||
resp_t1 = client.get(
|
||||
f"/api/v2/teams/{team_id}/evolutions?tier=1", headers=AUTH_HEADER
|
||||
f"/api/v2/teams/{team_id}/refractors?tier=1", headers=AUTH_HEADER
|
||||
)
|
||||
assert resp_t1.status_code == 200
|
||||
assert resp_t1.json()["count"] == 0
|
||||
|
||||
resp_t2 = client.get(
|
||||
f"/api/v2/teams/{team_id}/evolutions?tier=2", headers=AUTH_HEADER
|
||||
f"/api/v2/teams/{team_id}/refractors?tier=2", headers=AUTH_HEADER
|
||||
)
|
||||
assert resp_t2.status_code == 200
|
||||
t2_data = resp_t2.json()
|
||||
@ -426,14 +426,14 @@ def test_list_pagination(client, seeded_data, pg_conn):
|
||||
team_id = seeded_data["team_id"]
|
||||
|
||||
resp1 = client.get(
|
||||
f"/api/v2/teams/{team_id}/evolutions?page=1&per_page=1", headers=AUTH_HEADER
|
||||
f"/api/v2/teams/{team_id}/refractors?page=1&per_page=1", headers=AUTH_HEADER
|
||||
)
|
||||
assert resp1.status_code == 200
|
||||
data1 = resp1.json()
|
||||
assert len(data1["items"]) == 1
|
||||
|
||||
resp2 = client.get(
|
||||
f"/api/v2/teams/{team_id}/evolutions?page=2&per_page=1", headers=AUTH_HEADER
|
||||
f"/api/v2/teams/{team_id}/refractors?page=2&per_page=1", headers=AUTH_HEADER
|
||||
)
|
||||
assert resp2.status_code == 200
|
||||
data2 = resp2.json()
|
||||
@ -596,13 +596,13 @@ def test_auth_required(client, seeded_data):
|
||||
"""Both endpoints return 401 when no Bearer token is provided.
|
||||
|
||||
Verifies that the valid_token dependency is enforced on:
|
||||
GET /api/v2/teams/{id}/evolutions
|
||||
GET /api/v2/teams/{id}/refractors
|
||||
GET /api/v2/refractor/cards/{id}
|
||||
"""
|
||||
team_id = seeded_data["team_id"]
|
||||
card_id = seeded_data["card_id"]
|
||||
|
||||
resp_list = client.get(f"/api/v2/teams/{team_id}/evolutions")
|
||||
resp_list = client.get(f"/api/v2/teams/{team_id}/refractors")
|
||||
assert resp_list.status_code == 401
|
||||
|
||||
resp_card = client.get(f"/api/v2/refractor/cards/{card_id}")
|
||||
|
||||
Loading…
Reference in New Issue
Block a user