Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: Move to gomock #349

Merged
merged 26 commits into from
Aug 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
3757792
Removed example.lua file
harrisoncramer Aug 17, 2024
2a75ce3
Moving to mocks
harrisoncramer Aug 17, 2024
88465db
Updating approve_test.go
harrisoncramer Aug 17, 2024
33a8d50
Updated approve_test.go
harrisoncramer Aug 17, 2024
95a513a
Fixed assignee_test
harrisoncramer Aug 17, 2024
e1b5a0c
Updated attachment_test file
harrisoncramer Aug 17, 2024
728a60b
Updating comment_test.go
harrisoncramer Aug 17, 2024
816c765
Fixed comment_test.go
harrisoncramer Aug 17, 2024
f630607
Fixed merge_test.go
harrisoncramer Aug 17, 2024
3818401
Updated create_mr_test.go
harrisoncramer Aug 17, 2024
0a06e8c
Added more test fixes
harrisoncramer Aug 17, 2024
8345b37
Continuing to convert tests
harrisoncramer Aug 17, 2024
aaf1637
Updated cmd/draft_notes_test.go
harrisoncramer Aug 17, 2024
cca5abd
Updated cmd/draft_notes_test.go
harrisoncramer Aug 17, 2024
74cc21d
Updated cmd/info_test.go
harrisoncramer Aug 17, 2024
57abb4a
Updated cmd/job_test.go
harrisoncramer Aug 17, 2024
de703ec
Updated merge_requests and merge_requests_test
harrisoncramer Aug 17, 2024
dc60338
Tested pipelines
harrisoncramer Aug 17, 2024
9b2f3fb
Fixed up reply_test.go
harrisoncramer Aug 17, 2024
90a8985
Fixed members_test.go
harrisoncramer Aug 17, 2024
a7f7f7b
Updated list_discussions
harrisoncramer Aug 17, 2024
6b35fd8
Removed fake client
harrisoncramer Aug 17, 2024
db86013
Updated CONTRIBUTING
harrisoncramer Aug 17, 2024
aa2ffa5
Fixed up client
harrisoncramer Aug 18, 2024
976e228
Deleted opt checking when matching function calls
harrisoncramer Aug 18, 2024
07f7409
Updated .github/workflows/lua.yaml
harrisoncramer Aug 18, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .github/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,13 @@ $ go fmt ./...
$ golangci-lint run
```

If you are writing tests and have added something to the Go client, you can re-generate the mocked client like so:

```bash
$ go install go.uber.org/mock/mockgen@latest # Install the mockgen CLI on your machine
$ mockgen -source cmd/types.go > cmd/mocks/fake_client.go
```

For changes to the Lua codebase: We use <a href="https://github.com/JohnnyMorganz/StyLua">stylua</a> for formatting and <a href="https://github.com/mpeterv/luacheck">luacheck</a> for linting. Run these commands in the root of the repository:

```bash
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/lua.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ jobs:
- name: Install luajit
uses: leafo/gh-actions-lua@v10
with:
luaVersion: "luajit-2.1.0-beta3"
luaVersion: "luajit-openresty"
- name: Install luarocks
uses: leafo/gh-actions-luarocks@v4
- name: Run tests
Expand Down
2 changes: 1 addition & 1 deletion cmd/approve.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
)

