""" Unit tests for PlayerService. Tests business logic methods extracted from Player model, following test isolation guidelines with mocked dependencies. """ import pytest from unittest.mock import Mock from app.services.player_service import PlayerService from tests.factories.player_factory import PlayerFactory class TestPlayerServiceCardUrls: """Test card URL retrieval methods.""" def test_get_batter_card_url_from_primary_image(self, db_session): """Test getting batter card URL from primary image.""" player = PlayerFactory.create_with_batting_card(db_session) service = PlayerService(db_session) result = service.get_batter_card_url(player) assert result == player.image assert "batting" in result def test_get_batter_card_url_from_secondary_image(self, db_session): """Test getting batter card URL from secondary image.""" player = PlayerFactory.create( db_session, image="https://example.com/player_pitching.jpg", image2="https://example.com/player_batting.jpg" ) service = PlayerService(db_session) result = service.get_batter_card_url(player) assert result == player.image2 assert "batting" in result def test_get_batter_card_url_none_available(self, db_session): """Test getting batter card URL when none available.""" player = PlayerFactory.create( db_session, image="https://example.com/player_pitching.jpg", image2="https://example.com/player_fielding.jpg" ) service = PlayerService(db_session) result = service.get_batter_card_url(player) assert result is None def test_get_pitcher_card_url_from_primary_image(self, db_session): """Test getting pitcher card URL from primary image.""" player = PlayerFactory.create_with_pitching_card(db_session) service = PlayerService(db_session) result = service.get_pitcher_card_url(player) assert result == player.image assert "pitching" in result def test_get_pitcher_card_url_from_secondary_image(self, db_session): """Test getting pitcher card URL from secondary image.""" player = PlayerFactory.create( db_session, image="https://example.com/player_batting.jpg", image2="https://example.com/player_pitching.jpg" ) service = PlayerService(db_session) result = service.get_pitcher_card_url(player) assert result == player.image2 assert "pitching" in result def test_get_pitcher_card_url_none_available(self, db_session): """Test getting pitcher card URL when none available.""" player = PlayerFactory.create( db_session, image="https://example.com/player_batting.jpg", image2="https://example.com/player_fielding.jpg" ) service = PlayerService(db_session) result = service.get_pitcher_card_url(player) assert result is None class TestPlayerServiceNameCardLink: """Test name card link generation.""" def test_generate_batting_card_link(self, db_session): """Test generating batting card markdown link.""" player = PlayerFactory.create_with_batting_card( db_session, name="Test Batter" ) service = PlayerService(db_session) result = service.generate_name_card_link(player, 'batting') expected = f"[Test Batter]({player.image})" assert result == expected def test_generate_pitching_card_link(self, db_session): """Test generating pitching card markdown link.""" player = PlayerFactory.create_with_pitching_card( db_session, name="Test Pitcher" ) service = PlayerService(db_session) result = service.generate_name_card_link(player, 'pitching') expected = f"[Test Pitcher]({player.image})" assert result == expected def test_generate_card_link_no_url_available(self, db_session): """Test generating card link when URL not available.""" player = PlayerFactory.create( db_session, name="No Card Player", image="https://example.com/fielding_card.jpg", # Contains neither 'batting' nor 'pitching' image2=None ) service = PlayerService(db_session) with pytest.raises(ValueError, match="No batting card URL available"): service.generate_name_card_link(player, 'batting') with pytest.raises(ValueError, match="No pitching card URL available"): service.generate_name_card_link(player, 'pitching') def test_generate_card_link_both_types_available(self, db_session): """Test generating links when both card types are available.""" player = PlayerFactory.create_with_both_cards( db_session, name="Multi Card Player" ) service = PlayerService(db_session) batting_link = service.generate_name_card_link(player, 'batting') pitching_link = service.generate_name_card_link(player, 'pitching') assert f"[Multi Card Player]({player.image})" == batting_link assert f"[Multi Card Player]({player.image2})" == pitching_link class TestPlayerServiceFormatting: """Test player formatting methods.""" def test_get_formatted_name_with_description(self, db_session): """Test getting formatted name with description.""" player = PlayerFactory.create( db_session, name="John Smith", description="2023 Rookie" ) service = PlayerService(db_session) result = service.get_formatted_name_with_description(player) assert result == "2023 Rookie John Smith" def test_get_player_description_from_player_object(self, db_session): """Test getting description from Player object.""" player = PlayerFactory.create( db_session, name="Test Player", description="Prime" ) service = PlayerService(db_session) result = service.get_player_description(player=player) assert result == "Prime Test Player" def test_get_player_description_from_dict_with_name(self, db_session): """Test getting description from dictionary with 'name' key.""" player_dict = { "description": "Veteran", "name": "Dict Player" } service = PlayerService(db_session) result = service.get_player_description(player_dict=player_dict) assert result == "Veteran Dict Player" def test_get_player_description_from_dict_with_p_name(self, db_session): """Test getting description from dictionary with 'p_name' key.""" player_dict = { "description": "Legend", "p_name": "P Name Player" } service = PlayerService(db_session) result = service.get_player_description(player_dict=player_dict) assert result == "Legend P Name Player" def test_get_player_description_from_dict_description_only(self, db_session): """Test getting description from dictionary with only description.""" player_dict = { "description": "No Name Era" } service = PlayerService(db_session) result = service.get_player_description(player_dict=player_dict) assert result == "No Name Era" def test_get_player_description_no_parameters(self, db_session): """Test getting description with no parameters raises error.""" service = PlayerService(db_session) with pytest.raises(TypeError, match="One of \"player\" or \"player_dict\" must be included"): service.get_player_description() def test_get_player_description_missing_description_key(self, db_session): """Test getting description with missing description key.""" player_dict = { "name": "Missing Description Player" } service = PlayerService(db_session) with pytest.raises(KeyError, match="player_dict must contain \"description\" key"): service.get_player_description(player_dict=player_dict) class TestPlayerServiceIntegration: """Test PlayerService integration and edge cases.""" def test_service_inherits_from_base_service(self, db_session): """Test that PlayerService properly inherits from BaseService.""" service = PlayerService(db_session) # Should have BaseService methods assert hasattr(service, '_log_operation') assert hasattr(service, '_log_error') assert hasattr(service, 'session') assert hasattr(service, 'logger') def test_service_logging(self, db_session): """Test that service methods perform logging.""" player = PlayerFactory.create_with_batting_card(db_session, name="Log Test") service = PlayerService(db_session) # These methods should not raise exceptions and should log result = service.get_batter_card_url(player) assert result is not None result = service.get_formatted_name_with_description(player) assert "Log Test" in result def test_service_with_complex_player_data(self, db_session): """Test service methods with complex player data.""" player = PlayerFactory.create( db_session, name="Complex Player", description="2023 All-Star Rookie", image="https://example.com/complex_batting_card.jpg", image2="https://example.com/complex_pitching_card.jpg", pos_1="C", pos_2="1B", mlbclub="LAD", cost=45, headshot="https://example.com/headshot.jpg" ) service = PlayerService(db_session) # Test all service methods work with complex data batting_url = service.get_batter_card_url(player) pitching_url = service.get_pitcher_card_url(player) batting_link = service.generate_name_card_link(player, 'batting') pitching_link = service.generate_name_card_link(player, 'pitching') formatted_name = service.get_formatted_name_with_description(player) assert batting_url == player.image assert pitching_url == player.image2 assert "Complex Player" in batting_link assert "Complex Player" in pitching_link assert formatted_name == "2023 All-Star Rookie Complex Player" def test_service_methods_with_none_values(self, db_session): """Test service methods handle None values gracefully.""" player = PlayerFactory.create( db_session, image2=None, headshot=None ) service = PlayerService(db_session) # Methods should handle None values without errors pitcher_url = service.get_pitcher_card_url(player) formatted_name = service.get_formatted_name_with_description(player) # These should work even with None values assert formatted_name is not None assert player.name in formatted_name