Files
strava-mcp-server/tests/unit/test_map.py
T
matthias badc2f870e
CI/CD Pipeline / Lint & Check (push) Successful in 11s
CI/CD Pipeline / Publish to PyPI (push) Successful in 13s
CI/CD Pipeline / Build & Push Docker Image (push) Successful in 1m32s
feat(map): add start (🟢) and finish (🏁) route markers
2026-05-30 13:20:17 +02:00

97 lines
2.7 KiB
Python

from unittest.mock import AsyncMock, MagicMock
import pytest
from mcp.server.fastmcp import Context
from strava_mcp_server.tools.activities import register
class MockMCP:
def __init__(self):
self.tools = {}
def tool(self):
def decorator(func):
self.tools[func.__name__] = func
return func
return decorator
@pytest.mark.asyncio
async def test_get_activity_map_success():
mcp = MockMCP()
strava = MagicMock()
# Mock detailed activity with a valid polyline
strava.get_activity = AsyncMock(
return_value={
"name": "Evening Ride",
"map": {"polyline": "a~l~FqzbwOq}@it@..."},
"sport_type": "Ride",
}
)
strava.get_activity_streams = AsyncMock(
return_value={
"altitude": {"data": [100.0, 101.0, 102.0]},
"distance": {"data": [0.0, 100.0, 200.0]},
"latlng": {"data": [[47.1, 9.1], [47.2, 9.2], [47.3, 9.3]]},
}
)
ctx = AsyncMock(spec=Context)
# Register tools
register(mcp, strava)
# Retrieve and call get_activity_map tool
get_activity_map = mcp.tools["get_activity_map"]
result = await get_activity_map(ctx, 12345)
assert len(result) == 2
# First block is the HTML embedded resource
assert result[0].type == "resource"
assert result[0].resource.mimeType == "text/html"
assert "internal://activities/12345/map.html" in str(result[0].resource.uri)
html_text = result[0].resource.text
assert "<!DOCTYPE html>" in html_text
assert "a~l~FqzbwOq}@it@..." in html_text
assert "unpkg.com/leaflet" in html_text
assert "latlngData" in html_text
assert "[47.1, 9.1]" in html_text
assert 'sportEmoji = "🚴"' in html_text
assert "L.control.layers" in html_text
assert "satellite" in html_text
assert "🟢" in html_text
assert "🏁" in html_text
# Second block is the internal resource
assert result[1].type == "resource"
assert "internal://activities/12345/map" in str(result[1].resource.uri)
@pytest.mark.asyncio
async def test_get_activity_map_no_polyline():
mcp = MockMCP()
strava = MagicMock()
# Mock activity without GPS map info
strava.get_activity = AsyncMock(
return_value={
"name": "Indoor Trainer",
"map": {"polyline": None, "summary_polyline": None},
}
)
ctx = AsyncMock(spec=Context)
# Register tools
register(mcp, strava)
# Retrieve and call get_activity_map tool
get_activity_map = mcp.tools["get_activity_map"]
result = await get_activity_map(ctx, 67890)
assert len(result) == 1
assert result[0].type == "text"
assert "⚠️ Keine GPS-Routen-Daten" in result[0].text