@@ -590,6 +590,50 @@ func Test_GetDiscussion(t *testing.T) {
590590 }
591591}
592592
593+ func Test_GetDiscussionWithStringNumber (t * testing.T ) {
594+ // Test that WeakDecode handles string discussionNumber from MCP clients
595+ toolDef := GetDiscussion (translations .NullTranslationHelper )
596+
597+ qGetDiscussion := "query($discussionNumber:Int!$owner:String!$repo:String!){repository(owner: $owner, name: $repo){discussion(number: $discussionNumber){number,title,body,createdAt,closed,isAnswered,answerChosenAt,url,category{name}}}}"
598+
599+ vars := map [string ]any {
600+ "owner" : "owner" ,
601+ "repo" : "repo" ,
602+ "discussionNumber" : float64 (1 ),
603+ }
604+
605+ matcher := githubv4mock .NewQueryMatcher (qGetDiscussion , vars , githubv4mock .DataResponse (map [string ]any {
606+ "repository" : map [string ]any {"discussion" : map [string ]any {
607+ "number" : 1 ,
608+ "title" : "Test Discussion Title" ,
609+ "body" : "This is a test discussion" ,
610+ "url" : "https://github.com/owner/repo/discussions/1" ,
611+ "createdAt" : "2025-04-25T12:00:00Z" ,
612+ "closed" : false ,
613+ "isAnswered" : false ,
614+ "category" : map [string ]any {"name" : "General" },
615+ }},
616+ }))
617+ httpClient := githubv4mock .NewMockedHTTPClient (matcher )
618+ gqlClient := githubv4 .NewClient (httpClient )
619+ deps := BaseDeps {GQLClient : gqlClient }
620+ handler := toolDef .Handler (deps )
621+
622+ // Send discussionNumber as a string instead of a number
623+ reqParams := map [string ]any {"owner" : "owner" , "repo" : "repo" , "discussionNumber" : "1" }
624+ req := createMCPRequest (reqParams )
625+ res , err := handler (ContextWithDeps (context .Background (), deps ), & req )
626+ require .NoError (t , err )
627+
628+ text := getTextResult (t , res ).Text
629+ require .False (t , res .IsError , "expected no error, got: %s" , text )
630+
631+ var out map [string ]any
632+ require .NoError (t , json .Unmarshal ([]byte (text ), & out ))
633+ assert .Equal (t , float64 (1 ), out ["number" ])
634+ assert .Equal (t , "Test Discussion Title" , out ["title" ])
635+ }
636+
593637func Test_GetDiscussionComments (t * testing.T ) {
594638 // Verify tool definition and schema
595639 toolDef := GetDiscussionComments (translations .NullTranslationHelper )
@@ -675,6 +719,67 @@ func Test_GetDiscussionComments(t *testing.T) {
675719 }
676720}
677721
722+ func Test_GetDiscussionCommentsWithStringNumber (t * testing.T ) {
723+ // Test that WeakDecode handles string discussionNumber from MCP clients
724+ toolDef := GetDiscussionComments (translations .NullTranslationHelper )
725+
726+ qGetComments := "query($after:String$discussionNumber:Int!$first:Int!$owner:String!$repo:String!){repository(owner: $owner, name: $repo){discussion(number: $discussionNumber){comments(first: $first, after: $after){nodes{body},pageInfo{hasNextPage,hasPreviousPage,startCursor,endCursor},totalCount}}}}"
727+
728+ vars := map [string ]any {
729+ "owner" : "owner" ,
730+ "repo" : "repo" ,
731+ "discussionNumber" : float64 (1 ),
732+ "first" : float64 (30 ),
733+ "after" : (* string )(nil ),
734+ }
735+
736+ mockResponse := githubv4mock .DataResponse (map [string ]any {
737+ "repository" : map [string ]any {
738+ "discussion" : map [string ]any {
739+ "comments" : map [string ]any {
740+ "nodes" : []map [string ]any {
741+ {"body" : "First comment" },
742+ },
743+ "pageInfo" : map [string ]any {
744+ "hasNextPage" : false ,
745+ "hasPreviousPage" : false ,
746+ "startCursor" : "" ,
747+ "endCursor" : "" ,
748+ },
749+ "totalCount" : 1 ,
750+ },
751+ },
752+ },
753+ })
754+ matcher := githubv4mock .NewQueryMatcher (qGetComments , vars , mockResponse )
755+ httpClient := githubv4mock .NewMockedHTTPClient (matcher )
756+ gqlClient := githubv4 .NewClient (httpClient )
757+ deps := BaseDeps {GQLClient : gqlClient }
758+ handler := toolDef .Handler (deps )
759+
760+ // Send discussionNumber as a string instead of a number
761+ reqParams := map [string ]any {
762+ "owner" : "owner" ,
763+ "repo" : "repo" ,
764+ "discussionNumber" : "1" ,
765+ }
766+ request := createMCPRequest (reqParams )
767+
768+ result , err := handler (ContextWithDeps (context .Background (), deps ), & request )
769+ require .NoError (t , err )
770+
771+ textContent := getTextResult (t , result )
772+ require .False (t , result .IsError , "expected no error, got: %s" , textContent .Text )
773+
774+ var out struct {
775+ Comments []map [string ]any `json:"comments"`
776+ TotalCount int `json:"totalCount"`
777+ }
778+ require .NoError (t , json .Unmarshal ([]byte (textContent .Text ), & out ))
779+ assert .Len (t , out .Comments , 1 )
780+ assert .Equal (t , "First comment" , out .Comments [0 ]["body" ])
781+ }
782+
678783func Test_ListDiscussionCategories (t * testing.T ) {
679784 toolDef := ListDiscussionCategories (translations .NullTranslationHelper )
680785 tool := toolDef .Tool
0 commit comments