paper-dynasty-discord/tests/test_player_refractor_view.py
Cal Corum 78f313663e
All checks were successful
Ruff Lint / lint (pull_request) Successful in 11s
fix: review feedback — variant 0 guard, remove dead team param
- Use `variant is None` instead of `not variant` to avoid skipping
  variant 0 tier-ups (0 is falsy in Python)
- Remove unused `team` parameter from _build_refractor_response
- Update tests to match

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 17:33:36 -05:00

142 lines
4.9 KiB
Python

"""Tests for /player refractor_tier view.
Tests cover _build_refractor_response, a module-level helper that processes
raw API refractor data and returns structured response data for the slash command.
The function is pure (no network calls) so tests run without mocks for the
happy path cases, keeping tests readable and fast.
"""
import sys
import os
import pytest
# Make the repo root importable
sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))
from cogs.players import _build_refractor_response
REFRACTOR_CARDS_RESPONSE = {
"count": 3,
"items": [
{
"player_id": 100,
"player_name": "Mike Trout",
"current_tier": 3,
"current_value": 160,
"variant": 7,
"track": {"card_type": "batter"},
"image_url": "https://s3.example.com/cards/cardset-027/player-100/v7/battingcard.png",
},
{
"player_id": 200,
"player_name": "Barry Bonds",
"current_tier": 2,
"current_value": 110,
"variant": 3,
"track": {"card_type": "batter"},
"image_url": "https://s3.example.com/cards/cardset-027/player-200/v3/battingcard.png",
},
{
"player_id": 300,
"player_name": "Ken Griffey Jr.",
"current_tier": 1,
"current_value": 55,
"variant": 1,
"track": {"card_type": "batter"},
"image_url": None,
},
],
}
class TestBuildRefractorResponse:
"""Build embed content for /player refractor_tier views."""
@pytest.mark.asyncio
async def test_happy_path_returns_embed_with_image(self):
"""When user has the refractor at requested tier, embed includes S3 image.
Verifies that when a player_id match is found at or above the requested
tier, the result is marked as found and the image_url is passed through.
"""
result = await _build_refractor_response(
player_name="Mike Trout",
player_id=100,
refractor_tier=3,
refractor_data=REFRACTOR_CARDS_RESPONSE,
)
assert result["found"] is True
assert "s3.example.com" in result["image_url"]
@pytest.mark.asyncio
async def test_not_found_returns_top_5(self):
"""When user doesn't have the refractor, show top 5 cards.
Verifies that when no match is found for the given player_id + tier,
the response includes the top cards sorted by tier descending, and
the highest-tier card appears first.
"""
result = await _build_refractor_response(
player_name="Nobody",
player_id=999,
refractor_tier=2,
refractor_data=REFRACTOR_CARDS_RESPONSE,
)
assert result["found"] is False
assert len(result["top_cards"]) <= 5
assert result["top_cards"][0]["player_name"] == "Mike Trout"
@pytest.mark.asyncio
async def test_image_url_none_triggers_render(self):
"""When refractor exists but image_url is None, result signals render needed.
A card may exist at the requested tier without a cached S3 image URL
if it has never been rendered. The response should set needs_render=True
so the caller can construct a render endpoint URL and show a placeholder.
"""
result = await _build_refractor_response(
player_name="Ken Griffey Jr.",
player_id=300,
refractor_tier=1,
refractor_data=REFRACTOR_CARDS_RESPONSE,
)
assert result["found"] is True
assert result["image_url"] is None
assert result["needs_render"] is True
assert result["variant"] == 1
@pytest.mark.asyncio
async def test_no_refractors_at_all(self):
"""When user has zero refractor cards, clean message.
An empty items list should produce found=False with an empty top_cards
list, allowing the caller to show a "no refractors yet" message.
"""
empty_data = {"count": 0, "items": []}
result = await _build_refractor_response(
player_name="Someone",
player_id=500,
refractor_tier=1,
refractor_data=empty_data,
)
assert result["found"] is False
assert result["top_cards"] == []
@pytest.mark.asyncio
async def test_tier_higher_than_current_not_found(self):
"""Requesting T4 when player is at T3 returns not found.
The match condition requires current_tier >= refractor_tier. Requesting
a tier the player hasn't reached should return found=False so the
caller can show what tier they do have.
"""
result = await _build_refractor_response(
player_name="Mike Trout",
player_id=100,
refractor_tier=4,
refractor_data=REFRACTOR_CARDS_RESPONSE,
)
assert result["found"] is False