Skip to content

Commit f24eb55

Browse files
committed
Type hints for tests/unit/app/endpoints/test_tools.py
1 parent 013f200 commit f24eb55

1 file changed

Lines changed: 44 additions & 24 deletions

File tree

tests/unit/app/endpoints/test_tools.py

Lines changed: 44 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
"""Unit tests for tools endpoint."""
22

33
import pytest
4+
from pytest_mock import MockerFixture, MockType
45
from fastapi import HTTPException
56

67
from llama_stack_client import APIConnectionError
78

9+
from authentication.interface import AuthTuple
10+
811
# Import the function directly to bypass decorators
912
from app.endpoints import tools
1013
from models.responses import ToolsResponse
@@ -17,11 +20,11 @@
1720
)
1821

1922
# Shared mock auth tuple with 4 fields as expected by the application
20-
MOCK_AUTH = ("mock_user_id", "mock_username", False, "mock_token")
23+
MOCK_AUTH: AuthTuple = ("mock_user_id", "mock_username", False, "mock_token")
2124

2225

2326
@pytest.fixture
24-
def mock_configuration():
27+
def mock_configuration() -> Configuration:
2528
"""Create a mock configuration with MCP servers."""
2629
return Configuration(
2730
name="test",
@@ -44,7 +47,7 @@ def mock_configuration():
4447

4548

4649
@pytest.fixture
47-
def mock_tools_response(mocker):
50+
def mock_tools_response(mocker: MockerFixture) -> list[MockType]:
4851
"""Create mock tools response from LlamaStack client."""
4952
# Create mock tools that behave like dict when converted
5053
tool1 = mocker.Mock()
@@ -102,8 +105,10 @@ def mock_tools_response(mocker):
102105

103106
@pytest.mark.asyncio
104107
async def test_tools_endpoint_success(
105-
mocker, mock_configuration, mock_tools_response
106-
): # pylint: disable=redefined-outer-name
108+
mocker: MockerFixture,
109+
mock_configuration: Configuration, # pylint: disable=redefined-outer-name
110+
mock_tools_response: list[MockType], # pylint: disable=redefined-outer-name
111+
) -> None:
107112
"""Test successful tools endpoint response."""
108113
# Mock configuration
109114
mocker.patch("app.endpoints.tools.configuration", mock_configuration)
@@ -161,7 +166,7 @@ async def test_tools_endpoint_success(
161166

162167

163168
@pytest.mark.asyncio
164-
async def test_tools_endpoint_no_mcp_servers(mocker):
169+
async def test_tools_endpoint_no_mcp_servers(mocker: MockerFixture) -> None:
165170
"""Test tools endpoint with no MCP servers configured."""
166171
# Mock configuration with no MCP servers
167172
mock_config = Configuration(
@@ -198,8 +203,9 @@ async def test_tools_endpoint_no_mcp_servers(mocker):
198203

199204
@pytest.mark.asyncio
200205
async def test_tools_endpoint_api_connection_error(
201-
mocker, mock_configuration
202-
): # pylint: disable=redefined-outer-name
206+
mocker: MockerFixture, # pylint: disable=redefined-outer-name
207+
mock_configuration: Configuration, # pylint: disable=redefined-outer-name
208+
) -> None:
203209
"""Test tools endpoint with API connection error from individual servers."""
204210
# Mock configuration
205211
mocker.patch("app.endpoints.tools.configuration", mock_configuration)
@@ -237,8 +243,10 @@ async def test_tools_endpoint_api_connection_error(
237243

238244
@pytest.mark.asyncio
239245
async def test_tools_endpoint_partial_failure( # pylint: disable=redefined-outer-name
240-
mocker, mock_configuration, mock_tools_response
241-
):
246+
mocker: MockerFixture,
247+
mock_configuration: Configuration,
248+
mock_tools_response: list[MockType],
249+
) -> None:
242250
"""Test tools endpoint with one MCP server failing."""
243251
# Mock configuration
244252
mocker.patch("app.endpoints.tools.configuration", mock_configuration)
@@ -283,8 +291,9 @@ async def test_tools_endpoint_partial_failure( # pylint: disable=redefined-oute
283291

284292
@pytest.mark.asyncio
285293
async def test_tools_endpoint_builtin_toolgroup(
286-
mocker, mock_configuration
287-
): # pylint: disable=redefined-outer-name
294+
mocker: MockerFixture,
295+
mock_configuration: Configuration, # pylint: disable=redefined-outer-name
296+
) -> None:
288297
"""Test tools endpoint with built-in toolgroups."""
289298
# Mock configuration
290299
mocker.patch("app.endpoints.tools.configuration", mock_configuration)
@@ -336,7 +345,7 @@ async def test_tools_endpoint_builtin_toolgroup(
336345

337346

338347
@pytest.mark.asyncio
339-
async def test_tools_endpoint_mixed_toolgroups(mocker):
348+
async def test_tools_endpoint_mixed_toolgroups(mocker: MockerFixture) -> None:
340349
"""Test tools endpoint with both MCP and built-in toolgroups."""
341350
# Mock configuration with MCP servers
342351
mock_config = Configuration(
@@ -425,8 +434,9 @@ async def test_tools_endpoint_mixed_toolgroups(mocker):
425434

426435
@pytest.mark.asyncio
427436
async def test_tools_endpoint_value_attribute_error(
428-
mocker, mock_configuration
429-
): # pylint: disable=redefined-outer-name
437+
mocker: MockerFixture,
438+
mock_configuration: Configuration, # pylint: disable=redefined-outer-name
439+
) -> None:
430440
"""Test tools endpoint with ValueError/AttributeError in toolgroups.list."""
431441
# Mock configuration
432442
mocker.patch("app.endpoints.tools.configuration", mock_configuration)
@@ -456,8 +466,8 @@ async def test_tools_endpoint_value_attribute_error(
456466

457467
@pytest.mark.asyncio
458468
async def test_tools_endpoint_apiconnection_error_toolgroups( # pylint: disable=redefined-outer-name
459-
mocker, mock_configuration
460-
):
469+
mocker: MockerFixture, mock_configuration: Configuration
470+
) -> None:
461471
"""Test tools endpoint with APIConnectionError in toolgroups.list."""
462472
# Mock configuration
463473
mocker.patch("app.endpoints.tools.configuration", mock_configuration)
@@ -483,13 +493,16 @@ async def test_tools_endpoint_apiconnection_error_toolgroups( # pylint: disable
483493
await tools.tools_endpoint_handler.__wrapped__(mock_request, mock_auth)
484494

485495
assert exc_info.value.status_code == 500
486-
assert "Unable to connect to Llama Stack" in exc_info.value.detail["response"]
496+
497+
detail = exc_info.value.detail
498+
assert isinstance(detail, dict)
499+
assert "Unable to connect to Llama Stack" in detail["response"]
487500

488501

489502
@pytest.mark.asyncio
490503
async def test_tools_endpoint_client_holder_apiconnection_error( # pylint: disable=redefined-outer-name
491-
mocker, mock_configuration
492-
):
504+
mocker: MockerFixture, mock_configuration: Configuration
505+
) -> None:
493506
"""Test tools endpoint with APIConnectionError in client holder."""
494507
# Mock configuration
495508
mocker.patch("app.endpoints.tools.configuration", mock_configuration)
@@ -511,13 +524,17 @@ async def test_tools_endpoint_client_holder_apiconnection_error( # pylint: disa
511524
await tools.tools_endpoint_handler.__wrapped__(mock_request, mock_auth)
512525

513526
assert exc_info.value.status_code == 500
514-
assert "Unable to connect to Llama Stack" in exc_info.value.detail["response"]
527+
528+
detail = exc_info.value.detail
529+
assert isinstance(detail, dict)
530+
assert "Unable to connect to Llama Stack" in detail["response"]
515531

516532

517533
@pytest.mark.asyncio
518534
async def test_tools_endpoint_general_exception(
519-
mocker, mock_configuration
520-
): # pylint: disable=redefined-outer-name
535+
mocker: MockerFixture,
536+
mock_configuration: Configuration, # pylint: disable=redefined-outer-name
537+
) -> None:
521538
"""Test tools endpoint with general exception."""
522539
# Mock configuration
523540
mocker.patch("app.endpoints.tools.configuration", mock_configuration)
@@ -540,4 +557,7 @@ async def test_tools_endpoint_general_exception(
540557
await tools.tools_endpoint_handler.__wrapped__(mock_request, mock_auth)
541558

542559
assert exc_info.value.status_code == 500
543-
assert "Unable to retrieve list of tools" in exc_info.value.detail["response"]
560+
561+
detail = exc_info.value.detail
562+
assert isinstance(detail, dict)
563+
assert "Unable to retrieve list of tools" in detail["response"]

0 commit comments

Comments
 (0)