diff --git a/pkg/github/helper_test.go b/pkg/github/helper_test.go index 1e7cb37aa..fadfd9a73 100644 --- a/pkg/github/helper_test.go +++ b/pkg/github/helper_test.go @@ -9,6 +9,7 @@ import ( "strings" "testing" + "github.com/github/github-mcp-server/pkg/raw" "github.com/modelcontextprotocol/go-sdk/mcp" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" @@ -637,6 +638,8 @@ func normalizeEndpointKey(endpoint any) string { panic("nil EndpointPattern") } return v.Method + " " + v.Pattern + case raw.EndpointPattern: + return v.Method + " " + v.Pattern default: panic("unsupported endpoint type") } diff --git a/pkg/github/issues_test.go b/pkg/github/issues_test.go index b810cede3..328240cb8 100644 --- a/pkg/github/issues_test.go +++ b/pkg/github/issues_test.go @@ -17,7 +17,6 @@ import ( "github.com/github/github-mcp-server/pkg/translations" "github.com/google/go-github/v79/github" "github.com/google/jsonschema-go/jsonschema" - "github.com/migueleliasweb/go-github-mock/src/mock" "github.com/shurcooL/githubv4" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -181,9 +180,9 @@ func Test_GetIssue(t *testing.T) { }{ { name: "successful issue retrieval", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatch( - mock.GetReposIssuesByOwnerByRepoByIssueNumber, + mockedClient: NewMockedHTTPClient( + WithRequestMatch( + GetReposIssuesByOwnerByRepoByIssueNumber, mockIssue, ), ), @@ -197,9 +196,9 @@ func Test_GetIssue(t *testing.T) { }, { name: "issue not found", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.GetReposIssuesByOwnerByRepoByIssueNumber, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + GetReposIssuesByOwnerByRepoByIssueNumber, mockResponse(t, http.StatusNotFound, `{"message": "Issue not found"}`), ), ), @@ -214,9 +213,9 @@ func Test_GetIssue(t *testing.T) { }, { name: "lockdown enabled - private repository", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatch( - mock.GetReposIssuesByOwnerByRepoByIssueNumber, + mockedClient: NewMockedHTTPClient( + WithRequestMatch( + GetReposIssuesByOwnerByRepoByIssueNumber, mockIssue2, ), ), @@ -261,9 +260,9 @@ func Test_GetIssue(t *testing.T) { }, { name: "lockdown enabled - user lacks push access", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatch( - mock.GetReposIssuesByOwnerByRepoByIssueNumber, + mockedClient: NewMockedHTTPClient( + WithRequestMatch( + GetReposIssuesByOwnerByRepoByIssueNumber, mockIssue, ), ), @@ -406,9 +405,9 @@ func Test_AddIssueComment(t *testing.T) { }{ { name: "successful comment creation", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.PostReposIssuesCommentsByOwnerByRepoByIssueNumber, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + PostReposIssuesCommentsByOwnerByRepoByIssueNumber, mockResponse(t, http.StatusCreated, mockComment), ), ), @@ -423,9 +422,9 @@ func Test_AddIssueComment(t *testing.T) { }, { name: "comment creation fails", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.PostReposIssuesCommentsByOwnerByRepoByIssueNumber, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + PostReposIssuesCommentsByOwnerByRepoByIssueNumber, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusUnprocessableEntity) _, _ = w.Write([]byte(`{"message": "Invalid request"}`)) @@ -546,9 +545,9 @@ func Test_SearchIssues(t *testing.T) { }{ { name: "successful issues search with all parameters", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.GetSearchIssues, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + GetSearchIssues, expectQueryParams( t, map[string]string{ @@ -575,9 +574,9 @@ func Test_SearchIssues(t *testing.T) { }, { name: "issues search with owner and repo parameters", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.GetSearchIssues, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + GetSearchIssues, expectQueryParams( t, map[string]string{ @@ -604,9 +603,9 @@ func Test_SearchIssues(t *testing.T) { }, { name: "issues search with only owner parameter (should ignore it)", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.GetSearchIssues, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + GetSearchIssues, expectQueryParams( t, map[string]string{ @@ -628,9 +627,9 @@ func Test_SearchIssues(t *testing.T) { }, { name: "issues search with only repo parameter (should ignore it)", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.GetSearchIssues, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + GetSearchIssues, expectQueryParams( t, map[string]string{ @@ -652,9 +651,9 @@ func Test_SearchIssues(t *testing.T) { }, { name: "issues search with minimal parameters", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatch( - mock.GetSearchIssues, + mockedClient: NewMockedHTTPClient( + WithRequestMatch( + GetSearchIssues, mockSearchResult, ), ), @@ -666,9 +665,9 @@ func Test_SearchIssues(t *testing.T) { }, { name: "query with existing is:issue filter - no duplication", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.GetSearchIssues, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + GetSearchIssues, expectQueryParams( t, map[string]string{ @@ -689,9 +688,9 @@ func Test_SearchIssues(t *testing.T) { }, { name: "query with existing repo: filter and conflicting owner/repo params - uses query filter", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.GetSearchIssues, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + GetSearchIssues, expectQueryParams( t, map[string]string{ @@ -714,9 +713,9 @@ func Test_SearchIssues(t *testing.T) { }, { name: "query with both is: and repo: filters already present", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.GetSearchIssues, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + GetSearchIssues, expectQueryParams( t, map[string]string{ @@ -737,9 +736,9 @@ func Test_SearchIssues(t *testing.T) { }, { name: "complex query with multiple OR operators and existing filters", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.GetSearchIssues, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + GetSearchIssues, expectQueryParams( t, map[string]string{ @@ -760,9 +759,9 @@ func Test_SearchIssues(t *testing.T) { }, { name: "search issues fails", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.GetSearchIssues, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + GetSearchIssues, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusBadRequest) _, _ = w.Write([]byte(`{"message": "Validation Failed"}`)) @@ -868,9 +867,9 @@ func Test_CreateIssue(t *testing.T) { }{ { name: "successful issue creation with all fields", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.PostReposIssuesByOwnerByRepo, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + PostReposIssuesByOwnerByRepo, expectRequestBody(t, map[string]any{ "title": "Test Issue", "body": "This is a test issue", @@ -899,9 +898,9 @@ func Test_CreateIssue(t *testing.T) { }, { name: "successful issue creation with minimal fields", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.PostReposIssuesByOwnerByRepo, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + PostReposIssuesByOwnerByRepo, mockResponse(t, http.StatusCreated, &github.Issue{ Number: github.Ptr(124), Title: github.Ptr("Minimal Issue"), @@ -927,9 +926,9 @@ func Test_CreateIssue(t *testing.T) { }, { name: "issue creation fails", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.PostReposIssuesByOwnerByRepo, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + PostReposIssuesByOwnerByRepo, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusUnprocessableEntity) _, _ = w.Write([]byte(`{"message": "Validation failed"}`)) @@ -1427,9 +1426,9 @@ func Test_UpdateIssue(t *testing.T) { }{ { name: "partial update of non-state fields only", - mockedRESTClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.PatchReposIssuesByOwnerByRepoByIssueNumber, + mockedRESTClient: NewMockedHTTPClient( + WithRequestMatchHandler( + PatchReposIssuesByOwnerByRepoByIssueNumber, expectRequestBody(t, map[string]interface{}{ "title": "Updated Title", "body": "Updated Description", @@ -1452,9 +1451,9 @@ func Test_UpdateIssue(t *testing.T) { }, { name: "issue not found when updating non-state fields only", - mockedRESTClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.PatchReposIssuesByOwnerByRepoByIssueNumber, + mockedRESTClient: NewMockedHTTPClient( + WithRequestMatchHandler( + PatchReposIssuesByOwnerByRepoByIssueNumber, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusNotFound) _, _ = w.Write([]byte(`{"message": "Not Found"}`)) @@ -1474,9 +1473,9 @@ func Test_UpdateIssue(t *testing.T) { }, { name: "close issue as duplicate", - mockedRESTClient: mock.NewMockedHTTPClient( - mock.WithRequestMatch( - mock.PatchReposIssuesByOwnerByRepoByIssueNumber, + mockedRESTClient: NewMockedHTTPClient( + WithRequestMatch( + PatchReposIssuesByOwnerByRepoByIssueNumber, mockBaseIssue, ), ), @@ -1534,9 +1533,9 @@ func Test_UpdateIssue(t *testing.T) { }, { name: "reopen issue", - mockedRESTClient: mock.NewMockedHTTPClient( - mock.WithRequestMatch( - mock.PatchReposIssuesByOwnerByRepoByIssueNumber, + mockedRESTClient: NewMockedHTTPClient( + WithRequestMatch( + PatchReposIssuesByOwnerByRepoByIssueNumber, mockBaseIssue, ), ), @@ -1586,9 +1585,9 @@ func Test_UpdateIssue(t *testing.T) { }, { name: "main issue not found when trying to close it", - mockedRESTClient: mock.NewMockedHTTPClient( - mock.WithRequestMatch( - mock.PatchReposIssuesByOwnerByRepoByIssueNumber, + mockedRESTClient: NewMockedHTTPClient( + WithRequestMatch( + PatchReposIssuesByOwnerByRepoByIssueNumber, mockBaseIssue, ), ), @@ -1622,9 +1621,9 @@ func Test_UpdateIssue(t *testing.T) { }, { name: "duplicate issue not found when closing as duplicate", - mockedRESTClient: mock.NewMockedHTTPClient( - mock.WithRequestMatch( - mock.PatchReposIssuesByOwnerByRepoByIssueNumber, + mockedRESTClient: NewMockedHTTPClient( + WithRequestMatch( + PatchReposIssuesByOwnerByRepoByIssueNumber, mockBaseIssue, ), ), @@ -1663,9 +1662,9 @@ func Test_UpdateIssue(t *testing.T) { }, { name: "close as duplicate with combined non-state updates", - mockedRESTClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.PatchReposIssuesByOwnerByRepoByIssueNumber, + mockedRESTClient: NewMockedHTTPClient( + WithRequestMatchHandler( + PatchReposIssuesByOwnerByRepoByIssueNumber, expectRequestBody(t, map[string]interface{}{ "title": "Updated Title", "body": "Updated Description", @@ -1748,7 +1747,7 @@ func Test_UpdateIssue(t *testing.T) { }, { name: "duplicate_of without duplicate state_reason should fail", - mockedRESTClient: mock.NewMockedHTTPClient(), + mockedRESTClient: NewMockedHTTPClient(), mockedGQLClient: githubv4mock.NewMockedHTTPClient(), requestArgs: map[string]interface{}{ "method": "update", @@ -1910,9 +1909,9 @@ func Test_GetIssueComments(t *testing.T) { }{ { name: "successful comments retrieval", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatch( - mock.GetReposIssuesCommentsByOwnerByRepoByIssueNumber, + mockedClient: NewMockedHTTPClient( + WithRequestMatch( + GetReposIssuesCommentsByOwnerByRepoByIssueNumber, mockComments, ), ), @@ -1927,9 +1926,9 @@ func Test_GetIssueComments(t *testing.T) { }, { name: "successful comments retrieval with pagination", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.GetReposIssuesCommentsByOwnerByRepoByIssueNumber, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + GetReposIssuesCommentsByOwnerByRepoByIssueNumber, expectQueryParams(t, map[string]string{ "page": "2", "per_page": "10", @@ -1951,9 +1950,9 @@ func Test_GetIssueComments(t *testing.T) { }, { name: "issue not found", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.GetReposIssuesCommentsByOwnerByRepoByIssueNumber, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + GetReposIssuesCommentsByOwnerByRepoByIssueNumber, mockResponse(t, http.StatusNotFound, `{"message": "Issue not found"}`), ), ), @@ -1968,9 +1967,9 @@ func Test_GetIssueComments(t *testing.T) { }, { name: "lockdown enabled filters comments without push access", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatch( - mock.GetReposIssuesCommentsByOwnerByRepoByIssueNumber, + mockedClient: NewMockedHTTPClient( + WithRequestMatch( + GetReposIssuesCommentsByOwnerByRepoByIssueNumber, []*github.IssueComment{ { ID: github.Ptr(int64(789)), @@ -2631,9 +2630,9 @@ func Test_AddSubIssue(t *testing.T) { }{ { name: "successful sub-issue addition with all parameters", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.PostReposIssuesSubIssuesByOwnerByRepoByIssueNumber, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + PostReposIssuesSubIssuesByOwnerByRepoByIssueNumber, mockResponse(t, http.StatusCreated, mockIssue), ), ), @@ -2650,9 +2649,9 @@ func Test_AddSubIssue(t *testing.T) { }, { name: "successful sub-issue addition with minimal parameters", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.PostReposIssuesSubIssuesByOwnerByRepoByIssueNumber, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + PostReposIssuesSubIssuesByOwnerByRepoByIssueNumber, mockResponse(t, http.StatusCreated, mockIssue), ), ), @@ -2668,9 +2667,9 @@ func Test_AddSubIssue(t *testing.T) { }, { name: "successful sub-issue addition with replace_parent false", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.PostReposIssuesSubIssuesByOwnerByRepoByIssueNumber, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + PostReposIssuesSubIssuesByOwnerByRepoByIssueNumber, mockResponse(t, http.StatusCreated, mockIssue), ), ), @@ -2687,9 +2686,9 @@ func Test_AddSubIssue(t *testing.T) { }, { name: "parent issue not found", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.PostReposIssuesSubIssuesByOwnerByRepoByIssueNumber, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + PostReposIssuesSubIssuesByOwnerByRepoByIssueNumber, mockResponse(t, http.StatusNotFound, `{"message": "Parent issue not found"}`), ), ), @@ -2705,9 +2704,9 @@ func Test_AddSubIssue(t *testing.T) { }, { name: "sub-issue not found", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.PostReposIssuesSubIssuesByOwnerByRepoByIssueNumber, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + PostReposIssuesSubIssuesByOwnerByRepoByIssueNumber, mockResponse(t, http.StatusNotFound, `{"message": "Sub-issue not found"}`), ), ), @@ -2723,9 +2722,9 @@ func Test_AddSubIssue(t *testing.T) { }, { name: "validation failed - sub-issue cannot be parent of itself", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.PostReposIssuesSubIssuesByOwnerByRepoByIssueNumber, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + PostReposIssuesSubIssuesByOwnerByRepoByIssueNumber, mockResponse(t, http.StatusUnprocessableEntity, `{"message": "Validation failed", "errors": [{"message": "Sub-issue cannot be a parent of itself"}]}`), ), ), @@ -2741,9 +2740,9 @@ func Test_AddSubIssue(t *testing.T) { }, { name: "insufficient permissions", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.PostReposIssuesSubIssuesByOwnerByRepoByIssueNumber, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + PostReposIssuesSubIssuesByOwnerByRepoByIssueNumber, mockResponse(t, http.StatusForbidden, `{"message": "Must have write access to repository"}`), ), ), @@ -2759,7 +2758,7 @@ func Test_AddSubIssue(t *testing.T) { }, { name: "missing required parameter owner", - mockedClient: mock.NewMockedHTTPClient( + mockedClient: NewMockedHTTPClient( // No mocked requests needed since validation fails before HTTP call ), requestArgs: map[string]interface{}{ @@ -2773,7 +2772,7 @@ func Test_AddSubIssue(t *testing.T) { }, { name: "missing required parameter sub_issue_id", - mockedClient: mock.NewMockedHTTPClient( + mockedClient: NewMockedHTTPClient( // No mocked requests needed since validation fails before HTTP call ), requestArgs: map[string]interface{}{ @@ -2895,9 +2894,9 @@ func Test_GetSubIssues(t *testing.T) { }{ { name: "successful sub-issues listing with minimal parameters", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatch( - mock.GetReposIssuesSubIssuesByOwnerByRepoByIssueNumber, + mockedClient: NewMockedHTTPClient( + WithRequestMatch( + GetReposIssuesSubIssuesByOwnerByRepoByIssueNumber, mockSubIssues, ), ), @@ -2912,9 +2911,9 @@ func Test_GetSubIssues(t *testing.T) { }, { name: "successful sub-issues listing with pagination", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.GetReposIssuesSubIssuesByOwnerByRepoByIssueNumber, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + GetReposIssuesSubIssuesByOwnerByRepoByIssueNumber, expectQueryParams(t, map[string]string{ "page": "2", "per_page": "10", @@ -2936,9 +2935,9 @@ func Test_GetSubIssues(t *testing.T) { }, { name: "successful sub-issues listing with empty result", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatch( - mock.GetReposIssuesSubIssuesByOwnerByRepoByIssueNumber, + mockedClient: NewMockedHTTPClient( + WithRequestMatch( + GetReposIssuesSubIssuesByOwnerByRepoByIssueNumber, []*github.Issue{}, ), ), @@ -2953,9 +2952,9 @@ func Test_GetSubIssues(t *testing.T) { }, { name: "parent issue not found", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.GetReposIssuesSubIssuesByOwnerByRepoByIssueNumber, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + GetReposIssuesSubIssuesByOwnerByRepoByIssueNumber, mockResponse(t, http.StatusNotFound, `{"message": "Not Found"}`), ), ), @@ -2970,9 +2969,9 @@ func Test_GetSubIssues(t *testing.T) { }, { name: "repository not found", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.GetReposIssuesSubIssuesByOwnerByRepoByIssueNumber, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + GetReposIssuesSubIssuesByOwnerByRepoByIssueNumber, mockResponse(t, http.StatusNotFound, `{"message": "Not Found"}`), ), ), @@ -2987,9 +2986,9 @@ func Test_GetSubIssues(t *testing.T) { }, { name: "sub-issues feature gone/deprecated", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.GetReposIssuesSubIssuesByOwnerByRepoByIssueNumber, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + GetReposIssuesSubIssuesByOwnerByRepoByIssueNumber, mockResponse(t, http.StatusGone, `{"message": "This feature has been deprecated"}`), ), ), @@ -3004,7 +3003,7 @@ func Test_GetSubIssues(t *testing.T) { }, { name: "missing required parameter owner", - mockedClient: mock.NewMockedHTTPClient( + mockedClient: NewMockedHTTPClient( // No mocked requests needed since validation fails before HTTP call ), requestArgs: map[string]interface{}{ @@ -3017,7 +3016,7 @@ func Test_GetSubIssues(t *testing.T) { }, { name: "missing required parameter issue_number", - mockedClient: mock.NewMockedHTTPClient( + mockedClient: NewMockedHTTPClient( // No mocked requests needed since validation fails before HTTP call ), requestArgs: map[string]interface{}{ @@ -3135,9 +3134,9 @@ func Test_RemoveSubIssue(t *testing.T) { }{ { name: "successful sub-issue removal", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.DeleteReposIssuesSubIssueByOwnerByRepoByIssueNumber, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + DeleteReposIssuesSubIssueByOwnerByRepoByIssueNumber, mockResponse(t, http.StatusOK, mockIssue), ), ), @@ -3153,9 +3152,9 @@ func Test_RemoveSubIssue(t *testing.T) { }, { name: "parent issue not found", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.DeleteReposIssuesSubIssueByOwnerByRepoByIssueNumber, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + DeleteReposIssuesSubIssueByOwnerByRepoByIssueNumber, mockResponse(t, http.StatusNotFound, `{"message": "Not Found"}`), ), ), @@ -3171,9 +3170,9 @@ func Test_RemoveSubIssue(t *testing.T) { }, { name: "sub-issue not found", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.DeleteReposIssuesSubIssueByOwnerByRepoByIssueNumber, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + DeleteReposIssuesSubIssueByOwnerByRepoByIssueNumber, mockResponse(t, http.StatusNotFound, `{"message": "Sub-issue not found"}`), ), ), @@ -3189,9 +3188,9 @@ func Test_RemoveSubIssue(t *testing.T) { }, { name: "bad request - invalid sub_issue_id", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.DeleteReposIssuesSubIssueByOwnerByRepoByIssueNumber, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + DeleteReposIssuesSubIssueByOwnerByRepoByIssueNumber, mockResponse(t, http.StatusBadRequest, `{"message": "Invalid sub_issue_id"}`), ), ), @@ -3207,9 +3206,9 @@ func Test_RemoveSubIssue(t *testing.T) { }, { name: "repository not found", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.DeleteReposIssuesSubIssueByOwnerByRepoByIssueNumber, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + DeleteReposIssuesSubIssueByOwnerByRepoByIssueNumber, mockResponse(t, http.StatusNotFound, `{"message": "Not Found"}`), ), ), @@ -3225,9 +3224,9 @@ func Test_RemoveSubIssue(t *testing.T) { }, { name: "insufficient permissions", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.DeleteReposIssuesSubIssueByOwnerByRepoByIssueNumber, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + DeleteReposIssuesSubIssueByOwnerByRepoByIssueNumber, mockResponse(t, http.StatusForbidden, `{"message": "Must have write access to repository"}`), ), ), @@ -3243,7 +3242,7 @@ func Test_RemoveSubIssue(t *testing.T) { }, { name: "missing required parameter owner", - mockedClient: mock.NewMockedHTTPClient( + mockedClient: NewMockedHTTPClient( // No mocked requests needed since validation fails before HTTP call ), requestArgs: map[string]interface{}{ @@ -3257,7 +3256,7 @@ func Test_RemoveSubIssue(t *testing.T) { }, { name: "missing required parameter sub_issue_id", - mockedClient: mock.NewMockedHTTPClient( + mockedClient: NewMockedHTTPClient( // No mocked requests needed since validation fails before HTTP call ), requestArgs: map[string]interface{}{ @@ -3365,9 +3364,9 @@ func Test_ReprioritizeSubIssue(t *testing.T) { }{ { name: "successful reprioritization with after_id", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.PatchReposIssuesSubIssuesPriorityByOwnerByRepoByIssueNumber, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + PatchReposIssuesSubIssuesPriorityByOwnerByRepoByIssueNumber, mockResponse(t, http.StatusOK, mockIssue), ), ), @@ -3384,9 +3383,9 @@ func Test_ReprioritizeSubIssue(t *testing.T) { }, { name: "successful reprioritization with before_id", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.PatchReposIssuesSubIssuesPriorityByOwnerByRepoByIssueNumber, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + PatchReposIssuesSubIssuesPriorityByOwnerByRepoByIssueNumber, mockResponse(t, http.StatusOK, mockIssue), ), ), @@ -3403,7 +3402,7 @@ func Test_ReprioritizeSubIssue(t *testing.T) { }, { name: "validation error - neither after_id nor before_id specified", - mockedClient: mock.NewMockedHTTPClient( + mockedClient: NewMockedHTTPClient( // No mocked requests needed since validation fails before HTTP call ), requestArgs: map[string]interface{}{ @@ -3418,7 +3417,7 @@ func Test_ReprioritizeSubIssue(t *testing.T) { }, { name: "validation error - both after_id and before_id specified", - mockedClient: mock.NewMockedHTTPClient( + mockedClient: NewMockedHTTPClient( // No mocked requests needed since validation fails before HTTP call ), requestArgs: map[string]interface{}{ @@ -3435,9 +3434,9 @@ func Test_ReprioritizeSubIssue(t *testing.T) { }, { name: "parent issue not found", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.PatchReposIssuesSubIssuesPriorityByOwnerByRepoByIssueNumber, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + PatchReposIssuesSubIssuesPriorityByOwnerByRepoByIssueNumber, mockResponse(t, http.StatusNotFound, `{"message": "Not Found"}`), ), ), @@ -3454,9 +3453,9 @@ func Test_ReprioritizeSubIssue(t *testing.T) { }, { name: "sub-issue not found", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.PatchReposIssuesSubIssuesPriorityByOwnerByRepoByIssueNumber, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + PatchReposIssuesSubIssuesPriorityByOwnerByRepoByIssueNumber, mockResponse(t, http.StatusNotFound, `{"message": "Sub-issue not found"}`), ), ), @@ -3473,9 +3472,9 @@ func Test_ReprioritizeSubIssue(t *testing.T) { }, { name: "validation failed - positioning sub-issue not found", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.PatchReposIssuesSubIssuesPriorityByOwnerByRepoByIssueNumber, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + PatchReposIssuesSubIssuesPriorityByOwnerByRepoByIssueNumber, mockResponse(t, http.StatusUnprocessableEntity, `{"message": "Validation failed", "errors": [{"message": "Positioning sub-issue not found"}]}`), ), ), @@ -3492,9 +3491,9 @@ func Test_ReprioritizeSubIssue(t *testing.T) { }, { name: "insufficient permissions", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.PatchReposIssuesSubIssuesPriorityByOwnerByRepoByIssueNumber, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + PatchReposIssuesSubIssuesPriorityByOwnerByRepoByIssueNumber, mockResponse(t, http.StatusForbidden, `{"message": "Must have write access to repository"}`), ), ), @@ -3511,9 +3510,9 @@ func Test_ReprioritizeSubIssue(t *testing.T) { }, { name: "service unavailable", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.PatchReposIssuesSubIssuesPriorityByOwnerByRepoByIssueNumber, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + PatchReposIssuesSubIssuesPriorityByOwnerByRepoByIssueNumber, mockResponse(t, http.StatusServiceUnavailable, `{"message": "Service Unavailable"}`), ), ), @@ -3530,7 +3529,7 @@ func Test_ReprioritizeSubIssue(t *testing.T) { }, { name: "missing required parameter owner", - mockedClient: mock.NewMockedHTTPClient( + mockedClient: NewMockedHTTPClient( // No mocked requests needed since validation fails before HTTP call ), requestArgs: map[string]interface{}{ @@ -3545,7 +3544,7 @@ func Test_ReprioritizeSubIssue(t *testing.T) { }, { name: "missing required parameter sub_issue_id", - mockedClient: mock.NewMockedHTTPClient( + mockedClient: NewMockedHTTPClient( // No mocked requests needed since validation fails before HTTP call ), requestArgs: map[string]interface{}{ @@ -3645,9 +3644,9 @@ func Test_ListIssueTypes(t *testing.T) { }{ { name: "successful issue types retrieval", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.EndpointPattern{ + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + EndpointPattern{ Pattern: "/orgs/testorg/issue-types", Method: "GET", }, @@ -3662,9 +3661,9 @@ func Test_ListIssueTypes(t *testing.T) { }, { name: "organization not found", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.EndpointPattern{ + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + EndpointPattern{ Pattern: "/orgs/nonexistent/issue-types", Method: "GET", }, @@ -3679,9 +3678,9 @@ func Test_ListIssueTypes(t *testing.T) { }, { name: "missing owner parameter", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.EndpointPattern{ + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + EndpointPattern{ Pattern: "/orgs/testorg/issue-types", Method: "GET", }, diff --git a/pkg/github/repositories_test.go b/pkg/github/repositories_test.go index 9d7501f35..8a5cef66b 100644 --- a/pkg/github/repositories_test.go +++ b/pkg/github/repositories_test.go @@ -15,7 +15,6 @@ import ( "github.com/github/github-mcp-server/pkg/utils" "github.com/google/go-github/v79/github" "github.com/google/jsonschema-go/jsonschema" - "github.com/migueleliasweb/go-github-mock/src/mock" "github.com/modelcontextprotocol/go-sdk/mcp" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -72,16 +71,16 @@ func Test_GetFileContents(t *testing.T) { }{ { name: "successful text content fetch", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.GetReposGitRefByOwnerByRepoByRef, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + GetReposGitRefByOwnerByRepoByRef, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusOK) _, _ = w.Write([]byte(`{"ref": "refs/heads/main", "object": {"sha": ""}}`)) }), ), - mock.WithRequestMatchHandler( - mock.GetReposContentsByOwnerByRepoByPath, + WithRequestMatchHandler( + GetReposContentsByOwnerByRepoByPath, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusOK) fileContent := &github.RepositoryContent{ @@ -94,7 +93,7 @@ func Test_GetFileContents(t *testing.T) { _, _ = w.Write(contentBytes) }), ), - mock.WithRequestMatchHandler( + WithRequestMatchHandler( raw.GetRawReposContentsByOwnerByRepoByBranchByPath, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.Header().Set("Content-Type", "text/markdown") @@ -117,16 +116,16 @@ func Test_GetFileContents(t *testing.T) { }, { name: "successful file blob content fetch", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.GetReposGitRefByOwnerByRepoByRef, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + GetReposGitRefByOwnerByRepoByRef, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusOK) _, _ = w.Write([]byte(`{"ref": "refs/heads/main", "object": {"sha": ""}}`)) }), ), - mock.WithRequestMatchHandler( - mock.GetReposContentsByOwnerByRepoByPath, + WithRequestMatchHandler( + GetReposContentsByOwnerByRepoByPath, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusOK) fileContent := &github.RepositoryContent{ @@ -139,7 +138,7 @@ func Test_GetFileContents(t *testing.T) { _, _ = w.Write(contentBytes) }), ), - mock.WithRequestMatchHandler( + WithRequestMatchHandler( raw.GetRawReposContentsByOwnerByRepoByBranchByPath, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.Header().Set("Content-Type", "image/png") @@ -162,16 +161,16 @@ func Test_GetFileContents(t *testing.T) { }, { name: "successful PDF file content fetch", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.GetReposGitRefByOwnerByRepoByRef, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + GetReposGitRefByOwnerByRepoByRef, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusOK) _, _ = w.Write([]byte(`{"ref": "refs/heads/main", "object": {"sha": ""}}`)) }), ), - mock.WithRequestMatchHandler( - mock.GetReposContentsByOwnerByRepoByPath, + WithRequestMatchHandler( + GetReposContentsByOwnerByRepoByPath, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusOK) fileContent := &github.RepositoryContent{ @@ -184,7 +183,7 @@ func Test_GetFileContents(t *testing.T) { _, _ = w.Write(contentBytes) }), ), - mock.WithRequestMatchHandler( + WithRequestMatchHandler( raw.GetRawReposContentsByOwnerByRepoByBranchByPath, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.Header().Set("Content-Type", "application/pdf") @@ -207,28 +206,28 @@ func Test_GetFileContents(t *testing.T) { }, { name: "successful directory content fetch", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.GetReposByOwnerByRepo, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + GetReposByOwnerByRepo, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusOK) _, _ = w.Write([]byte(`{"name": "repo", "default_branch": "main"}`)) }), ), - mock.WithRequestMatchHandler( - mock.GetReposGitRefByOwnerByRepoByRef, + WithRequestMatchHandler( + GetReposGitRefByOwnerByRepoByRef, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusOK) _, _ = w.Write([]byte(`{"ref": "refs/heads/main", "object": {"sha": ""}}`)) }), ), - mock.WithRequestMatchHandler( - mock.GetReposContentsByOwnerByRepoByPath, + WithRequestMatchHandler( + GetReposContentsByOwnerByRepoByPath, expectQueryParams(t, map[string]string{}).andThen( mockResponse(t, http.StatusOK, mockDirContent), ), ), - mock.WithRequestMatchHandler( + WithRequestMatchHandler( raw.GetRawReposContentsByOwnerByRepoByPath, expectQueryParams(t, map[string]string{ "branch": "main", @@ -247,16 +246,16 @@ func Test_GetFileContents(t *testing.T) { }, { name: "successful text content fetch with leading slash in path", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.GetReposGitRefByOwnerByRepoByRef, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + GetReposGitRefByOwnerByRepoByRef, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusOK) _, _ = w.Write([]byte(`{"ref": "refs/heads/main", "object": {"sha": ""}}`)) }), ), - mock.WithRequestMatchHandler( - mock.GetReposContentsByOwnerByRepoByPath, + WithRequestMatchHandler( + GetReposContentsByOwnerByRepoByPath, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusOK) fileContent := &github.RepositoryContent{ @@ -269,7 +268,7 @@ func Test_GetFileContents(t *testing.T) { _, _ = w.Write(contentBytes) }), ), - mock.WithRequestMatchHandler( + WithRequestMatchHandler( raw.GetRawReposContentsByOwnerByRepoByBranchByPath, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.Header().Set("Content-Type", "text/markdown") @@ -292,22 +291,22 @@ func Test_GetFileContents(t *testing.T) { }, { name: "content fetch fails", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.GetReposGitRefByOwnerByRepoByRef, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + GetReposGitRefByOwnerByRepoByRef, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusOK) _, _ = w.Write([]byte(`{"ref": "refs/heads/main", "object": {"sha": ""}}`)) }), ), - mock.WithRequestMatchHandler( - mock.GetReposContentsByOwnerByRepoByPath, + WithRequestMatchHandler( + GetReposContentsByOwnerByRepoByPath, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusNotFound) _, _ = w.Write([]byte(`{"message": "Not Found"}`)) }), ), - mock.WithRequestMatchHandler( + WithRequestMatchHandler( raw.GetRawReposContentsByOwnerByRepoByPath, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusNotFound) @@ -418,9 +417,9 @@ func Test_ForkRepository(t *testing.T) { }{ { name: "successful repository fork", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.PostReposForksByOwnerByRepo, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + PostReposForksByOwnerByRepo, mockResponse(t, http.StatusAccepted, mockForkedRepo), ), ), @@ -433,9 +432,9 @@ func Test_ForkRepository(t *testing.T) { }, { name: "repository fork fails", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.PostReposForksByOwnerByRepo, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + PostReposForksByOwnerByRepo, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusForbidden) _, _ = w.Write([]byte(`{"message": "Forbidden"}`)) @@ -534,13 +533,13 @@ func Test_CreateBranch(t *testing.T) { }{ { name: "successful branch creation with from_branch", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatch( - mock.GetReposGitRefByOwnerByRepoByRef, + mockedClient: NewMockedHTTPClient( + WithRequestMatch( + GetReposGitRefByOwnerByRepoByRef, mockSourceRef, ), - mock.WithRequestMatch( - mock.PostReposGitRefsByOwnerByRepo, + WithRequestMatch( + PostReposGitRefsByOwnerByRepo, mockCreatedRef, ), ), @@ -555,17 +554,17 @@ func Test_CreateBranch(t *testing.T) { }, { name: "successful branch creation with default branch", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatch( - mock.GetReposByOwnerByRepo, + mockedClient: NewMockedHTTPClient( + WithRequestMatch( + GetReposByOwnerByRepo, mockRepo, ), - mock.WithRequestMatch( - mock.GetReposGitRefByOwnerByRepoByRef, + WithRequestMatch( + GetReposGitRefByOwnerByRepoByRef, mockSourceRef, ), - mock.WithRequestMatchHandler( - mock.PostReposGitRefsByOwnerByRepo, + WithRequestMatchHandler( + PostReposGitRefsByOwnerByRepo, expectRequestBody(t, map[string]interface{}{ "ref": "refs/heads/new-feature", "sha": "abc123def456", @@ -584,9 +583,9 @@ func Test_CreateBranch(t *testing.T) { }, { name: "fail to get repository", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.GetReposByOwnerByRepo, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + GetReposByOwnerByRepo, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusNotFound) _, _ = w.Write([]byte(`{"message": "Repository not found"}`)) @@ -603,9 +602,9 @@ func Test_CreateBranch(t *testing.T) { }, { name: "fail to get reference", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.GetReposGitRefByOwnerByRepoByRef, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + GetReposGitRefByOwnerByRepoByRef, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusNotFound) _, _ = w.Write([]byte(`{"message": "Reference not found"}`)) @@ -623,13 +622,13 @@ func Test_CreateBranch(t *testing.T) { }, { name: "fail to create branch", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatch( - mock.GetReposGitRefByOwnerByRepoByRef, + mockedClient: NewMockedHTTPClient( + WithRequestMatch( + GetReposGitRefByOwnerByRepoByRef, mockSourceRef, ), - mock.WithRequestMatchHandler( - mock.PostReposGitRefsByOwnerByRepo, + WithRequestMatchHandler( + PostReposGitRefsByOwnerByRepo, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusUnprocessableEntity) _, _ = w.Write([]byte(`{"message": "Reference already exists"}`)) @@ -744,9 +743,9 @@ func Test_GetCommit(t *testing.T) { }{ { name: "successful commit fetch", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.GetReposCommitsByOwnerByRepoByRef, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + GetReposCommitsByOwnerByRepoByRef, mockResponse(t, http.StatusOK, mockCommit), ), ), @@ -760,9 +759,9 @@ func Test_GetCommit(t *testing.T) { }, { name: "commit fetch fails", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.GetReposCommitsByOwnerByRepoByRef, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + GetReposCommitsByOwnerByRepoByRef, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusNotFound) _, _ = w.Write([]byte(`{"message": "Not Found"}`)) @@ -926,9 +925,9 @@ func Test_ListCommits(t *testing.T) { }{ { name: "successful commits fetch with default params", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatch( - mock.GetReposCommitsByOwnerByRepo, + mockedClient: NewMockedHTTPClient( + WithRequestMatch( + GetReposCommitsByOwnerByRepo, mockCommits, ), ), @@ -941,9 +940,9 @@ func Test_ListCommits(t *testing.T) { }, { name: "successful commits fetch with branch", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.GetReposCommitsByOwnerByRepo, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + GetReposCommitsByOwnerByRepo, expectQueryParams(t, map[string]string{ "author": "username", "sha": "main", @@ -965,9 +964,9 @@ func Test_ListCommits(t *testing.T) { }, { name: "successful commits fetch with pagination", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.GetReposCommitsByOwnerByRepo, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + GetReposCommitsByOwnerByRepo, expectQueryParams(t, map[string]string{ "page": "2", "per_page": "10", @@ -987,9 +986,9 @@ func Test_ListCommits(t *testing.T) { }, { name: "commits fetch fails", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.GetReposCommitsByOwnerByRepo, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + GetReposCommitsByOwnerByRepo, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusNotFound) _, _ = w.Write([]byte(`{"message": "Not Found"}`)) @@ -1110,9 +1109,9 @@ func Test_CreateOrUpdateFile(t *testing.T) { }{ { name: "successful file creation", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.PutReposContentsByOwnerByRepoByPath, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + PutReposContentsByOwnerByRepoByPath, expectRequestBody(t, map[string]interface{}{ "message": "Add example file", "content": "IyBFeGFtcGxlCgpUaGlzIGlzIGFuIGV4YW1wbGUgZmlsZS4=", // Base64 encoded content @@ -1135,9 +1134,9 @@ func Test_CreateOrUpdateFile(t *testing.T) { }, { name: "successful file update with SHA", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.PutReposContentsByOwnerByRepoByPath, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + PutReposContentsByOwnerByRepoByPath, expectRequestBody(t, map[string]interface{}{ "message": "Update example file", "content": "IyBVcGRhdGVkIEV4YW1wbGUKClRoaXMgZmlsZSBoYXMgYmVlbiB1cGRhdGVkLg==", // Base64 encoded content @@ -1162,9 +1161,9 @@ func Test_CreateOrUpdateFile(t *testing.T) { }, { name: "file creation fails", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.PutReposContentsByOwnerByRepoByPath, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + PutReposContentsByOwnerByRepoByPath, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusUnprocessableEntity) _, _ = w.Write([]byte(`{"message": "Invalid request"}`)) @@ -1184,9 +1183,9 @@ func Test_CreateOrUpdateFile(t *testing.T) { }, { name: "sha validation - current sha matches (304 Not Modified)", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.EndpointPattern{ + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + EndpointPattern{ Pattern: "/repos/owner/repo/contents/docs/example.md", Method: "HEAD", }, @@ -1201,8 +1200,8 @@ func Test_CreateOrUpdateFile(t *testing.T) { } }), ), - mock.WithRequestMatchHandler( - mock.PutReposContentsByOwnerByRepoByPath, + WithRequestMatchHandler( + PutReposContentsByOwnerByRepoByPath, expectRequestBody(t, map[string]interface{}{ "message": "Update example file", "content": "IyBVcGRhdGVkIEV4YW1wbGUKClRoaXMgZmlsZSBoYXMgYmVlbiB1cGRhdGVkLg==", @@ -1227,9 +1226,9 @@ func Test_CreateOrUpdateFile(t *testing.T) { }, { name: "sha validation - stale sha detected (200 OK with different ETag)", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.EndpointPattern{ + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + EndpointPattern{ Pattern: "/repos/owner/repo/contents/docs/example.md", Method: "HEAD", }, @@ -1254,9 +1253,9 @@ func Test_CreateOrUpdateFile(t *testing.T) { }, { name: "sha validation - file doesn't exist (404), proceed with create", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.EndpointPattern{ + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + EndpointPattern{ Pattern: "/repos/owner/repo/contents/docs/example.md", Method: "HEAD", }, @@ -1264,8 +1263,8 @@ func Test_CreateOrUpdateFile(t *testing.T) { w.WriteHeader(http.StatusNotFound) }), ), - mock.WithRequestMatchHandler( - mock.PutReposContentsByOwnerByRepoByPath, + WithRequestMatchHandler( + PutReposContentsByOwnerByRepoByPath, expectRequestBody(t, map[string]interface{}{ "message": "Create new file", "content": "IyBOZXcgRmlsZQoKVGhpcyBpcyBhIG5ldyBmaWxlLg==", @@ -1290,9 +1289,9 @@ func Test_CreateOrUpdateFile(t *testing.T) { }, { name: "no sha provided - file exists, returns warning", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.EndpointPattern{ + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + EndpointPattern{ Pattern: "/repos/owner/repo/contents/docs/example.md", Method: "HEAD", }, @@ -1301,8 +1300,8 @@ func Test_CreateOrUpdateFile(t *testing.T) { w.WriteHeader(http.StatusOK) }), ), - mock.WithRequestMatchHandler( - mock.PutReposContentsByOwnerByRepoByPath, + WithRequestMatchHandler( + PutReposContentsByOwnerByRepoByPath, expectRequestBody(t, map[string]interface{}{ "message": "Update without SHA", "content": "IyBVcGRhdGVkCgpVcGRhdGVkIHdpdGhvdXQgU0hBLg==", @@ -1326,9 +1325,9 @@ func Test_CreateOrUpdateFile(t *testing.T) { }, { name: "no sha provided - file doesn't exist, no warning", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.EndpointPattern{ + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + EndpointPattern{ Pattern: "/repos/owner/repo/contents/docs/example.md", Method: "HEAD", }, @@ -1336,8 +1335,8 @@ func Test_CreateOrUpdateFile(t *testing.T) { w.WriteHeader(http.StatusNotFound) }), ), - mock.WithRequestMatchHandler( - mock.PutReposContentsByOwnerByRepoByPath, + WithRequestMatchHandler( + PutReposContentsByOwnerByRepoByPath, expectRequestBody(t, map[string]interface{}{ "message": "Create new file", "content": "IyBOZXcgRmlsZQoKQ3JlYXRlZCB3aXRob3V0IFNIQQ==", @@ -1453,9 +1452,9 @@ func Test_CreateRepository(t *testing.T) { }{ { name: "successful repository creation with all parameters", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.EndpointPattern{ + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + EndpointPattern{ Pattern: "/user/repos", Method: "POST", }, @@ -1480,9 +1479,9 @@ func Test_CreateRepository(t *testing.T) { }, { name: "successful repository creation in organization", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.EndpointPattern{ + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + EndpointPattern{ Pattern: "/orgs/testorg/repos", Method: "POST", }, @@ -1508,9 +1507,9 @@ func Test_CreateRepository(t *testing.T) { }, { name: "successful repository creation with minimal parameters", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.EndpointPattern{ + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + EndpointPattern{ Pattern: "/user/repos", Method: "POST", }, @@ -1532,9 +1531,9 @@ func Test_CreateRepository(t *testing.T) { }, { name: "repository creation fails", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.EndpointPattern{ + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + EndpointPattern{ Pattern: "/user/repos", Method: "POST", }, @@ -1656,20 +1655,20 @@ func Test_PushFiles(t *testing.T) { }{ { name: "successful push of multiple files", - mockedClient: mock.NewMockedHTTPClient( + mockedClient: NewMockedHTTPClient( // Get branch reference - mock.WithRequestMatch( - mock.GetReposGitRefByOwnerByRepoByRef, + WithRequestMatch( + GetReposGitRefByOwnerByRepoByRef, mockRef, ), // Get commit - mock.WithRequestMatch( - mock.GetReposGitCommitsByOwnerByRepoByCommitSha, + WithRequestMatch( + GetReposGitCommitsByOwnerByRepoByCommitSHA, mockCommit, ), // Create tree - mock.WithRequestMatchHandler( - mock.PostReposGitTreesByOwnerByRepo, + WithRequestMatchHandler( + PostReposGitTreesByOwnerByRepo, expectRequestBody(t, map[string]interface{}{ "base_tree": "def456", "tree": []interface{}{ @@ -1691,8 +1690,8 @@ func Test_PushFiles(t *testing.T) { ), ), // Create commit - mock.WithRequestMatchHandler( - mock.PostReposGitCommitsByOwnerByRepo, + WithRequestMatchHandler( + PostReposGitCommitsByOwnerByRepo, expectRequestBody(t, map[string]interface{}{ "message": "Update multiple files", "tree": "ghi789", @@ -1702,8 +1701,8 @@ func Test_PushFiles(t *testing.T) { ), ), // Update reference - mock.WithRequestMatchHandler( - mock.PatchReposGitRefsByOwnerByRepoByRef, + WithRequestMatchHandler( + PatchReposGitRefsByOwnerByRepoByRef, expectRequestBody(t, map[string]interface{}{ "sha": "jkl012", "force": false, @@ -1733,7 +1732,7 @@ func Test_PushFiles(t *testing.T) { }, { name: "fails when files parameter is invalid", - mockedClient: mock.NewMockedHTTPClient( + mockedClient: NewMockedHTTPClient( // No requests expected ), requestArgs: map[string]interface{}{ @@ -1748,15 +1747,15 @@ func Test_PushFiles(t *testing.T) { }, { name: "fails when files contains object without path", - mockedClient: mock.NewMockedHTTPClient( + mockedClient: NewMockedHTTPClient( // Get branch reference - mock.WithRequestMatch( - mock.GetReposGitRefByOwnerByRepoByRef, + WithRequestMatch( + GetReposGitRefByOwnerByRepoByRef, mockRef, ), // Get commit - mock.WithRequestMatch( - mock.GetReposGitCommitsByOwnerByRepoByCommitSha, + WithRequestMatch( + GetReposGitCommitsByOwnerByRepoByCommitSHA, mockCommit, ), ), @@ -1776,15 +1775,15 @@ func Test_PushFiles(t *testing.T) { }, { name: "fails when files contains object without content", - mockedClient: mock.NewMockedHTTPClient( + mockedClient: NewMockedHTTPClient( // Get branch reference - mock.WithRequestMatch( - mock.GetReposGitRefByOwnerByRepoByRef, + WithRequestMatch( + GetReposGitRefByOwnerByRepoByRef, mockRef, ), // Get commit - mock.WithRequestMatch( - mock.GetReposGitCommitsByOwnerByRepoByCommitSha, + WithRequestMatch( + GetReposGitCommitsByOwnerByRepoByCommitSHA, mockCommit, ), ), @@ -1805,9 +1804,9 @@ func Test_PushFiles(t *testing.T) { }, { name: "fails to get branch reference", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.GetReposGitRefByOwnerByRepoByRef, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + GetReposGitRefByOwnerByRepoByRef, mockResponse(t, http.StatusNotFound, nil), ), ), @@ -1828,15 +1827,15 @@ func Test_PushFiles(t *testing.T) { }, { name: "fails to get base commit", - mockedClient: mock.NewMockedHTTPClient( + mockedClient: NewMockedHTTPClient( // Get branch reference - mock.WithRequestMatch( - mock.GetReposGitRefByOwnerByRepoByRef, + WithRequestMatch( + GetReposGitRefByOwnerByRepoByRef, mockRef, ), // Fail to get commit - mock.WithRequestMatchHandler( - mock.GetReposGitCommitsByOwnerByRepoByCommitSha, + WithRequestMatchHandler( + GetReposGitCommitsByOwnerByRepoByCommitSHA, mockResponse(t, http.StatusNotFound, nil), ), ), @@ -1857,20 +1856,20 @@ func Test_PushFiles(t *testing.T) { }, { name: "fails to create tree", - mockedClient: mock.NewMockedHTTPClient( + mockedClient: NewMockedHTTPClient( // Get branch reference - mock.WithRequestMatch( - mock.GetReposGitRefByOwnerByRepoByRef, + WithRequestMatch( + GetReposGitRefByOwnerByRepoByRef, mockRef, ), // Get commit - mock.WithRequestMatch( - mock.GetReposGitCommitsByOwnerByRepoByCommitSha, + WithRequestMatch( + GetReposGitCommitsByOwnerByRepoByCommitSHA, mockCommit, ), // Fail to create tree - mock.WithRequestMatchHandler( - mock.PostReposGitTreesByOwnerByRepo, + WithRequestMatchHandler( + PostReposGitTreesByOwnerByRepo, mockResponse(t, http.StatusInternalServerError, nil), ), ), @@ -1973,7 +1972,7 @@ func Test_ListBranches(t *testing.T) { tests := []struct { name string args map[string]interface{} - mockResponses []mock.MockBackendOption + mockResponses []MockBackendOption wantErr bool errContains string }{ @@ -1984,9 +1983,9 @@ func Test_ListBranches(t *testing.T) { "repo": "repo", "page": float64(2), }, - mockResponses: []mock.MockBackendOption{ - mock.WithRequestMatch( - mock.GetReposBranchesByOwnerByRepo, + mockResponses: []MockBackendOption{ + WithRequestMatch( + GetReposBranchesByOwnerByRepo, mockBranches, ), }, @@ -1997,7 +1996,7 @@ func Test_ListBranches(t *testing.T) { args: map[string]interface{}{ "repo": "repo", }, - mockResponses: []mock.MockBackendOption{}, + mockResponses: []MockBackendOption{}, wantErr: false, errContains: "missing required parameter: owner", }, @@ -2006,7 +2005,7 @@ func Test_ListBranches(t *testing.T) { args: map[string]interface{}{ "owner": "owner", }, - mockResponses: []mock.MockBackendOption{}, + mockResponses: []MockBackendOption{}, wantErr: false, errContains: "missing required parameter: repo", }, @@ -2015,7 +2014,7 @@ func Test_ListBranches(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { // Create mock client - mockClient := github.NewClient(mock.NewMockedHTTPClient(tt.mockResponses...)) + mockClient := github.NewClient(NewMockedHTTPClient(tt.mockResponses...)) deps := BaseDeps{ Client: mockClient, } @@ -2112,20 +2111,20 @@ func Test_DeleteFile(t *testing.T) { }{ { name: "successful file deletion using Git Data API", - mockedClient: mock.NewMockedHTTPClient( + mockedClient: NewMockedHTTPClient( // Get branch reference - mock.WithRequestMatch( - mock.GetReposGitRefByOwnerByRepoByRef, + WithRequestMatch( + GetReposGitRefByOwnerByRepoByRef, mockRef, ), // Get commit - mock.WithRequestMatch( - mock.GetReposGitCommitsByOwnerByRepoByCommitSha, + WithRequestMatch( + GetReposGitCommitsByOwnerByRepoByCommitSHA, mockCommit, ), // Create tree - mock.WithRequestMatchHandler( - mock.PostReposGitTreesByOwnerByRepo, + WithRequestMatchHandler( + PostReposGitTreesByOwnerByRepo, expectRequestBody(t, map[string]interface{}{ "base_tree": "def456", "tree": []interface{}{ @@ -2141,8 +2140,8 @@ func Test_DeleteFile(t *testing.T) { ), ), // Create commit - mock.WithRequestMatchHandler( - mock.PostReposGitCommitsByOwnerByRepo, + WithRequestMatchHandler( + PostReposGitCommitsByOwnerByRepo, expectRequestBody(t, map[string]interface{}{ "message": "Delete example file", "tree": "ghi789", @@ -2152,8 +2151,8 @@ func Test_DeleteFile(t *testing.T) { ), ), // Update reference - mock.WithRequestMatchHandler( - mock.PatchReposGitRefsByOwnerByRepoByRef, + WithRequestMatchHandler( + PatchReposGitRefsByOwnerByRepoByRef, expectRequestBody(t, map[string]interface{}{ "sha": "jkl012", "force": false, @@ -2179,9 +2178,9 @@ func Test_DeleteFile(t *testing.T) { }, { name: "file deletion fails - branch not found", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.GetReposGitRefByOwnerByRepoByRef, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + GetReposGitRefByOwnerByRepoByRef, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusNotFound) _, _ = w.Write([]byte(`{"message": "Reference not found"}`)) @@ -2289,9 +2288,9 @@ func Test_ListTags(t *testing.T) { }{ { name: "successful tags list", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.GetReposTagsByOwnerByRepo, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + GetReposTagsByOwnerByRepo, expectPath( t, "/repos/owner/repo/tags", @@ -2309,9 +2308,9 @@ func Test_ListTags(t *testing.T) { }, { name: "list tags fails", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.GetReposTagsByOwnerByRepo, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + GetReposTagsByOwnerByRepo, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusInternalServerError) _, _ = w.Write([]byte(`{"message": "Internal Server Error"}`)) @@ -2415,9 +2414,9 @@ func Test_GetTag(t *testing.T) { }{ { name: "successful tag retrieval", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.GetReposGitRefByOwnerByRepoByRef, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + GetReposGitRefByOwnerByRepoByRef, expectPath( t, "/repos/owner/repo/git/ref/tags/v1.0.0", @@ -2425,8 +2424,8 @@ func Test_GetTag(t *testing.T) { mockResponse(t, http.StatusOK, mockTagRef), ), ), - mock.WithRequestMatchHandler( - mock.GetReposGitTagsByOwnerByRepoByTagSha, + WithRequestMatchHandler( + GetReposGitTagsByOwnerByRepoByTagSHA, expectPath( t, "/repos/owner/repo/git/tags/v1.0.0-tag-sha", @@ -2445,9 +2444,9 @@ func Test_GetTag(t *testing.T) { }, { name: "tag reference not found", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.GetReposGitRefByOwnerByRepoByRef, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + GetReposGitRefByOwnerByRepoByRef, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusNotFound) _, _ = w.Write([]byte(`{"message": "Reference does not exist"}`)) @@ -2464,13 +2463,13 @@ func Test_GetTag(t *testing.T) { }, { name: "tag object not found", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatch( - mock.GetReposGitRefByOwnerByRepoByRef, + mockedClient: NewMockedHTTPClient( + WithRequestMatch( + GetReposGitRefByOwnerByRepoByRef, mockTagRef, ), - mock.WithRequestMatchHandler( - mock.GetReposGitTagsByOwnerByRepoByTagSha, + WithRequestMatchHandler( + GetReposGitTagsByOwnerByRepoByTagSHA, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusNotFound) _, _ = w.Write([]byte(`{"message": "Tag object does not exist"}`)) @@ -2568,9 +2567,9 @@ func Test_ListReleases(t *testing.T) { }{ { name: "successful releases list", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatch( - mock.GetReposReleasesByOwnerByRepo, + mockedClient: NewMockedHTTPClient( + WithRequestMatch( + GetReposReleasesByOwnerByRepo, mockReleases, ), ), @@ -2583,9 +2582,9 @@ func Test_ListReleases(t *testing.T) { }, { name: "releases list fails", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.GetReposReleasesByOwnerByRepo, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + GetReposReleasesByOwnerByRepo, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusNotFound) _, _ = w.Write([]byte(`{"message": "Not Found"}`)) @@ -2659,9 +2658,9 @@ func Test_GetLatestRelease(t *testing.T) { }{ { name: "successful latest release fetch", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatch( - mock.GetReposReleasesLatestByOwnerByRepo, + mockedClient: NewMockedHTTPClient( + WithRequestMatch( + GetReposReleasesLatestByOwnerByRepo, mockRelease, ), ), @@ -2674,9 +2673,9 @@ func Test_GetLatestRelease(t *testing.T) { }, { name: "latest release fetch fails", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.GetReposReleasesLatestByOwnerByRepo, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + GetReposReleasesLatestByOwnerByRepo, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusNotFound) _, _ = w.Write([]byte(`{"message": "Not Found"}`)) @@ -2756,9 +2755,9 @@ func Test_GetReleaseByTag(t *testing.T) { }{ { name: "successful release by tag fetch", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatch( - mock.GetReposReleasesTagsByOwnerByRepoByTag, + mockedClient: NewMockedHTTPClient( + WithRequestMatch( + GetReposReleasesTagsByOwnerByRepoByTag, mockRelease, ), ), @@ -2772,7 +2771,7 @@ func Test_GetReleaseByTag(t *testing.T) { }, { name: "missing owner parameter", - mockedClient: mock.NewMockedHTTPClient(), + mockedClient: NewMockedHTTPClient(), requestArgs: map[string]interface{}{ "repo": "repo", "tag": "v1.0.0", @@ -2782,7 +2781,7 @@ func Test_GetReleaseByTag(t *testing.T) { }, { name: "missing repo parameter", - mockedClient: mock.NewMockedHTTPClient(), + mockedClient: NewMockedHTTPClient(), requestArgs: map[string]interface{}{ "owner": "owner", "tag": "v1.0.0", @@ -2792,7 +2791,7 @@ func Test_GetReleaseByTag(t *testing.T) { }, { name: "missing tag parameter", - mockedClient: mock.NewMockedHTTPClient(), + mockedClient: NewMockedHTTPClient(), requestArgs: map[string]interface{}{ "owner": "owner", "repo": "repo", @@ -2802,9 +2801,9 @@ func Test_GetReleaseByTag(t *testing.T) { }, { name: "release by tag not found", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.GetReposReleasesTagsByOwnerByRepoByTag, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + GetReposReleasesTagsByOwnerByRepoByTag, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusNotFound) _, _ = w.Write([]byte(`{"message": "Not Found"}`)) @@ -2821,9 +2820,9 @@ func Test_GetReleaseByTag(t *testing.T) { }, { name: "server error", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.GetReposReleasesTagsByOwnerByRepoByTag, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + GetReposReleasesTagsByOwnerByRepoByTag, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusInternalServerError) _, _ = w.Write([]byte(`{"message": "Internal Server Error"}`)) @@ -3004,7 +3003,7 @@ func Test_resolveGitReference(t *testing.T) { sha: "123sha456", mockSetup: func() *http.Client { // No API calls should be made when SHA is provided - return mock.NewMockedHTTPClient() + return NewMockedHTTPClient() }, expectedOutput: &raw.ContentOpts{ SHA: "123sha456", @@ -3016,16 +3015,16 @@ func Test_resolveGitReference(t *testing.T) { ref: "", sha: "", mockSetup: func() *http.Client { - return mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.GetReposByOwnerByRepo, + return NewMockedHTTPClient( + WithRequestMatchHandler( + GetReposByOwnerByRepo, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusOK) _, _ = w.Write([]byte(`{"name": "repo", "default_branch": "main"}`)) }), ), - mock.WithRequestMatchHandler( - mock.GetReposGitRefByOwnerByRepoByRef, + WithRequestMatchHandler( + GetReposGitRefByOwnerByRepoByRef, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { assert.Contains(t, r.URL.Path, "/git/ref/heads/main") w.WriteHeader(http.StatusOK) @@ -3045,9 +3044,9 @@ func Test_resolveGitReference(t *testing.T) { ref: "refs/heads/feature-branch", sha: "", mockSetup: func() *http.Client { - return mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.GetReposGitRefByOwnerByRepoByRef, + return NewMockedHTTPClient( + WithRequestMatchHandler( + GetReposGitRefByOwnerByRepoByRef, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { assert.Contains(t, r.URL.Path, "/git/ref/heads/feature-branch") w.WriteHeader(http.StatusOK) @@ -3067,9 +3066,9 @@ func Test_resolveGitReference(t *testing.T) { ref: "main", sha: "", mockSetup: func() *http.Client { - return mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.GetReposGitRefByOwnerByRepoByRef, + return NewMockedHTTPClient( + WithRequestMatchHandler( + GetReposGitRefByOwnerByRepoByRef, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if strings.Contains(r.URL.Path, "/git/ref/heads/main") { w.WriteHeader(http.StatusOK) @@ -3093,9 +3092,9 @@ func Test_resolveGitReference(t *testing.T) { ref: "v1.0.0", sha: "", mockSetup: func() *http.Client { - return mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.GetReposGitRefByOwnerByRepoByRef, + return NewMockedHTTPClient( + WithRequestMatchHandler( + GetReposGitRefByOwnerByRepoByRef, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { switch { case strings.Contains(r.URL.Path, "/git/ref/heads/v1.0.0"): @@ -3123,9 +3122,9 @@ func Test_resolveGitReference(t *testing.T) { ref: "heads/feature-branch", sha: "", mockSetup: func() *http.Client { - return mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.GetReposGitRefByOwnerByRepoByRef, + return NewMockedHTTPClient( + WithRequestMatchHandler( + GetReposGitRefByOwnerByRepoByRef, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { assert.Contains(t, r.URL.Path, "/git/ref/heads/feature-branch") w.WriteHeader(http.StatusOK) @@ -3145,9 +3144,9 @@ func Test_resolveGitReference(t *testing.T) { ref: "tags/v1.0.0", sha: "", mockSetup: func() *http.Client { - return mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.GetReposGitRefByOwnerByRepoByRef, + return NewMockedHTTPClient( + WithRequestMatchHandler( + GetReposGitRefByOwnerByRepoByRef, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { assert.Contains(t, r.URL.Path, "/git/ref/tags/v1.0.0") w.WriteHeader(http.StatusOK) @@ -3167,9 +3166,9 @@ func Test_resolveGitReference(t *testing.T) { ref: "nonexistent", sha: "", mockSetup: func() *http.Client { - return mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.GetReposGitRefByOwnerByRepoByRef, + return NewMockedHTTPClient( + WithRequestMatchHandler( + GetReposGitRefByOwnerByRepoByRef, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { // Both branch and tag attempts should return 404 w.WriteHeader(http.StatusNotFound) @@ -3186,9 +3185,9 @@ func Test_resolveGitReference(t *testing.T) { ref: "refs/pull/123/head", sha: "", mockSetup: func() *http.Client { - return mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.GetReposGitRefByOwnerByRepoByRef, + return NewMockedHTTPClient( + WithRequestMatchHandler( + GetReposGitRefByOwnerByRepoByRef, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { assert.Contains(t, r.URL.Path, "/git/ref/pull/123/head") w.WriteHeader(http.StatusOK) @@ -3304,12 +3303,12 @@ func Test_ListStarredRepositories(t *testing.T) { }{ { name: "successful list for authenticated user", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.GetUserStarred, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + GetUserStarred, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusOK) - _, _ = w.Write(mock.MustMarshal(mockStarredRepos)) + _, _ = w.Write(MustMarshal(mockStarredRepos)) }), ), ), @@ -3319,12 +3318,12 @@ func Test_ListStarredRepositories(t *testing.T) { }, { name: "successful list for specific user", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.GetUsersStarredByUsername, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + GetUsersStarredByUsername, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusOK) - _, _ = w.Write(mock.MustMarshal(mockStarredRepos)) + _, _ = w.Write(MustMarshal(mockStarredRepos)) }), ), ), @@ -3336,9 +3335,9 @@ func Test_ListStarredRepositories(t *testing.T) { }, { name: "list fails", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.GetUserStarred, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + GetUserStarred, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusNotFound) _, _ = w.Write([]byte(`{"message": "Not Found"}`)) @@ -3418,9 +3417,9 @@ func Test_StarRepository(t *testing.T) { }{ { name: "successful star", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.PutUserStarredByOwnerByRepo, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + PutUserStarredByOwnerByRepo, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusNoContent) }), @@ -3434,9 +3433,9 @@ func Test_StarRepository(t *testing.T) { }, { name: "star fails", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.PutUserStarredByOwnerByRepo, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + PutUserStarredByOwnerByRepo, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusNotFound) _, _ = w.Write([]byte(`{"message": "Not Found"}`)) @@ -3509,9 +3508,9 @@ func Test_UnstarRepository(t *testing.T) { }{ { name: "successful unstar", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.DeleteUserStarredByOwnerByRepo, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + DeleteUserStarredByOwnerByRepo, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusNoContent) }), @@ -3525,9 +3524,9 @@ func Test_UnstarRepository(t *testing.T) { }, { name: "unstar fails", - mockedClient: mock.NewMockedHTTPClient( - mock.WithRequestMatchHandler( - mock.DeleteUserStarredByOwnerByRepo, + mockedClient: NewMockedHTTPClient( + WithRequestMatchHandler( + DeleteUserStarredByOwnerByRepo, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusNotFound) _, _ = w.Write([]byte(`{"message": "Not Found"}`)) diff --git a/pkg/raw/raw_mock.go b/pkg/raw/raw_mock.go index 30c7759d3..3357e2dfc 100644 --- a/pkg/raw/raw_mock.go +++ b/pkg/raw/raw_mock.go @@ -1,20 +1,24 @@ package raw -import "github.com/migueleliasweb/go-github-mock/src/mock" +// EndpointPattern represents an HTTP method and URL path pattern for mock matching. +type EndpointPattern struct { + Pattern string + Method string +} -var GetRawReposContentsByOwnerByRepoByPath mock.EndpointPattern = mock.EndpointPattern{ +var GetRawReposContentsByOwnerByRepoByPath = EndpointPattern{ Pattern: "/{owner}/{repo}/HEAD/{path:.*}", Method: "GET", } -var GetRawReposContentsByOwnerByRepoByBranchByPath mock.EndpointPattern = mock.EndpointPattern{ +var GetRawReposContentsByOwnerByRepoByBranchByPath = EndpointPattern{ Pattern: "/{owner}/{repo}/refs/heads/{branch}/{path:.*}", Method: "GET", } -var GetRawReposContentsByOwnerByRepoByTagByPath mock.EndpointPattern = mock.EndpointPattern{ +var GetRawReposContentsByOwnerByRepoByTagByPath = EndpointPattern{ Pattern: "/{owner}/{repo}/refs/tags/{tag}/{path:.*}", Method: "GET", } -var GetRawReposContentsByOwnerByRepoBySHAByPath mock.EndpointPattern = mock.EndpointPattern{ +var GetRawReposContentsByOwnerByRepoBySHAByPath = EndpointPattern{ Pattern: "/{owner}/{repo}/{sha}/{path:.*}", Method: "GET", }