@@ -169,7 +169,7 @@ func TestE2E_Basic(t *testing.T) {
169
169
// The Go SDK performs validation inside Invoke, so we check the error there.
170
170
_ , err := tool .Invoke (context .Background (), map [string ]any {})
171
171
require .Error (t , err )
172
- assert .Contains (t , err .Error (), "parameter \" num_rows \" is required " )
172
+ assert .Contains (t , err .Error (), "missing required parameter 'num_rows' " )
173
173
})
174
174
175
175
t .Run ("test_run_tool_wrong_param_type" , func (t * testing.T ) {
@@ -337,3 +337,141 @@ func TestE2E_Auth(t *testing.T) {
337
337
assert .Contains (t , err .Error (), "no field named row_data in claims" )
338
338
})
339
339
}
340
+
341
+ // TestE2E_OptionalParams maps to the TestOptionalParams class
342
+ func TestE2E_OptionalParams (t * testing.T ) {
343
+ // Helper to create a new client
344
+ newClient := func (t * testing.T ) * core.ToolboxClient {
345
+ client , err := core .NewToolboxClient ("http://localhost:5000" )
346
+ require .NoError (t , err , "Failed to create ToolboxClient" )
347
+ return client
348
+ }
349
+
350
+ // Helper to load the search-rows tool
351
+ searchRowsTool := func (t * testing.T , client * core.ToolboxClient ) * core.ToolboxTool {
352
+ tool , err := client .LoadTool ("search-rows" , context .Background ())
353
+ require .NoError (t , err , "Failed to load tool 'search-rows'" )
354
+ return tool
355
+ }
356
+
357
+ t .Run ("test_tool_schema_is_correct" , func (t * testing.T ) {
358
+ client := newClient (t )
359
+ tool := searchRowsTool (t , client )
360
+ params := tool .Parameters ()
361
+
362
+ // Convert slice to map for easy lookup
363
+ paramMap := make (map [string ]core.ParameterSchema )
364
+ for _ , p := range params {
365
+ paramMap [p .Name ] = p
366
+ }
367
+
368
+ // Check required parameter 'email'
369
+ emailParam , ok := paramMap ["email" ]
370
+ require .True (t , ok , "email parameter should exist" )
371
+ assert .True (t , emailParam .Required , "'email' should be required" )
372
+ assert .Equal (t , "string" , emailParam .Type )
373
+
374
+ // Check optional parameter 'data'
375
+ dataParam , ok := paramMap ["data" ]
376
+ require .True (t , ok , "data parameter should exist" )
377
+ assert .False (t , dataParam .Required , "'data' should be optional" )
378
+ assert .Equal (t , "string" , dataParam .Type )
379
+
380
+ // Check optional parameter 'id'
381
+ idParam , ok := paramMap ["id" ]
382
+ require .True (t , ok , "id parameter should exist" )
383
+ assert .False (t , idParam .Required , "'id' should be optional" )
384
+ assert .Equal (t , "integer" , idParam .Type )
385
+ })
386
+
387
+ t .Run ("test_run_tool_omitting_optionals" , func (t * testing.T ) {
388
+ client := newClient (t )
389
+ tool := searchRowsTool (t , client )
390
+
391
+ // Test case 1: Optional params are completely omitted
392
+ response1 , err1 := tool .Invoke (context .Background (), map [string ]any {
393
+
394
+ })
395
+ require .NoError (t , err1 )
396
+ respStr1 , ok1 := response1 .(string )
397
+ require .True (t , ok1 )
398
+ assert .
Contains (
t ,
respStr1 ,
`"email":"[email protected] "` )
399
+ assert .Contains (t , respStr1 , "row2" )
400
+ assert .NotContains (t , respStr1 , "row3" )
401
+
402
+ // Test case 2: Optional params are explicitly nil
403
+ // This should produce the same result as omitting them
404
+ response2 , err2 := tool .Invoke (context .Background (), map [string ]any {
405
+
406
+ "data" : nil ,
407
+ "id" : nil ,
408
+ })
409
+ require .NoError (t , err2 )
410
+ respStr2 , ok2 := response2 .(string )
411
+ require .True (t , ok2 )
412
+ assert .Equal (t , respStr1 , respStr2 )
413
+ })
414
+
415
+ t .Run ("test_run_tool_with_all_params_provided" , func (t * testing.T ) {
416
+ client := newClient (t )
417
+ tool := searchRowsTool (t , client )
418
+ response , err := tool .Invoke (context .Background (), map [string ]any {
419
+
420
+ "data" : "row3" ,
421
+ "id" : 3 ,
422
+ })
423
+ require .NoError (t , err )
424
+ respStr , ok := response .(string )
425
+ require .True (t , ok )
426
+ assert .
Contains (
t ,
respStr ,
`"email":"[email protected] "` )
427
+ assert .Contains (t , respStr , `"id":3` )
428
+ assert .Contains (t , respStr , "row3" )
429
+ assert .NotContains (t , respStr , "row2" )
430
+ })
431
+
432
+ t .Run ("test_run_tool_missing_required_param" , func (t * testing.T ) {
433
+ client := newClient (t )
434
+ tool := searchRowsTool (t , client )
435
+ _ , err := tool .Invoke (context .Background (), map [string ]any {
436
+ "data" : "row5" ,
437
+ "id" : 5 ,
438
+ })
439
+ require .Error (t , err )
440
+ assert .Contains (t , err .Error (), "missing required parameter 'email'" )
441
+ })
442
+
443
+ t .Run ("test_run_tool_required_param_is_nil" , func (t * testing.T ) {
444
+ client := newClient (t )
445
+ tool := searchRowsTool (t , client )
446
+ _ , err := tool .Invoke (context .Background (), map [string ]any {
447
+ "email" : nil ,
448
+ "id" : 5 ,
449
+ })
450
+ require .Error (t , err )
451
+ assert .Contains (t , err .Error (), "parameter 'email' is required but received a nil value" )
452
+ })
453
+
454
+ // Corresponds to tests that check server-side logic by providing data that doesn't match
455
+ t .Run ("test_run_tool_with_non_matching_data" , func (t * testing.T ) {
456
+ client := newClient (t )
457
+ tool := searchRowsTool (t , client )
458
+
459
+ // Test with a different email
460
+ response , err := tool .Invoke (context .Background (), map [string ]any {
461
+
462
+ "id" : 3 ,
463
+ "data" : "row3" ,
464
+ })
465
+ require .NoError (t , err )
466
+ assert .Equal (t , "null" , response , "Response should be null for non-matching email" )
467
+
468
+ // Test with different data
469
+ response , err = tool .Invoke (context .Background (), map [string ]any {
470
+
471
+ "id" : 3 ,
472
+ "data" : "row4" , // This data doesn't match the id
473
+ })
474
+ require .NoError (t , err )
475
+ assert .Equal (t , "null" , response , "Response should be null for non-matching data" )
476
+ })
477
+ }
0 commit comments