OpenDota MCP Server

  • tests
""" Mock data and response handlers for testing the OpenDota MCP Server. """ from typing import Any, Dict, Optional # Mock API responses for unit tests MOCK_RESPONSES = { # Players "players/123": { "account_id": 123, "profile": { "personaname": "MockPlayer", "name": "Mock Player", "steamid": "76561198000000123", "avatarfull": "https://example.com/avatar.jpg", "profileurl": "https://example.com/profile", "loccountrycode": "US", }, "rank_tier": 65, "mmr_estimate": {"estimate": 4500}, "is_pro": False, }, # Pro player "players/456": { "account_id": 456, "profile": { "personaname": "ProPlayer", "name": "Pro Player", "steamid": "76561198000000456", "avatarfull": "https://example.com/pro_avatar.jpg", "profileurl": "https://example.com/pro_profile", "loccountrycode": "UA", }, "rank_tier": 80, "mmr_estimate": {"estimate": 8000}, "is_pro": True, "team_name": "Mock Team", "team_id": 789, }, # Pro player recent matches "players/456/recentMatches": [ { "match_id": 6789125, "player_slot": 128, "radiant_win": True, "duration": 2200, "game_mode": 2, "lobby_type": 7, "hero_id": 3, "start_time": 1593100000, "kills": 12, "deaths": 2, "assists": 8, "gold_per_min": 600, "xp_per_min": 700, }, { "match_id": 6789126, "player_slot": 1, "radiant_win": False, "duration": 1900, "game_mode": 2, "lobby_type": 7, "hero_id": 4, "start_time": 1593090000, "kills": 8, "deaths": 3, "assists": 15, "gold_per_min": 550, "xp_per_min": 650, }, ], # Player win/loss "players/123/wl": { "win": 500, "lose": 400, }, # Player recent matches "players/123/recentMatches": [ { "match_id": 6789123, "player_slot": 128, "radiant_win": False, "duration": 2400, "game_mode": 2, "lobby_type": 7, "hero_id": 1, "start_time": 1593000000, "kills": 10, "deaths": 5, "assists": 15, "gold_per_min": 500, "xp_per_min": 600, }, { "match_id": 6789124, "player_slot": 1, "radiant_win": True, "duration": 1800, "game_mode": 2, "lobby_type": 7, "hero_id": 2, "start_time": 1592990000, "kills": 5, "deaths": 2, "assists": 20, "gold_per_min": 450, "xp_per_min": 550, }, ], # Match details "matches/6789123": { "match_id": 6789123, "duration": 2400, "start_time": 1593000000, "radiant_win": False, "radiant_score": 25, "dire_score": 40, "game_mode": 2, "lobby_type": 7, "region": 1, "players": [ { "account_id": 123, "player_slot": 128, "hero_id": 1, "kills": 10, "deaths": 5, "assists": 15, "gold_per_min": 500, "xp_per_min": 600, }, { "account_id": 124, "player_slot": 129, "hero_id": 2, "kills": 8, "deaths": 3, "assists": 12, "gold_per_min": 480, "xp_per_min": 580, }, ], }, # Heroes "heroes": [ { "id": 1, "name": "npc_dota_hero_antimage", "localized_name": "Anti-Mage", "primary_attr": "agi", "attack_type": "Melee", "roles": ["Carry", "Escape", "Nuker"], }, { "id": 2, "name": "npc_dota_hero_axe", "localized_name": "Axe", "primary_attr": "str", "attack_type": "Melee", "roles": ["Initiator", "Durable", "Disabler", "Jungler"], }, ], # Hero stats "heroStats": [ { "id": 1, "name": "npc_dota_hero_antimage", "localized_name": "Anti-Mage", "primary_attr": "agi", "attack_type": "Melee", "roles": ["Carry", "Escape", "Nuker"], "1_pick": 1000, "1_win": 500, "2_pick": 2000, "2_win": 1100, "3_pick": 3000, "3_win": 1500, "4_pick": 4000, "4_win": 2000, "5_pick": 5000, "5_win": 2500, "6_pick": 3000, "6_win": 1600, "7_pick": 2000, "7_win": 1000, "8_pick": 1000, "8_win": 550, "pro_pick": 100, "pro_win": 55, "pro_ban": 80, }, { "id": 2, "name": "npc_dota_hero_axe", "localized_name": "Axe", "primary_attr": "str", "attack_type": "Melee", "roles": ["Initiator", "Durable", "Disabler", "Jungler"], "1_pick": 1200, "1_win": 700, "2_pick": 2200, "2_win": 1300, "3_pick": 3200, "3_win": 1700, "4_pick": 4200, "4_win": 2100, "5_pick": 5200, "5_win": 2700, "6_pick": 3200, "6_win": 1700, "7_pick": 2200, "7_win": 1150, "8_pick": 1200, "8_win": 650, "pro_pick": 120, "pro_win": 65, "pro_ban": 90, }, ], # Search "search?q=dendi": [ { "account_id": 70388657, "personaname": "Dendi", "similarity": 0.95, }, { "account_id": 123456789, "personaname": "DendiClone", "similarity": 0.8, }, ], # Pro players "proPlayers": [ { "account_id": 70388657, "name": "Dendi", "team_name": "B8", "country_code": "UA", }, { "account_id": 111620041, "name": "SumaiL", "team_name": "Team Liquid", "country_code": "PK", }, ], # Pro matches "proMatches": [ { "match_id": 7123456, "duration": 2400, "start_time": 1593100000, "radiant_name": "Team Secret", "dire_name": "Team Liquid", "league_name": "The International 2023", "radiant_score": 30, "dire_score": 25, "radiant_win": True, }, ], # Team info "teams/1": { "name": "Team Secret", "tag": "Secret", "rating": 1500, "wins": 300, "losses": 150, "last_match_time": 1593100000, }, # Team players "teams/1/players": [ { "name": "Puppey", "account_id": 87278757, "games_played": 1000, "wins": 650, "is_current_team_member": True, }, ], # Public matches "publicMatches": [ { "match_id": 7234567, "duration": 1800, "start_time": 1593200000, "avg_rank_tier": 65, "radiant_win": True, "radiant_team": [1, 2, 3, 4, 5], "dire_team": [6, 7, 8, 9, 10], }, ], # Player heroes "players/123/heroes": [ { "hero_id": 1, "games": 50, "win": 30, }, { "hero_id": 2, "games": 40, "win": 25, }, ], # Player peers "players/123/peers": [ { "account_id": 234, "personaname": "Peer1", "matches": 20, "win": 12, "with_win": 10, "with_games": 15, }, { "account_id": 345, "personaname": "Peer2", "matches": 15, "win": 8, "with_win": 6, "with_games": 10, }, ], # Player totals "players/123/totals": [ { "field": "kills", "sum": 1500, "n": 100, "avg": 15.0, }, { "field": "deaths", "sum": 800, "n": 100, "avg": 8.0, }, { "field": "assists", "sum": 2000, "n": 100, "avg": 20.0, }, ], # Player rankings "players/123/rankings": [ { "hero_id": 1, "score": 80.5, "percent_rank": 0.95, }, { "hero_id": 2, "score": 75.2, "percent_rank": 0.92, }, ], # Player wordcloud "players/123/wordcloud": { "my_word_counts": { "gg": 100, "wp": 80, "noob": 50, "thanks": 30, }, "all_word_counts": { "gg": 200, "wp": 150, "noob": 100, "thanks": 60, }, }, } def get_mock_response(endpoint: str, params: Optional[Dict[str, Any]] = None) -> Dict[str, Any]: """Get a mock response for the given API endpoint.""" # Handle query parameters in the endpoint if params and "q" in params: combined_endpoint = f"{endpoint}?q={params['q']}" if combined_endpoint in MOCK_RESPONSES: return MOCK_RESPONSES[combined_endpoint] # Try to find a direct match for the endpoint if endpoint in MOCK_RESPONSES: return MOCK_RESPONSES[endpoint] # Return an error response if endpoint not found return {"error": f"Mock endpoint not found: {endpoint}"}