/* approveHandler approves a merge request. */
func (a *api) approveHandler(w http.ResponseWriter, r *http.Request) {
func (a *Api) approveHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
if r.Method != http.MethodPost {
w.Header().Set("Access-Control-Allow-Methods", http.MethodPost)
Expand Down
41 changes: 24 additions & 17 deletions cmd/approve_test.go
Original file line number Diff line number Diff line change
@@ -1,52 +1,59 @@
package main

import (
"errors"
"net/http"
"testing"

"github.com/xanzy/go-gitlab"
mock_main "gitlab.com/harrisoncramer/gitlab.nvim/cmd/mocks"
)

func approveMergeRequest(pid interface{}, mr int, opt *gitlab.ApproveMergeRequestOptions, options ...gitlab.RequestOptionFunc) (*gitlab.MergeRequestApprovals, *gitlab.Response, error) {
return &gitlab.MergeRequestApprovals{}, makeResponse(http.StatusOK), nil
}

func approveMergeRequestNon200(pid interface{}, mr int, opt *gitlab.ApproveMergeRequestOptions, options ...gitlab.RequestOptionFunc) (*gitlab.MergeRequestApprovals, *gitlab.Response, error) {
return &gitlab.MergeRequestApprovals{}, makeResponse(http.StatusSeeOther), nil
}

func approveMergeRequestErr(pid interface{}, mr int, opt *gitlab.ApproveMergeRequestOptions, options ...gitlab.RequestOptionFunc) (*gitlab.MergeRequestApprovals, *gitlab.Response, error) {
return &gitlab.MergeRequestApprovals{}, nil, errors.New("Some error from Gitlab")
}

func TestApproveHandler(t *testing.T) {
t.Run("Approves merge request", func(t *testing.T) {
client := mock_main.NewMockClient(t)
mock_main.WithMr(t, client)
client.EXPECT().ApproveMergeRequest("", mock_main.MergeId, nil, nil).Return(&gitlab.MergeRequestApprovals{}, makeResponse(http.StatusOK), nil)

request := makeRequest(t, http.MethodPost, "/mr/approve", nil)
server, _ := createRouterAndApi(fakeClient{approveMergeRequest: approveMergeRequest})
server, _ := CreateRouterAndApi(client)
data := serveRequest(t, server, request, SuccessResponse{})

assert(t, data.Message, "Approved MR")
assert(t, data.Status, http.StatusOK)
})

t.Run("Disallows non-POST method", func(t *testing.T) {
client := mock_main.NewMockClient(t)
mock_main.WithMr(t, client)
client.EXPECT().ApproveMergeRequest("", mock_main.MergeId, nil, nil).Return(&gitlab.MergeRequestApprovals{}, makeResponse(http.StatusOK), nil)

request := makeRequest(t, http.MethodPut, "/mr/approve", nil)
server, _ := createRouterAndApi(fakeClient{approveMergeRequest: approveMergeRequest})
server, _ := CreateRouterAndApi(client)
data := serveRequest(t, server, request, ErrorResponse{})
checkBadMethod(t, *data, http.MethodPost)
})

t.Run("Handles errors from Gitlab client", func(t *testing.T) {
client := mock_main.NewMockClient(t)
mock_main.WithMr(t, client)
client.EXPECT().ApproveMergeRequest("", mock_main.MergeId, nil, nil).Return(nil, nil, errorFromGitlab)

request := makeRequest(t, http.MethodPost, "/mr/approve", nil)
server, _ := createRouterAndApi(fakeClient{approveMergeRequest: approveMergeRequestErr})
server, _ := CreateRouterAndApi(client)
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) {
client := mock_main.NewMockClient(t)
mock_main.WithMr(t, client)
client.EXPECT().ApproveMergeRequest("", mock_main.MergeId, nil, nil).Return(nil, makeResponse(http.StatusSeeOther), nil)

request := makeRequest(t, http.MethodPost, "/mr/approve", nil)
server, _ := createRouterAndApi(fakeClient{approveMergeRequest: approveMergeRequestNon200})
server, _ := CreateRouterAndApi(client)
data := serveRequest(t, server, request, ErrorResponse{})

checkNon200(t, *data, "Could not approve merge request", "/mr/approve")
})
}
2 changes: 1 addition & 1 deletion cmd/assignee.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ type AssigneesRequestResponse struct {
}

/* assigneesHandler adds or removes assignees from a merge request. */
func (a *api) assigneesHandler(w http.ResponseWriter, r *http.Request) {
func (a *Api) assigneesHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
if r.Method != http.MethodPut {
w.Header().Set("Access-Control-Allow-Methods", http.MethodPut)
Expand Down
49 changes: 30 additions & 19 deletions cmd/assignee_test.go
Original file line number Diff line number Diff line change
@@ -1,56 +1,67 @@
package main

import (
"errors"
"net/http"
"testing"

"github.com/xanzy/go-gitlab"
mock_main "gitlab.com/harrisoncramer/gitlab.nvim/cmd/mocks"
"go.uber.org/mock/gomock"
)

func updateAssignees(pid interface{}, mergeRequest int, opt *gitlab.UpdateMergeRequestOptions, options ...gitlab.RequestOptionFunc) (*gitlab.MergeRequest, *gitlab.Response, error) {
return &gitlab.MergeRequest{}, makeResponse(http.StatusOK), nil
}

func updateAssigneesNon200(pid interface{}, mergeRequest int, opt *gitlab.UpdateMergeRequestOptions, options ...gitlab.RequestOptionFunc) (*gitlab.MergeRequest, *gitlab.Response, error) {
return nil, makeResponse(http.StatusSeeOther), nil
}

func updateAssigneesErr(pid interface{}, mergeRequest int, opt *gitlab.UpdateMergeRequestOptions, options ...gitlab.RequestOptionFunc) (*gitlab.MergeRequest, *gitlab.Response, error) {
return nil, nil, errors.New("Some error from Gitlab")
}
var updatePayload = AssigneeUpdateRequest{Ids: []int{1, 2}}

func TestAssigneeHandler(t *testing.T) {
t.Run("Updates assignees", func(t *testing.T) {
request := makeRequest(t, http.MethodPut, "/mr/assignee", AssigneeUpdateRequest{Ids: []int{1, 2}})
server, _ := createRouterAndApi(fakeClient{updateMergeRequest: updateAssignees})
client := mock_main.NewMockClient(t)
mock_main.WithMr(t, client)
client.EXPECT().UpdateMergeRequest("", mock_main.MergeId, gomock.Any()).Return(&gitlab.MergeRequest{}, makeResponse(http.StatusOK), nil)

request := makeRequest(t, http.MethodPut, "/mr/assignee", updatePayload)
server, _ := CreateRouterAndApi(client)
data := serveRequest(t, server, request, AssigneeUpdateResponse{})

assert(t, data.SuccessResponse.Message, "Assignees updated")
assert(t, data.SuccessResponse.Status, http.StatusOK)
})

t.Run("Disallows non-PUT method", func(t *testing.T) {
client := mock_main.NewMockClient(t)
mock_main.WithMr(t, client)
client.EXPECT().UpdateMergeRequest("", mock_main.MergeId, gomock.Any()).Return(&gitlab.MergeRequest{}, makeResponse(http.StatusOK), nil)

request := makeRequest(t, http.MethodPost, "/mr/assignee", nil)
server, _ := createRouterAndApi(fakeClient{updateMergeRequest: updateAssignees})
server, _ := CreateRouterAndApi(client)
data := serveRequest(t, server, request, ErrorResponse{})

assert(t, data.Status, http.StatusMethodNotAllowed)
assert(t, data.Details, "Invalid request type")
assert(t, data.Message, "Expected PUT")
})

t.Run("Handles errors from Gitlab client", func(t *testing.T) {
request := makeRequest(t, http.MethodPut, "/mr/assignee", AssigneeUpdateRequest{Ids: []int{1, 2}})
server, _ := createRouterAndApi(fakeClient{updateMergeRequest: updateAssigneesErr})
client := mock_main.NewMockClient(t)
mock_main.WithMr(t, client)
client.EXPECT().UpdateMergeRequest("", mock_main.MergeId, gomock.Any()).Return(nil, nil, errorFromGitlab)

request := makeRequest(t, http.MethodPut, "/mr/assignee", updatePayload)
server, _ := CreateRouterAndApi(client)
data := serveRequest(t, server, request, ErrorResponse{})

assert(t, data.Status, http.StatusInternalServerError)
assert(t, data.Message, "Could not modify merge request assignees")
assert(t, data.Details, "Some error from Gitlab")
})

t.Run("Handles non-200s from Gitlab client", func(t *testing.T) {
request := makeRequest(t, http.MethodPut, "/mr/assignee", AssigneeUpdateRequest{Ids: []int{1, 2}})
server, _ := createRouterAndApi(fakeClient{updateMergeRequest: updateAssigneesNon200})
client := mock_main.NewMockClient(t)
mock_main.WithMr(t, client)
client.EXPECT().UpdateMergeRequest("", mock_main.MergeId, gomock.Any()).Return(nil, makeResponse(http.StatusSeeOther), nil)

request := makeRequest(t, http.MethodPut, "/mr/assignee", updatePayload)
server, _ := CreateRouterAndApi(client)
data := serveRequest(t, server, request, ErrorResponse{})

assert(t, data.Status, http.StatusSeeOther)
assert(t, data.Message, "Could not modify merge request assignees")
assert(t, data.Details, "An error occurred on the /mr/assignee endpoint")
Expand Down
2 changes: 1 addition & 1 deletion cmd/attachment.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ func (ar attachmentReader) ReadFile(path string) (io.Reader, error) {
}

/* attachmentHandler uploads an attachment (file, image, etc) to Gitlab and returns metadata about the upload. */
func (a *api) attachmentHandler(w http.ResponseWriter, r *http.Request) {
func (a *Api) attachmentHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
if r.Method != http.MethodPost {
w.Header().Set("Access-Control-Allow-Methods", http.MethodPost)
Expand Down
63 changes: 33 additions & 30 deletions cmd/attachment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,64 +2,67 @@ package main

import (
"bytes"
"errors"
"io"
"net/http"
"testing"

"github.com/xanzy/go-gitlab"
mock_main "gitlab.com/harrisoncramer/gitlab.nvim/cmd/mocks"
)

type MockAttachmentReader struct{}

func (mf MockAttachmentReader) ReadFile(path string) (io.Reader, error) {
return bytes.NewReader([]byte{}), nil
}

func uploadFile(pid interface{}, content io.Reader, filename string, options ...gitlab.RequestOptionFunc) (*gitlab.ProjectFile, *gitlab.Response, error) {
return &gitlab.ProjectFile{}, makeResponse(http.StatusOK), nil
}

func uploadFileNon200(pid interface{}, content io.Reader, filename string, options ...gitlab.RequestOptionFunc) (*gitlab.ProjectFile, *gitlab.Response, error) {
return &gitlab.ProjectFile{}, makeResponse(http.StatusSeeOther), nil
}

func uploadFileErr(pid interface{}, content io.Reader, filename string, options ...gitlab.RequestOptionFunc) (*gitlab.ProjectFile, *gitlab.Response, error) {
return nil, nil, errors.New("Some error from Gitlab")
}

func withMockFileReader(a *api) error {
reader := MockAttachmentReader{}
func withMockFileReader(a *Api) error {
reader := mock_main.MockAttachmentReader{}
a.fileReader = reader
return nil
}

var reader = bytes.NewReader([]byte{})
var attachmentTestRequestData = AttachmentRequest{
FileName: "some_file_name",
FilePath: "some_file_path",
}

func TestAttachmentHandler(t *testing.T) {
t.Run("Returns 200-status response after upload", func(t *testing.T) {
request := makeRequest(t, http.MethodPost, "/attachment", AttachmentRequest{FilePath: "some_file_path", FileName: "some_file_name"})
router, _ := createRouterAndApi(fakeClient{uploadFile: uploadFile}, withMockFileReader)
client := mock_main.NewMockClient(t)
client.EXPECT().UploadFile("", reader, attachmentTestRequestData.FileName).Return(&gitlab.ProjectFile{}, makeResponse(http.StatusOK), nil)

request := makeRequest(t, http.MethodPost, "/attachment", attachmentTestRequestData)
router, _ := CreateRouterAndApi(client, withMockFileReader)
data := serveRequest(t, router, request, AttachmentResponse{})

assert(t, data.SuccessResponse.Status, http.StatusOK)
assert(t, data.SuccessResponse.Message, "File uploaded successfully")
})

t.Run("Disallows non-POST method", func(t *testing.T) {
request := makeRequest(t, http.MethodPut, "/attachment", AttachmentRequest{FilePath: "some_file_path", FileName: "some_file_name"})
router, _ := createRouterAndApi(fakeClient{uploadFile: uploadFile}, withMockFileReader)
client := mock_main.NewMockClient(t)
client.EXPECT().UploadFile("", reader, attachmentTestRequestData.FileName).Return(&gitlab.ProjectFile{}, makeResponse(http.StatusOK), nil)

request := makeRequest(t, http.MethodPut, "/attachment", attachmentTestRequestData)
router, _ := CreateRouterAndApi(client, 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, "/attachment", AttachmentRequest{FilePath: "some_file_path", FileName: "some_file_name"})
router, _ := createRouterAndApi(fakeClient{uploadFile: uploadFileErr}, withMockFileReader)
client := mock_main.NewMockClient(t)
client.EXPECT().UploadFile("", reader, attachmentTestRequestData.FileName).Return(nil, nil, errorFromGitlab)

request := makeRequest(t, http.MethodPost, "/attachment", attachmentTestRequestData)
router, _ := CreateRouterAndApi(client, 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, "/attachment", AttachmentRequest{FilePath: "some_file_path", FileName: "some_file_name"})
router, _ := createRouterAndApi(fakeClient{uploadFile: uploadFileNon200}, withMockFileReader)
client := mock_main.NewMockClient(t)
client.EXPECT().UploadFile("", reader, attachmentTestRequestData.FileName).Return(nil, makeResponse(http.StatusSeeOther), nil)

request := makeRequest(t, http.MethodPost, "/attachment", attachmentTestRequestData)
router, _ := CreateRouterAndApi(client, withMockFileReader)

data := serveRequest(t, router, request, ErrorResponse{})
checkNon200(t, *data, "Could not upload some_file_name to Gitlab", "/attachment")
})
Expand Down
5 changes: 1 addition & 4 deletions cmd/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,12 +130,9 @@ func initProjectSettings(c *Client, gitInfo GitProjectInfo) (error, *ProjectInfo
if err != nil {
return fmt.Errorf(fmt.Sprintf("Error getting project at %s", gitInfo.RemoteUrl), err), nil
}
if project == nil {
return fmt.Errorf(fmt.Sprintf("Could not find project at %s", gitInfo.RemoteUrl), err), nil
}

if project == nil {
return fmt.Errorf("No projects you are a member of contained remote URL %s", gitInfo.RemoteUrl), nil
return fmt.Errorf(fmt.Sprintf("Could not find project at %s", gitInfo.RemoteUrl), err), nil
}

projectId := fmt.Sprint(project.ID)
Expand Down
8 changes: 4 additions & 4 deletions cmd/comment.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ func (comment CommentWithPosition) GetPositionData() PositionData {
}

/* commentHandler creates, edits, and deletes discussions (comments, multi-line comments) */
func (a *api) commentHandler(w http.ResponseWriter, r *http.Request) {
func (a *Api) commentHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
switch r.Method {
case http.MethodPost:
Expand All @@ -58,7 +58,7 @@ func (a *api) commentHandler(w http.ResponseWriter, r *http.Request) {
}

/* deleteComment deletes a note, multiline comment, or comment, which are all considered discussion notes. */
func (a *api) deleteComment(w http.ResponseWriter, r *http.Request) {
func (a *Api) deleteComment(w http.ResponseWriter, r *http.Request) {
body, err := io.ReadAll(r.Body)
if err != nil {
handleError(w, err, "Could not read request body", http.StatusBadRequest)
Expand Down Expand Up @@ -99,7 +99,7 @@ func (a *api) deleteComment(w http.ResponseWriter, r *http.Request) {
}

/* postComment creates a note, multiline comment, or comment. */
func (a *api) postComment(w http.ResponseWriter, r *http.Request) {
func (a *Api) postComment(w http.ResponseWriter, r *http.Request) {
body, err := io.ReadAll(r.Body)
if err != nil {
handleError(w, err, "Could not read request body", http.StatusBadRequest)
Expand Down Expand Up @@ -156,7 +156,7 @@ func (a *api) postComment(w http.ResponseWriter, r *http.Request) {
}

/* editComment changes the text of a comment or changes it's resolved status. */
func (a *api) editComment(w http.ResponseWriter, r *http.Request) {
func (a *Api) editComment(w http.ResponseWriter, r *http.Request) {
body, err := io.ReadAll(r.Body)

if err != nil {
Expand Down
Loading
Loading