fix: address reviewer issues — rename evolution endpoints, add TIER_BADGES
All checks were successful
Build Docker Image / build (pull_request) Successful in 1m32s

- Update module docstring: replace evolution/cards with refractor/cards,
  drop old tier names (Unranked/Initiate/Rising/Ascendant/Evolved), add
  correct tier names (Base Card/Base Chrome/Refractor/Gold Refractor/
  Superfractor)
- Fix API call: db_get("evolution/cards") → db_get("refractor/cards")
- Add TIER_BADGES dict {1:"[BC]", 2:"[R]", 3:"[GR]", 4:"[SF]"}
- Update format_refractor_entry to prepend badge label for T1-T4 (T0 has
  no badge)
- Add TestTierBadges test class (11 tests) asserting badge values and
  presence in formatted output
- Update test_player_name_in_output to accommodate badge-prefixed bold name

Dead utilities/evolution_notifications.py has no source file on this branch
(WP-14/PR #112 already delivered the replacement).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Cal Corum 2026-03-23 15:08:39 -05:00
parent 5670cd6e88
commit 45d71c61e3
2 changed files with 90 additions and 6 deletions

View File

@ -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."

View File

@ -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
# ---------------------------------------------------------------------------