Feat: Create Merge Request (#149)
- Adds the ability to create MRs to the plugin - Adds the ability to jump to specific discussions/notes in the browser - Fixes stale icons - Adds debug keybinding for discussion tree for developers
This commit is contained in:
committed by
GitHub
parent
35f0bc16a5
commit
37a53842d0
@@ -22,7 +22,7 @@ func (a *api) approveHandler(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
if res.StatusCode >= 300 {
|
||||
handleError(w, GenericError{endpoint: "/approve"}, "Could not approve merge request", res.StatusCode)
|
||||
handleError(w, GenericError{endpoint: "/mr/approve"}, "Could not approve merge request", res.StatusCode)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ func approveMergeRequestErr(pid interface{}, mr int, opt *gitlab.ApproveMergeReq
|
||||
|
||||
func TestApproveHandler(t *testing.T) {
|
||||
t.Run("Approves merge request", func(t *testing.T) {
|
||||
request := makeRequest(t, http.MethodPost, "/approve", nil)
|
||||
request := makeRequest(t, http.MethodPost, "/mr/approve", nil)
|
||||
server, _ := createRouterAndApi(fakeClient{approveMergeRequest: approveMergeRequest})
|
||||
data := serveRequest(t, server, request, SuccessResponse{})
|
||||
assert(t, data.Message, "Approved MR")
|
||||
@@ -30,23 +30,23 @@ func TestApproveHandler(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("Disallows non-POST method", func(t *testing.T) {
|
||||
request := makeRequest(t, http.MethodPut, "/approve", nil)
|
||||
request := makeRequest(t, http.MethodPut, "/mr/approve", nil)
|
||||
server, _ := createRouterAndApi(fakeClient{approveMergeRequest: approveMergeRequest})
|
||||
data := serveRequest(t, server, request, ErrorResponse{})
|
||||
checkBadMethod(t, *data, http.MethodPost)
|
||||
})
|
||||
|
||||
t.Run("Handles errors from Gitlab client", func(t *testing.T) {
|
||||
request := makeRequest(t, http.MethodPost, "/approve", nil)
|
||||
request := makeRequest(t, http.MethodPost, "/mr/approve", nil)
|
||||
server, _ := createRouterAndApi(fakeClient{approveMergeRequest: approveMergeRequestErr})
|
||||
data := serveRequest(t, server, request, ErrorResponse{})
|
||||
checkErrorFromGitlab(t, *data, "Could not approve merge request")
|
||||
})
|
||||
|
||||
t.Run("Handles non-200s from Gitlab client", func(t *testing.T) {
|
||||
request := makeRequest(t, http.MethodPost, "/approve", nil)
|
||||
request := makeRequest(t, http.MethodPost, "/mr/approve", nil)
|
||||
server, _ := createRouterAndApi(fakeClient{approveMergeRequest: approveMergeRequestNon200})
|
||||
data := serveRequest(t, server, request, ErrorResponse{})
|
||||
checkNon200(t, *data, "Could not approve merge request", "/approve")
|
||||
checkNon200(t, *data, "Could not approve merge request", "/mr/approve")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@ func (a *api) attachmentHandler(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
if res.StatusCode >= 300 {
|
||||
handleError(w, GenericError{endpoint: "/mr/attachment"}, fmt.Sprintf("Could not upload %s to Gitlab", attachmentRequest.FileName), res.StatusCode)
|
||||
handleError(w, GenericError{endpoint: "/attachment"}, fmt.Sprintf("Could not upload %s to Gitlab", attachmentRequest.FileName), res.StatusCode)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ func withMockFileReader(a *api) error {
|
||||
|
||||
func TestAttachmentHandler(t *testing.T) {
|
||||
t.Run("Returns 200-status response after upload", func(t *testing.T) {
|
||||
request := makeRequest(t, http.MethodPost, "/mr/attachment", AttachmentRequest{FilePath: "some_file_path", FileName: "some_file_name"})
|
||||
request := makeRequest(t, http.MethodPost, "/attachment", AttachmentRequest{FilePath: "some_file_path", FileName: "some_file_name"})
|
||||
router, _ := createRouterAndApi(fakeClient{uploadFile: uploadFile}, withMockFileReader)
|
||||
data := serveRequest(t, router, request, AttachmentResponse{})
|
||||
assert(t, data.SuccessResponse.Status, http.StatusOK)
|
||||
@@ -44,23 +44,23 @@ func TestAttachmentHandler(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("Disallows non-POST method", func(t *testing.T) {
|
||||
request := makeRequest(t, http.MethodPut, "/mr/attachment", AttachmentRequest{FilePath: "some_file_path", FileName: "some_file_name"})
|
||||
request := makeRequest(t, http.MethodPut, "/attachment", AttachmentRequest{FilePath: "some_file_path", FileName: "some_file_name"})
|
||||
router, _ := createRouterAndApi(fakeClient{uploadFile: uploadFile}, withMockFileReader)
|
||||
data := serveRequest(t, router, request, ErrorResponse{})
|
||||
checkBadMethod(t, *data, http.MethodPost)
|
||||
})
|
||||
|
||||
t.Run("Handles errors from Gitlab client", func(t *testing.T) {
|
||||
request := makeRequest(t, http.MethodPost, "/mr/attachment", AttachmentRequest{FilePath: "some_file_path", FileName: "some_file_name"})
|
||||
request := makeRequest(t, http.MethodPost, "/attachment", AttachmentRequest{FilePath: "some_file_path", FileName: "some_file_name"})
|
||||
router, _ := createRouterAndApi(fakeClient{uploadFile: uploadFileErr}, withMockFileReader)
|
||||
data := serveRequest(t, router, request, ErrorResponse{})
|
||||
checkErrorFromGitlab(t, *data, "Could not upload some_file_name to Gitlab")
|
||||
})
|
||||
|
||||
t.Run("Handles non-200s from Gitlab client", func(t *testing.T) {
|
||||
request := makeRequest(t, http.MethodPost, "/mr/attachment", AttachmentRequest{FilePath: "some_file_path", FileName: "some_file_name"})
|
||||
request := makeRequest(t, http.MethodPost, "/attachment", AttachmentRequest{FilePath: "some_file_path", FileName: "some_file_name"})
|
||||
router, _ := createRouterAndApi(fakeClient{uploadFile: uploadFileNon200}, withMockFileReader)
|
||||
data := serveRequest(t, router, request, ErrorResponse{})
|
||||
checkNon200(t, *data, "Could not upload some_file_name to Gitlab", "/mr/attachment")
|
||||
checkNon200(t, *data, "Could not upload some_file_name to Gitlab", "/attachment")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@ import (
|
||||
"net/http"
|
||||
"net/http/httputil"
|
||||
"os"
|
||||
"strconv"
|
||||
|
||||
"github.com/hashicorp/go-retryablehttp"
|
||||
"github.com/xanzy/go-gitlab"
|
||||
@@ -90,7 +89,7 @@ func initGitlabClient() (error, *Client) {
|
||||
}
|
||||
}
|
||||
|
||||
/* initProjectSettings fetch the project ID and merge request ID using the client. */
|
||||
/* initProjectSettings fetch the project ID using the client */
|
||||
func initProjectSettings(c *Client, gitInfo GitProjectInfo) (error, *ProjectInfo) {
|
||||
|
||||
opt := gitlab.GetProjectOptions{}
|
||||
@@ -109,31 +108,10 @@ func initProjectSettings(c *Client, gitInfo GitProjectInfo) (error, *ProjectInfo
|
||||
|
||||
projectId := fmt.Sprint(project.ID)
|
||||
|
||||
options := gitlab.ListProjectMergeRequestsOptions{
|
||||
Scope: gitlab.String("all"),
|
||||
State: gitlab.String("opened"),
|
||||
SourceBranch: &gitInfo.BranchName,
|
||||
}
|
||||
|
||||
mergeRequests, _, err := c.ListProjectMergeRequests(projectId, &options)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to list merge requests: %w", err), nil
|
||||
}
|
||||
|
||||
if len(mergeRequests) == 0 {
|
||||
return errors.New("No merge requests found"), nil
|
||||
}
|
||||
|
||||
mergeId := strconv.Itoa(mergeRequests[0].IID)
|
||||
mergeIdInt, err := strconv.Atoi(mergeId)
|
||||
if err != nil {
|
||||
return err, nil
|
||||
}
|
||||
|
||||
return nil, &ProjectInfo{
|
||||
MergeId: mergeIdInt,
|
||||
ProjectId: projectId,
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* handleError is a utililty handler that returns errors to the client along with their statuses and messages */
|
||||
|
||||
@@ -95,7 +95,7 @@ func (a *api) deleteComment(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
if res.StatusCode >= 300 {
|
||||
handleError(w, GenericError{endpoint: "/comment"}, "Could not delete comment", res.StatusCode)
|
||||
handleError(w, GenericError{endpoint: "/mr/comment"}, "Could not delete comment", res.StatusCode)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -186,7 +186,7 @@ func (a *api) postComment(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
if res.StatusCode >= 300 {
|
||||
handleError(w, GenericError{endpoint: "/comment"}, "Could not create discussion", res.StatusCode)
|
||||
handleError(w, GenericError{endpoint: "/mr/comment"}, "Could not create discussion", res.StatusCode)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -236,7 +236,7 @@ func (a *api) editComment(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
if res.StatusCode >= 300 {
|
||||
handleError(w, GenericError{endpoint: "/comment"}, "Could not update comment", res.StatusCode)
|
||||
handleError(w, GenericError{endpoint: "/mr/comment"}, "Could not update comment", res.StatusCode)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ func createMergeRequestDiscussionErr(pid interface{}, mergeRequest int, opt *git
|
||||
|
||||
func TestPostComment(t *testing.T) {
|
||||
t.Run("Creates a new note (unlinked comment)", func(t *testing.T) {
|
||||
request := makeRequest(t, http.MethodPost, "/comment", PostCommentRequest{})
|
||||
request := makeRequest(t, http.MethodPost, "/mr/comment", PostCommentRequest{})
|
||||
server, _ := createRouterAndApi(fakeClient{createMergeRequestDiscussion: createMergeRequestDiscussion})
|
||||
data := serveRequest(t, server, request, CommentResponse{})
|
||||
assert(t, data.SuccessResponse.Message, "Note created successfully")
|
||||
@@ -30,7 +30,7 @@ func TestPostComment(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("Creates a new comment", func(t *testing.T) {
|
||||
request := makeRequest(t, http.MethodPost, "/comment", PostCommentRequest{FileName: "some_file.txt"})
|
||||
request := makeRequest(t, http.MethodPost, "/mr/comment", PostCommentRequest{FileName: "some_file.txt"})
|
||||
server, _ := createRouterAndApi(fakeClient{createMergeRequestDiscussion: createMergeRequestDiscussion})
|
||||
data := serveRequest(t, server, request, CommentResponse{})
|
||||
assert(t, data.SuccessResponse.Message, "Comment created successfully")
|
||||
@@ -38,7 +38,7 @@ func TestPostComment(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("Creates a new multiline comment", func(t *testing.T) {
|
||||
request := makeRequest(t, http.MethodPost, "/comment", PostCommentRequest{
|
||||
request := makeRequest(t, http.MethodPost, "/mr/comment", PostCommentRequest{
|
||||
FileName: "some_file.txt",
|
||||
LineRange: &LineRange{
|
||||
StartRange: &LinePosition{}, /* These would have real data */
|
||||
@@ -52,17 +52,17 @@ func TestPostComment(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("Handles errors from Gitlab client", func(t *testing.T) {
|
||||
request := makeRequest(t, http.MethodPost, "/comment", PostCommentRequest{})
|
||||
request := makeRequest(t, http.MethodPost, "/mr/comment", PostCommentRequest{})
|
||||
server, _ := createRouterAndApi(fakeClient{createMergeRequestDiscussion: createMergeRequestDiscussionErr})
|
||||
data := serveRequest(t, server, request, ErrorResponse{})
|
||||
checkErrorFromGitlab(t, *data, "Could not create discussion")
|
||||
})
|
||||
|
||||
t.Run("Handles non-200s from Gitlab", func(t *testing.T) {
|
||||
request := makeRequest(t, http.MethodPost, "/comment", PostCommentRequest{})
|
||||
request := makeRequest(t, http.MethodPost, "/mr/comment", PostCommentRequest{})
|
||||
server, _ := createRouterAndApi(fakeClient{createMergeRequestDiscussion: createMergeRequestDiscussionNon200})
|
||||
data := serveRequest(t, server, request, ErrorResponse{})
|
||||
checkNon200(t, *data, "Could not create discussion", "/comment")
|
||||
checkNon200(t, *data, "Could not create discussion", "/mr/comment")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ func deleteMergeRequestDiscussionNoteNon200(pid interface{}, mergeRequest int, d
|
||||
|
||||
func TestDeleteComment(t *testing.T) {
|
||||
t.Run("Deletes a comment", func(t *testing.T) {
|
||||
request := makeRequest(t, http.MethodDelete, "/comment", DeleteCommentRequest{})
|
||||
request := makeRequest(t, http.MethodDelete, "/mr/comment", DeleteCommentRequest{})
|
||||
server, _ := createRouterAndApi(fakeClient{deleteMergeRequestDiscussionNote: deleteMergeRequestDiscussionNote})
|
||||
data := serveRequest(t, server, request, CommentResponse{})
|
||||
assert(t, data.SuccessResponse.Message, "Comment deleted successfully")
|
||||
@@ -88,17 +88,17 @@ func TestDeleteComment(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("Handles errors from Gitlab client", func(t *testing.T) {
|
||||
request := makeRequest(t, http.MethodDelete, "/comment", DeleteCommentRequest{})
|
||||
request := makeRequest(t, http.MethodDelete, "/mr/comment", DeleteCommentRequest{})
|
||||
server, _ := createRouterAndApi(fakeClient{deleteMergeRequestDiscussionNote: deleteMergeRequestDiscussionNoteErr})
|
||||
data := serveRequest(t, server, request, ErrorResponse{})
|
||||
checkErrorFromGitlab(t, *data, "Could not delete comment")
|
||||
})
|
||||
|
||||
t.Run("Handles non-200s from Gitlab", func(t *testing.T) {
|
||||
request := makeRequest(t, http.MethodDelete, "/comment", DeleteCommentRequest{})
|
||||
request := makeRequest(t, http.MethodDelete, "/mr/comment", DeleteCommentRequest{})
|
||||
server, _ := createRouterAndApi(fakeClient{deleteMergeRequestDiscussionNote: deleteMergeRequestDiscussionNoteNon200})
|
||||
data := serveRequest(t, server, request, ErrorResponse{})
|
||||
checkNon200(t, *data, "Could not delete comment", "/comment")
|
||||
checkNon200(t, *data, "Could not delete comment", "/mr/comment")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -116,7 +116,7 @@ func updateMergeRequestDiscussionNoteNon200(pid interface{}, mergeRequest int, d
|
||||
|
||||
func TestEditComment(t *testing.T) {
|
||||
t.Run("Edits a comment", func(t *testing.T) {
|
||||
request := makeRequest(t, http.MethodPatch, "/comment", EditCommentRequest{})
|
||||
request := makeRequest(t, http.MethodPatch, "/mr/comment", EditCommentRequest{})
|
||||
server, _ := createRouterAndApi(fakeClient{updateMergeRequestDiscussionNote: updateMergeRequestDiscussionNote})
|
||||
data := serveRequest(t, server, request, CommentResponse{})
|
||||
assert(t, data.SuccessResponse.Message, "Comment updated successfully")
|
||||
@@ -124,16 +124,16 @@ func TestEditComment(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("Handles errors from Gitlab client", func(t *testing.T) {
|
||||
request := makeRequest(t, http.MethodPatch, "/comment", EditCommentRequest{})
|
||||
request := makeRequest(t, http.MethodPatch, "/mr/comment", EditCommentRequest{})
|
||||
server, _ := createRouterAndApi(fakeClient{updateMergeRequestDiscussionNote: updateMergeRequestDiscussionNoteErr})
|
||||
data := serveRequest(t, server, request, ErrorResponse{})
|
||||
checkErrorFromGitlab(t, *data, "Could not update comment")
|
||||
})
|
||||
|
||||
t.Run("Handles non-200s from Gitlab", func(t *testing.T) {
|
||||
request := makeRequest(t, http.MethodPatch, "/comment", EditCommentRequest{})
|
||||
request := makeRequest(t, http.MethodPatch, "/mr/comment", EditCommentRequest{})
|
||||
server, _ := createRouterAndApi(fakeClient{updateMergeRequestDiscussionNote: updateMergeRequestDiscussionNoteNon200})
|
||||
data := serveRequest(t, server, request, ErrorResponse{})
|
||||
checkNon200(t, *data, "Could not update comment", "/comment")
|
||||
checkNon200(t, *data, "Could not update comment", "/mr/comment")
|
||||
})
|
||||
}
|
||||
|
||||
81
cmd/create_mr.go
Normal file
81
cmd/create_mr.go
Normal file
@@ -0,0 +1,81 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"github.com/xanzy/go-gitlab"
|
||||
)
|
||||
|
||||
type CreateMrRequest struct {
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description"`
|
||||
TargetBranch string `json:"target_branch"`
|
||||
}
|
||||
|
||||
/* createMr creates a merge request */
|
||||
func (a *api) createMr(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.Header().Set("Access-Control-Allow-Methods", http.MethodGet)
|
||||
if r.Method != http.MethodPost {
|
||||
handleError(w, InvalidRequestError{}, "Expected POST", http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
|
||||
body, err := io.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
handleError(w, err, "Could not read request body", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
var createMrRequest CreateMrRequest
|
||||
err = json.Unmarshal(body, &createMrRequest)
|
||||
if err != nil {
|
||||
handleError(w, err, "Could not unmarshal request body", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
if createMrRequest.Title == "" {
|
||||
handleError(w, errors.New("Title cannot be empty"), "Could not create MR", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
if createMrRequest.TargetBranch == "" {
|
||||
handleError(w, errors.New("Target branch cannot be empty"), "Could not create MR", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
opts := gitlab.CreateMergeRequestOptions{
|
||||
Title: &createMrRequest.Title,
|
||||
Description: &createMrRequest.Description,
|
||||
TargetBranch: &createMrRequest.TargetBranch,
|
||||
SourceBranch: &a.gitInfo.BranchName,
|
||||
}
|
||||
|
||||
_, res, err := a.client.CreateMergeRequest(a.projectInfo.ProjectId, &opts)
|
||||
|
||||
if err != nil {
|
||||
handleError(w, err, "Could not create MR", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
if res.StatusCode >= 300 {
|
||||
handleError(w, GenericError{endpoint: "/create_mr"}, "Could not create MR", res.StatusCode)
|
||||
return
|
||||
}
|
||||
|
||||
response := SuccessResponse{
|
||||
Status: http.StatusOK,
|
||||
Message: fmt.Sprintf("MR '%s' created", createMrRequest.Title),
|
||||
}
|
||||
|
||||
w.WriteHeader(http.StatusOK)
|
||||
|
||||
err = json.NewEncoder(w).Encode(response)
|
||||
if err != nil {
|
||||
handleError(w, err, "Could not encode response", http.StatusInternalServerError)
|
||||
}
|
||||
}
|
||||
97
cmd/create_mr_test.go
Normal file
97
cmd/create_mr_test.go
Normal file
@@ -0,0 +1,97 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/xanzy/go-gitlab"
|
||||
)
|
||||
|
||||
func createMrFn(pid interface{}, opt *gitlab.CreateMergeRequestOptions, options ...gitlab.RequestOptionFunc) (*gitlab.MergeRequest, *gitlab.Response, error) {
|
||||
return &gitlab.MergeRequest{}, makeResponse(http.StatusOK), nil
|
||||
}
|
||||
|
||||
func createMrFnErr(pid interface{}, opt *gitlab.CreateMergeRequestOptions, options ...gitlab.RequestOptionFunc) (*gitlab.MergeRequest, *gitlab.Response, error) {
|
||||
return nil, nil, errors.New("Some error from Gitlab")
|
||||
}
|
||||
|
||||
func createMrFnNon200(pid interface{}, opt *gitlab.CreateMergeRequestOptions, options ...gitlab.RequestOptionFunc) (*gitlab.MergeRequest, *gitlab.Response, error) {
|
||||
return nil, makeResponse(http.StatusSeeOther), nil
|
||||
}
|
||||
|
||||
func TestCreateMr(t *testing.T) {
|
||||
t.Run("Creates an MR", func(t *testing.T) {
|
||||
|
||||
body := CreateMrRequest{
|
||||
Title: "Some title",
|
||||
Description: "Some description",
|
||||
TargetBranch: "main",
|
||||
}
|
||||
|
||||
request := makeRequest(t, http.MethodPost, "/create_mr", body)
|
||||
server, _ := createRouterAndApi(fakeClient{createMrFn: createMrFn})
|
||||
data := serveRequest(t, server, request, SuccessResponse{})
|
||||
assert(t, data.Message, "MR 'Some title' created")
|
||||
assert(t, data.Status, http.StatusOK)
|
||||
})
|
||||
|
||||
t.Run("Disallows non-POST methods", func(t *testing.T) {
|
||||
request := makeRequest(t, http.MethodGet, "/create_mr", CreateMrRequest{})
|
||||
server, _ := createRouterAndApi(fakeClient{createMrFn: createMrFn})
|
||||
data := serveRequest(t, server, request, ErrorResponse{})
|
||||
checkBadMethod(t, *data, http.MethodPost)
|
||||
})
|
||||
|
||||
t.Run("Handles errors from Gitlab client", func(t *testing.T) {
|
||||
body := CreateMrRequest{
|
||||
Title: "Some title",
|
||||
Description: "Some description",
|
||||
TargetBranch: "main",
|
||||
}
|
||||
request := makeRequest(t, http.MethodPost, "/create_mr", body)
|
||||
server, _ := createRouterAndApi(fakeClient{createMrFn: createMrFnErr})
|
||||
data := serveRequest(t, server, request, ErrorResponse{})
|
||||
checkErrorFromGitlab(t, *data, "Could not create MR")
|
||||
})
|
||||
|
||||
t.Run("Handles non-200s from Gitlab client", func(t *testing.T) {
|
||||
body := CreateMrRequest{
|
||||
Title: "Some title",
|
||||
Description: "Some description",
|
||||
TargetBranch: "main",
|
||||
}
|
||||
request := makeRequest(t, http.MethodPost, "/create_mr", body)
|
||||
server, _ := createRouterAndApi(fakeClient{createMrFn: createMrFnNon200})
|
||||
data := serveRequest(t, server, request, ErrorResponse{})
|
||||
checkNon200(t, *data, "Could not create MR", "/create_mr")
|
||||
})
|
||||
|
||||
t.Run("Handles missing titles", func(t *testing.T) {
|
||||
body := CreateMrRequest{
|
||||
Title: "",
|
||||
Description: "Some description",
|
||||
TargetBranch: "main",
|
||||
}
|
||||
request := makeRequest(t, http.MethodPost, "/create_mr", body)
|
||||
server, _ := createRouterAndApi(fakeClient{createMrFn: createMrFn})
|
||||
data := serveRequest(t, server, request, ErrorResponse{})
|
||||
assert(t, data.Status, http.StatusBadRequest)
|
||||
assert(t, data.Message, "Could not create MR")
|
||||
assert(t, data.Details, "Title cannot be empty")
|
||||
})
|
||||
|
||||
t.Run("Handles missing target branch", func(t *testing.T) {
|
||||
body := CreateMrRequest{
|
||||
Title: "Some title",
|
||||
Description: "Some description",
|
||||
TargetBranch: "",
|
||||
}
|
||||
request := makeRequest(t, http.MethodPost, "/create_mr", body)
|
||||
server, _ := createRouterAndApi(fakeClient{createMrFn: createMrFn})
|
||||
data := serveRequest(t, server, request, ErrorResponse{})
|
||||
assert(t, data.Status, http.StatusBadRequest)
|
||||
assert(t, data.Message, "Could not create MR")
|
||||
assert(t, data.Details, "Target branch cannot be empty")
|
||||
})
|
||||
}
|
||||
@@ -28,7 +28,7 @@ func (a *api) infoHandler(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
if res.StatusCode >= 300 {
|
||||
handleError(w, GenericError{endpoint: "/info"}, "Could not get project info", res.StatusCode)
|
||||
handleError(w, GenericError{endpoint: "/mr/info"}, "Could not get project info", res.StatusCode)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ func getInfoErr(pid interface{}, mergeRequest int, opt *gitlab.GetMergeRequestsO
|
||||
|
||||
func TestInfoHandler(t *testing.T) {
|
||||
t.Run("Returns normal information", func(t *testing.T) {
|
||||
request := makeRequest(t, http.MethodGet, "/info", nil)
|
||||
request := makeRequest(t, http.MethodGet, "/mr/info", nil)
|
||||
server, _ := createRouterAndApi(fakeClient{getMergeRequestFn: getInfo})
|
||||
data := serveRequest(t, server, request, InfoResponse{})
|
||||
assert(t, data.Info.Title, "Some Title")
|
||||
@@ -31,23 +31,23 @@ func TestInfoHandler(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("Disallows non-GET method", func(t *testing.T) {
|
||||
request := makeRequest(t, http.MethodPost, "/info", nil)
|
||||
request := makeRequest(t, http.MethodPost, "/mr/info", nil)
|
||||
server, _ := createRouterAndApi(fakeClient{getMergeRequestFn: getInfo})
|
||||
data := serveRequest(t, server, request, ErrorResponse{})
|
||||
checkBadMethod(t, *data, http.MethodGet)
|
||||
})
|
||||
|
||||
t.Run("Handles errors from Gitlab client", func(t *testing.T) {
|
||||
request := makeRequest(t, http.MethodGet, "/info", nil)
|
||||
request := makeRequest(t, http.MethodGet, "/mr/info", nil)
|
||||
server, _ := createRouterAndApi(fakeClient{getMergeRequestFn: getInfoErr})
|
||||
data := serveRequest(t, server, request, ErrorResponse{})
|
||||
checkErrorFromGitlab(t, *data, "Could not get project info")
|
||||
})
|
||||
|
||||
t.Run("Handles non-200s from Gitlab client", func(t *testing.T) {
|
||||
request := makeRequest(t, http.MethodGet, "/info", nil)
|
||||
request := makeRequest(t, http.MethodGet, "/mr/info", nil)
|
||||
server, _ := createRouterAndApi(fakeClient{getMergeRequestFn: getInfoNon200})
|
||||
data := serveRequest(t, server, request, ErrorResponse{})
|
||||
checkNon200(t, *data, "Could not get project info", "/info")
|
||||
checkNon200(t, *data, "Could not get project info", "/mr/info")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ func (a *api) listDiscussionsHandler(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
if res.StatusCode >= 300 {
|
||||
handleError(w, GenericError{endpoint: "/discussions/list"}, "Could not list discussions", res.StatusCode)
|
||||
handleError(w, GenericError{endpoint: "/mr/discussions/list"}, "Could not list discussions", res.StatusCode)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ func listMergeRequestDiscussionsNon200(pid interface{}, mergeRequest int, opt *g
|
||||
|
||||
func TestListDiscussionsHandler(t *testing.T) {
|
||||
t.Run("Returns sorted discussions", func(t *testing.T) {
|
||||
request := makeRequest(t, http.MethodPost, "/discussions/list", DiscussionsRequest{})
|
||||
request := makeRequest(t, http.MethodPost, "/mr/discussions/list", DiscussionsRequest{})
|
||||
server, _ := createRouterAndApi(fakeClient{listMergeRequestDiscussions: listMergeRequestDiscussions})
|
||||
data := serveRequest(t, server, request, DiscussionsResponse{})
|
||||
assert(t, data.SuccessResponse.Message, "Discussions retrieved")
|
||||
@@ -59,7 +59,7 @@ func TestListDiscussionsHandler(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("Uses blacklist to filter unwanted authors", func(t *testing.T) {
|
||||
request := makeRequest(t, http.MethodPost, "/discussions/list", DiscussionsRequest{Blacklist: []string{"hcramer"}})
|
||||
request := makeRequest(t, http.MethodPost, "/mr/discussions/list", DiscussionsRequest{Blacklist: []string{"hcramer"}})
|
||||
server, _ := createRouterAndApi(fakeClient{listMergeRequestDiscussions: listMergeRequestDiscussions})
|
||||
data := serveRequest(t, server, request, DiscussionsResponse{})
|
||||
assert(t, data.SuccessResponse.Message, "Discussions retrieved")
|
||||
@@ -69,23 +69,23 @@ func TestListDiscussionsHandler(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("Disallows non-POST method", func(t *testing.T) {
|
||||
request := makeRequest(t, http.MethodPatch, "/discussions/list", DiscussionsRequest{})
|
||||
request := makeRequest(t, http.MethodPatch, "/mr/discussions/list", DiscussionsRequest{})
|
||||
server, _ := createRouterAndApi(fakeClient{listMergeRequestDiscussions: listMergeRequestDiscussions})
|
||||
data := serveRequest(t, server, request, ErrorResponse{})
|
||||
checkBadMethod(t, *data, http.MethodPost)
|
||||
})
|
||||
|
||||
t.Run("Handles errors from Gitlab client", func(t *testing.T) {
|
||||
request := makeRequest(t, http.MethodPost, "/discussions/list", DiscussionsRequest{})
|
||||
request := makeRequest(t, http.MethodPost, "/mr/discussions/list", DiscussionsRequest{})
|
||||
server, _ := createRouterAndApi(fakeClient{listMergeRequestDiscussions: listMergeRequestDiscussionsErr})
|
||||
data := serveRequest(t, server, request, ErrorResponse{})
|
||||
checkErrorFromGitlab(t, *data, "Could not list discussions")
|
||||
})
|
||||
|
||||
t.Run("Handles non-200s from Gitlab client", func(t *testing.T) {
|
||||
request := makeRequest(t, http.MethodPost, "/discussions/list", DiscussionsRequest{})
|
||||
request := makeRequest(t, http.MethodPost, "/mr/discussions/list", DiscussionsRequest{})
|
||||
server, _ := createRouterAndApi(fakeClient{listMergeRequestDiscussions: listMergeRequestDiscussionsNon200})
|
||||
data := serveRequest(t, server, request, ErrorResponse{})
|
||||
checkNon200(t, *data, "Could not list discussions", "/discussions/list")
|
||||
checkNon200(t, *data, "Could not list discussions", "/mr/discussions/list")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -20,5 +20,5 @@ func main() {
|
||||
log.Fatalf("Failed to initialize project settings: %v", err)
|
||||
}
|
||||
|
||||
startServer(client, projectInfo)
|
||||
startServer(client, projectInfo, gitInfo)
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ func (a *api) acceptAndMergeHandler(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
if res.StatusCode >= 300 {
|
||||
handleError(w, GenericError{endpoint: "/merge"}, "Could not merge MR", res.StatusCode)
|
||||
handleError(w, GenericError{endpoint: "/mr/merge"}, "Could not merge MR", res.StatusCode)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ func acceptAndMergeNon200(pid interface{}, mergeRequest int, opt *gitlab.AcceptM
|
||||
|
||||
func TestAcceptAndMergeHandler(t *testing.T) {
|
||||
t.Run("Accepts and merges a merge request", func(t *testing.T) {
|
||||
request := makeRequest(t, http.MethodPost, "/merge", AcceptMergeRequestRequest{})
|
||||
request := makeRequest(t, http.MethodPost, "/mr/merge", AcceptMergeRequestRequest{})
|
||||
server, _ := createRouterAndApi(fakeClient{acceptAndMergeFn: acceptAndMergeFn})
|
||||
data := serveRequest(t, server, request, SuccessResponse{})
|
||||
assert(t, data.Message, "MR merged successfully")
|
||||
@@ -30,23 +30,23 @@ func TestAcceptAndMergeHandler(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("Disallows non-POST methods", func(t *testing.T) {
|
||||
request := makeRequest(t, http.MethodGet, "/merge", AcceptMergeRequestRequest{})
|
||||
request := makeRequest(t, http.MethodGet, "/mr/merge", AcceptMergeRequestRequest{})
|
||||
server, _ := createRouterAndApi(fakeClient{acceptAndMergeFn: acceptAndMergeFn})
|
||||
data := serveRequest(t, server, request, ErrorResponse{})
|
||||
checkBadMethod(t, *data, http.MethodPost)
|
||||
})
|
||||
|
||||
t.Run("Handles errors from Gitlab client", func(t *testing.T) {
|
||||
request := makeRequest(t, http.MethodPost, "/merge", AcceptMergeRequestRequest{})
|
||||
request := makeRequest(t, http.MethodPost, "/mr/merge", AcceptMergeRequestRequest{})
|
||||
server, _ := createRouterAndApi(fakeClient{acceptAndMergeFn: acceptAndMergeFnErr})
|
||||
data := serveRequest(t, server, request, ErrorResponse{})
|
||||
checkErrorFromGitlab(t, *data, "Could not merge MR")
|
||||
})
|
||||
|
||||
t.Run("Handles non-200s from Gitlab client", func(t *testing.T) {
|
||||
request := makeRequest(t, http.MethodPost, "/merge", AcceptMergeRequestRequest{})
|
||||
request := makeRequest(t, http.MethodPost, "/mr/merge", AcceptMergeRequestRequest{})
|
||||
server, _ := createRouterAndApi(fakeClient{acceptAndMergeFn: acceptAndMergeNon200})
|
||||
data := serveRequest(t, server, request, ErrorResponse{})
|
||||
checkNon200(t, *data, "Could not merge MR", "/merge")
|
||||
checkNon200(t, *data, "Could not merge MR", "/mr/merge")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ func (a *api) replyHandler(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
if res.StatusCode >= 300 {
|
||||
handleError(w, GenericError{endpoint: "/reply"}, "Could not leave reply", res.StatusCode)
|
||||
handleError(w, GenericError{endpoint: "/mr/reply"}, "Could not leave reply", res.StatusCode)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ func addMergeRequestDiscussionNoteNon200(pid interface{}, mergeRequest int, disc
|
||||
|
||||
func TestReplyHandler(t *testing.T) {
|
||||
t.Run("Sends a reply", func(t *testing.T) {
|
||||
request := makeRequest(t, http.MethodPost, "/reply", ReplyRequest{})
|
||||
request := makeRequest(t, http.MethodPost, "/mr/reply", ReplyRequest{})
|
||||
server, _ := createRouterAndApi(fakeClient{addMergeRequestDiscussionNote: addMergeRequestDiscussionNote})
|
||||
data := serveRequest(t, server, request, ReplyResponse{})
|
||||
assert(t, data.SuccessResponse.Message, "Replied to comment")
|
||||
@@ -30,23 +30,23 @@ func TestReplyHandler(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("Disallows non-POST methods", func(t *testing.T) {
|
||||
request := makeRequest(t, http.MethodGet, "/reply", ReplyRequest{})
|
||||
request := makeRequest(t, http.MethodGet, "/mr/reply", ReplyRequest{})
|
||||
server, _ := createRouterAndApi(fakeClient{addMergeRequestDiscussionNote: addMergeRequestDiscussionNote})
|
||||
data := serveRequest(t, server, request, ErrorResponse{})
|
||||
checkBadMethod(t, *data, http.MethodPost)
|
||||
})
|
||||
|
||||
t.Run("Handles errors from Gitlab client", func(t *testing.T) {
|
||||
request := makeRequest(t, http.MethodPost, "/reply", ReplyRequest{})
|
||||
request := makeRequest(t, http.MethodPost, "/mr/reply", ReplyRequest{})
|
||||
server, _ := createRouterAndApi(fakeClient{addMergeRequestDiscussionNote: addMergeRequestDiscussionNoteErr})
|
||||
data := serveRequest(t, server, request, ErrorResponse{})
|
||||
checkErrorFromGitlab(t, *data, "Could not leave reply")
|
||||
})
|
||||
|
||||
t.Run("Handles non-200s from Gitlab client", func(t *testing.T) {
|
||||
request := makeRequest(t, http.MethodPost, "/reply", ReplyRequest{})
|
||||
request := makeRequest(t, http.MethodPost, "/mr/reply", ReplyRequest{})
|
||||
server, _ := createRouterAndApi(fakeClient{addMergeRequestDiscussionNote: addMergeRequestDiscussionNoteNon200})
|
||||
data := serveRequest(t, server, request, ErrorResponse{})
|
||||
checkNon200(t, *data, "Could not leave reply", "/reply")
|
||||
checkNon200(t, *data, "Could not leave reply", "/mr/reply")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ func (a *api) discussionsResolveHandler(w http.ResponseWriter, r *http.Request)
|
||||
}
|
||||
|
||||
if res.StatusCode >= 300 {
|
||||
handleError(w, GenericError{endpoint: "/discussions/resolve"}, fmt.Sprintf("Could not %s discussion", friendlyName), res.StatusCode)
|
||||
handleError(w, GenericError{endpoint: "/mr/discussions/resolve"}, fmt.Sprintf("Could not %s discussion", friendlyName), res.StatusCode)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ func (a *api) revokeHandler(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
if res.StatusCode >= 300 {
|
||||
handleError(w, GenericError{endpoint: "/revoke"}, "Could not revoke approval", res.StatusCode)
|
||||
handleError(w, GenericError{endpoint: "/mr/revoke"}, "Could not revoke approval", res.StatusCode)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -7,14 +7,17 @@ import (
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/xanzy/go-gitlab"
|
||||
)
|
||||
|
||||
/*
|
||||
startSever starts the server and runs concurrent goroutines
|
||||
to handle potential shutdown requests and incoming HTTP requests.
|
||||
*/
|
||||
func startServer(client *Client, projectInfo *ProjectInfo) {
|
||||
func startServer(client *Client, projectInfo *ProjectInfo, gitInfo GitProjectInfo) {
|
||||
|
||||
m, a := createRouterAndApi(client,
|
||||
func(a *api) error {
|
||||
@@ -24,6 +27,10 @@ func startServer(client *Client, projectInfo *ProjectInfo) {
|
||||
func(a *api) error {
|
||||
a.fileReader = attachmentReader{}
|
||||
return nil
|
||||
},
|
||||
func(a *api) error {
|
||||
a.gitInfo = &gitInfo
|
||||
return nil
|
||||
})
|
||||
|
||||
l := createListener()
|
||||
@@ -73,6 +80,7 @@ with the client value, which is a go-gitlab client.
|
||||
type api struct {
|
||||
client ClientInterface
|
||||
projectInfo *ProjectInfo
|
||||
gitInfo *GitProjectInfo
|
||||
fileReader FileReader
|
||||
sigCh chan os.Signal
|
||||
}
|
||||
@@ -84,11 +92,13 @@ createRouterAndApi wires up the router and attaches all handlers to their respec
|
||||
iterates over all option functions to configure API fields such as the project information and default
|
||||
file reader functionality
|
||||
*/
|
||||
|
||||
func createRouterAndApi(client ClientInterface, optFuncs ...optFunc) (*http.ServeMux, api) {
|
||||
m := http.NewServeMux()
|
||||
a := api{
|
||||
client: client,
|
||||
projectInfo: &ProjectInfo{},
|
||||
gitInfo: &GitProjectInfo{},
|
||||
fileReader: nil,
|
||||
sigCh: make(chan os.Signal, 1),
|
||||
}
|
||||
@@ -101,24 +111,27 @@ func createRouterAndApi(client ClientInterface, optFuncs ...optFunc) (*http.Serv
|
||||
}
|
||||
}
|
||||
|
||||
m.Handle("/ping", http.HandlerFunc(pingHandler))
|
||||
m.HandleFunc("/shutdown", a.shutdownHandler)
|
||||
m.HandleFunc("/approve", a.approveHandler)
|
||||
m.HandleFunc("/comment", a.commentHandler)
|
||||
m.HandleFunc("/merge", a.acceptAndMergeHandler)
|
||||
m.HandleFunc("/discussions/list", a.listDiscussionsHandler)
|
||||
m.HandleFunc("/discussions/resolve", a.discussionsResolveHandler)
|
||||
m.HandleFunc("/info", a.infoHandler)
|
||||
m.HandleFunc("/mr/approve", a.withMr(a.approveHandler))
|
||||
m.HandleFunc("/mr/comment", a.withMr(a.commentHandler))
|
||||
m.HandleFunc("/mr/merge", a.withMr(a.acceptAndMergeHandler))
|
||||
m.HandleFunc("/mr/discussions/list", a.withMr(a.listDiscussionsHandler))
|
||||
m.HandleFunc("/mr/discussions/resolve", a.withMr(a.discussionsResolveHandler))
|
||||
m.HandleFunc("/mr/info", a.withMr(a.infoHandler))
|
||||
m.HandleFunc("/mr/assignee", a.withMr(a.assigneesHandler))
|
||||
m.HandleFunc("/mr/summary", a.withMr(a.summaryHandler))
|
||||
m.HandleFunc("/mr/reviewer", a.withMr(a.reviewersHandler))
|
||||
m.HandleFunc("/mr/revisions", a.withMr(a.revisionsHandler))
|
||||
m.HandleFunc("/mr/reply", a.withMr(a.replyHandler))
|
||||
m.HandleFunc("/mr/revoke", a.withMr(a.revokeHandler))
|
||||
|
||||
m.HandleFunc("/attachment", a.attachmentHandler)
|
||||
m.HandleFunc("/create_mr", a.createMr)
|
||||
m.HandleFunc("/job", a.jobHandler)
|
||||
m.HandleFunc("/mr/attachment", a.attachmentHandler)
|
||||
m.HandleFunc("/mr/assignee", a.assigneesHandler)
|
||||
m.HandleFunc("/mr/summary", a.summaryHandler)
|
||||
m.HandleFunc("/mr/reviewer", a.reviewersHandler)
|
||||
m.HandleFunc("/mr/revisions", a.revisionsHandler)
|
||||
m.HandleFunc("/pipeline/", a.pipelineHandler)
|
||||
m.HandleFunc("/project/members", a.projectMembersHandler)
|
||||
m.HandleFunc("/reply", a.replyHandler)
|
||||
m.HandleFunc("/revoke", a.revokeHandler)
|
||||
m.HandleFunc("/shutdown", a.shutdownHandler)
|
||||
|
||||
m.Handle("/ping", http.HandlerFunc(pingHandler))
|
||||
|
||||
return m, a
|
||||
}
|
||||
@@ -157,3 +170,41 @@ func createListener() (l net.Listener) {
|
||||
|
||||
return l
|
||||
}
|
||||
|
||||
/* withMr is a Middlware that gets the current merge request ID and attaches it to the projectInfo */
|
||||
func (a *api) withMr(f func(w http.ResponseWriter, r *http.Request)) func(http.ResponseWriter, *http.Request) {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
if a.projectInfo.MergeId != 0 {
|
||||
f(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
options := gitlab.ListProjectMergeRequestsOptions{
|
||||
Scope: gitlab.String("all"),
|
||||
State: gitlab.String("opened"),
|
||||
SourceBranch: &a.gitInfo.BranchName,
|
||||
}
|
||||
|
||||
mergeRequests, _, err := a.client.ListProjectMergeRequests(a.projectInfo.ProjectId, &options)
|
||||
if err != nil {
|
||||
handleError(w, fmt.Errorf("Failed to list merge requests: %w", err), "Failed to list merge requests", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
if len(mergeRequests) == 0 {
|
||||
handleError(w, fmt.Errorf("No merge requests found for branch '%s'", a.gitInfo.BranchName), "No merge requests found", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
mergeId := strconv.Itoa(mergeRequests[0].IID)
|
||||
mergeIdInt, err := strconv.Atoi(mergeId)
|
||||
if err != nil {
|
||||
handleError(w, err, "Could not convert merge ID to integer", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
a.projectInfo.MergeId = mergeIdInt
|
||||
f(w, r)
|
||||
}
|
||||
}
|
||||
|
||||
39
cmd/test.go
39
cmd/test.go
@@ -18,6 +18,7 @@ The FakeHandlerClient is used to create a fake gitlab client for testing our han
|
||||
*/
|
||||
|
||||
type fakeClient struct {
|
||||
createMrFn func(pid interface{}, opt *gitlab.CreateMergeRequestOptions, options ...gitlab.RequestOptionFunc) (*gitlab.MergeRequest, *gitlab.Response, error)
|
||||
getMergeRequestFn func(pid interface{}, mergeRequest int, opt *gitlab.GetMergeRequestsOptions, options ...gitlab.RequestOptionFunc) (*gitlab.MergeRequest, *gitlab.Response, error)
|
||||
updateMergeRequestFn func(pid interface{}, mergeRequest int, opt *gitlab.UpdateMergeRequestOptions, options ...gitlab.RequestOptionFunc) (*gitlab.MergeRequest, *gitlab.Response, error)
|
||||
acceptAndMergeFn func(pid interface{}, mergeRequest int, opt *gitlab.AcceptMergeRequestOptions, options ...gitlab.RequestOptionFunc) (*gitlab.MergeRequest, *gitlab.Response, error)
|
||||
@@ -47,6 +48,10 @@ type Author struct {
|
||||
WebURL string `json:"web_url"`
|
||||
}
|
||||
|
||||
func (f fakeClient) CreateMergeRequest(pid interface{}, opt *gitlab.CreateMergeRequestOptions, options ...gitlab.RequestOptionFunc) (*gitlab.MergeRequest, *gitlab.Response, error) {
|
||||
return f.createMrFn(pid, opt, options...)
|
||||
}
|
||||
|
||||
func (f fakeClient) AcceptMergeRequest(pid interface{}, mergeRequest int, opt *gitlab.AcceptMergeRequestOptions, options ...gitlab.RequestOptionFunc) (*gitlab.MergeRequest, *gitlab.Response, error) {
|
||||
return f.acceptAndMergeFn(pid, mergeRequest, opt, options...)
|
||||
}
|
||||
@@ -77,35 +82,6 @@ func (f fakeClient) ApproveMergeRequest(pid interface{}, mr int, opt *gitlab.App
|
||||
|
||||
func (f fakeClient) ListMergeRequestDiscussions(pid interface{}, mergeRequest int, opt *gitlab.ListMergeRequestDiscussionsOptions, options ...gitlab.RequestOptionFunc) ([]*gitlab.Discussion, *gitlab.Response, error) {
|
||||
return f.listMergeRequestDiscussions(pid, mergeRequest, opt, options...)
|
||||
|
||||
// now := time.Now()
|
||||
// later := now.Add(time.Second * 100)
|
||||
//
|
||||
// discussions := []*gitlab.Discussion{
|
||||
// {
|
||||
// Notes: []*gitlab.Note{
|
||||
// {
|
||||
// CreatedAt: &now,
|
||||
// Type: "DiffNote",
|
||||
// Author: Author{
|
||||
// Username: "hcramer",
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// Notes: []*gitlab.Note{
|
||||
// {
|
||||
// CreatedAt: &later,
|
||||
// Type: "DiffNote",
|
||||
// Author: Author{
|
||||
// Username: "hcramer2",
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// }
|
||||
// return discussions, makeResponse(200), nil
|
||||
}
|
||||
|
||||
func (f fakeClient) ResolveMergeRequestDiscussion(pid interface{}, mergeRequest int, discussion string, opt *gitlab.ResolveMergeRequestDiscussionOptions, options ...gitlab.RequestOptionFunc) (*gitlab.Discussion, *gitlab.Response, error) {
|
||||
@@ -144,6 +120,11 @@ func (f fakeClient) GetTraceFile(pid interface{}, jobID int, options ...gitlab.R
|
||||
return f.getTraceFile(pid, jobID, options...)
|
||||
}
|
||||
|
||||
/* This middleware function needs to return an ID for the rest of the handlers */
|
||||
func (f fakeClient) ListProjectMergeRequests(pid interface{}, opt *gitlab.ListProjectMergeRequestsOptions, options ...gitlab.RequestOptionFunc) ([]*gitlab.MergeRequest, *gitlab.Response, error) {
|
||||
return []*gitlab.MergeRequest{{ID: 1}}, &gitlab.Response{}, nil
|
||||
}
|
||||
|
||||
/* The assert function is a helper function used to check two comparables */
|
||||
func assert[T comparable](t *testing.T, got T, want T) {
|
||||
t.Helper()
|
||||
|
||||
@@ -35,6 +35,8 @@ func (e InvalidRequestError) Error() string {
|
||||
|
||||
/* The ClientInterface interface implements all the methods that our handlers need */
|
||||
type ClientInterface interface {
|
||||
CreateMergeRequest(pid interface{}, opt *gitlab.CreateMergeRequestOptions, options ...gitlab.RequestOptionFunc) (*gitlab.MergeRequest, *gitlab.Response, error)
|
||||
ListProjectMergeRequests(pid interface{}, opt *gitlab.ListProjectMergeRequestsOptions, options ...gitlab.RequestOptionFunc) ([]*gitlab.MergeRequest, *gitlab.Response, error)
|
||||
GetMergeRequest(pid interface{}, mr int, opt *gitlab.GetMergeRequestsOptions, options ...gitlab.RequestOptionFunc) (*gitlab.MergeRequest, *gitlab.Response, error)
|
||||
AcceptMergeRequest(pid interface{}, mergeRequest int, opt *gitlab.AcceptMergeRequestOptions, options ...gitlab.RequestOptionFunc) (*gitlab.MergeRequest, *gitlab.Response, error)
|
||||
UpdateMergeRequest(pid interface{}, mr int, opt *gitlab.UpdateMergeRequestOptions, options ...gitlab.RequestOptionFunc) (*gitlab.MergeRequest, *gitlab.Response, error)
|
||||
|
||||
Reference in New Issue
Block a user