paper-dynasty-discord/tests/players_refactor/conftest.py
Cal Corum ee80cd72ae fix: apply Black formatting and resolve ruff lint violations
Run Black formatter across 83 files and fix 1514 ruff violations:
- E722: bare except → typed exceptions (17 fixes)
- E711/E712/E721: comparison style fixes with noqa for SQLAlchemy (44 fixes)
- F841: unused variable assignments (70 fixes)
- F541/F401: f-string and import cleanup (1383 auto-fixes)

Remaining 925 errors are all F403/F405 (star imports) — structural,
requires converting to explicit imports in a separate effort.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 11:37:46 -05:00

288 lines
7.6 KiB
Python

# Shared fixtures and mocks for players refactor tests
import pytest
import asyncio
from unittest.mock import AsyncMock, Mock
import discord
from discord.ext import commands
@pytest.fixture
def mock_bot():
"""Mock Discord bot for testing."""
bot = AsyncMock(spec=commands.Bot)
bot.get_cog = Mock(return_value=None)
bot.add_cog = AsyncMock()
bot.wait_until_ready = AsyncMock()
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.followup = AsyncMock()
interaction.followup.send = AsyncMock()
interaction.edit_original_response = AsyncMock()
# Mock user
interaction.user = Mock(spec=discord.Member)
interaction.user.id = 12345
interaction.user.mention = "<@12345>"
# Mock channel
interaction.channel = Mock(spec=discord.TextChannel)
interaction.channel.name = "test-channel"
interaction.channel.send = AsyncMock()
return interaction
@pytest.fixture
def mock_context():
"""Mock Discord context for traditional commands."""
ctx = AsyncMock(spec=commands.Context)
ctx.send = AsyncMock()
ctx.author = Mock(spec=discord.Member)
ctx.author.id = 12345
ctx.author.mention = "<@12345>"
ctx.author.roles = []
ctx.author.guild_permissions = Mock()
ctx.author.guild_permissions.administrator = False
# Mock channel
ctx.channel = Mock(spec=discord.TextChannel)
ctx.channel.name = "test-channel"
ctx.channel.send = AsyncMock()
# Mock guild
ctx.guild = Mock(spec=discord.Guild)
ctx.guild.roles = []
return ctx
@pytest.fixture
def sample_player():
"""Sample player data for testing."""
return {
"id": 1,
"player_id": 12345,
"name": "Test Player",
"franchise": "BOS",
"cardset": "MLB 2024",
"positions": "SS, 2B",
"rarity": {"name": "All-Star", "value": 3, "color": "1f8b4c"},
"cost": 150,
"image": "https://example.com/player.jpg",
"headshot": "https://example.com/headshot.jpg",
"batting_card": {
"contact_r": 85,
"contact_l": 80,
"power_r": 70,
"power_l": 65,
"vision": 75,
"speed": 60,
"stealing": 55,
},
"pitching_card": None,
}
@pytest.fixture
def sample_team():
"""Sample team data for testing."""
return {
"id": 1,
"abbrev": "TST",
"sname": "Test",
"lname": "Test Team",
"gm_id": 12345,
"gmname": "Test GM",
"gsheet": "None",
"season": 4,
"wallet": 1000,
"color": "a6ce39",
"logo": "https://example.com/logo.png",
"ranking": 85,
}
@pytest.fixture
def sample_cardset():
"""Sample cardset data for testing."""
return {
"id": 1,
"name": "MLB 2024",
"description": "Major League Baseball 2024 season cards",
"active": True,
}
@pytest.fixture
def sample_paperdex():
"""Sample paperdex data for testing."""
return {
"id": 1,
"team_id": 1,
"cardset": "MLB 2024",
"total_cards": 100,
"unique_cards": 45,
"rarity_counts": {
"replacement": 20,
"reserve": 15,
"starter": 8,
"all-star": 2,
},
"team_counts": {"BOS": 5, "NYY": 4, "TB": 3},
}
@pytest.fixture
def sample_game_data():
"""Sample game data for records/standings."""
return [
{
"home_score": 7,
"away_score": 4,
"home_team": {"abbrev": "BOS", "is_ai": True},
"away_team": {"abbrev": "TST", "is_ai": False},
"game_type": "minor-league",
"created_at": "2024-01-01T12:00:00Z",
},
{
"home_score": 3,
"away_score": 8,
"home_team": {"abbrev": "TST", "is_ai": False},
"away_team": {"abbrev": "NYY", "is_ai": True},
"game_type": "minor-league",
"created_at": "2024-01-02T15:00:00Z",
},
]
# Mock API calls
@pytest.fixture
def mock_db_get(monkeypatch):
"""Mock db_get function for API calls."""
async def mock_get(
endpoint, params=None, timeout=None, none_okay=False, object_id=None
):
if "players" in endpoint:
return {"count": 1, "players": [sample_player()]}
elif "teams" in endpoint:
return {"count": 1, "teams": [sample_team()]}
elif "cardsets" in endpoint:
return {"count": 1, "cardsets": [sample_cardset()]}
elif "paperdex" in endpoint:
return {"count": 1, "paperdex": [sample_paperdex()]}
else:
return {"count": 0}
mock_fn = AsyncMock(side_effect=mock_get)
monkeypatch.setattr("api_calls.db_get", mock_fn)
return mock_fn
@pytest.fixture
def mock_db_post(monkeypatch):
"""Mock db_post function for API calls."""
async def mock_post(endpoint, payload=None, timeout=None):
return (
{"id": 1, "status": "success", **payload}
if payload
else {"id": 1, "status": "success"}
)
mock_fn = AsyncMock(side_effect=mock_post)
monkeypatch.setattr("api_calls.db_post", mock_fn)
return mock_fn
@pytest.fixture
def mock_db_patch(monkeypatch):
"""Mock db_patch function for API calls."""
async def mock_patch(endpoint, object_id=None, params=None):
return {"id": object_id, "status": "updated"}
mock_fn = AsyncMock(side_effect=mock_patch)
monkeypatch.setattr("api_calls.db_patch", mock_fn)
return mock_fn
@pytest.fixture
def mock_db_delete(monkeypatch):
"""Mock db_delete function for API calls."""
async def mock_delete(endpoint, object_id=None):
return {"id": object_id, "status": "deleted"}
mock_fn = AsyncMock(side_effect=mock_delete)
monkeypatch.setattr("api_calls.db_delete", mock_fn)
return mock_fn
@pytest.fixture
def mock_helper_functions(monkeypatch):
"""Mock helper functions commonly used across modules."""
# Mock helper functions
monkeypatch.setattr("helpers.legal_channel", lambda ctx: True)
monkeypatch.setattr(
"helpers.get_team_by_owner", AsyncMock(return_value=sample_team())
)
monkeypatch.setattr(
"helpers.get_card_embeds", lambda player: [Mock(spec=discord.Embed)]
)
monkeypatch.setattr("helpers.embed_pagination", AsyncMock())
monkeypatch.setattr(
"helpers.get_team_embed", lambda title, team: Mock(spec=discord.Embed)
)
monkeypatch.setattr("search_utils.cardset_search", lambda query: ["MLB 2024"])
monkeypatch.setattr(
"search_utils.fuzzy_player_search", lambda query: ["Test Player"]
)
@pytest.fixture
def mock_role():
"""Mock Discord role for permission testing."""
role = Mock(spec=discord.Role)
role.name = "Paper Dynasty Players"
return role
@pytest.fixture
def mock_permissions():
"""Mock permission checks."""
def has_role_mock(*role_names):
async def decorator(func):
return func
return decorator
return has_role_mock
# Event loop fixture for async tests
@pytest.fixture(scope="session")
def event_loop():
"""Create an instance of the default event loop for the test session."""
loop = asyncio.get_event_loop_policy().new_event_loop()
yield loop
loop.close()
@pytest.fixture(autouse=True)
def setup_logging():
"""Setup logging for tests to avoid noise."""
import logging
logging.getLogger("discord_app").setLevel(logging.CRITICAL)