@@ -341,3 +341,167 @@ func Test_CreateGist(t *testing.T) {
341
341
})
342
342
}
343
343
}
344
+
345
+ func Test_UpdateGist (t * testing.T ) {
346
+ // Verify tool definition
347
+ mockClient := github .NewClient (nil )
348
+ tool ,_ := UpdateGist (stubGetClientFn (mockClient ),translations .NullTranslationHelper )
349
+
350
+ assert .Equal (t ,"update_gist" ,tool .Name )
351
+ assert .NotEmpty (t ,tool .Description )
352
+ assert .Contains (t ,tool .InputSchema .Properties ,"gist_id" )
353
+ assert .Contains (t ,tool .InputSchema .Properties ,"description" )
354
+ assert .Contains (t ,tool .InputSchema .Properties ,"filename" )
355
+ assert .Contains (t ,tool .InputSchema .Properties ,"content" )
356
+
357
+ // Verify required parameters
358
+ assert .Contains (t ,tool .InputSchema .Required ,"gist_id" )
359
+ assert .Contains (t ,tool .InputSchema .Required ,"filename" )
360
+ assert .Contains (t ,tool .InputSchema .Required ,"content" )
361
+
362
+ // Setup mock data for test cases
363
+ updatedGist := & github.Gist {
364
+ ID :github .Ptr ("existing-gist-id" ),
365
+ Description :github .Ptr ("Updated Test Gist" ),
366
+ HTMLURL :github .Ptr ("https://gist.github.com/user/existing-gist-id" ),
367
+ Public :github .Ptr (true ),
368
+ UpdatedAt :& github.Timestamp {Time :time .Now ()},
369
+ Owner :& github.User {Login :github .Ptr ("user" )},
370
+ Files :map [github.GistFilename ]github.GistFile {
371
+ "updated.go" : {
372
+ Filename :github .Ptr ("updated.go" ),
373
+ Content :github .Ptr ("package main\n \n func main() {\n \t fmt.Println(\" Updated Gist!\" )\n }" ),
374
+ },
375
+ },
376
+ }
377
+
378
+ tests := []struct {
379
+ name string
380
+ mockedClient * http.Client
381
+ requestArgs map [string ]interface {}
382
+ expectError bool
383
+ expectedErrMsg string
384
+ expectedGist * github.Gist
385
+ }{
386
+ {
387
+ name :"update gist successfully" ,
388
+ mockedClient :mock .NewMockedHTTPClient (
389
+ mock .WithRequestMatchHandler (
390
+ mock .PatchGistsByGistId ,
391
+ mockResponse (t ,http .StatusOK ,updatedGist ),
392
+ ),
393
+ ),
394
+ requestArgs :map [string ]interface {}{
395
+ "gist_id" :"existing-gist-id" ,
396
+ "filename" :"updated.go" ,
397
+ "content" :"package main\n \n func main() {\n \t fmt.Println(\" Updated Gist!\" )\n }" ,
398
+ "description" :"Updated Test Gist" ,
399
+ },
400
+ expectError :false ,
401
+ expectedGist :updatedGist ,
402
+ },
403
+ {
404
+ name :"missing required gist_id" ,
405
+ mockedClient :mock .NewMockedHTTPClient (),
406
+ requestArgs :map [string ]interface {}{
407
+ "filename" :"updated.go" ,
408
+ "content" :"updated content" ,
409
+ "description" :"Updated Test Gist" ,
410
+ },
411
+ expectError :true ,
412
+ expectedErrMsg :"missing required parameter: gist_id" ,
413
+ },
414
+ {
415
+ name :"missing required filename" ,
416
+ mockedClient :mock .NewMockedHTTPClient (),
417
+ requestArgs :map [string ]interface {}{
418
+ "gist_id" :"existing-gist-id" ,
419
+ "content" :"updated content" ,
420
+ "description" :"Updated Test Gist" ,
421
+ },
422
+ expectError :true ,
423
+ expectedErrMsg :"missing required parameter: filename" ,
424
+ },
425
+ {
426
+ name :"missing required content" ,
427
+ mockedClient :mock .NewMockedHTTPClient (),
428
+ requestArgs :map [string ]interface {}{
429
+ "gist_id" :"existing-gist-id" ,
430
+ "filename" :"updated.go" ,
431
+ "description" :"Updated Test Gist" ,
432
+ },
433
+ expectError :true ,
434
+ expectedErrMsg :"missing required parameter: content" ,
435
+ },
436
+ {
437
+ name :"api returns error" ,
438
+ mockedClient :mock .NewMockedHTTPClient (
439
+ mock .WithRequestMatchHandler (
440
+ mock .PatchGistsByGistId ,
441
+ http .HandlerFunc (func (w http.ResponseWriter ,_ * http.Request ) {
442
+ w .WriteHeader (http .StatusNotFound )
443
+ _ ,_ = w .Write ([]byte (`{"message": "Not Found"}` ))
444
+ }),
445
+ ),
446
+ ),
447
+ requestArgs :map [string ]interface {}{
448
+ "gist_id" :"nonexistent-gist-id" ,
449
+ "filename" :"updated.go" ,
450
+ "content" :"package main" ,
451
+ "description" :"Updated Test Gist" ,
452
+ },
453
+ expectError :true ,
454
+ expectedErrMsg :"failed to update gist" ,
455
+ },
456
+ }
457
+
458
+ for _ ,tc := range tests {
459
+ t .Run (tc .name ,func (t * testing.T ) {
460
+ // Setup client with mock
461
+ client := github .NewClient (tc .mockedClient )
462
+ _ ,handler := UpdateGist (stubGetClientFn (client ),translations .NullTranslationHelper )
463
+
464
+ // Create call request
465
+ request := createMCPRequest (tc .requestArgs )
466
+
467
+ // Call handler
468
+ result ,err := handler (context .Background (),request )
469
+
470
+ // Verify results
471
+ if tc .expectError {
472
+ if err != nil {
473
+ assert .Contains (t ,err .Error (),tc .expectedErrMsg )
474
+ }else {
475
+ // For errors returned as part of the result, not as an error
476
+ assert .NotNil (t ,result )
477
+ textContent := getTextResult (t ,result )
478
+ assert .Contains (t ,textContent .Text ,tc .expectedErrMsg )
479
+ }
480
+ return
481
+ }
482
+
483
+ require .NoError (t ,err )
484
+ assert .NotNil (t ,result )
485
+
486
+ // Parse the result and get the text content
487
+ textContent := getTextResult (t ,result )
488
+
489
+ // Unmarshal and verify the result
490
+ var gist * github.Gist
491
+ err = json .Unmarshal ([]byte (textContent .Text ),& gist )
492
+ require .NoError (t ,err )
493
+
494
+ assert .Equal (t ,* tc .expectedGist .ID ,* gist .ID )
495
+ assert .Equal (t ,* tc .expectedGist .Description ,* gist .Description )
496
+ assert .Equal (t ,* tc .expectedGist .HTMLURL ,* gist .HTMLURL )
497
+
498
+ // Verify file content
499
+ for filename ,expectedFile := range tc .expectedGist .Files {
500
+ actualFile ,exists := gist .Files [filename ]
501
+ assert .True (t ,exists )
502
+ assert .Equal (t ,* expectedFile .Filename ,* actualFile .Filename )
503
+ assert .Equal (t ,* expectedFile .Content ,* actualFile .Content )
504
+ }
505
+ })
506
+ }
507
+ }