diff --git a/pkg/github/pullrequests.go b/pkg/github/pullrequests.go index 5cee8b3231..4e24e14021 100644 --- a/pkg/github/pullrequests.go +++ b/pkg/github/pullrequests.go @@ -2180,9 +2180,14 @@ func ResolveReviewThreadWithReason(ctx context.Context, client *githubv4.Client, } `graphql:"resolveReviewThread(input: $input)"` } - input := ResolveReviewThreadInput{ - ThreadID: githubv4.ID(threadID), - ResolutionReason: newGQLStringlikePtr[githubv4.String](resolutionReason), + var input any + if resolutionReason == nil { + input = githubv4.ResolveReviewThreadInput{ThreadID: githubv4.ID(threadID)} + } else { + input = ResolveReviewThreadInput{ + ThreadID: githubv4.ID(threadID), + ResolutionReason: newGQLStringlikePtr[githubv4.String](resolutionReason), + } } if err := client.Mutate(ctx, &mutation, input, nil); err != nil { diff --git a/pkg/github/pullrequests_test.go b/pkg/github/pullrequests_test.go index c0e392aea6..6c52dd2758 100644 --- a/pkg/github/pullrequests_test.go +++ b/pkg/github/pullrequests_test.go @@ -1,8 +1,10 @@ package github import ( + "bytes" "context" "encoding/json" + "io" "net/http" "strings" "sync/atomic" @@ -19,6 +21,31 @@ import ( "github.com/stretchr/testify/require" ) +type captureGraphQLTransport struct { + response string + variables map[string]any +} + +func (t *captureGraphQLTransport) RoundTrip(req *http.Request) (*http.Response, error) { + body, err := io.ReadAll(req.Body) + if err != nil { + return nil, err + } + var request struct { + Variables map[string]any `json:"variables"` + } + if err := json.Unmarshal(body, &request); err != nil { + return nil, err + } + t.variables = request.Variables + return &http.Response{ + StatusCode: http.StatusOK, + Header: make(http.Header), + Body: io.NopCloser(bytes.NewBufferString(t.response)), + Request: req, + }, nil +} + func Test_GetPullRequest(t *testing.T) { // Verify tool definition once serverTool := PullRequestRead(translations.NullTranslationHelper) @@ -4877,3 +4904,19 @@ func TestResolveReviewThread(t *testing.T) { }) } } + +func TestResolveReviewThreadWithoutReasonOmitsOptionalInputField(t *testing.T) { + transport := &captureGraphQLTransport{ + response: `{"data":{"resolveReviewThread":{"thread":{"id":"PRRT_test","isResolved":true}}}}`, + } + client := githubv4.NewClient(&http.Client{Transport: transport}) + + result, err := ResolveReviewThread(context.Background(), client, "PRRT_test", true) + require.NoError(t, err) + require.False(t, result.IsError) + require.NotNil(t, transport.variables) + input, ok := transport.variables["input"].(map[string]any) + require.True(t, ok) + assert.Equal(t, "PRRT_test", input["threadId"]) + assert.NotContains(t, input, "resolutionReason") +} diff --git a/pkg/http/oauth/oauth_test.go b/pkg/http/oauth/oauth_test.go index c2ef660104..515a0a471f 100644 --- a/pkg/http/oauth/oauth_test.go +++ b/pkg/http/oauth/oauth_test.go @@ -436,7 +436,7 @@ func TestHandleProtectedResource(t *testing.T) { host: "api.example.com", method: http.MethodGet, expectedStatusCode: http.StatusOK, -expectedScopes: []string{ + expectedScopes: []string{ "repo", "read:org", "read:user",