Skip to content

Commit 5cfd36a

Browse files
authored
Validate issue type rationale input
1 parent 2ce2ced commit 5cfd36a

2 files changed

Lines changed: 56 additions & 2 deletions

File tree

pkg/github/granular_tools_test.go

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package github
33
import (
44
"context"
55
"net/http"
6+
"strings"
67
"testing"
78

89
"github.com/github/github-mcp-server/internal/githubv4mock"
@@ -328,7 +329,7 @@ func TestGranularUpdateIssueType(t *testing.T) {
328329
"repo": "repo",
329330
"issue_number": float64(1),
330331
"issue_type": "feature",
331-
"rationale": "This issue requests a new capability",
332+
"rationale": " This issue requests a new capability ",
332333
},
333334
expectedReq: map[string]any{
334335
"type": map[string]any{
@@ -357,6 +358,52 @@ func TestGranularUpdateIssueType(t *testing.T) {
357358
}
358359
}
359360

361+
func TestGranularUpdateIssueTypeInvalidRationale(t *testing.T) {
362+
tests := []struct {
363+
name string
364+
requestArgs map[string]any
365+
expectedErrText string
366+
}{
367+
{
368+
name: "rationale wrong type",
369+
requestArgs: map[string]any{
370+
"owner": "owner",
371+
"repo": "repo",
372+
"issue_number": float64(1),
373+
"issue_type": "feature",
374+
"rationale": float64(123),
375+
},
376+
expectedErrText: "parameter rationale is not of type string, is float64",
377+
},
378+
{
379+
name: "rationale too long",
380+
requestArgs: map[string]any{
381+
"owner": "owner",
382+
"repo": "repo",
383+
"issue_number": float64(1),
384+
"issue_type": "feature",
385+
"rationale": strings.Repeat("a", 281),
386+
},
387+
expectedErrText: "parameter rationale must be 280 characters or less",
388+
},
389+
}
390+
391+
for _, tc := range tests {
392+
t.Run(tc.name, func(t *testing.T) {
393+
deps := BaseDeps{Client: gogithub.NewClient(MockHTTPClientWithHandlers(nil))}
394+
serverTool := GranularUpdateIssueType(translations.NullTranslationHelper)
395+
handler := serverTool.Handler(deps)
396+
397+
request := createMCPRequest(tc.requestArgs)
398+
result, err := handler(ContextWithDeps(context.Background(), deps), &request)
399+
require.NoError(t, err)
400+
401+
errorContent := getErrorResult(t, result)
402+
assert.Contains(t, errorContent.Text, tc.expectedErrText)
403+
})
404+
}
405+
}
406+
360407
func TestGranularUpdateIssueState(t *testing.T) {
361408
tests := []struct {
362409
name string

pkg/github/issues_granular.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -383,7 +383,14 @@ func GranularUpdateIssueType(t translations.TranslationHelperFunc) inventory.Ser
383383
if err != nil {
384384
return utils.NewToolResultError(err.Error()), nil, nil
385385
}
386-
rationale, _ := OptionalParam[string](args, "rationale")
386+
rationale, err := OptionalParam[string](args, "rationale")
387+
if err != nil {
388+
return utils.NewToolResultError(err.Error()), nil, nil
389+
}
390+
rationale = strings.TrimSpace(rationale)
391+
if len([]rune(rationale)) > 280 {
392+
return utils.NewToolResultError("parameter rationale must be 280 characters or less"), nil, nil
393+
}
387394

388395
client, err := deps.GetClient(ctx)
389396
if err != nil {

0 commit comments

Comments
 (0)