from __future__ import annotations
import asyncio
from types import SimpleNamespace
from typing import Any, cast
import pytest
from schwab.client import AsyncClient
from schwab_mcp.approvals import ApprovalDecision, ApprovalManager, ApprovalRequest
from schwab_mcp.context import SchwabContext, SchwabServerContext
class DummyApprovalManager(ApprovalManager):
async def require(self, request: ApprovalRequest) -> ApprovalDecision: # noqa: ARG002
return ApprovalDecision.APPROVED
def make_ctx(client: Any) -> SchwabContext:
lifespan_context = SchwabServerContext(
client=cast(AsyncClient, client),
approval_manager=DummyApprovalManager(),
)
request_context = SimpleNamespace(lifespan_context=lifespan_context)
return SchwabContext.model_construct(
_request_context=cast(Any, request_context),
_fastmcp=None,
)
def run(coro: Any) -> Any:
return asyncio.run(coro)
@pytest.fixture
def ctx_factory():
return make_ctx
@pytest.fixture
def fake_call_capture():
captured: dict[str, Any] = {}
async def fake_call(func, *args, **kwargs):
captured["func"] = func
captured["args"] = args
captured["kwargs"] = kwargs
return "ok"
return captured, fake_call