feat: add mergeability checks to summary view
This commit is contained in:
@@ -32,6 +32,7 @@ type Client struct {
|
||||
gitlab.UsersServiceInterface
|
||||
gitlab.DraftNotesServiceInterface
|
||||
gitlab.ProjectMarkdownUploadsServiceInterface
|
||||
gitlab.GraphQLInterface
|
||||
}
|
||||
|
||||
/* NewClient parses and validates the project settings and initializes the Gitlab client. */
|
||||
@@ -100,6 +101,7 @@ func NewClient() (*Client, error) {
|
||||
client.Users,
|
||||
client.DraftNotes,
|
||||
client.ProjectMarkdownUploads,
|
||||
client.GraphQL,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
||||
83
cmd/app/mergeability_checks.go
Normal file
83
cmd/app/mergeability_checks.go
Normal file
@@ -0,0 +1,83 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
gitlab "gitlab.com/gitlab-org/api/client-go"
|
||||
)
|
||||
|
||||
type MergeabilityCheck struct {
|
||||
Identifier string `json:"identifier"`
|
||||
Status string `json:"status"`
|
||||
}
|
||||
|
||||
type MergeabilityChecksResponse struct {
|
||||
SuccessResponse
|
||||
MergeabilityChecks []*MergeabilityCheck `json:"mergeability_checks"`
|
||||
}
|
||||
|
||||
type mergeabilityChecksGraphQLResponse struct {
|
||||
Data struct {
|
||||
Project struct {
|
||||
MergeRequest struct {
|
||||
MergeabilityChecks []*MergeabilityCheck `json:"mergeabilityChecks"`
|
||||
} `json:"mergeRequest"`
|
||||
} `json:"project"`
|
||||
} `json:"data"`
|
||||
}
|
||||
|
||||
const mergeabilityChecksQuery = `
|
||||
query GetMergeabilityChecks($projectPath: ID!, $iid: String!) {
|
||||
project(fullPath: $projectPath) {
|
||||
mergeRequest(iid: $iid) {
|
||||
mergeabilityChecks {
|
||||
identifier
|
||||
status
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
type mergeabilityChecksService struct {
|
||||
data
|
||||
client gitlab.GraphQLInterface
|
||||
}
|
||||
|
||||
func (a mergeabilityChecksService) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
checks, err := a.fetchMergeabilityChecks()
|
||||
if err != nil {
|
||||
handleError(w, err, "Could not get mergeability checks", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
w.WriteHeader(http.StatusOK)
|
||||
response := MergeabilityChecksResponse{
|
||||
SuccessResponse: SuccessResponse{Message: "Mergeability checks retrieved"},
|
||||
MergeabilityChecks: checks,
|
||||
}
|
||||
|
||||
err = json.NewEncoder(w).Encode(response)
|
||||
if err != nil {
|
||||
handleError(w, err, "Could not encode response", http.StatusInternalServerError)
|
||||
}
|
||||
}
|
||||
|
||||
func (a mergeabilityChecksService) fetchMergeabilityChecks() ([]*MergeabilityCheck, error) {
|
||||
var response mergeabilityChecksGraphQLResponse
|
||||
|
||||
_, err := a.client.Do(gitlab.GraphQLQuery{
|
||||
Query: mergeabilityChecksQuery,
|
||||
Variables: map[string]any{
|
||||
"projectPath": a.gitInfo.ProjectPath(),
|
||||
"iid": fmt.Sprintf("%d", a.projectInfo.MergeId),
|
||||
},
|
||||
}, &response)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to fetch mergeability checks: %w", err)
|
||||
}
|
||||
|
||||
return response.Data.Project.MergeRequest.MergeabilityChecks, nil
|
||||
}
|
||||
119
cmd/app/mergeability_checks_test.go
Normal file
119
cmd/app/mergeability_checks_test.go
Normal file
@@ -0,0 +1,119 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/harrisoncramer/gitlab.nvim/cmd/app/git"
|
||||
gitlab "gitlab.com/gitlab-org/api/client-go"
|
||||
)
|
||||
|
||||
type fakeGraphQLClient struct {
|
||||
err error
|
||||
jsonData []byte
|
||||
}
|
||||
|
||||
func (f fakeGraphQLClient) Do(query gitlab.GraphQLQuery, response any, options ...gitlab.RequestOptionFunc) (*gitlab.Response, error) {
|
||||
if f.err != nil {
|
||||
return nil, f.err
|
||||
}
|
||||
|
||||
// Actually unmarshal JSON into the response struct
|
||||
if err := json.Unmarshal(f.jsonData, response); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// if resp, ok := response.(mergeabilityChecksGraphQLResponse); ok {
|
||||
// resp.Data.Project.MergeRequest.MergeabilityChecks = f.checks
|
||||
// }
|
||||
|
||||
return makeResponse(http.StatusOK), nil
|
||||
}
|
||||
|
||||
var testMergeabilityData = data{
|
||||
projectInfo: &ProjectInfo{MergeId: 123},
|
||||
gitInfo: &git.GitData{
|
||||
BranchName: "feature-branch",
|
||||
Namespace: "test-namespace",
|
||||
ProjectName: "test-project",
|
||||
},
|
||||
}
|
||||
|
||||
func TestMergeabilityChecksHandler(t *testing.T) {
|
||||
t.Run("Returns mergeability checks", func(t *testing.T) {
|
||||
request := makeRequest(t, http.MethodGet, "/mr/mergeability_checks", nil)
|
||||
client := fakeGraphQLClient{
|
||||
jsonData: []byte(`{
|
||||
"data": {
|
||||
"project": {
|
||||
"mergeRequest": {
|
||||
"mergeabilityChecks": [
|
||||
{"identifier": "CI_MUST_PASS", "status": "SUCCESS"},
|
||||
{"identifier": "CONFLICT", "status": "FAILED"}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}`),
|
||||
}
|
||||
svc := middleware(
|
||||
mergeabilityChecksService{testMergeabilityData, client},
|
||||
withMethodCheck(http.MethodGet),
|
||||
)
|
||||
|
||||
res := httptest.NewRecorder()
|
||||
svc.ServeHTTP(res, request)
|
||||
|
||||
var data MergeabilityChecksResponse
|
||||
json.Unmarshal(res.Body.Bytes(), &data)
|
||||
|
||||
assert(t, data.Message, "Mergeability checks retrieved")
|
||||
assert(t, len(data.MergeabilityChecks), 2)
|
||||
assert(t, data.MergeabilityChecks[0].Identifier, "CI_MUST_PASS")
|
||||
assert(t, data.MergeabilityChecks[0].Status, "SUCCESS")
|
||||
assert(t, data.MergeabilityChecks[1].Identifier, "CONFLICT")
|
||||
assert(t, data.MergeabilityChecks[1].Status, "FAILED")
|
||||
})
|
||||
|
||||
t.Run("Returns empty list when there are no checks", func(t *testing.T) {
|
||||
request := makeRequest(t, http.MethodGet, "/mr/mergeability_checks", nil)
|
||||
client := fakeGraphQLClient{
|
||||
jsonData: []byte(`{
|
||||
"data": {
|
||||
"project": {
|
||||
"mergeRequest": {
|
||||
"mergeabilityChecks": []
|
||||
}
|
||||
}
|
||||
}
|
||||
}`),
|
||||
}
|
||||
svc := middleware(
|
||||
mergeabilityChecksService{testMergeabilityData, client},
|
||||
withMethodCheck(http.MethodGet),
|
||||
)
|
||||
|
||||
res := httptest.NewRecorder()
|
||||
svc.ServeHTTP(res, request)
|
||||
|
||||
var data MergeabilityChecksResponse
|
||||
json.Unmarshal(res.Body.Bytes(), &data)
|
||||
|
||||
assert(t, data.Message, "Mergeability checks retrieved")
|
||||
assert(t, len(data.MergeabilityChecks), 0)
|
||||
})
|
||||
|
||||
t.Run("Handles errors from Gitlab client", func(t *testing.T) {
|
||||
request := makeRequest(t, http.MethodGet, "/mr/mergeability_checks", nil)
|
||||
client := fakeGraphQLClient{err: errorFromGitlab}
|
||||
svc := middleware(
|
||||
mergeabilityChecksService{testMergeabilityData, client},
|
||||
withMethodCheck(http.MethodGet),
|
||||
)
|
||||
data, _ := getFailData(t, svc, request)
|
||||
assert(t, data.Message, "Could not get mergeability checks")
|
||||
assert(t, data.Details, "failed to fetch mergeability checks: "+errorFromGitlab.Error())
|
||||
})
|
||||
}
|
||||
@@ -134,6 +134,11 @@ func CreateRouter(gitlabClient *Client, projectInfo *ProjectInfo, s *shutdownSer
|
||||
withMr(d, gitlabClient),
|
||||
withMethodCheck(http.MethodGet),
|
||||
))
|
||||
m.HandleFunc("/mr/info/mergeability", middleware(
|
||||
mergeabilityChecksService{d, gitlabClient},
|
||||
withMr(d, gitlabClient),
|
||||
withMethodCheck(http.MethodGet),
|
||||
))
|
||||
m.HandleFunc("/mr/assignee", middleware(
|
||||
assigneesService{d, gitlabClient},
|
||||
withMr(d, gitlabClient),
|
||||
|
||||
Reference in New Issue
Block a user