""" Unit tests for roster models (Pydantic). Tests polymorphic roster link models for type safety across leagues. Author: Claude Date: 2025-10-22 """ import pytest from uuid import uuid4 from pydantic import ValidationError from app.models.roster_models import ( PdRosterLinkData, SbaRosterLinkData, RosterLinkCreate, ) class TestPdRosterLinkData: """Test PD league roster link data model""" def test_create_valid_pd_roster_link(self): """Test creating valid PD roster link""" game_id = uuid4() data = PdRosterLinkData( game_id=game_id, card_id=123, team_id=1 ) assert data.game_id == game_id assert data.card_id == 123 assert data.team_id == 1 assert data.id is None # Not yet saved to DB def test_pd_roster_link_with_id(self): """Test PD roster link with database ID""" game_id = uuid4() data = PdRosterLinkData( id=42, game_id=game_id, card_id=123, team_id=1 ) assert data.id == 42 def test_pd_roster_link_invalid_card_id(self): """Test PD roster link rejects negative card_id""" game_id = uuid4() with pytest.raises(ValidationError) as exc_info: PdRosterLinkData( game_id=game_id, card_id=-1, team_id=1 ) assert "card_id must be positive" in str(exc_info.value) def test_pd_roster_link_zero_card_id(self): """Test PD roster link rejects zero card_id""" game_id = uuid4() with pytest.raises(ValidationError) as exc_info: PdRosterLinkData( game_id=game_id, card_id=0, team_id=1 ) assert "card_id must be positive" in str(exc_info.value) def test_pd_get_entity_id(self): """Test get_entity_id returns card_id""" data = PdRosterLinkData( game_id=uuid4(), card_id=123, team_id=1 ) assert data.get_entity_id() == 123 def test_pd_get_entity_type(self): """Test get_entity_type returns 'card'""" data = PdRosterLinkData( game_id=uuid4(), card_id=123, team_id=1 ) assert data.get_entity_type() == "card" class TestSbaRosterLinkData: """Test SBA league roster link data model""" def test_create_valid_sba_roster_link(self): """Test creating valid SBA roster link""" game_id = uuid4() data = SbaRosterLinkData( game_id=game_id, player_id=456, team_id=2 ) assert data.game_id == game_id assert data.player_id == 456 assert data.team_id == 2 assert data.id is None def test_sba_roster_link_with_id(self): """Test SBA roster link with database ID""" game_id = uuid4() data = SbaRosterLinkData( id=99, game_id=game_id, player_id=456, team_id=2 ) assert data.id == 99 def test_sba_roster_link_invalid_player_id(self): """Test SBA roster link rejects negative player_id""" game_id = uuid4() with pytest.raises(ValidationError) as exc_info: SbaRosterLinkData( game_id=game_id, player_id=-5, team_id=2 ) assert "player_id must be positive" in str(exc_info.value) def test_sba_roster_link_zero_player_id(self): """Test SBA roster link rejects zero player_id""" game_id = uuid4() with pytest.raises(ValidationError) as exc_info: SbaRosterLinkData( game_id=game_id, player_id=0, team_id=2 ) assert "player_id must be positive" in str(exc_info.value) def test_sba_get_entity_id(self): """Test get_entity_id returns player_id""" data = SbaRosterLinkData( game_id=uuid4(), player_id=456, team_id=2 ) assert data.get_entity_id() == 456 def test_sba_get_entity_type(self): """Test get_entity_type returns 'player'""" data = SbaRosterLinkData( game_id=uuid4(), player_id=456, team_id=2 ) assert data.get_entity_type() == "player" class TestRosterLinkCreate: """Test RosterLinkCreate request model""" def test_create_with_card_id(self): """Test creating request with card_id only""" game_id = uuid4() data = RosterLinkCreate( game_id=game_id, team_id=1, card_id=123 ) assert data.game_id == game_id assert data.team_id == 1 assert data.card_id == 123 assert data.player_id is None def test_create_with_player_id(self): """Test creating request with player_id only""" game_id = uuid4() data = RosterLinkCreate( game_id=game_id, team_id=2, player_id=456 ) assert data.game_id == game_id assert data.team_id == 2 assert data.player_id == 456 assert data.card_id is None def test_create_with_both_ids_fails(self): """Test that providing both IDs raises error""" game_id = uuid4() with pytest.raises(ValidationError) as exc_info: RosterLinkCreate( game_id=game_id, team_id=1, card_id=123, player_id=456 ) assert "Exactly one of card_id or player_id must be provided" in str(exc_info.value) def test_create_with_neither_id_fails(self): """Test that providing neither ID raises error""" game_id = uuid4() with pytest.raises(ValidationError) as exc_info: RosterLinkCreate( game_id=game_id, team_id=1 ) assert "Exactly one of card_id or player_id must be provided" in str(exc_info.value) def test_invalid_team_id(self): """Test that negative team_id raises error""" game_id = uuid4() with pytest.raises(ValidationError) as exc_info: RosterLinkCreate( game_id=game_id, team_id=-1, card_id=123 ) assert "team_id must be positive" in str(exc_info.value) def test_zero_team_id(self): """Test that zero team_id raises error""" game_id = uuid4() with pytest.raises(ValidationError) as exc_info: RosterLinkCreate( game_id=game_id, team_id=0, player_id=456 ) assert "team_id must be positive" in str(exc_info.value) def test_to_pd_data_success(self): """Test converting to PdRosterLinkData""" game_id = uuid4() create_data = RosterLinkCreate( game_id=game_id, team_id=1, card_id=123 ) pd_data = create_data.to_pd_data() assert isinstance(pd_data, PdRosterLinkData) assert pd_data.game_id == game_id assert pd_data.team_id == 1 assert pd_data.card_id == 123 def test_to_pd_data_fails_without_card_id(self): """Test converting to PdRosterLinkData fails without card_id""" game_id = uuid4() create_data = RosterLinkCreate( game_id=game_id, team_id=1, player_id=456 ) with pytest.raises(ValueError) as exc_info: create_data.to_pd_data() assert "card_id required for PD roster" in str(exc_info.value) def test_to_sba_data_success(self): """Test converting to SbaRosterLinkData""" game_id = uuid4() create_data = RosterLinkCreate( game_id=game_id, team_id=2, player_id=456 ) sba_data = create_data.to_sba_data() assert isinstance(sba_data, SbaRosterLinkData) assert sba_data.game_id == game_id assert sba_data.team_id == 2 assert sba_data.player_id == 456 def test_to_sba_data_fails_without_player_id(self): """Test converting to SbaRosterLinkData fails without player_id""" game_id = uuid4() create_data = RosterLinkCreate( game_id=game_id, team_id=1, card_id=123 ) with pytest.raises(ValueError) as exc_info: create_data.to_sba_data() assert "player_id required for SBA roster" in str(exc_info.value) class TestPolymorphicBehavior: """Test polymorphic patterns across roster types""" def test_both_types_have_get_entity_id(self): """Test both types implement get_entity_id""" pd_data = PdRosterLinkData( game_id=uuid4(), card_id=123, team_id=1 ) sba_data = SbaRosterLinkData( game_id=uuid4(), player_id=456, team_id=2 ) # Both should have the method assert callable(pd_data.get_entity_id) assert callable(sba_data.get_entity_id) # Different return values assert pd_data.get_entity_id() == 123 assert sba_data.get_entity_id() == 456 def test_both_types_have_get_entity_type(self): """Test both types implement get_entity_type""" pd_data = PdRosterLinkData( game_id=uuid4(), card_id=123, team_id=1 ) sba_data = SbaRosterLinkData( game_id=uuid4(), player_id=456, team_id=2 ) # Different return values assert pd_data.get_entity_type() == "card" assert sba_data.get_entity_type() == "player"