From 0482fff8c57c509272ffa571cf9aed52e32cd8b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Y=C3=BBki=20VACHOT?= Date: Sat, 29 Nov 2025 06:29:35 +0100 Subject: [PATCH] Fix format with black --- src/geoguessr_mcp/monitoring/__init__.py | 3 +- src/geoguessr_mcp/tools/game_tools.py | 4 +- src/geoguessr_mcp/tools/monitoring_tools.py | 19 +++--- src/geoguessr_mcp/tools/profile_tools.py | 4 +- src/tests/conftest.py | 4 +- src/tests/integration/test_api_client.py | 2 + .../unit/services/test_analysis_service.py | 56 ++++++++++------ src/tests/unit/services/test_game_service.py | 64 +++++++------------ .../unit/services/test_profile_service.py | 43 ++++++------- 9 files changed, 100 insertions(+), 99 deletions(-) diff --git a/src/geoguessr_mcp/monitoring/__init__.py b/src/geoguessr_mcp/monitoring/__init__.py index 4158ce8..a5e390b 100644 --- a/src/geoguessr_mcp/monitoring/__init__.py +++ b/src/geoguessr_mcp/monitoring/__init__.py @@ -1,7 +1,6 @@ """Monitoring module for API endpoint tracking and schema detection.""" -from .endpoint.endpoint_monitor import (MONITORED_ENDPOINTS, EndpointMonitor, - endpoint_monitor) +from .endpoint.endpoint_monitor import MONITORED_ENDPOINTS, EndpointMonitor, endpoint_monitor from .schema.endpoint_schema import EndpointSchema from .schema.schema_detector import SchemaDetector, SchemaField from .schema.schema_registry import SchemaRegistry, schema_registry diff --git a/src/geoguessr_mcp/tools/game_tools.py b/src/geoguessr_mcp/tools/game_tools.py index f567e39..f707e69 100644 --- a/src/geoguessr_mcp/tools/game_tools.py +++ b/src/geoguessr_mcp/tools/game_tools.py @@ -74,9 +74,7 @@ def register_game_tools(mcp: FastMCP, game_service: GameService): "success": True, "total_entries": len(entries), "entry_types": list(categorized.keys()), - "entries_by_type": { - t: len(e) for t, e in categorized.items() - }, + "entries_by_type": {t: len(e) for t, e in categorized.items()}, "recent_entries": entries[:5], # First 5 for context "available_fields": response.available_fields, } diff --git a/src/geoguessr_mcp/tools/monitoring_tools.py b/src/geoguessr_mcp/tools/monitoring_tools.py index dec84c6..9a28e10 100644 --- a/src/geoguessr_mcp/tools/monitoring_tools.py +++ b/src/geoguessr_mcp/tools/monitoring_tools.py @@ -36,6 +36,7 @@ def register_monitoring_tools(mcp: FastMCP): session_token = get_current_session_token() if session_token: from ..auth.session import SessionManager + session_manager = SessionManager() session = await session_manager.get_session(session_token) if session: @@ -136,14 +137,16 @@ def register_monitoring_tools(mcp: FastMCP): previous = history[-1] if history else None if current and previous: - changes.append({ - "endpoint": endpoint, - "current_hash": current.schema_hash, - "previous_hash": previous.schema_hash, - "current_fields": len(current.fields), - "previous_fields": len(previous.fields), - "changed_at": current.last_updated.isoformat(), - }) + changes.append( + { + "endpoint": endpoint, + "current_hash": current.schema_hash, + "previous_hash": previous.schema_hash, + "current_fields": len(current.fields), + "previous_fields": len(previous.fields), + "changed_at": current.last_updated.isoformat(), + } + ) return { "total_changes_tracked": len(changes), diff --git a/src/geoguessr_mcp/tools/profile_tools.py b/src/geoguessr_mcp/tools/profile_tools.py index 588aaa2..6337457 100644 --- a/src/geoguessr_mcp/tools/profile_tools.py +++ b/src/geoguessr_mcp/tools/profile_tools.py @@ -87,7 +87,9 @@ def register_profile_tools(mcp: FastMCP, profile_service: ProfileService): "total": len(achievements), "unlocked": len(unlocked), "locked": len(locked), - "completion_rate": f"{len(unlocked) / len(achievements) * 100:.1f}%" if achievements else "0%", + "completion_rate": ( + f"{len(unlocked) / len(achievements) * 100:.1f}%" if achievements else "0%" + ), }, "unlocked_achievements": [ {"name": a.name, "description": a.description, "unlocked_at": a.unlocked_at} diff --git a/src/tests/conftest.py b/src/tests/conftest.py index 8c49252..e365300 100644 --- a/src/tests/conftest.py +++ b/src/tests/conftest.py @@ -1,4 +1,5 @@ """Shared test fixtures.""" + import os from unittest.mock import AsyncMock, MagicMock, patch @@ -16,7 +17,7 @@ from geoguessr_mcp.services import AnalysisService, GameService, ProfileService def mock_env(request, monkeypatch): """Set up environment variables for testing.""" # Skip this fixture if the test has the 'real_env' marker - if 'real_env' in request.keywords: + if "real_env" in request.keywords: yield return @@ -25,6 +26,7 @@ def mock_env(request, monkeypatch): # Clear schema registry to avoid interference from registered schemas from geoguessr_mcp.monitoring.schema.schema_registry import schema_registry + # Store original schemas original_schemas = schema_registry.schemas.copy() # Clear all schemas for testing diff --git a/src/tests/integration/test_api_client.py b/src/tests/integration/test_api_client.py index 5b98ffd..f5b58e6 100644 --- a/src/tests/integration/test_api_client.py +++ b/src/tests/integration/test_api_client.py @@ -304,6 +304,7 @@ class TestGeoGuessrClientIntegration: """Test real API call to profile endpoint.""" # This test requires GEOGUESSR_NCFA_COOKIE to be set import os + if not os.environ.get("GEOGUESSR_NCFA_COOKIE"): pytest.skip("GEOGUESSR_NCFA_COOKIE not set") @@ -317,6 +318,7 @@ class TestGeoGuessrClientIntegration: """Test real API call to stats' endpoint.""" # This test requires GEOGUESSR_NCFA_COOKIE to be set import os + if not os.environ.get("GEOGUESSR_NCFA_COOKIE"): pytest.skip("GEOGUESSR_NCFA_COOKIE not set") diff --git a/src/tests/unit/services/test_analysis_service.py b/src/tests/unit/services/test_analysis_service.py index e43919d..037ee6b 100644 --- a/src/tests/unit/services/test_analysis_service.py +++ b/src/tests/unit/services/test_analysis_service.py @@ -103,7 +103,9 @@ class TestAnalysisService: games = [] for i in range(6): base_score = 15000 + (i * 2000) # Increasing scores - rounds = [RoundGuess(round_number=1, score=base_score, distance_meters=100, time_seconds=30)] + rounds = [ + RoundGuess(round_number=1, score=base_score, distance_meters=100, time_seconds=30) + ] game = Game( token=f"game-{i}", map_name="World", @@ -124,7 +126,9 @@ class TestAnalysisService: games = [] for i in range(6): base_score = 25000 - (i * 2000) # Decreasing scores - rounds = [RoundGuess(round_number=1, score=base_score, distance_meters=100, time_seconds=30)] + rounds = [ + RoundGuess(round_number=1, score=base_score, distance_meters=100, time_seconds=30) + ] game = Game( token=f"game-{i}", map_name="World", @@ -182,17 +186,11 @@ class TestAnalysisService: assert all(area["score"] >= 4500 for area in result.strong_areas) @pytest.mark.asyncio - async def test_analyze_recent_games( - self, analysis_service, mock_game_service, sample_games - ): + async def test_analyze_recent_games(self, analysis_service, mock_game_service, sample_games): """Test analyze_recent_games method.""" mock_game_service.get_recent_games.return_value = sample_games - with patch.object( - analysis_service, - 'analyze_games', - wraps=AnalysisService.analyze_games - ): + with patch.object(analysis_service, "analyze_games", wraps=AnalysisService.analyze_games): result = await analysis_service.analyze_recent_games(count=5) assert "analysis" in result @@ -207,17 +205,20 @@ class TestAnalysisService: """Test analyze_recent_games with session token.""" mock_game_service.get_recent_games.return_value = sample_games - await analysis_service.analyze_recent_games( - count=10, - session_token="test_token" - ) + await analysis_service.analyze_recent_games(count=10, session_token="test_token") mock_game_service.get_recent_games.assert_called_once_with(10, "test_token") @pytest.mark.asyncio async def test_get_performance_summary( - self, analysis_service, mock_game_service, mock_profile_service, - mock_client, sample_games, mock_season_stats_data, mock_dynamic_response + self, + analysis_service, + mock_game_service, + mock_profile_service, + mock_client, + sample_games, + mock_season_stats_data, + mock_dynamic_response, ): """Test comprehensive performance summary.""" mock_profile_service.get_comprehensive_profile.return_value = { @@ -227,6 +228,7 @@ class TestAnalysisService: mock_season_response = mock_dynamic_response(mock_season_stats_data) from geoguessr_mcp.models import SeasonStats + mock_season_stats = SeasonStats.from_api_response(mock_season_stats_data) mock_game_service.get_season_stats.return_value = (mock_season_stats, mock_season_response) mock_game_service.get_recent_games.return_value = sample_games[:3] @@ -267,7 +269,14 @@ class TestAnalysisService: for i in range(5) ] games = [ - Game(token="g1", map_name="World", mode="standard", total_score=15000, rounds=rounds, finished=True) + Game( + token="g1", + map_name="World", + mode="standard", + total_score=15000, + rounds=rounds, + finished=True, + ) for _ in range(5) ] mock_game_service.get_recent_games.return_value = games @@ -289,7 +298,14 @@ class TestAnalysisService: for i in range(5) ] games = [ - Game(token="g1", map_name="World", mode="standard", total_score=17500, rounds=rounds, finished=True) + Game( + token="g1", + map_name="World", + mode="standard", + total_score=17500, + rounds=rounds, + finished=True, + ) for _ in range(5) ] mock_game_service.get_recent_games.return_value = games @@ -308,7 +324,9 @@ class TestAnalysisService: games = [] for i in range(6): base_score = 25000 - (i * 3000) - rounds = [RoundGuess(round_number=1, score=base_score, distance_meters=100, time_seconds=45)] + rounds = [ + RoundGuess(round_number=1, score=base_score, distance_meters=100, time_seconds=45) + ] game = Game( token=f"game-{i}", map_name="World", diff --git a/src/tests/unit/services/test_game_service.py b/src/tests/unit/services/test_game_service.py index 67d9154..df4dd60 100644 --- a/src/tests/unit/services/test_game_service.py +++ b/src/tests/unit/services/test_game_service.py @@ -40,32 +40,23 @@ class TestGameService: """Test game details with explicit session token.""" mock_client.get.return_value = mock_dynamic_response(mock_game_data) - game, response = await game_service.get_game_details( - "ABC123", - session_token="test_token" - ) + game, response = await game_service.get_game_details("ABC123", session_token="test_token") call_args = mock_client.get.call_args assert call_args[0][1] == "test_token" @pytest.mark.asyncio - async def test_get_game_details_failure( - self, game_service, mock_client, mock_dynamic_response - ): + async def test_get_game_details_failure(self, game_service, mock_client, mock_dynamic_response): """Test game details retrieval failure.""" mock_client.get.return_value = mock_dynamic_response( - {"error": "Game not found"}, - success=False, - status_code=404 + {"error": "Game not found"}, success=False, status_code=404 ) with pytest.raises(ValueError, match="Failed to get game details"): await game_service.get_game_details("INVALID") @pytest.mark.asyncio - async def test_get_unfinished_games( - self, game_service, mock_client, mock_dynamic_response - ): + async def test_get_unfinished_games(self, game_service, mock_client, mock_dynamic_response): """Test unfinished games retrieval.""" unfinished_data = [ {"token": "game-1", "map": {"name": "World"}}, @@ -79,9 +70,7 @@ class TestGameService: assert len(response.data) == 2 @pytest.mark.asyncio - async def test_get_streak_game( - self, game_service, mock_client, mock_dynamic_response - ): + async def test_get_streak_game(self, game_service, mock_client, mock_dynamic_response): """Test streak game retrieval.""" streak_data = { "token": "streak-123", @@ -122,7 +111,12 @@ class TestGameService: @pytest.mark.asyncio async def test_get_recent_games_success( - self, game_service, mock_client, mock_activity_feed_data, mock_game_data, mock_dynamic_response + self, + game_service, + mock_client, + mock_activity_feed_data, + mock_game_data, + mock_dynamic_response, ): """Test recent games retrieval.""" # First call returns activity feed, subsequent calls return game details @@ -153,10 +147,7 @@ class TestGameService: self, game_service, mock_client, mock_dynamic_response ): """Test recent games when feed fails.""" - mock_client.get.return_value = mock_dynamic_response( - {"error": "Failed"}, - success=False - ) + mock_client.get.return_value = mock_dynamic_response({"error": "Failed"}, success=False) games = await game_service.get_recent_games(count=5) @@ -164,7 +155,12 @@ class TestGameService: @pytest.mark.asyncio async def test_get_recent_games_skips_failed_game_fetch( - self, game_service, mock_client, mock_activity_feed_data, mock_game_data, mock_dynamic_response + self, + game_service, + mock_client, + mock_activity_feed_data, + mock_game_data, + mock_dynamic_response, ): """Test that failed individual game fetches are skipped.""" mock_client.get.side_effect = [ @@ -193,14 +189,10 @@ class TestGameService: assert stats.division == "Gold" @pytest.mark.asyncio - async def test_get_season_stats_failure( - self, game_service, mock_client, mock_dynamic_response - ): + async def test_get_season_stats_failure(self, game_service, mock_client, mock_dynamic_response): """Test season stats failure.""" mock_client.get.return_value = mock_dynamic_response( - {"error": "No active season"}, - success=False, - status_code=404 + {"error": "No active season"}, success=False, status_code=404 ) with pytest.raises(ValueError, match="Failed to get season stats"): @@ -246,18 +238,14 @@ class TestGameService: ): """Test daily challenge failure.""" mock_client.get.return_value = mock_dynamic_response( - {"error": "Challenge not found"}, - success=False, - status_code=404 + {"error": "Challenge not found"}, success=False, status_code=404 ) with pytest.raises(ValueError, match="Failed to get daily challenge"): await game_service.get_daily_challenge() @pytest.mark.asyncio - async def test_get_battle_royale( - self, game_service, mock_client, mock_dynamic_response - ): + async def test_get_battle_royale(self, game_service, mock_client, mock_dynamic_response): """Test battle royale game retrieval.""" br_data = { "gameId": "br-123", @@ -272,9 +260,7 @@ class TestGameService: assert response.data["players"] == 10 @pytest.mark.asyncio - async def test_get_duel( - self, game_service, mock_client, mock_dynamic_response - ): + async def test_get_duel(self, game_service, mock_client, mock_dynamic_response): """Test duel game retrieval.""" duel_data = { "duelId": "duel-456", @@ -289,9 +275,7 @@ class TestGameService: assert response.data["player1"]["score"] == 5000 @pytest.mark.asyncio - async def test_get_tournaments( - self, game_service, mock_client, mock_dynamic_response - ): + async def test_get_tournaments(self, game_service, mock_client, mock_dynamic_response): """Test tournaments retrieval.""" tournaments_data = [ {"id": "t1", "name": "Weekly Tournament", "status": "active"}, diff --git a/src/tests/unit/services/test_profile_service.py b/src/tests/unit/services/test_profile_service.py index 35c9191..ae12345 100644 --- a/src/tests/unit/services/test_profile_service.py +++ b/src/tests/unit/services/test_profile_service.py @@ -46,14 +46,10 @@ class TestProfileService: assert call_args[0][1] == "test_token" @pytest.mark.asyncio - async def test_get_profile_failure( - self, profile_service, mock_client, mock_dynamic_response - ): + async def test_get_profile_failure(self, profile_service, mock_client, mock_dynamic_response): """Test profile retrieval failure.""" mock_client.get.return_value = mock_dynamic_response( - {"error": "Unauthorized"}, - success=False, - status_code=401 + {"error": "Unauthorized"}, success=False, status_code=401 ) with pytest.raises(ValueError, match="Failed to get profile"): @@ -75,23 +71,17 @@ class TestProfileService: assert stats.win_rate == 0.65 @pytest.mark.asyncio - async def test_get_stats_failure( - self, profile_service, mock_client, mock_dynamic_response - ): + async def test_get_stats_failure(self, profile_service, mock_client, mock_dynamic_response): """Test stats retrieval failure.""" mock_client.get.return_value = mock_dynamic_response( - {"error": "Server error"}, - success=False, - status_code=500 + {"error": "Server error"}, success=False, status_code=500 ) with pytest.raises(ValueError, match="Failed to get stats"): await profile_service.get_stats() @pytest.mark.asyncio - async def test_get_extended_stats( - self, profile_service, mock_client, mock_dynamic_response - ): + async def test_get_extended_stats(self, profile_service, mock_client, mock_dynamic_response): """Test extended stats retrieval.""" extended_data = { "totalDistance": 1500000, @@ -154,9 +144,7 @@ class TestProfileService: assert achievements[0].name == "Winner" @pytest.mark.asyncio - async def test_get_public_profile( - self, profile_service, mock_client, mock_dynamic_response - ): + async def test_get_public_profile(self, profile_service, mock_client, mock_dynamic_response): """Test public profile retrieval.""" public_profile_data = { "id": "other-user-123", @@ -172,9 +160,7 @@ class TestProfileService: assert profile.nick == "OtherPlayer" @pytest.mark.asyncio - async def test_get_user_maps( - self, profile_service, mock_client, mock_dynamic_response - ): + async def test_get_user_maps(self, profile_service, mock_client, mock_dynamic_response): """Test user maps retrieval.""" maps_data = [ {"id": "map-1", "name": "My Custom Map"}, @@ -189,7 +175,12 @@ class TestProfileService: @pytest.mark.asyncio async def test_get_comprehensive_profile_success( - self, profile_service, mock_client, mock_profile_data, mock_stats_data, mock_dynamic_response + self, + profile_service, + mock_client, + mock_profile_data, + mock_stats_data, + mock_dynamic_response, ): """Test comprehensive profile aggregation.""" # Setup mock responses for each call @@ -197,9 +188,11 @@ class TestProfileService: mock_dynamic_response(mock_profile_data), # profile mock_dynamic_response(mock_stats_data), # stats mock_dynamic_response({"totalDistance": 1000}), # extended stats - mock_dynamic_response([ # achievements - {"id": "ach-1", "name": "Test", "unlocked": True, "unlockedAt": "2024-01-01"}, - ]), + mock_dynamic_response( + [ # achievements + {"id": "ach-1", "name": "Test", "unlocked": True, "unlockedAt": "2024-01-01"}, + ] + ), ] result = await profile_service.get_comprehensive_profile()