Skip to main content
Glama
test_resources.py15.7 kB
"""Integration tests for config MCP direct imports.""" # Test imports from domain-specific config modules from config.mcp.resources import MCP_RESOURCES from config.mcp.tools import TOOL_NAMES class TestMcpResources: """Test MCP_RESOURCES dictionary structure and contents.""" def test_resources_is_dict(self) -> None: """Test MCP_RESOURCES is a dictionary.""" assert isinstance(MCP_RESOURCES, dict) assert len(MCP_RESOURCES) > 0 def test_show_resources_exist(self) -> None: """Test show-related resources are present.""" show_resources = [ "shows_trending", "shows_popular", "shows_favorited", "shows_played", "shows_watched", ] for resource in show_resources: assert resource in MCP_RESOURCES assert isinstance(MCP_RESOURCES[resource], str) def test_movie_resources_exist(self) -> None: """Test movie-related resources are present.""" movie_resources = [ "movies_trending", "movies_popular", "movies_favorited", "movies_played", "movies_watched", ] for resource in movie_resources: assert resource in MCP_RESOURCES assert isinstance(MCP_RESOURCES[resource], str) def test_user_resources_exist(self) -> None: """Test user-related resources are present.""" user_resources = [ "user_auth_status", "user_watched_shows", "user_watched_movies", ] for resource in user_resources: assert resource in MCP_RESOURCES assert isinstance(MCP_RESOURCES[resource], str) def test_comment_resources_not_exist(self) -> None: """Test comment-related resources are NOT present (they are tools, not resources).""" comment_resources = [ "comments_movie", "comments_show", "comments_season", "comments_episode", "comment", "comment_replies", ] for resource in comment_resources: assert resource not in MCP_RESOURCES, ( f"Comment {resource} should be a tool, not a resource" ) def test_rating_resources_not_exist(self) -> None: """Test rating resources are NOT present (they are tools, not resources).""" rating_resources = ["show_ratings", "movie_ratings"] for resource in rating_resources: assert resource not in MCP_RESOURCES, ( f"Rating {resource} should be a tool, not a resource" ) class TestResourceUriFormats: """Test MCP resource URI formats and structure.""" def test_all_resources_use_trakt_scheme(self) -> None: """Test all resource URIs use 'trakt://' scheme.""" for resource_key, resource_uri in MCP_RESOURCES.items(): assert resource_uri.startswith("trakt://"), ( f"Resource {resource_key} should start with 'trakt://'" ) def test_show_resource_uri_formats(self) -> None: """Test show resource URI formats.""" show_resources = [ "shows_trending", "shows_popular", "shows_favorited", "shows_played", "shows_watched", ] for resource in show_resources: uri = MCP_RESOURCES[resource] assert uri.startswith("trakt://shows/"), ( f"Show resource {resource} should start with 'trakt://shows/'" ) def test_movie_resource_uri_formats(self) -> None: """Test movie resource URI formats.""" movie_resources = [ "movies_trending", "movies_popular", "movies_favorited", "movies_played", "movies_watched", ] for resource in movie_resources: uri = MCP_RESOURCES[resource] assert uri.startswith("trakt://movies/"), ( f"Movie resource {resource} should start with 'trakt://movies/'" ) def test_user_resource_uri_formats(self) -> None: """Test user resource URI formats.""" user_resources = { "user_auth_status": "trakt://user/auth/status", "user_watched_shows": "trakt://user/watched/shows", "user_watched_movies": "trakt://user/watched/movies", } for resource_key, expected_uri in user_resources.items(): assert MCP_RESOURCES[resource_key] == expected_uri def test_comment_tools_not_in_resources(self) -> None: """Test comment tools are not mistakenly included in resources.""" comment_tools = [ "comments_movie", "comments_show", "comments_season", "comments_episode", "comment", "comment_replies", ] for tool in comment_tools: assert tool not in MCP_RESOURCES, ( f"Comment tool {tool} should not be in MCP_RESOURCES (it's a tool, not a resource)" ) def test_resources_only_contain_static_data(self) -> None: """Test MCP resources only contain static data endpoints (not parameterized tools).""" # Resources should be static data that doesn't require parameters # All current resources are static lists (trending, popular, etc.) for resource_key, resource_uri in MCP_RESOURCES.items(): # Resources should not contain parameter placeholders assert ":id" not in resource_uri, ( f"Resource {resource_key} contains parameter placeholder, should be a tool instead" ) assert ":season" not in resource_uri, ( f"Resource {resource_key} contains parameter placeholder, should be a tool instead" ) assert ":episode" not in resource_uri, ( f"Resource {resource_key} contains parameter placeholder, should be a tool instead" ) def test_uri_consistency_with_categories(self) -> None: """Test URI paths are consistent with resource categories.""" # Show resources should contain 'shows' in path show_keys = [k for k in MCP_RESOURCES if k.startswith("shows_")] for key in show_keys: assert "/shows/" in MCP_RESOURCES[key], ( f"Show resource {key} should contain '/shows/'" ) # Movie resources should contain 'movies' in path movie_keys = [k for k in MCP_RESOURCES if k.startswith("movies_")] for key in movie_keys: assert "/movies/" in MCP_RESOURCES[key], ( f"Movie resource {key} should contain '/movies/'" ) # User resources should contain 'user' in path user_keys = [k for k in MCP_RESOURCES if k.startswith("user_")] for key in user_keys: assert "/user/" in MCP_RESOURCES[key], ( f"User resource {key} should contain '/user/'" ) class TestToolNames: """Test TOOL_NAMES dictionary structure and contents.""" def test_tool_names_is_dict(self) -> None: """Test TOOL_NAMES is a dictionary.""" assert isinstance(TOOL_NAMES, dict) assert len(TOOL_NAMES) > 0 def test_show_tools_exist(self) -> None: """Test show-related tools are present.""" show_tools = [ "fetch_trending_shows", "fetch_popular_shows", "fetch_favorited_shows", "fetch_played_shows", "fetch_watched_shows", ] for tool in show_tools: assert tool in TOOL_NAMES assert isinstance(TOOL_NAMES[tool], str) def test_movie_tools_exist(self) -> None: """Test movie-related tools are present.""" movie_tools = [ "fetch_trending_movies", "fetch_popular_movies", "fetch_favorited_movies", "fetch_played_movies", "fetch_watched_movies", ] for tool in movie_tools: assert tool in TOOL_NAMES assert isinstance(TOOL_NAMES[tool], str) def test_auth_tools_exist(self) -> None: """Test authentication tools are present.""" auth_tools = [ "start_device_auth", "check_auth_status", "clear_auth", ] for tool in auth_tools: assert tool in TOOL_NAMES assert isinstance(TOOL_NAMES[tool], str) def test_user_tools_exist(self) -> None: """Test user-specific tools are present.""" user_tools = [ "fetch_user_watched_shows", "fetch_user_watched_movies", "checkin_to_show", ] for tool in user_tools: assert tool in TOOL_NAMES assert isinstance(TOOL_NAMES[tool], str) def test_comment_tools_exist(self) -> None: """Test comment tools are present.""" comment_tools = [ "fetch_movie_comments", "fetch_show_comments", "fetch_season_comments", "fetch_episode_comments", "fetch_comment", "fetch_comment_replies", ] for tool in comment_tools: assert tool in TOOL_NAMES assert isinstance(TOOL_NAMES[tool], str) def test_rating_tools_exist(self) -> None: """Test rating tools are present.""" rating_tools = [ "fetch_show_ratings", "fetch_movie_ratings", ] for tool in rating_tools: assert tool in TOOL_NAMES assert isinstance(TOOL_NAMES[tool], str) def test_search_tools_exist(self) -> None: """Test search tools are present.""" search_tools = [ "search_shows", "search_movies", ] for tool in search_tools: assert tool in TOOL_NAMES assert isinstance(TOOL_NAMES[tool], str) class TestToolNamingConsistency: """Test tool naming consistency and conventions.""" def test_tool_names_match_keys(self) -> None: """Test tool names match their dictionary keys.""" for key, value in TOOL_NAMES.items(): assert key == value, f"Tool name key {key} should match value {value}" def test_tool_naming_conventions(self) -> None: """Test tool names follow consistent naming conventions.""" for tool_name in TOOL_NAMES: # Should use lowercase and underscores assert tool_name.islower(), f"Tool name {tool_name} should be lowercase" assert " " not in tool_name, ( f"Tool name {tool_name} should not contain spaces" ) # Should not start or end with underscore assert not tool_name.startswith("_"), ( f"Tool name {tool_name} should not start with underscore" ) assert not tool_name.endswith("_"), ( f"Tool name {tool_name} should not end with underscore" ) def test_fetch_tools_start_with_fetch(self) -> None: """Test tools that fetch data start with 'fetch_'.""" fetch_tools = [k for k in TOOL_NAMES if "fetch" in k] for tool in fetch_tools: assert tool.startswith("fetch_"), ( f"Fetch tool {tool} should start with 'fetch_'" ) def test_tool_categories_consistency(self) -> None: """Test tool names are consistent within categories.""" # Show tools should contain 'shows' show_tools = [ k for k in TOOL_NAMES if "show" in k and not k.startswith("checkin") ] for tool in show_tools: assert "show" in tool, f"Show tool {tool} should contain 'show'" # Movie tools should contain 'movies' movie_tools = [k for k in TOOL_NAMES if "movie" in k] for tool in movie_tools: assert "movie" in tool, f"Movie tool {tool} should contain 'movie'" # Auth tools should contain 'auth' auth_tools = [k for k in TOOL_NAMES if "auth" in k] for tool in auth_tools: assert "auth" in tool, f"Auth tool {tool} should contain 'auth'" class TestResourcesIntegration: """Test integration aspects between resources and tools.""" def test_no_duplicate_resource_uris(self) -> None: """Test there are no duplicate resource URIs.""" uris = list(MCP_RESOURCES.values()) unique_uris = set(uris) # Most URIs should be unique (some aliases may exist) assert len(unique_uris) >= len(uris) * 0.9 # At least 90% should be unique def test_no_duplicate_tool_names(self) -> None: """Test there are no duplicate tool names.""" tool_names = list(TOOL_NAMES.values()) unique_names = set(tool_names) assert len(unique_names) == len(tool_names), "All tool names should be unique" def test_resource_tool_correlation(self) -> None: """Test that resources and tools have logical correlation.""" # For each show resource, there should be a corresponding tool show_resources = [k for k in MCP_RESOURCES if k.startswith("shows_")] show_tools = [k for k in TOOL_NAMES if "shows" in k and k.startswith("fetch_")] # Should have reasonable correlation (not necessarily 1:1) assert len(show_tools) >= len(show_resources) * 0.8, ( "Should have tools for most show resources" ) # Same for movies movie_resources = [k for k in MCP_RESOURCES if k.startswith("movies_")] movie_tools = [ k for k in TOOL_NAMES if "movies" in k and k.startswith("fetch_") ] assert len(movie_tools) >= len(movie_resources) * 0.8, ( "Should have tools for most movie resources" ) def test_all_values_are_strings(self) -> None: """Test all resource URIs and tool names are strings.""" for key, value in MCP_RESOURCES.items(): assert isinstance(value, str), ( f"Resource {key} URI should be string, got {type(value)}" ) for key, value in TOOL_NAMES.items(): assert isinstance(value, str), ( f"Tool {key} name should be string, got {type(value)}" ) def test_no_empty_values(self) -> None: """Test no resource URIs or tool names are empty.""" for key, value in MCP_RESOURCES.items(): assert value, f"Resource {key} URI should not be empty" for key, value in TOOL_NAMES.items(): assert value, f"Tool {key} name should not be empty" def test_mcp_config_matches_domain_modules(self) -> None: """Test that MCP configs from main config match domain-specific modules.""" # Import from domain-specific modules from config.mcp.resources import MCP_RESOURCES as MCP_RESOURCES_DOMAIN from config.mcp.tools import TOOL_NAMES as TOOL_NAMES_DOMAIN # Should be identical assert MCP_RESOURCES == MCP_RESOURCES_DOMAIN, ( "MCP_RESOURCES should match domain module" ) assert TOOL_NAMES == TOOL_NAMES_DOMAIN, "TOOL_NAMES should match domain module" # Verify individual items match for key, value in MCP_RESOURCES_DOMAIN.items(): assert key in MCP_RESOURCES, f"Resource {key} missing from main config" assert MCP_RESOURCES[key] == value, f"Resource {key} value mismatch" for key, value in TOOL_NAMES_DOMAIN.items(): assert key in TOOL_NAMES, f"Tool {key} missing from main config" assert TOOL_NAMES[key] == value, f"Tool {key} value mismatch"

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/wwiens/trakt_mcpserver'

If you have feedback or need assistance with the MCP directory API, please join our Discord server