fix(mcp): Move all imports to the top of modules
This commit is contained in:
@@ -17,6 +17,7 @@ Architecture:
|
||||
MCP Client → Keycloak DCR → Keycloak OAuth → MCP Server → Nextcloud APIs
|
||||
"""
|
||||
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import secrets
|
||||
@@ -623,7 +624,6 @@ async def test_keycloak_dcr_architecture():
|
||||
}
|
||||
|
||||
logger.info("Keycloak DCR Architecture:")
|
||||
import json
|
||||
|
||||
logger.info(json.dumps(architecture, indent=2))
|
||||
|
||||
|
||||
@@ -11,13 +11,15 @@ Note: Tests use JWT OAuth tokens because scopes are embedded in the token payloa
|
||||
enabling efficient scope-based tool filtering without additional API calls.
|
||||
"""
|
||||
|
||||
import logging
|
||||
|
||||
import httpx
|
||||
import pytest
|
||||
|
||||
|
||||
@pytest.mark.integration
|
||||
async def test_prm_endpoint():
|
||||
"""Test that the Protected Resource Metadata endpoint returns correct data."""
|
||||
import httpx
|
||||
|
||||
# Test the PRM endpoint directly (RFC 9728 - path includes /mcp resource)
|
||||
async with httpx.AsyncClient() as client:
|
||||
@@ -60,7 +62,6 @@ async def test_basicauth_shows_all_tools(nc_mcp_client):
|
||||
@pytest.mark.integration
|
||||
async def test_read_only_token_filters_write_tools(nc_mcp_oauth_client_read_only):
|
||||
"""Test that a token with only read scopes filters out write tools."""
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -109,7 +110,6 @@ async def test_read_only_token_filters_write_tools(nc_mcp_oauth_client_read_only
|
||||
@pytest.mark.integration
|
||||
async def test_write_only_token_filters_read_tools(nc_mcp_oauth_client_write_only):
|
||||
"""Test that a token with only write scopes filters out read tools."""
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -158,7 +158,6 @@ async def test_write_only_token_filters_read_tools(nc_mcp_oauth_client_write_onl
|
||||
@pytest.mark.integration
|
||||
async def test_full_access_token_shows_all_tools(nc_mcp_oauth_client_full_access):
|
||||
"""Test that a token with both read and write scopes scopes can see all tools."""
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -402,7 +401,6 @@ async def test_jwt_with_no_custom_scopes_returns_zero_tools(
|
||||
- OAuth provisioning tools (requiring only 'openid') remain visible
|
||||
so users can provision Nextcloud access after authentication
|
||||
"""
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -442,7 +440,6 @@ async def test_jwt_consent_scenarios_read_only(nc_mcp_oauth_client_read_only):
|
||||
Simulates user granting only read permission during OAuth consent.
|
||||
Expected: Should see read tools but not write tools.
|
||||
"""
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -480,7 +477,6 @@ async def test_jwt_consent_scenarios_write_only(nc_mcp_oauth_client_write_only):
|
||||
Simulates user granting only write permission during OAuth consent.
|
||||
Expected: Should see write tools but not read-only tools.
|
||||
"""
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -518,7 +514,6 @@ async def test_jwt_consent_scenarios_full_access(nc_mcp_oauth_client_full_access
|
||||
Simulates user granting both permissions during OAuth consent.
|
||||
Expected: Should see all 90+ tools (both read and write).
|
||||
"""
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@@ -6,10 +6,12 @@ Tests the critical token exchange pattern that separates:
|
||||
"""
|
||||
|
||||
import os
|
||||
import tempfile
|
||||
from unittest.mock import AsyncMock, MagicMock, patch
|
||||
|
||||
import jwt
|
||||
import pytest
|
||||
from cryptography.fernet import Fernet
|
||||
|
||||
from nextcloud_mcp_server.auth.storage import RefreshTokenStorage
|
||||
from nextcloud_mcp_server.auth.token_broker import TokenBrokerService
|
||||
@@ -21,9 +23,6 @@ pytestmark = pytest.mark.unit
|
||||
@pytest.fixture
|
||||
async def token_storage():
|
||||
"""Create test token storage."""
|
||||
import tempfile
|
||||
|
||||
from cryptography.fernet import Fernet
|
||||
|
||||
# Generate valid Fernet key
|
||||
encryption_key = Fernet.generate_key()
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
"""Integration tests for Calendar VTODO (task) MCP tools."""
|
||||
|
||||
import json
|
||||
import logging
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
@@ -41,7 +42,6 @@ async def test_mcp_todo_complete_workflow(
|
||||
|
||||
# Extract UID from the result
|
||||
result_data = create_result.content[0].text
|
||||
import json
|
||||
|
||||
result_json = json.loads(result_data)
|
||||
todo_uid = result_json["uid"]
|
||||
@@ -156,7 +156,6 @@ async def test_mcp_list_todos_with_filters(
|
||||
{"calendar_name": calendar_name, "status": "NEEDS-ACTION"},
|
||||
)
|
||||
assert result.isError is False
|
||||
import json
|
||||
|
||||
data = json.loads(result.content[0].text)
|
||||
needs_action_todos = [t for t in data["todos"] if t["uid"] in created_uids]
|
||||
@@ -253,8 +252,6 @@ async def test_mcp_search_todos_across_calendars(
|
||||
)
|
||||
assert search_result.isError is False
|
||||
|
||||
import json
|
||||
|
||||
data = json.loads(search_result.content[0].text)
|
||||
assert "todos" in data
|
||||
|
||||
@@ -388,8 +385,6 @@ async def test_mcp_todo_with_dates(
|
||||
)
|
||||
assert create_result.isError is False
|
||||
|
||||
import json
|
||||
|
||||
result_data = json.loads(create_result.content[0].text)
|
||||
todo_uid = result_data["uid"]
|
||||
|
||||
@@ -432,8 +427,6 @@ async def test_mcp_todo_categories(
|
||||
)
|
||||
assert create_result.isError is False
|
||||
|
||||
import json
|
||||
|
||||
result_data = json.loads(create_result.content[0].text)
|
||||
todo_uid = result_data["uid"]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user