2929from toolbox_core .tool import ToolboxTool
3030from toolbox_core .toolbox_transport import ToolboxTransport
3131from toolbox_core .utils import create_func_docstring , resolve_value
32+ from toolbox_core .tool import ToolboxTool
33+ from toolbox_core .toolbox_transport import ToolboxTransport
34+ from toolbox_core .utils import create_func_docstring , resolve_value
3235
3336TEST_BASE_URL = "http://toolbox.example.com"
3437HTTPS_BASE_URL = "https://toolbox.example.com"
@@ -113,7 +116,9 @@ def toolbox_tool(
113116) -> ToolboxTool :
114117 """Fixture for a ToolboxTool instance with common test setup."""
115118 transport = ToolboxTransport (TEST_BASE_URL , http_session )
119+ transport = ToolboxTransport (TEST_BASE_URL , http_session )
116120 return ToolboxTool (
121+ transport = transport ,
117122 transport = transport ,
118123 name = TEST_TOOL_NAME ,
119124 description = sample_tool_description ,
@@ -232,8 +237,10 @@ async def test_tool_creation_callable_and_run(
232237 with aioresponses () as m :
233238 m .post (invoke_url , status = 200 , payload = mock_server_response_body )
234239 transport = ToolboxTransport (base_url , http_session )
240+ transport = ToolboxTransport (base_url , http_session )
235241
236242 tool_instance = ToolboxTool (
243+ transport = transport ,
237244 transport = transport ,
238245 name = tool_name ,
239246 description = sample_tool_description ,
@@ -278,8 +285,10 @@ async def test_tool_run_with_pydantic_validation_error(
278285 with aioresponses () as m :
279286 m .post (invoke_url , status = 200 , payload = {"result" : "Should not be called" })
280287 transport = ToolboxTransport (base_url , http_session )
288+ transport = ToolboxTransport (base_url , http_session )
281289
282290 tool_instance = ToolboxTool (
291+ transport = transport ,
283292 transport = transport ,
284293 name = tool_name ,
285294 description = sample_tool_description ,
@@ -369,8 +378,10 @@ def test_tool_init_basic(http_session, sample_tool_params, sample_tool_descripti
369378 with catch_warnings (record = True ) as record :
370379 simplefilter ("always" )
371380 transport = ToolboxTransport (HTTPS_BASE_URL , http_session )
381+ transport = ToolboxTransport (HTTPS_BASE_URL , http_session )
372382
373383 tool_instance = ToolboxTool (
384+ transport = transport ,
374385 transport = transport ,
375386 name = TEST_TOOL_NAME ,
376387 description = sample_tool_description ,
@@ -399,7 +410,9 @@ def test_tool_init_with_client_headers(
399410):
400411 """Tests tool initialization *with* client headers."""
401412 transport = ToolboxTransport (HTTPS_BASE_URL , http_session )
413+ transport = ToolboxTransport (HTTPS_BASE_URL , http_session )
402414 tool_instance = ToolboxTool (
415+ transport = transport ,
403416 transport = transport ,
404417 name = TEST_TOOL_NAME ,
405418 description = sample_tool_description ,
@@ -423,7 +436,9 @@ def test_tool_add_auth_token_getters_conflict_with_existing_client_header(
423436 whose token name conflicts with an existing client header.
424437 """
425438 transport = ToolboxTransport (HTTPS_BASE_URL , http_session )
439+ transport = ToolboxTransport (HTTPS_BASE_URL , http_session )
426440 tool_instance = ToolboxTool (
441+ transport = transport ,
427442 transport = transport ,
428443 name = "tool_with_client_header" ,
429444 description = sample_tool_description ,
@@ -473,6 +488,21 @@ async def test_auth_token_overrides_client_header(
473488 "X-Another-Header" : "another-value" ,
474489 },
475490 )
491+ transport = ToolboxTransport (HTTPS_BASE_URL , http_session )
492+ tool_instance = ToolboxTool (
493+ transport = transport ,
494+ name = TEST_TOOL_NAME ,
495+ description = sample_tool_description ,
496+ params = sample_tool_params ,
497+ required_authn_params = {},
498+ required_authz_tokens = [],
499+ auth_service_token_getters = {"test-auth" : lambda : "value-from-auth-getter-123" },
500+ bound_params = {},
501+ client_headers = {
502+ "test-auth_token" : "value-from-client" ,
503+ "X-Another-Header" : "another-value" ,
504+ },
505+ )
476506 tool_name = TEST_TOOL_NAME
477507 base_url = HTTPS_BASE_URL
478508 invoke_url = f"{ base_url } /api/tool/{ tool_name } /invoke"
@@ -490,6 +520,7 @@ async def test_auth_token_overrides_client_header(
490520 method = "POST" ,
491521 json = input_args ,
492522 headers = {
523+ "test-auth_token" : "value-from-auth-getter-123" ,
493524 "test-auth_token" : "value-from-auth-getter-123" ,
494525 "X-Another-Header" : "another-value" ,
495526 },
@@ -507,7 +538,9 @@ def test_add_auth_token_getter_unused_token(
507538 an unused authentication service.
508539 """
509540 transport = ToolboxTransport (HTTPS_BASE_URL , http_session )
541+ transport = ToolboxTransport (HTTPS_BASE_URL , http_session )
510542 tool_instance = ToolboxTool (
543+ transport = transport ,
511544 transport = transport ,
512545 name = TEST_TOOL_NAME ,
513546 description = sample_tool_description ,
@@ -526,162 +559,3 @@ def test_add_auth_token_getter_unused_token(
526559 next (iter (unused_auth_getters )),
527560 unused_auth_getters [next (iter (unused_auth_getters ))],
528561 )
529-
530-
531- # --- Tests for Parameter Binding ---
532-
533-
534- @pytest .mark .asyncio
535- async def test_bind_param_success (
536- http_session : ClientSession ,
537- sample_tool_params : list [ParameterSchema ],
538- sample_tool_description : str ,
539- ):
540- """
541- Tests successfully binding a single parameter with a static value using bind_param.
542- """
543- transport = ToolboxTransport (HTTPS_BASE_URL , http_session )
544- original_tool = ToolboxTool (
545- transport = transport ,
546- name = TEST_TOOL_NAME ,
547- description = sample_tool_description ,
548- params = sample_tool_params ,
549- required_authn_params = {},
550- required_authz_tokens = [],
551- auth_service_token_getters = {},
552- bound_params = {},
553- client_headers = {},
554- )
555-
556- # Bind the 'count' parameter
557- bound_tool = original_tool .bind_param ("count" , 100 )
558-
559- # Assert immutability and changes
560- assert bound_tool is not original_tool
561- assert "count" not in bound_tool .__signature__ .parameters
562- assert "message" in bound_tool .__signature__ .parameters
563- assert "count" in original_tool .__signature__ .parameters
564- assert bound_tool ._bound_params == {"count" : 100 }
565- assert original_tool ._bound_params == {}
566-
567- # Test invocation of the new tool
568- invoke_url = f"{ HTTPS_BASE_URL } /api/tool/{ TEST_TOOL_NAME } /invoke"
569- with aioresponses () as m :
570- m .post (invoke_url , status = 200 , payload = {"result" : "Success" })
571- await bound_tool (message = "hello" )
572-
573- # Verify the payload includes both the argument and the bound parameter
574- expected_payload = {"message" : "hello" , "count" : 100 }
575- m .assert_called_once_with (
576- invoke_url , method = "POST" , json = expected_payload , headers = {}
577- )
578-
579-
580- @pytest .mark .asyncio
581- async def test_bind_params_success_with_callable (
582- http_session : ClientSession ,
583- sample_tool_params : list [ParameterSchema ],
584- sample_tool_description : str ,
585- ):
586- """
587- Tests successfully binding multiple parameters, including one with a callable.
588- """
589- transport = ToolboxTransport (HTTPS_BASE_URL , http_session )
590- tool = ToolboxTool (
591- transport = transport ,
592- name = TEST_TOOL_NAME ,
593- description = sample_tool_description ,
594- params = sample_tool_params ,
595- required_authn_params = {},
596- required_authz_tokens = [],
597- auth_service_token_getters = {},
598- bound_params = {},
599- client_headers = {},
600- )
601-
602- # Bind both parameters, one with a lambda
603- bound_tool = tool .bind_params ({"message" : lambda : "from-callable" , "count" : 99 })
604-
605- assert "message" not in bound_tool .__signature__ .parameters
606- assert "count" not in bound_tool .__signature__ .parameters
607- assert len (bound_tool .__signature__ .parameters ) == 0
608-
609- # Test invocation
610- invoke_url = f"{ HTTPS_BASE_URL } /api/tool/{ TEST_TOOL_NAME } /invoke"
611- with aioresponses () as m :
612- m .post (invoke_url , status = 200 , payload = {"result" : "Success" })
613- await bound_tool () # Call with no arguments
614-
615- expected_payload = {"message" : "from-callable" , "count" : 99 }
616- m .assert_called_once_with (
617- invoke_url , method = "POST" , json = expected_payload , headers = {}
618- )
619-
620-
621- def test_bind_param_invalid_parameter_name (toolbox_tool : ToolboxTool ):
622- """
623- Tests that binding a parameter that does not exist raises a ValueError.
624- """
625- with pytest .raises (
626- ValueError , match = "unable to bind parameters: no parameter named invalid_param"
627- ):
628- toolbox_tool .bind_param ("invalid_param" , "some_value" )
629-
630-
631- def test_bind_params_rebinding_parameter_fails (toolbox_tool : ToolboxTool ):
632- """
633- Tests that attempting to re-bind an already bound parameter raises a ValueError.
634- """
635- tool_with_one_bound_param = toolbox_tool .bind_param ("count" , 50 )
636-
637- with pytest .raises (
638- ValueError , match = "cannot re-bind parameter: parameter 'count' is already bound"
639- ):
640- tool_with_one_bound_param .bind_params ({"count" : 75 })
641-
642-
643- @pytest .mark .asyncio
644- async def test_bind_param_chaining (
645- http_session : ClientSession ,
646- sample_tool_params : list [ParameterSchema ],
647- sample_tool_description : str ,
648- ):
649- """
650- Tests that bind_param calls can be chained to bind multiple parameters sequentially.
651- """
652- transport = ToolboxTransport (HTTPS_BASE_URL , http_session )
653- tool = ToolboxTool (
654- transport = transport ,
655- name = TEST_TOOL_NAME ,
656- description = sample_tool_description ,
657- params = sample_tool_params ,
658- required_authn_params = {},
659- required_authz_tokens = [],
660- auth_service_token_getters = {},
661- bound_params = {},
662- client_headers = {},
663- )
664-
665- # Chain the calls
666- fully_bound_tool = tool .bind_param ("count" , 42 ).bind_param (
667- "message" , "chained-call"
668- )
669-
670- assert len (fully_bound_tool .__signature__ .parameters ) == 0
671- assert fully_bound_tool ._bound_params == {
672- "count" : 42 ,
673- "message" : "chained-call" ,
674- }
675-
676- # Test invocation
677- invoke_url = f"{ HTTPS_BASE_URL } /api/tool/{ TEST_TOOL_NAME } /invoke"
678- with aioresponses () as m :
679- m .post (invoke_url , status = 200 , payload = {"result" : "Success" })
680- await fully_bound_tool ()
681-
682- m .assert_called_once_with (
683- invoke_url ,
684- method = "POST" ,
685- json = {"count" : 42 , "message" : "chained-call" },
686- headers = {},
687- )
0 commit comments