Files
nadlan-mcp/tests/test_mcp_tools_fast.py
T
Nitzan Pomerantz e4aa6487ff Ruff fixes
2025-10-30 22:24:40 +02:00

162 lines
5.5 KiB
Python

"""
Fast unit tests for MCP tools using cached fixtures.
These tests use pre-recorded API responses to run quickly (~1s)
without hitting the real Govmap API.
For full E2E tests with real API calls, see tests/e2e/test_mcp_tools.py
"""
import json
from pathlib import Path
from unittest.mock import patch
import pytest
from nadlan_mcp.fastmcp_server import (
autocomplete_address,
get_deals_by_radius,
get_neighborhood_deals,
get_street_deals,
)
from nadlan_mcp.govmap.models import AutocompleteResponse, AutocompleteResult, Deal
# Load fixtures
FIXTURES_DIR = Path(__file__).parent / "fixtures"
def load_fixture(filename):
"""Load a JSON fixture file."""
with open(FIXTURES_DIR / filename, encoding="utf-8") as f:
return json.load(f)
@pytest.fixture
def mock_autocomplete_data():
"""Cached autocomplete response."""
data = load_fixture("autocomplete_response.json")
results = [AutocompleteResult.model_validate(r) for r in data]
return AutocompleteResponse(results=results, resultsCount=len(results))
@pytest.fixture
def mock_street_deals_data():
"""Cached street deals response."""
data = load_fixture("street_deals.json")
return [Deal.model_validate(d) for d in data]
@pytest.fixture
def mock_neighborhood_deals_data():
"""Cached neighborhood deals response."""
data = load_fixture("neighborhood_deals.json")
return [Deal.model_validate(d) for d in data]
@pytest.fixture
def mock_polygon_metadata_data():
"""Cached polygon metadata response."""
return load_fixture("polygon_metadata.json")
class TestMCPToolsFast:
"""Fast unit tests for MCP tools using mocked data."""
@patch("nadlan_mcp.fastmcp_server.client")
def test_autocomplete_address_fast(self, mock_client, mock_autocomplete_data):
"""Test autocomplete with cached data."""
mock_client.autocomplete_address.return_value = mock_autocomplete_data
result = autocomplete_address("חולון סוקולוב")
data = json.loads(result)
assert isinstance(data, list)
assert len(data) > 0
assert "text" in data[0]
assert "coordinates" in data[0]
@patch("nadlan_mcp.fastmcp_server.client")
def test_get_street_deals_fast(self, mock_client, mock_street_deals_data):
"""Test street deals with cached data."""
mock_client.get_street_deals.return_value = mock_street_deals_data
result = get_street_deals("52385050", limit=100, deal_type=2)
data = json.loads(result)
assert "total_deals" in data
assert data["total_deals"] == len(mock_street_deals_data)
assert "deals" in data
assert len(data["deals"]) > 0
# Verify deal structure
deal = data["deals"][0]
assert "deal_amount" in deal
assert "deal_date" in deal
@patch("nadlan_mcp.fastmcp_server.client")
def test_get_neighborhood_deals_fast(self, mock_client, mock_neighborhood_deals_data):
"""Test neighborhood deals with cached data."""
mock_client.get_neighborhood_deals.return_value = mock_neighborhood_deals_data
result = get_neighborhood_deals("52385050", limit=100, deal_type=2)
data = json.loads(result)
assert "total_deals" in data
assert data["total_deals"] == len(mock_neighborhood_deals_data)
assert "deals" in data
@patch("nadlan_mcp.fastmcp_server.client")
def test_get_deals_by_radius_fast(self, mock_client, mock_polygon_metadata_data):
"""Test deals by radius with cached data."""
mock_client.get_deals_by_radius.return_value = mock_polygon_metadata_data
result = get_deals_by_radius(37.6629, 38.7093, radius_meters=500)
data = json.loads(result)
assert "total_polygons" in data
assert data["total_polygons"] == len(mock_polygon_metadata_data)
assert "polygons" in data
@pytest.mark.skip(reason="Complex workflow with statistics - tested in E2E suite")
@patch("nadlan_mcp.fastmcp_server.client")
def test_find_recent_deals_fast(
self,
mock_client,
mock_street_deals_data,
mock_neighborhood_deals_data,
mock_polygon_metadata_data,
mock_autocomplete_data,
):
"""Test find_recent_deals with fully mocked workflow.
NOTE: This test is skipped because find_recent_deals_for_address has complex
statistics calculations that require specific data structure. Use E2E tests
in tests/e2e/test_mcp_tools.py for full integration testing.
"""
pass
@patch("nadlan_mcp.fastmcp_server.client")
def test_no_deals_found(self, mock_client):
"""Test handling when no deals are found."""
mock_client.get_street_deals.return_value = []
result = get_street_deals("999999", limit=100, deal_type=2)
# Should return a message string when no deals found
assert isinstance(result, str)
assert "No" in result or "found" in result.lower()
@patch("nadlan_mcp.fastmcp_server.client")
def test_deal_type_filtering(self, mock_client, mock_street_deals_data):
"""Test that deal_type parameter is passed correctly."""
mock_client.get_street_deals.return_value = mock_street_deals_data
# Test with deal_type=1 (first hand)
result = get_street_deals("52385050", limit=100, deal_type=1)
data = json.loads(result)
# Verify client was called with correct deal_type
mock_client.get_street_deals.assert_called_once_with("52385050", 100, deal_type=1)
assert "deal_type" in data
assert data["deal_type"] == 1