diff --git a/cogs/refractor.py b/cogs/refractor.py index 1bb413f..49674e6 100644 --- a/cogs/refractor.py +++ b/cogs/refractor.py @@ -4,7 +4,10 @@ Refractor cog — /refractor status slash command. Displays a team's refractor progress: formula value vs next threshold with a progress bar, paginated 10 cards per page. -Depends on WP-07 (evolution/cards API endpoint). +Tier names: Base Card (T0) / Base Chrome (T1) / Refractor (T2) / +Gold Refractor (T3) / Superfractor (T4). + +Depends on WP-07 (refractor/cards API endpoint). """ import logging @@ -35,6 +38,8 @@ FORMULA_LABELS = { "rp": "IP+K", } +TIER_BADGES = {1: "[BC]", 2: "[R]", 3: "[GR]", 4: "[SF]"} + def render_progress_bar(current: int, threshold: int, width: int = 10) -> str: """ @@ -61,8 +66,11 @@ def format_refractor_entry(card_state: dict) -> str: Expected keys: player_name, card_type, current_tier, formula_value, next_threshold (None if fully evolved). + A tier badge prefix (e.g. [BC], [R], [GR], [SF]) is prepended to the + player name for tiers 1-4. T0 cards have no badge. + Output example: - **Mike Trout** (Refractor) + **[BC] Mike Trout** (Base Chrome) [========--] 120/149 (PA+TB×2) — T1 → T2 """ player_name = card_state.get("player_name", "Unknown") @@ -74,6 +82,9 @@ def format_refractor_entry(card_state: dict) -> str: tier_label = TIER_NAMES.get(current_tier, f"T{current_tier}") formula_label = FORMULA_LABELS.get(card_type, card_type) + badge = TIER_BADGES.get(current_tier, "") + display_name = f"{badge} {player_name}" if badge else player_name + if current_tier >= 4 or next_threshold is None: bar = "[==========]" detail = "FULLY EVOLVED ★" @@ -81,7 +92,7 @@ def format_refractor_entry(card_state: dict) -> str: bar = render_progress_bar(formula_value, next_threshold) detail = f"{formula_value}/{next_threshold} ({formula_label}) — T{current_tier} → T{current_tier + 1}" - first_line = f"**{player_name}** ({tier_label})" + first_line = f"**{display_name}** ({tier_label})" second_line = f"{bar} {detail}" return f"{first_line}\n{second_line}" @@ -163,7 +174,7 @@ class Refractor(commands.Cog): if tier is not None: params.append(("tier", tier)) - data = await db_get("evolution/cards", params=params) + data = await db_get("refractor/cards", params=params) if not data: await interaction.edit_original_response( content="No refractor data found for your team." diff --git a/tests/test_refractor_commands.py b/tests/test_refractor_commands.py index f2253dd..12cb035 100644 --- a/tests/test_refractor_commands.py +++ b/tests/test_refractor_commands.py @@ -29,6 +29,7 @@ from cogs.refractor import ( apply_close_filter, paginate, TIER_NAMES, + TIER_BADGES, PAGE_SIZE, ) @@ -131,9 +132,10 @@ class TestFormatRefractorEntry: """ def test_player_name_in_output(self, batter_state): - """Player name is bold in the first line.""" + """Player name appears bold in the first line (badge may prefix it).""" result = format_refractor_entry(batter_state) - assert "**Mike Trout**" in result + assert "Mike Trout" in result + assert "**" in result def test_tier_label_in_output(self, batter_state): """Current tier name (Base Chrome for T1) appears in output.""" @@ -184,6 +186,77 @@ class TestFormatRefractorEntry: assert len(lines) == 2 + + +# --------------------------------------------------------------------------- +# TIER_BADGES +# --------------------------------------------------------------------------- + + +class TestTierBadges: + """ + Verify TIER_BADGES values and that format_refractor_entry prepends badges + correctly for T1-T4. T0 cards should have no badge prefix. + """ + + def test_t1_badge_value(self): + """T1 badge is [BC] (Base Chrome).""" + assert TIER_BADGES[1] == "[BC]" + + def test_t2_badge_value(self): + """T2 badge is [R] (Refractor).""" + assert TIER_BADGES[2] == "[R]" + + def test_t3_badge_value(self): + """T3 badge is [GR] (Gold Refractor).""" + assert TIER_BADGES[3] == "[GR]" + + def test_t4_badge_value(self): + """T4 badge is [SF] (Superfractor).""" + assert TIER_BADGES[4] == "[SF]" + + def test_t0_no_badge(self): + """T0 has no badge entry in TIER_BADGES.""" + assert 0 not in TIER_BADGES + + def test_format_entry_t1_badge_present(self, batter_state): + """format_refractor_entry prepends [BC] badge for T1 cards.""" + result = format_refractor_entry(batter_state) + assert "[BC]" in result + + def test_format_entry_t2_badge_present(self, sp_state): + """format_refractor_entry prepends [R] badge for T2 cards.""" + result = format_refractor_entry(sp_state) + assert "[R]" in result + + def test_format_entry_t4_badge_present(self, evolved_state): + """format_refractor_entry prepends [SF] badge for T4 cards.""" + result = format_refractor_entry(evolved_state) + assert "[SF]" in result + + def test_format_entry_t0_no_badge(self): + """format_refractor_entry does not prepend any badge for T0 cards.""" + state = { + "player_name": "Rookie Player", + "card_type": "batter", + "current_tier": 0, + "formula_value": 10, + "next_threshold": 50, + } + result = format_refractor_entry(state) + assert "[BC]" not in result + assert "[R]" not in result + assert "[GR]" not in result + assert "[SF]" not in result + + def test_format_entry_badge_before_name(self, batter_state): + """Badge appears before the player name in the bold section.""" + result = format_refractor_entry(batter_state) + first_line = result.split("\n")[0] + badge_pos = first_line.find("[BC]") + name_pos = first_line.find("Mike Trout") + assert badge_pos < name_pos + # --------------------------------------------------------------------------- # apply_close_filter # ---------------------------------------------------------------------------