This commit includes various enhancements across the bot architecture: **New Infrastructure:** - Added tests/factories.py - Factory classes for creating test data objects - Added PRE_LAUNCH_ROADMAP.md - Project planning and roadmap documentation **Model Enhancements:** - Updated models/roster.py - Enhanced roster data structures - Updated models/team.py - Improved team model definitions **Service Layer Improvements:** - Enhanced services/player_service.py - Better player data handling - Updated services/roster_service.py - Roster management improvements - Enhanced services/team_service.py - Team data service refinements - Updated services/transaction_service.py - Transaction processing enhancements **Command Updates:** - Updated commands/teams/info.py - Team information command improvements - Enhanced commands/voice/tracker.py - Voice channel tracking refinements **Background Tasks:** - Updated tasks/custom_command_cleanup.py - Automated cleanup improvements **View Components:** - Enhanced views/transaction_embed.py - Transaction embed UI improvements **Test Coverage Enhancements:** - Updated tests/test_commands_voice.py - Voice command test improvements - Enhanced tests/test_dropadd_integration.py - Integration test coverage - Updated tests/test_services_player_service.py - Player service test coverage - Enhanced tests/test_services_transaction_builder.py - Transaction builder tests - Updated tests/test_transactions_integration.py - Transaction integration tests - Enhanced tests/test_views_transaction_embed.py - UI component test coverage These changes collectively improve the bot's reliability, maintainability, and test coverage while adding essential infrastructure for continued development. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
658 lines
24 KiB
Python
658 lines
24 KiB
Python
"""
|
||
Tests for TransactionBuilder service
|
||
|
||
Validates transaction building, roster validation, and move management.
|
||
"""
|
||
import pytest
|
||
from unittest.mock import AsyncMock, MagicMock, patch
|
||
from datetime import datetime
|
||
|
||
from services.transaction_builder import (
|
||
TransactionBuilder,
|
||
TransactionMove,
|
||
RosterType,
|
||
RosterValidationResult,
|
||
get_transaction_builder,
|
||
clear_transaction_builder
|
||
)
|
||
from models.team import Team
|
||
from models.player import Player
|
||
from models.roster import TeamRoster
|
||
from models.transaction import Transaction
|
||
from tests.factories import PlayerFactory, TeamFactory
|
||
|
||
|
||
class TestTransactionBuilder:
|
||
"""Test TransactionBuilder core functionality."""
|
||
|
||
@pytest.fixture
|
||
def mock_team(self):
|
||
"""Create a mock team for testing."""
|
||
return Team(
|
||
id=499,
|
||
abbrev='WV',
|
||
sname='Black Bears',
|
||
lname='West Virginia Black Bears',
|
||
season=12
|
||
)
|
||
|
||
@pytest.fixture
|
||
def mock_player(self):
|
||
"""Create a mock player for testing."""
|
||
return Player(
|
||
id=12472,
|
||
name='Test Player',
|
||
wara=2.5,
|
||
season=12,
|
||
pos_1='OF'
|
||
)
|
||
|
||
@pytest.fixture
|
||
def mock_roster(self):
|
||
"""Create a mock roster for testing."""
|
||
# Create roster players
|
||
ml_players = []
|
||
for i in range(24): # 24 ML players (under limit)
|
||
ml_players.append(Player(
|
||
id=1000 + i,
|
||
name=f'ML Player {i}',
|
||
wara=1.5,
|
||
season=12,
|
||
team_id=499,
|
||
team=None,
|
||
image=None,
|
||
image2=None,
|
||
vanity_card=None,
|
||
headshot=None,
|
||
pos_1='OF',
|
||
pitcher_injury=None,
|
||
injury_rating=None,
|
||
il_return=None,
|
||
demotion_week=None,
|
||
last_game=None,
|
||
last_game2=None,
|
||
strat_code=None,
|
||
bbref_id=None,
|
||
sbaplayer=None
|
||
))
|
||
|
||
mil_players = []
|
||
for i in range(6): # 6 MiL players (at limit)
|
||
mil_players.append(Player(
|
||
id=2000 + i,
|
||
name=f'MiL Player {i}',
|
||
wara=0.5,
|
||
season=12,
|
||
team_id=499,
|
||
team=None,
|
||
image=None,
|
||
image2=None,
|
||
vanity_card=None,
|
||
headshot=None,
|
||
pos_1='OF',
|
||
pitcher_injury=None,
|
||
injury_rating=None,
|
||
il_return=None,
|
||
demotion_week=None,
|
||
last_game=None,
|
||
last_game2=None,
|
||
strat_code=None,
|
||
bbref_id=None,
|
||
sbaplayer=None
|
||
))
|
||
|
||
return TeamRoster(
|
||
team_id=499,
|
||
team_abbrev='WV',
|
||
week=10,
|
||
season=12,
|
||
active_players=ml_players,
|
||
minor_league_players=mil_players
|
||
)
|
||
|
||
@pytest.fixture
|
||
def builder(self, mock_team):
|
||
"""Create a TransactionBuilder for testing."""
|
||
return TransactionBuilder(mock_team, user_id=123456789, season=12)
|
||
|
||
def test_builder_initialization(self, builder, mock_team):
|
||
"""Test transaction builder initialization."""
|
||
assert builder.team == mock_team
|
||
assert builder.user_id == 123456789
|
||
assert builder.season == 12
|
||
assert builder.is_empty is True
|
||
assert builder.move_count == 0
|
||
assert len(builder.moves) == 0
|
||
|
||
def test_add_move_success(self, builder, mock_player):
|
||
"""Test successfully adding a move."""
|
||
move = TransactionMove(
|
||
player=mock_player,
|
||
from_roster=RosterType.FREE_AGENCY,
|
||
to_roster=RosterType.MAJOR_LEAGUE,
|
||
to_team=builder.team
|
||
)
|
||
|
||
success, error_message = builder.add_move(move)
|
||
|
||
assert success is True
|
||
assert error_message == ""
|
||
assert builder.move_count == 1
|
||
assert builder.is_empty is False
|
||
assert move in builder.moves
|
||
|
||
def test_add_duplicate_move_fails(self, builder, mock_player):
|
||
"""Test that adding duplicate moves for same player fails."""
|
||
move1 = TransactionMove(
|
||
player=mock_player,
|
||
from_roster=RosterType.FREE_AGENCY,
|
||
to_roster=RosterType.MAJOR_LEAGUE,
|
||
to_team=builder.team
|
||
)
|
||
|
||
move2 = TransactionMove(
|
||
player=mock_player,
|
||
from_roster=RosterType.MAJOR_LEAGUE,
|
||
to_roster=RosterType.FREE_AGENCY,
|
||
from_team=builder.team
|
||
)
|
||
|
||
success1, error_message1 = builder.add_move(move1)
|
||
success2, error_message2 = builder.add_move(move2)
|
||
|
||
assert success1 is True
|
||
assert error_message1 == ""
|
||
assert success2 is False # Should fail due to duplicate player
|
||
assert "already has a move" in error_message2
|
||
assert builder.move_count == 1
|
||
|
||
def test_add_move_same_team_same_roster_fails(self, builder, mock_player):
|
||
"""Test that adding a move where from_team, to_team, from_roster, and to_roster are all the same fails."""
|
||
move = TransactionMove(
|
||
player=mock_player,
|
||
from_roster=RosterType.MAJOR_LEAGUE,
|
||
to_roster=RosterType.MAJOR_LEAGUE, # Same roster
|
||
from_team=builder.team,
|
||
to_team=builder.team # Same team - should fail when roster is also same
|
||
)
|
||
|
||
success, error_message = builder.add_move(move)
|
||
|
||
assert success is False
|
||
assert "already in that location" in error_message
|
||
assert builder.move_count == 0
|
||
assert builder.is_empty is True
|
||
|
||
def test_add_move_same_team_different_roster_succeeds(self, builder, mock_player):
|
||
"""Test that adding a move where teams are same but rosters are different succeeds."""
|
||
move = TransactionMove(
|
||
player=mock_player,
|
||
from_roster=RosterType.MAJOR_LEAGUE,
|
||
to_roster=RosterType.MINOR_LEAGUE, # Different roster
|
||
from_team=builder.team,
|
||
to_team=builder.team # Same team - should succeed when rosters differ
|
||
)
|
||
|
||
success, error_message = builder.add_move(move)
|
||
|
||
assert success is True
|
||
assert error_message == ""
|
||
assert builder.move_count == 1
|
||
assert builder.is_empty is False
|
||
|
||
def test_add_move_different_teams_succeeds(self, builder, mock_player):
|
||
"""Test that adding a move where from_team and to_team are different succeeds."""
|
||
other_team = Team(
|
||
id=500,
|
||
abbrev='NY',
|
||
sname='Mets',
|
||
lname='New York Mets',
|
||
season=12
|
||
)
|
||
|
||
move = TransactionMove(
|
||
player=mock_player,
|
||
from_roster=RosterType.MAJOR_LEAGUE,
|
||
to_roster=RosterType.MAJOR_LEAGUE,
|
||
from_team=other_team,
|
||
to_team=builder.team
|
||
)
|
||
|
||
success, error_message = builder.add_move(move)
|
||
|
||
assert success is True
|
||
assert error_message == ""
|
||
assert builder.move_count == 1
|
||
assert builder.is_empty is False
|
||
|
||
def test_add_move_none_teams_succeeds(self, builder, mock_player):
|
||
"""Test that adding a move where one or both teams are None succeeds."""
|
||
# From FA to team (from_team=None)
|
||
move1 = TransactionMove(
|
||
player=mock_player,
|
||
from_roster=RosterType.FREE_AGENCY,
|
||
to_roster=RosterType.MAJOR_LEAGUE,
|
||
from_team=None,
|
||
to_team=builder.team
|
||
)
|
||
|
||
success1, error_message1 = builder.add_move(move1)
|
||
assert success1 is True
|
||
assert error_message1 == ""
|
||
|
||
builder.clear_moves()
|
||
|
||
# Create different player for second test
|
||
other_player = Player(
|
||
id=12473,
|
||
name='Other Player',
|
||
wara=1.5,
|
||
season=12,
|
||
pos_1='OF'
|
||
)
|
||
|
||
# From team to FA (to_team=None)
|
||
move2 = TransactionMove(
|
||
player=other_player,
|
||
from_roster=RosterType.MAJOR_LEAGUE,
|
||
to_roster=RosterType.FREE_AGENCY,
|
||
from_team=builder.team,
|
||
to_team=None
|
||
)
|
||
|
||
success2, error_message2 = builder.add_move(move2)
|
||
assert success2 is True
|
||
assert error_message2 == ""
|
||
|
||
def test_remove_move_success(self, builder, mock_player):
|
||
"""Test successfully removing a move."""
|
||
move = TransactionMove(
|
||
player=mock_player,
|
||
from_roster=RosterType.FREE_AGENCY,
|
||
to_roster=RosterType.MAJOR_LEAGUE,
|
||
to_team=builder.team
|
||
)
|
||
|
||
success, _ = builder.add_move(move)
|
||
assert success
|
||
assert builder.move_count == 1
|
||
|
||
removed = builder.remove_move(mock_player.id)
|
||
|
||
assert removed is True
|
||
assert builder.move_count == 0
|
||
assert builder.is_empty is True
|
||
|
||
def test_remove_nonexistent_move(self, builder):
|
||
"""Test removing a move that doesn't exist."""
|
||
removed = builder.remove_move(99999)
|
||
|
||
assert removed is False
|
||
assert builder.move_count == 0
|
||
|
||
def test_get_move_for_player(self, builder, mock_player):
|
||
"""Test getting move for a specific player."""
|
||
move = TransactionMove(
|
||
player=mock_player,
|
||
from_roster=RosterType.FREE_AGENCY,
|
||
to_roster=RosterType.MAJOR_LEAGUE,
|
||
to_team=builder.team
|
||
)
|
||
|
||
builder.add_move(move)
|
||
|
||
found_move = builder.get_move_for_player(mock_player.id)
|
||
not_found = builder.get_move_for_player(99999)
|
||
|
||
assert found_move == move
|
||
assert not_found is None
|
||
|
||
def test_clear_moves(self, builder, mock_player):
|
||
"""Test clearing all moves."""
|
||
move = TransactionMove(
|
||
player=mock_player,
|
||
from_roster=RosterType.FREE_AGENCY,
|
||
to_roster=RosterType.MAJOR_LEAGUE,
|
||
to_team=builder.team
|
||
)
|
||
|
||
success, _ = builder.add_move(move)
|
||
assert success
|
||
assert builder.move_count == 1
|
||
|
||
builder.clear_moves()
|
||
|
||
assert builder.move_count == 0
|
||
assert builder.is_empty is True
|
||
|
||
@pytest.mark.asyncio
|
||
async def test_validate_transaction_no_roster(self, builder):
|
||
"""Test validation when roster data cannot be loaded."""
|
||
with patch.object(builder, '_current_roster', None):
|
||
with patch.object(builder, '_roster_loaded', True):
|
||
validation = await builder.validate_transaction()
|
||
|
||
assert validation.is_legal is False
|
||
assert len(validation.errors) == 1
|
||
assert "Could not load current roster data" in validation.errors[0]
|
||
|
||
@pytest.mark.asyncio
|
||
async def test_validate_transaction_legal(self, builder, mock_roster, mock_player):
|
||
"""Test validation of a legal transaction."""
|
||
with patch.object(builder, '_current_roster', mock_roster):
|
||
with patch.object(builder, '_roster_loaded', True):
|
||
# Add a move that keeps roster under limit (24 -> 25)
|
||
move = TransactionMove(
|
||
player=mock_player,
|
||
from_roster=RosterType.FREE_AGENCY,
|
||
to_roster=RosterType.MAJOR_LEAGUE,
|
||
to_team=builder.team
|
||
)
|
||
success, _ = builder.add_move(move)
|
||
assert success
|
||
|
||
validation = await builder.validate_transaction()
|
||
|
||
assert validation.is_legal is True
|
||
assert validation.major_league_count == 25 # 24 + 1
|
||
assert len(validation.errors) == 0
|
||
|
||
@pytest.mark.asyncio
|
||
async def test_validate_transaction_over_limit(self, builder, mock_roster):
|
||
"""Test validation when transaction would exceed roster limit."""
|
||
with patch.object(builder, '_current_roster', mock_roster):
|
||
with patch.object(builder, '_roster_loaded', True):
|
||
# Add 3 players to exceed limit (24 + 3 = 27 > 26)
|
||
for i in range(3):
|
||
player = Player(
|
||
id=3000 + i,
|
||
name=f'New Player {i}',
|
||
wara=1.0,
|
||
season=12,
|
||
pos_1='OF'
|
||
)
|
||
move = TransactionMove(
|
||
player=player,
|
||
from_roster=RosterType.FREE_AGENCY,
|
||
to_roster=RosterType.MAJOR_LEAGUE,
|
||
to_team=builder.team
|
||
)
|
||
success, _ = builder.add_move(move)
|
||
assert success
|
||
|
||
validation = await builder.validate_transaction()
|
||
|
||
assert validation.is_legal is False
|
||
assert validation.major_league_count == 27 # 24 + 3
|
||
assert len(validation.errors) == 1
|
||
assert "27 players (limit: 26)" in validation.errors[0]
|
||
assert len(validation.suggestions) == 1
|
||
assert "Drop 1 ML player" in validation.suggestions[0]
|
||
|
||
@pytest.mark.asyncio
|
||
async def test_validate_transaction_empty(self, builder, mock_roster):
|
||
"""Test validation of empty transaction."""
|
||
with patch.object(builder, '_current_roster', mock_roster):
|
||
with patch.object(builder, '_roster_loaded', True):
|
||
validation = await builder.validate_transaction()
|
||
|
||
assert validation.is_legal is True # Empty transaction is legal
|
||
assert validation.major_league_count == 24 # No changes
|
||
assert len(validation.suggestions) == 1
|
||
assert "Add player moves" in validation.suggestions[0]
|
||
|
||
@pytest.mark.asyncio
|
||
async def test_submit_transaction_empty(self, builder):
|
||
"""Test submitting empty transaction fails."""
|
||
with pytest.raises(ValueError, match="Cannot submit empty transaction"):
|
||
await builder.submit_transaction(week=11)
|
||
|
||
@pytest.mark.asyncio
|
||
async def test_submit_transaction_illegal(self, builder, mock_roster):
|
||
"""Test submitting illegal transaction fails."""
|
||
with patch.object(builder, '_current_roster', mock_roster):
|
||
with patch.object(builder, '_roster_loaded', True):
|
||
# Add moves that exceed limit
|
||
for i in range(3): # 24 + 3 = 27 > 25
|
||
player = Player(
|
||
id=4000 + i,
|
||
name=f'Illegal Player {i}',
|
||
wara=1.5,
|
||
season=12,
|
||
pos_1='OF'
|
||
)
|
||
move = TransactionMove(
|
||
player=player,
|
||
from_roster=RosterType.FREE_AGENCY,
|
||
to_roster=RosterType.MAJOR_LEAGUE,
|
||
to_team=builder.team
|
||
)
|
||
success, _ = builder.add_move(move)
|
||
assert success
|
||
|
||
with pytest.raises(ValueError, match="Cannot submit illegal transaction"):
|
||
await builder.submit_transaction(week=11)
|
||
|
||
@pytest.mark.asyncio
|
||
async def test_submit_transaction_success(self, builder, mock_roster, mock_player):
|
||
"""Test successful transaction submission."""
|
||
with patch.object(builder, '_current_roster', mock_roster):
|
||
with patch.object(builder, '_roster_loaded', True):
|
||
# Add a legal move
|
||
move = TransactionMove(
|
||
player=mock_player,
|
||
from_roster=RosterType.FREE_AGENCY,
|
||
to_roster=RosterType.MAJOR_LEAGUE,
|
||
to_team=builder.team
|
||
)
|
||
success, _ = builder.add_move(move)
|
||
assert success
|
||
|
||
transactions = await builder.submit_transaction(week=11)
|
||
|
||
assert len(transactions) == 1
|
||
transaction = transactions[0]
|
||
assert isinstance(transaction, Transaction)
|
||
assert transaction.week == 11
|
||
assert transaction.season == 12
|
||
assert transaction.player == mock_player
|
||
assert transaction.newteam == builder.team
|
||
assert "Season-012-Week-11-" in transaction.moveid
|
||
|
||
@pytest.mark.asyncio
|
||
async def test_submit_complex_transaction(self, builder, mock_roster):
|
||
"""Test submitting transaction with multiple moves."""
|
||
with patch.object(builder, '_current_roster', mock_roster):
|
||
with patch.object(builder, '_roster_loaded', True):
|
||
# Add one player and drop one player (net zero)
|
||
add_player = Player(id=5001, name='Add Player', wara=2.0, season=12, pos_1='OF')
|
||
drop_player = Player(id=5002, name='Drop Player', wara=1.0, season=12, pos_1='OF')
|
||
|
||
add_move = TransactionMove(
|
||
player=add_player,
|
||
from_roster=RosterType.FREE_AGENCY,
|
||
to_roster=RosterType.MAJOR_LEAGUE,
|
||
to_team=builder.team
|
||
)
|
||
|
||
drop_move = TransactionMove(
|
||
player=drop_player,
|
||
from_roster=RosterType.MAJOR_LEAGUE,
|
||
to_roster=RosterType.FREE_AGENCY,
|
||
from_team=builder.team
|
||
)
|
||
|
||
success1, _ = builder.add_move(add_move)
|
||
success2, _ = builder.add_move(drop_move)
|
||
assert success1 and success2
|
||
|
||
transactions = await builder.submit_transaction(week=11)
|
||
|
||
assert len(transactions) == 2
|
||
# Both transactions should have the same move_id
|
||
assert transactions[0].moveid == transactions[1].moveid
|
||
|
||
|
||
class TestTransactionMove:
|
||
"""Test TransactionMove dataclass functionality."""
|
||
|
||
@pytest.fixture
|
||
def mock_player(self):
|
||
"""Create a mock player."""
|
||
return Player(id=123, name='Test Player', wara=2.0, season=12, pos_1='OF')
|
||
|
||
@pytest.fixture
|
||
def mock_team(self):
|
||
"""Create a mock team."""
|
||
return Team(id=499, abbrev='WV', sname='Black Bears', lname='West Virginia Black Bears', season=12)
|
||
|
||
def test_add_move_description(self, mock_player, mock_team):
|
||
"""Test ADD move description."""
|
||
move = TransactionMove(
|
||
player=mock_player,
|
||
from_roster=RosterType.FREE_AGENCY,
|
||
to_roster=RosterType.MAJOR_LEAGUE,
|
||
to_team=mock_team
|
||
)
|
||
|
||
expected = "➕ Test Player: FA → WV (ML)"
|
||
assert move.description == expected
|
||
|
||
def test_drop_move_description(self, mock_player, mock_team):
|
||
"""Test DROP move description."""
|
||
move = TransactionMove(
|
||
player=mock_player,
|
||
from_roster=RosterType.MAJOR_LEAGUE,
|
||
to_roster=RosterType.FREE_AGENCY,
|
||
from_team=mock_team
|
||
)
|
||
|
||
expected = "➖ Test Player: WV (ML) → FA"
|
||
assert move.description == expected
|
||
|
||
def test_recall_move_description(self, mock_player, mock_team):
|
||
"""Test RECALL move description."""
|
||
move = TransactionMove(
|
||
player=mock_player,
|
||
from_roster=RosterType.MINOR_LEAGUE,
|
||
to_roster=RosterType.MAJOR_LEAGUE,
|
||
from_team=mock_team,
|
||
to_team=mock_team
|
||
)
|
||
|
||
expected = "⬆️ Test Player: WV (MiL) → WV (ML)"
|
||
assert move.description == expected
|
||
|
||
def test_demote_move_description(self, mock_player, mock_team):
|
||
"""Test DEMOTE move description."""
|
||
move = TransactionMove(
|
||
player=mock_player,
|
||
from_roster=RosterType.MAJOR_LEAGUE,
|
||
to_roster=RosterType.MINOR_LEAGUE,
|
||
from_team=mock_team,
|
||
to_team=mock_team
|
||
)
|
||
|
||
expected = "⬇️ Test Player: WV (ML) → WV (MiL)"
|
||
assert move.description == expected
|
||
|
||
|
||
class TestRosterValidationResult:
|
||
"""Test RosterValidationResult functionality."""
|
||
|
||
def test_major_league_status_over_limit(self):
|
||
"""Test status when over major league limit."""
|
||
result = RosterValidationResult(
|
||
is_legal=False,
|
||
major_league_count=27,
|
||
minor_league_count=6,
|
||
warnings=[],
|
||
errors=[],
|
||
suggestions=[]
|
||
)
|
||
|
||
expected = "❌ Major League: 27/26 (Over limit!)"
|
||
assert result.major_league_status == expected
|
||
|
||
def test_major_league_status_at_limit(self):
|
||
"""Test status when at major league limit."""
|
||
result = RosterValidationResult(
|
||
is_legal=True,
|
||
major_league_count=26,
|
||
minor_league_count=6,
|
||
warnings=[],
|
||
errors=[],
|
||
suggestions=[]
|
||
)
|
||
|
||
expected = "✅ Major League: 26/26 (Legal)"
|
||
assert result.major_league_status == expected
|
||
|
||
def test_major_league_status_under_limit(self):
|
||
"""Test status when under major league limit."""
|
||
result = RosterValidationResult(
|
||
is_legal=True,
|
||
major_league_count=23,
|
||
minor_league_count=6,
|
||
warnings=[],
|
||
errors=[],
|
||
suggestions=[]
|
||
)
|
||
|
||
expected = "✅ Major League: 23/26 (Legal)"
|
||
assert result.major_league_status == expected
|
||
|
||
def test_minor_league_status(self):
|
||
"""Test minor league status with limit."""
|
||
result = RosterValidationResult(
|
||
is_legal=False,
|
||
major_league_count=25,
|
||
minor_league_count=7,
|
||
warnings=[],
|
||
errors=[],
|
||
suggestions=[]
|
||
)
|
||
|
||
expected = "❌ Minor League: 7/6 (Over limit!)"
|
||
assert result.minor_league_status == expected
|
||
|
||
|
||
class TestTransactionBuilderGlobalFunctions:
|
||
"""Test global transaction builder functions."""
|
||
|
||
def test_get_transaction_builder_new(self):
|
||
"""Test getting new transaction builder."""
|
||
team = Team(id=499, abbrev='WV', sname='Black Bears', lname='West Virginia Black Bears', season=12)
|
||
|
||
builder = get_transaction_builder(user_id=123, team=team)
|
||
|
||
assert isinstance(builder, TransactionBuilder)
|
||
assert builder.user_id == 123
|
||
assert builder.team == team
|
||
|
||
def test_get_transaction_builder_existing(self):
|
||
"""Test getting existing transaction builder."""
|
||
team = Team(id=499, abbrev='WV', sname='Black Bears', lname='West Virginia Black Bears', season=12)
|
||
|
||
builder1 = get_transaction_builder(user_id=123, team=team)
|
||
builder2 = get_transaction_builder(user_id=123, team=team)
|
||
|
||
assert builder1 is builder2 # Should return same instance
|
||
|
||
def test_clear_transaction_builder(self):
|
||
"""Test clearing transaction builder."""
|
||
team = Team(id=499, abbrev='WV', sname='Black Bears', lname='West Virginia Black Bears', season=12)
|
||
|
||
builder = get_transaction_builder(user_id=123, team=team)
|
||
assert builder is not None
|
||
|
||
clear_transaction_builder(user_id=123)
|
||
|
||
# Getting builder again should create new instance
|
||
new_builder = get_transaction_builder(user_id=123, team=team)
|
||
assert new_builder is not builder
|
||
|
||
def test_clear_nonexistent_builder(self):
|
||
"""Test clearing non-existent builder doesn't error."""
|
||
# Should not raise any exception
|
||
clear_transaction_builder(user_id=99999) |