Skip to content

Commit a6cbd57

Browse files
committed
refactor: mock GQL client instead of getFileSHA function to follow conventions
1 parent 7cc1ff4 commit a6cbd57

File tree

2 files changed

+40
-25
lines changed

2 files changed

+40
-25
lines changed

pkg/github/repositories.go

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,6 @@ import (
1919
"github.com/shurcooL/githubv4"
2020
)
2121

22-
// getFileSHAFunc is a package-level variable that holds the getFileSHA function
23-
// This allows tests to mock the behavior
24-
var getFileSHAFunc = getFileSHA
25-
2622
func GetCommit(getClient GetClientFn, t translations.TranslationHelperFunc) (tool mcp.Tool, handler server.ToolHandlerFunc) {
2723
return mcp.NewTool("get_commit",
2824
mcp.WithDescription(t("TOOL_GET_COMMITS_DESCRIPTION", "Get details for a commit from a GitHub repository")),
@@ -516,7 +512,7 @@ func GetFileContents(getClient GetClientFn, getRawClient raw.GetRawClientFn, get
516512
if err != nil {
517513
return mcp.NewToolResultError("failed to get GitHub GraphQL client"), nil
518514
}
519-
fileSHA, err := getFileSHAFunc(ctx, gqlClient, owner, repo, path, rawOpts)
515+
fileSHA, err := getFileSHA(ctx, gqlClient, owner, repo, path, rawOpts)
520516
if err != nil {
521517
return mcp.NewToolResultError(fmt.Sprintf("failed to get file SHA: %s", err)), nil
522518
}

pkg/github/repositories_test.go

Lines changed: 39 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"testing"
1010
"time"
1111

12+
"github.com/github/github-mcp-server/internal/githubv4mock"
1213
"github.com/github/github-mcp-server/internal/toolsnaps"
1314
"github.com/github/github-mcp-server/pkg/raw"
1415
"github.com/github/github-mcp-server/pkg/translations"
@@ -20,11 +21,39 @@ import (
2021
"github.com/stretchr/testify/require"
2122
)
2223

23-
// mockGetFileSHA is a test helper that mocks the getFileSHA function so that we don't need to mock the GraphQL client in Test_GetFileContents.
24-
func mockGetFileSHA(expectedSHA string) func(context.Context, *githubv4.Client, string, string, string, *raw.ContentOpts) (string, error) {
25-
return func(_ context.Context, _ *githubv4.Client, _, _, _ string, _ *raw.ContentOpts) (string, error) {
26-
return expectedSHA, nil
24+
func mockGQLClientFileSHA(t *testing.T, owner, repo, expression, expectedSHA string) *githubv4.Client {
25+
// Create the query structure that matches getFileSHA function
26+
query := struct {
27+
Repository struct {
28+
Object struct {
29+
Blob struct {
30+
OID string
31+
} `graphql:"... on Blob"`
32+
} `graphql:"object(expression: $expression)"`
33+
} `graphql:"repository(owner: $owner, name: $repo)"`
34+
}{}
35+
36+
// Match any variables, we don't care about the exact values in this test
37+
variables := map[string]interface{}{
38+
"owner": githubv4.String(owner),
39+
"repo": githubv4.String(repo),
40+
"expression": githubv4.String(expression),
2741
}
42+
43+
// Create the mock response with the expected SHA
44+
mockResponse := githubv4mock.DataResponse(map[string]any{
45+
"repository": map[string]any{
46+
"object": map[string]any{
47+
"oid": expectedSHA,
48+
},
49+
},
50+
})
51+
52+
// Create the matcher and mock client
53+
matcher := githubv4mock.NewQueryMatcher(query, variables, mockResponse)
54+
httpClient := githubv4mock.NewMockedHTTPClient(matcher)
55+
56+
return githubv4.NewClient(httpClient)
2857
}
2958

3059
func Test_GetFileContents(t *testing.T) {
@@ -68,7 +97,7 @@ func Test_GetFileContents(t *testing.T) {
6897
tests := []struct {
6998
name string
7099
mockedClient *http.Client
71-
mockFileSHA string
100+
mockGQLClient *githubv4.Client
72101
requestArgs map[string]interface{}
73102
expectError bool
74103
expectedResult interface{}
@@ -107,7 +136,7 @@ func Test_GetFileContents(t *testing.T) {
107136
}),
108137
),
109138
),
110-
mockFileSHA: "abc123",
139+
mockGQLClient: mockGQLClientFileSHA(t, "owner", "repo", "refs/heads/main:README.md", "abc123"),
111140
requestArgs: map[string]interface{}{
112141
"owner": "owner",
113142
"repo": "repo",
@@ -153,7 +182,7 @@ func Test_GetFileContents(t *testing.T) {
153182
}),
154183
),
155184
),
156-
mockFileSHA: "def456",
185+
mockGQLClient: mockGQLClientFileSHA(t, "owner", "repo", "refs/heads/main:test.png", "def456"),
157186
requestArgs: map[string]interface{}{
158187
"owner": "owner",
159188
"repo": "repo",
@@ -199,7 +228,7 @@ func Test_GetFileContents(t *testing.T) {
199228
),
200229
),
201230
),
202-
mockFileSHA: "", // Directory content doesn't need SHA
231+
mockGQLClient: nil,
203232
requestArgs: map[string]interface{}{
204233
"owner": "owner",
205234
"repo": "repo",
@@ -233,7 +262,7 @@ func Test_GetFileContents(t *testing.T) {
233262
}),
234263
),
235264
),
236-
mockFileSHA: "", // Error case doesn't need SHA
265+
mockGQLClient: mockGQLClientFileSHA(t, "owner", "repo", "refs/heads/main:nonexistent.md", ""),
237266
requestArgs: map[string]interface{}{
238267
"owner": "owner",
239268
"repo": "repo",
@@ -247,20 +276,10 @@ func Test_GetFileContents(t *testing.T) {
247276

248277
for _, tc := range tests {
249278
t.Run(tc.name, func(t *testing.T) {
250-
// Mock the getFileSHA function if mockFileSHA is provided
251-
if tc.mockFileSHA != "" {
252-
originalGetFileSHA := getFileSHAFunc
253-
getFileSHAFunc = mockGetFileSHA(tc.mockFileSHA)
254-
defer func() {
255-
getFileSHAFunc = originalGetFileSHA
256-
}()
257-
}
258-
259279
// Setup client with mock
260280
client := github.NewClient(tc.mockedClient)
261281
mockRawClient := raw.NewClient(client, &url.URL{Scheme: "https", Host: "raw.example.com", Path: "/"})
262-
mockGQLClient := githubv4.NewClient(tc.mockedClient)
263-
_, handler := GetFileContents(stubGetClientFn(client), stubGetRawClientFn(mockRawClient), stubGetGQLClientFn(mockGQLClient), translations.NullTranslationHelper)
282+
_, handler := GetFileContents(stubGetClientFn(client), stubGetRawClientFn(mockRawClient), stubGetGQLClientFn(tc.mockGQLClient), translations.NullTranslationHelper)
264283

265284
// Create call request
266285
request := createMCPRequest(tc.requestArgs)

0 commit comments

Comments
 (0)