@@ -385,3 +385,142 @@ func Test_ListRepositorySecurityAdvisories(t *testing.T) {
385385 })
386386 }
387387}
388+
389+ func Test_ListOrgRepositorySecurityAdvisories (t * testing.T ) {
390+ // Verify tool definition once
391+ mockClient := github .NewClient (nil )
392+ tool , _ := ListOrgRepositorySecurityAdvisories (stubGetClientFn (mockClient ), translations .NullTranslationHelper )
393+
394+ assert .Equal (t , "list_org_repository_security_advisories" , tool .Name )
395+ assert .NotEmpty (t , tool .Description )
396+ assert .Contains (t , tool .InputSchema .Properties , "org" )
397+ assert .Contains (t , tool .InputSchema .Properties , "direction" )
398+ assert .Contains (t , tool .InputSchema .Properties , "sort" )
399+ assert .Contains (t , tool .InputSchema .Properties , "state" )
400+ assert .ElementsMatch (t , tool .InputSchema .Required , []string {"org" })
401+
402+ // Endpoint pattern for org repository security advisories
403+ var GetOrgsSecurityAdvisoriesByOrg = mock.EndpointPattern {
404+ Pattern : "/orgs/{org}/security-advisories" ,
405+ Method : "GET" ,
406+ }
407+
408+ adv1 := & github.SecurityAdvisory {
409+ GHSAID : github .Ptr ("GHSA-aaaa-bbbb-cccc" ),
410+ Summary : github .Ptr ("Org repo advisory 1" ),
411+ Description : github .Ptr ("First advisory" ),
412+ Severity : github .Ptr ("low" ),
413+ }
414+ adv2 := & github.SecurityAdvisory {
415+ GHSAID : github .Ptr ("GHSA-dddd-eeee-ffff" ),
416+ Summary : github .Ptr ("Org repo advisory 2" ),
417+ Description : github .Ptr ("Second advisory" ),
418+ Severity : github .Ptr ("critical" ),
419+ }
420+
421+ tests := []struct {
422+ name string
423+ mockedClient * http.Client
424+ requestArgs map [string ]interface {}
425+ expectError bool
426+ expectedAdvisories []* github.SecurityAdvisory
427+ expectedErrMsg string
428+ }{
429+ {
430+ name : "successful listing (no filters)" ,
431+ mockedClient : mock .NewMockedHTTPClient (
432+ mock .WithRequestMatchHandler (
433+ GetOrgsSecurityAdvisoriesByOrg ,
434+ expect (t , expectations {
435+ path : "/orgs/octo/security-advisories" ,
436+ queryParams : map [string ]string {},
437+ }).andThen (
438+ mockResponse (t , http .StatusOK , []* github.SecurityAdvisory {adv1 , adv2 }),
439+ ),
440+ ),
441+ ),
442+ requestArgs : map [string ]interface {}{
443+ "org" : "octo" ,
444+ },
445+ expectError : false ,
446+ expectedAdvisories : []* github.SecurityAdvisory {adv1 , adv2 },
447+ },
448+ {
449+ name : "successful listing with filters" ,
450+ mockedClient : mock .NewMockedHTTPClient (
451+ mock .WithRequestMatchHandler (
452+ GetOrgsSecurityAdvisoriesByOrg ,
453+ expect (t , expectations {
454+ path : "/orgs/octo/security-advisories" ,
455+ queryParams : map [string ]string {
456+ "direction" : "asc" ,
457+ "sort" : "created" ,
458+ "state" : "triage" ,
459+ },
460+ }).andThen (
461+ mockResponse (t , http .StatusOK , []* github.SecurityAdvisory {adv1 }),
462+ ),
463+ ),
464+ ),
465+ requestArgs : map [string ]interface {}{
466+ "org" : "octo" ,
467+ "direction" : "asc" ,
468+ "sort" : "created" ,
469+ "state" : "triage" ,
470+ },
471+ expectError : false ,
472+ expectedAdvisories : []* github.SecurityAdvisory {adv1 },
473+ },
474+ {
475+ name : "listing fails" ,
476+ mockedClient : mock .NewMockedHTTPClient (
477+ mock .WithRequestMatchHandler (
478+ GetOrgsSecurityAdvisoriesByOrg ,
479+ expect (t , expectations {
480+ path : "/orgs/octo/security-advisories" ,
481+ queryParams : map [string ]string {},
482+ }).andThen (
483+ mockResponse (t , http .StatusForbidden , map [string ]string {"message" : "Forbidden" }),
484+ ),
485+ ),
486+ ),
487+ requestArgs : map [string ]interface {}{
488+ "org" : "octo" ,
489+ },
490+ expectError : true ,
491+ expectedErrMsg : "failed to list organization repository security advisories" ,
492+ },
493+ }
494+
495+ for _ , tc := range tests {
496+ t .Run (tc .name , func (t * testing.T ) {
497+ client := github .NewClient (tc .mockedClient )
498+ _ , handler := ListOrgRepositorySecurityAdvisories (stubGetClientFn (client ), translations .NullTranslationHelper )
499+
500+ request := createMCPRequest (tc .requestArgs )
501+
502+ result , err := handler (context .Background (), request )
503+
504+ if tc .expectError {
505+ require .Error (t , err )
506+ assert .Contains (t , err .Error (), tc .expectedErrMsg )
507+ return
508+ }
509+
510+ require .NoError (t , err )
511+
512+ textContent := getTextResult (t , result )
513+
514+ var returnedAdvisories []* github.SecurityAdvisory
515+ err = json .Unmarshal ([]byte (textContent .Text ), & returnedAdvisories )
516+ assert .NoError (t , err )
517+ assert .Len (t , returnedAdvisories , len (tc .expectedAdvisories ))
518+ for i , advisory := range returnedAdvisories {
519+ assert .Equal (t , * tc .expectedAdvisories [i ].GHSAID , * advisory .GHSAID )
520+ assert .Equal (t , * tc .expectedAdvisories [i ].Summary , * advisory .Summary )
521+ assert .Equal (t , * tc .expectedAdvisories [i ].Description , * advisory .Description )
522+ assert .Equal (t , * tc .expectedAdvisories [i ].Severity , * advisory .Severity )
523+ }
524+ })
525+ }
526+ }
0 commit comments