Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion assemblymcp/initialization.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
# This API returns the list of all available APIs.
SERVICE_LIST_API_ID = "OPENSRVAPI"

# Bundled specs file path (can be patched in tests)
BUNDLED_SPECS_FILE = Path(__file__).parent / "specs" / "all_apis.json"


async def ensure_master_list(client: AssemblyAPIClient) -> None:
"""
Expand All @@ -33,7 +36,7 @@ async def ensure_master_list(client: AssemblyAPIClient) -> None:
return

# 2. Try to copy from bundled specs (AssemblyMCP/assemblymcp/specs/all_apis.json)
bundled_file = Path(__file__).parent / "specs" / "all_apis.json"
bundled_file = BUNDLED_SPECS_FILE
if bundled_file.exists():
logger.info(f"Copying bundled master list from {bundled_file} to {master_file}")
shutil.copy(bundled_file, master_file)
Expand Down
37 changes: 25 additions & 12 deletions tests/test_fixes.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import json
from unittest.mock import AsyncMock, MagicMock
from unittest.mock import AsyncMock, MagicMock, patch

import pytest
from assembly_client.api import AssemblyAPIClient

from assemblymcp.initialization import ensure_master_list
from assemblymcp.initialization import BUNDLED_SPECS_FILE, ensure_master_list
from assemblymcp.services import BillService, MemberService


Expand All @@ -21,12 +21,27 @@ def mock_client(tmp_path):


@pytest.mark.asyncio
async def test_ensure_master_list_downloads_if_missing(mock_client):
"""Test that ensure_master_list downloads the master list if it doesn't exist."""
async def test_ensure_master_list_copies_bundled_if_missing(mock_client):
"""Test that ensure_master_list copies the bundled file when cache is absent."""
master_file = mock_client.spec_parser.cache_dir / "all_apis.json"
assert not master_file.exists()

await ensure_master_list(mock_client)

# Verify file was created from bundled specs (exact content match)
assert master_file.exists()
assert master_file.read_text(encoding="utf-8") == BUNDLED_SPECS_FILE.read_text(encoding="utf-8")

# Bundled file was used — no API call needed
mock_client.client.get.assert_not_called()


@pytest.mark.asyncio
async def test_ensure_master_list_downloads_if_bundled_also_missing(mock_client, tmp_path):
"""Test that ensure_master_list falls back to API download when bundled file is absent."""
master_file = mock_client.spec_parser.cache_dir / "all_apis.json"
assert not master_file.exists()

# Mock API response
mock_response = MagicMock()
mock_response.json.return_value = {
"OPENSRVAPI": [
Expand All @@ -36,20 +51,18 @@ async def test_ensure_master_list_downloads_if_missing(mock_client):
}
mock_client.client.get.return_value = mock_response

await ensure_master_list(mock_client)
# Patch bundled file path to a non-existent location to force API download
with patch("assemblymcp.initialization.BUNDLED_SPECS_FILE", tmp_path / "no_bundled.json"):
await ensure_master_list(mock_client)

# Verify file created
assert master_file.exists()

# Verify content
with open(master_file) as f:
with open(master_file, encoding="utf-8") as f:
data = json.load(f)
assert "OPENSRVAPI" in data
assert data["OPENSRVAPI"][1]["row"][0]["INF_ID"] == "TEST_ID"

# Verify API call
mock_client.client.get.assert_called_once()
args, kwargs = mock_client.client.get.call_args
args, _ = mock_client.client.get.call_args
assert "OPENSRVAPI" in args[0]


Expand Down
Loading