171 lines
4.7 KiB
Python
171 lines
4.7 KiB
Python
"""Shared fixtures for scouting feature tests."""
|
|
|
|
import pytest
|
|
import asyncio
|
|
from unittest.mock import AsyncMock, MagicMock, Mock
|
|
|
|
import discord
|
|
from discord.ext import commands
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Sample data factories
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
def _make_player(
|
|
player_id,
|
|
name,
|
|
rarity_name,
|
|
rarity_value,
|
|
headshot=None,
|
|
description="2023",
|
|
image=None,
|
|
):
|
|
"""Build a minimal player dict matching the API shape used by scouting."""
|
|
return {
|
|
"player_id": player_id,
|
|
"p_name": name,
|
|
"rarity": {"name": rarity_name, "value": rarity_value, "color": "ffffff"},
|
|
"headshot": headshot or "https://example.com/headshot.jpg",
|
|
"description": description,
|
|
"image": image or f"https://example.com/cards/{player_id}/battingcard.png",
|
|
}
|
|
|
|
|
|
def _make_card(card_id, player, pack_id=100):
|
|
"""Wrap a player dict inside a card dict (as returned by the cards API)."""
|
|
return {"id": card_id, "player": player, "pack": {"id": pack_id}}
|
|
|
|
|
|
@pytest.fixture
|
|
def sample_players():
|
|
"""Five players spanning different rarities for a realistic pack."""
|
|
return [
|
|
_make_player(101, "Mike Trout", "MVP", 5),
|
|
_make_player(102, "Juan Soto", "All-Star", 3),
|
|
_make_player(103, "Marcus Semien", "Starter", 2),
|
|
_make_player(104, "Willy Adames", "Reserve", 1),
|
|
_make_player(105, "Generic Bench", "Replacement", 0),
|
|
]
|
|
|
|
|
|
@pytest.fixture
|
|
def sample_cards(sample_players):
|
|
"""Five card dicts wrapping the sample players."""
|
|
return [_make_card(i + 1, p) for i, p in enumerate(sample_players)]
|
|
|
|
|
|
@pytest.fixture
|
|
def opener_team():
|
|
"""Team dict for the pack opener."""
|
|
return {
|
|
"id": 10,
|
|
"abbrev": "OPN",
|
|
"sname": "Openers",
|
|
"lname": "Opening Squad",
|
|
"gm_id": 99999,
|
|
"gmname": "Opener GM",
|
|
"color": "a6ce39",
|
|
"logo": "https://example.com/logo.png",
|
|
"season": 4,
|
|
}
|
|
|
|
|
|
@pytest.fixture
|
|
def scouter_team():
|
|
"""Team dict for a player who scouts a card."""
|
|
return {
|
|
"id": 20,
|
|
"abbrev": "SCT",
|
|
"sname": "Scouts",
|
|
"lname": "Scouting Squad",
|
|
"gm_id": 88888,
|
|
"gmname": "Scout GM",
|
|
"color": "3498db",
|
|
"logo": "https://example.com/scout_logo.png",
|
|
"season": 4,
|
|
}
|
|
|
|
|
|
@pytest.fixture
|
|
def scouter_team_2():
|
|
"""Second scouter team for multi-scout tests."""
|
|
return {
|
|
"id": 30,
|
|
"abbrev": "SC2",
|
|
"sname": "Scouts2",
|
|
"lname": "Second Scouts",
|
|
"gm_id": 77777,
|
|
"gmname": "Scout GM 2",
|
|
"color": "e74c3c",
|
|
"logo": "https://example.com/scout2_logo.png",
|
|
"season": 4,
|
|
}
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Discord mocks
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
@pytest.fixture
|
|
def mock_bot():
|
|
"""Mock Discord bot."""
|
|
bot = AsyncMock(spec=commands.Bot)
|
|
bot.get_cog = Mock(return_value=None)
|
|
bot.add_cog = AsyncMock()
|
|
bot.wait_until_ready = AsyncMock()
|
|
|
|
# Mock guild / channel lookup for send_to_channel
|
|
channel_mock = AsyncMock(spec=discord.TextChannel)
|
|
channel_mock.send = AsyncMock()
|
|
guild_mock = Mock(spec=discord.Guild)
|
|
guild_mock.text_channels = [channel_mock]
|
|
channel_mock.name = "pd-network-news"
|
|
bot.guilds = [guild_mock]
|
|
return bot
|
|
|
|
|
|
@pytest.fixture
|
|
def mock_interaction():
|
|
"""Mock Discord interaction for slash commands."""
|
|
interaction = AsyncMock(spec=discord.Interaction)
|
|
interaction.response = AsyncMock()
|
|
interaction.response.defer = AsyncMock()
|
|
interaction.response.send_message = AsyncMock()
|
|
interaction.response.is_done = Mock(return_value=False)
|
|
interaction.followup = AsyncMock()
|
|
interaction.followup.send = AsyncMock()
|
|
|
|
interaction.user = Mock(spec=discord.Member)
|
|
interaction.user.id = 12345
|
|
interaction.user.mention = "<@12345>"
|
|
|
|
interaction.channel = Mock(spec=discord.TextChannel)
|
|
interaction.channel.name = "pack-openings"
|
|
interaction.channel.send = AsyncMock()
|
|
|
|
return interaction
|
|
|
|
|
|
@pytest.fixture
|
|
def mock_channel():
|
|
"""Mock #pack-openings channel."""
|
|
channel = AsyncMock(spec=discord.TextChannel)
|
|
channel.name = "pack-openings"
|
|
channel.send = AsyncMock()
|
|
return channel
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Logging suppression
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
@pytest.fixture(autouse=True)
|
|
def silence_logging():
|
|
"""Suppress log noise during tests."""
|
|
import logging
|
|
|
|
logging.getLogger("discord_app").setLevel(logging.CRITICAL)
|