Files
github--github-mcp-server/pkg/github/transport_test.go
Sam Morrow 09adfc71ba feat: poll for linked PR after assigning Copilot to issue
Enhances the assign_copilot_to_issue tool to automatically poll for
the PR created by the Copilot coding agent after assignment.

Changes:
- Add findLinkedCopilotPR() to query issue timeline for CrossReferencedEvent
  items from PRs authored by copilot-swe-agent
- Add polling loop (9 attempts, 1s delay) matching remote server latency
- Return structured JSON with PR details when found, or helpful note otherwise
- Add PollConfig for configurable polling (used in tests to disable)
- Add GraphQLFeaturesTransport for feature flag header support

The returned response now includes:
- issue_number, issue_url, owner, repo
- pull_request object (if found during polling)
- Note with instructions to use get_copilot_job_status if PR not yet created
2026-01-16 11:37:26 +01:00

152 lines
3.8 KiB
Go

package github
import (
"context"
"net/http"
"net/http/httptest"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestGraphQLFeaturesTransport(t *testing.T) {
t.Parallel()
tests := []struct {
name string
features []string
expectedHeader string
hasHeader bool
}{
{
name: "no features in context",
features: nil,
expectedHeader: "",
hasHeader: false,
},
{
name: "single feature in context",
features: []string{"issues_copilot_assignment_api_support"},
expectedHeader: "issues_copilot_assignment_api_support",
hasHeader: true,
},
{
name: "multiple features in context",
features: []string{"feature1", "feature2", "feature3"},
expectedHeader: "feature1, feature2, feature3",
hasHeader: true,
},
{
name: "empty features slice",
features: []string{},
expectedHeader: "",
hasHeader: false,
},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
var capturedHeader string
var headerExists bool
// Create a test server that captures the request header
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
capturedHeader = r.Header.Get("GraphQL-Features")
headerExists = r.Header.Get("GraphQL-Features") != ""
w.WriteHeader(http.StatusOK)
}))
defer server.Close()
// Create the transport
transport := &GraphQLFeaturesTransport{
Transport: http.DefaultTransport,
}
// Create a request
ctx := context.Background()
if tc.features != nil {
ctx = withGraphQLFeatures(ctx, tc.features...)
}
req, err := http.NewRequestWithContext(ctx, http.MethodPost, server.URL, nil)
require.NoError(t, err)
// Execute the request
resp, err := transport.RoundTrip(req)
require.NoError(t, err)
defer resp.Body.Close()
// Verify the header
assert.Equal(t, tc.hasHeader, headerExists)
if tc.hasHeader {
assert.Equal(t, tc.expectedHeader, capturedHeader)
}
})
}
}
func TestGraphQLFeaturesTransport_NilTransport(t *testing.T) {
t.Parallel()
var capturedHeader string
// Create a test server
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
capturedHeader = r.Header.Get("GraphQL-Features")
w.WriteHeader(http.StatusOK)
}))
defer server.Close()
// Create the transport with nil Transport (should use DefaultTransport)
transport := &GraphQLFeaturesTransport{
Transport: nil,
}
// Create a request with features
ctx := withGraphQLFeatures(context.Background(), "test_feature")
req, err := http.NewRequestWithContext(ctx, http.MethodPost, server.URL, nil)
require.NoError(t, err)
// Execute the request
resp, err := transport.RoundTrip(req)
require.NoError(t, err)
defer resp.Body.Close()
// Verify the header was added
assert.Equal(t, "test_feature", capturedHeader)
}
func TestGraphQLFeaturesTransport_DoesNotMutateOriginalRequest(t *testing.T) {
t.Parallel()
// Create a test server
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
w.WriteHeader(http.StatusOK)
}))
defer server.Close()
// Create the transport
transport := &GraphQLFeaturesTransport{
Transport: http.DefaultTransport,
}
// Create a request with features
ctx := withGraphQLFeatures(context.Background(), "test_feature")
req, err := http.NewRequestWithContext(ctx, http.MethodPost, server.URL, nil)
require.NoError(t, err)
// Store the original header value
originalHeader := req.Header.Get("GraphQL-Features")
// Execute the request
resp, err := transport.RoundTrip(req)
require.NoError(t, err)
defer resp.Body.Close()
// Verify the original request was not mutated
assert.Equal(t, originalHeader, req.Header.Get("GraphQL-Features"))
}