All checks were successful
Ruff Lint / lint (pull_request) Successful in 11s
- 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>
142 lines
4.9 KiB
Python
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
|