@@ -1130,3 +1130,139 @@ func Test_GetIssueComments(t *testing.T) {
1130
1130
})
1131
1131
}
1132
1132
}
1133
+
1134
+ func Test_UpdateIssueComment (t * testing.T ) {
1135
+ // Verify tool definition once
1136
+ mockClient := github .NewClient (nil )
1137
+ tool ,_ := UpdateIssueComment (stubGetClientFn (mockClient ),translations .NullTranslationHelper )
1138
+
1139
+ assert .Equal (t ,"update_issue_comment" ,tool .Name )
1140
+ assert .NotEmpty (t ,tool .Description )
1141
+ assert .Contains (t ,tool .InputSchema .Properties ,"owner" )
1142
+ assert .Contains (t ,tool .InputSchema .Properties ,"repo" )
1143
+ assert .Contains (t ,tool .InputSchema .Properties ,"commentId" )
1144
+ assert .Contains (t ,tool .InputSchema .Properties ,"body" )
1145
+ assert .ElementsMatch (t ,tool .InputSchema .Required , []string {"owner" ,"repo" ,"commentId" ,"body" })
1146
+
1147
+ // Setup mock comment for success case
1148
+ mockUpdatedComment := & github.IssueComment {
1149
+ ID :github .Ptr (int64 (123 )),
1150
+ Body :github .Ptr ("Updated issue comment text here" ),
1151
+ HTMLURL :github .Ptr ("https://github.com/owner/repo/issues/1#issuecomment-123" ),
1152
+ CreatedAt :& github.Timestamp {Time :time .Now ().Add (- 1 * time .Hour )},
1153
+ UpdatedAt :& github.Timestamp {Time :time .Now ()},
1154
+ User :& github.User {
1155
+ Login :github .Ptr ("testuser" ),
1156
+ },
1157
+ }
1158
+
1159
+ tests := []struct {
1160
+ name string
1161
+ mockedClient * http.Client
1162
+ requestArgs map [string ]interface {}
1163
+ expectError bool
1164
+ expectedComment * github.IssueComment
1165
+ expectedErrMsg string
1166
+ }{
1167
+ {
1168
+ name :"successful comment update" ,
1169
+ mockedClient :mock .NewMockedHTTPClient (
1170
+ mock .WithRequestMatchHandler (
1171
+ mock .PatchReposIssuesCommentsByOwnerByRepoByCommentId ,
1172
+ expectRequestBody (t ,map [string ]interface {}{
1173
+ "body" :"Updated issue comment text here" ,
1174
+ }).andThen (
1175
+ mockResponse (t ,http .StatusOK ,mockUpdatedComment ),
1176
+ ),
1177
+ ),
1178
+ ),
1179
+ requestArgs :map [string ]interface {}{
1180
+ "owner" :"owner" ,
1181
+ "repo" :"repo" ,
1182
+ "commentId" :float64 (123 ),
1183
+ "body" :"Updated issue comment text here" ,
1184
+ },
1185
+ expectError :false ,
1186
+ expectedComment :mockUpdatedComment ,
1187
+ },
1188
+ {
1189
+ name :"comment update fails - not found" ,
1190
+ mockedClient :mock .NewMockedHTTPClient (
1191
+ mock .WithRequestMatchHandler (
1192
+ mock .PatchReposIssuesCommentsByOwnerByRepoByCommentId ,
1193
+ http .HandlerFunc (func (w http.ResponseWriter ,_ * http.Request ) {
1194
+ w .WriteHeader (http .StatusNotFound )
1195
+ w .Header ().Set ("Content-Type" ,"application/json" )
1196
+ _ ,_ = w .Write ([]byte (`{"message": "Comment not found"}` ))
1197
+ }),
1198
+ ),
1199
+ ),
1200
+ requestArgs :map [string ]interface {}{
1201
+ "owner" :"owner" ,
1202
+ "repo" :"repo" ,
1203
+ "commentId" :float64 (999 ),
1204
+ "body" :"This should fail" ,
1205
+ },
1206
+ expectError :true ,
1207
+ expectedErrMsg :"failed to update issue comment" ,
1208
+ },
1209
+ {
1210
+ name :"comment update fails - validation error" ,
1211
+ mockedClient :mock .NewMockedHTTPClient (
1212
+ mock .WithRequestMatchHandler (
1213
+ mock .PatchReposIssuesCommentsByOwnerByRepoByCommentId ,
1214
+ http .HandlerFunc (func (w http.ResponseWriter ,_ * http.Request ) {
1215
+ w .WriteHeader (http .StatusUnprocessableEntity )
1216
+ w .Header ().Set ("Content-Type" ,"application/json" )
1217
+ _ ,_ = w .Write ([]byte (`{"message": "Validation Failed"}` ))
1218
+ }),
1219
+ ),
1220
+ ),
1221
+ requestArgs :map [string ]interface {}{
1222
+ "owner" :"owner" ,
1223
+ "repo" :"repo" ,
1224
+ "commentId" :float64 (123 ),
1225
+ "body" :"Invalid body" ,
1226
+ },
1227
+ expectError :true ,
1228
+ expectedErrMsg :"failed to update issue comment" ,
1229
+ },
1230
+ }
1231
+
1232
+ for _ ,tc := range tests {
1233
+ t .Run (tc .name ,func (t * testing.T ) {
1234
+ client := github .NewClient (tc .mockedClient )
1235
+ _ ,handler := UpdateIssueComment (stubGetClientFn (client ),translations .NullTranslationHelper )
1236
+
1237
+ request := createMCPRequest (tc .requestArgs )
1238
+
1239
+ result ,err := handler (context .Background (),request )
1240
+
1241
+ if tc .expectError {
1242
+ require .Error (t ,err )
1243
+ assert .Contains (t ,err .Error (),tc .expectedErrMsg )
1244
+ return
1245
+ }
1246
+
1247
+ require .NoError (t ,err )
1248
+ assert .NotNil (t ,result )
1249
+ require .Len (t ,result .Content ,1 )
1250
+
1251
+ textContent := getTextResult (t ,result )
1252
+
1253
+ // For non-error cases, check the returned comment
1254
+ var returnedComment github.IssueComment
1255
+ err = json .Unmarshal ([]byte (textContent .Text ),& returnedComment )
1256
+ require .NoError (t ,err )
1257
+
1258
+ assert .Equal (t ,* tc .expectedComment .ID ,* returnedComment .ID )
1259
+ assert .Equal (t ,* tc .expectedComment .Body ,* returnedComment .Body )
1260
+ if tc .expectedComment .HTMLURL != nil {
1261
+ assert .Equal (t ,* tc .expectedComment .HTMLURL ,* returnedComment .HTMLURL )
1262
+ }
1263
+ if tc .expectedComment .User != nil && tc .expectedComment .User .Login != nil {
1264
+ assert .Equal (t ,* tc .expectedComment .User .Login ,* returnedComment .User .Login )
1265
+ }
1266
+ })
1267
+ }
1268
+ }