Skip to main content
Glama

Jentic

Official
by jentic
test_api_hub.py6.04 kB
from typing import Any, List import pytest from jentic.lib.agent_runtime.api_hub import JenticAPIClient # Assuming models are accessible via the path below # Split imports to potentially resolve import errors from jentic.lib.models import AssociatedFiles, FileEntry, FileId, WorkflowEntry # Minimal mock models for testing class MockAssociatedFiles(AssociatedFiles): arazzo: List[FileId] = [] # Use FileId open_api: List[FileId] = [] # Use FileId class MockFileEntry(FileEntry): pass class MockWorkflowEntry(WorkflowEntry): # Override fields that expect complex types if not needed directly api_references: List[Any] = [] # Keep it simple for this test files: MockAssociatedFiles = MockAssociatedFiles() # Use updated mock with defaults @pytest.fixture def api_client() -> JenticAPIClient: """Fixture to create a JenticAPIClient instance for testing.""" # No need for real URLs or API keys for testing this method return JenticAPIClient() # --- Test Cases --- # def test_build_source_descriptions_happy_path(api_client): """Test URL-based matching of Arazzo OpenAPI sources to OpenAPI files.""" workflow_entry = MockWorkflowEntry( workflow_id="wf1", workflow_uuid="uuid1", name="Test Workflow", files=MockAssociatedFiles(open_api=[FileId(id="file1_id"), FileId(id="file2_id")]), api_references=[], ) # Content for the first available file (file1_id) content1 = {"openapi": "3.0", "info": {"title": "API One - First File"}} # Content for the second file (file2_id) content2 = {"openapi": "3.0", "info": {"title": "API Two - Second File"}} all_openapi_files = { "file1_id": MockFileEntry( id="file1_id", type="open_api", filename="api_one.json", content=content1, source_path="./specs/api_one.json", ), "file2_id": MockFileEntry( id="file2_id", type="open_api", filename="api_two.yaml", content=content2, source_path="./specs/api_two.yaml", ), } # Sources with URLs that match the filenames first_source_name = "ApiOneSourceFirst" second_source_name = "ApiTwoSourceSecond" arazzo_doc = { "sourceDescriptions": [ {"name": first_source_name, "url": "./specs/api_one.json", "type": "openapi"}, {"name": second_source_name, "url": "./specs/api_two.yaml", "type": "openapi"}, ] } result = api_client._build_source_descriptions( workflow_entry=workflow_entry, all_openapi_files=all_openapi_files, arazzo_doc=arazzo_doc, ) # Each source should map to the file with matching filename in the URL assert len(result) == 2 assert first_source_name in result assert second_source_name in result assert result[first_source_name] == content1 assert result[second_source_name] == content2 def test_build_source_descriptions_no_arazzo_sources(api_client): """Test when Arazzo doc has no sourceDescriptions. Should return empty dict.""" workflow_entry = MockWorkflowEntry( workflow_id="wf1", workflow_uuid="uuid1", name="Test", files=MockAssociatedFiles(open_api=[FileId(id="file1_id")]), ) all_openapi_files = { "file1_id": MockFileEntry(id="file1_id", type="open_api", filename="./api.json", content={}) } arazzo_doc = {} # No sourceDescriptions result = api_client._build_source_descriptions(workflow_entry, all_openapi_files, arazzo_doc) assert result == {} def test_build_source_descriptions_empty_arazzo_sources(api_client): """Test when Arazzo doc has empty sourceDescriptions list. Should return empty dict.""" workflow_entry = MockWorkflowEntry( workflow_id="wf1", workflow_uuid="uuid1", name="Test", files=MockAssociatedFiles(open_api=[FileId(id="file1_id")]), ) all_openapi_files = { "file1_id": MockFileEntry(id="file1_id", type="open_api", filename="./api.json", content={}) } arazzo_doc = {"sourceDescriptions": []} result = api_client._build_source_descriptions(workflow_entry, all_openapi_files, arazzo_doc) assert result == {} def test_build_source_descriptions_missing_file_in_response(api_client): """Test when there's no URL match but a default content is available. Should use the default content (first available file content) as fallback. """ # Workflow references 'missing_id' first, then 'file2_id' workflow_entry = MockWorkflowEntry( workflow_id="wf1", workflow_uuid="uuid1", name="Test", # The actual file IDs listed here ('missing_id', 'file2_id') are less critical # than what's in `all_openapi_files` for this specific test of matching logic. files=MockAssociatedFiles(open_api=[FileId(id="file2_id")]), ) # Only the second file's content is available in the response content2 = {"info": "API Two - Content"} all_openapi_files = { "file2_id": MockFileEntry( id="file2_id", type="open_api", filename="api_two.json", content=content2, source_path="./actual_path/api_two.json", ) # 'missing_id' is not present here, which is fine for this test's purpose. } # Arazzo source with URL that doesn't match any source_path arazzo_source_name = "ApiSourceNoMatch" arazzo_doc = { "sourceDescriptions": [ {"name": arazzo_source_name, "url": "./specs/no_match.json", "type": "openapi"} ] } result = api_client._build_source_descriptions( workflow_entry=workflow_entry, all_openapi_files=all_openapi_files, arazzo_doc=arazzo_doc, ) # With source_path matching, if no exact match is found, the source is not included. # The previous fallback logic is removed. assert len(result) == 0 assert arazzo_source_name not in result

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/jentic/jentic-tools'

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