diff options
Diffstat (limited to 'internal/command/githttp/push_test.go')
-rw-r--r-- | internal/command/githttp/push_test.go | 150 |
1 files changed, 150 insertions, 0 deletions
diff --git a/internal/command/githttp/push_test.go b/internal/command/githttp/push_test.go new file mode 100644 index 0000000..1363abd --- /dev/null +++ b/internal/command/githttp/push_test.go @@ -0,0 +1,150 @@ +package githttp + +import ( + "bytes" + "context" + "io" + "net/http" + "strings" + "testing" + + "github.com/stretchr/testify/require" + + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/accessverifier" +) + +var ( + flush = "0000" + infoRefsWithoutPrefix = "00c4e56497bb5f03a90a51293fc6d516788730953899 refs/heads/'test'report-status " + + "report-status-v2 delete-refs side-band-64k quiet atomic ofs-delta push-options object-format=sha1 " + + "agent=git/2.38.3.gl200\n" + flush +) + +func TestExecute(t *testing.T) { + url, input := setup(t, http.StatusOK) + output := &bytes.Buffer{} + + cmd := &PushCommand{ + Config: &config.Config{GitlabUrl: url}, + ReadWriter: &readwriter.ReadWriter{Out: output, In: input}, + Response: &accessverifier.Response{ + Payload: accessverifier.CustomPayload{ + Data: accessverifier.CustomPayloadData{PrimaryRepo: url}, + }, + }, + } + + require.NoError(t, cmd.Execute(context.Background())) + require.Equal(t, infoRefsWithoutPrefix, output.String()) +} + +func TestExecuteWithFailedInfoRefs(t *testing.T) { + testCases := []struct { + desc string + statusCode int + responseContent string + expectedErr string + }{ + { + desc: "request failed", + statusCode: http.StatusForbidden, + expectedErr: "Internal API error (403)", + }, { + desc: "unexpected response", + statusCode: http.StatusOK, + responseContent: "unexpected response", + expectedErr: "Unexpected git-receive-pack response", + }, + } + + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + requests := []testserver.TestRequestHandler{ + { + Path: "/info/refs", + Handler: func(w http.ResponseWriter, r *http.Request) { + require.Equal(t, "git-receive-pack", r.URL.Query().Get("service")) + + w.WriteHeader(tc.statusCode) + w.Write([]byte(tc.responseContent)) + }, + }, + } + + url := testserver.StartHttpServer(t, requests) + + cmd := &PushCommand{ + Config: &config.Config{GitlabUrl: url}, + Response: &accessverifier.Response{ + Payload: accessverifier.CustomPayload{ + Data: accessverifier.CustomPayloadData{PrimaryRepo: url}, + }, + }, + } + + err := cmd.Execute(context.Background()) + require.Error(t, err) + require.Equal(t, tc.expectedErr, err.Error()) + }) + } +} + +func TestExecuteWithFailedReceivePack(t *testing.T) { + url, input := setup(t, http.StatusForbidden) + output := &bytes.Buffer{} + + cmd := &PushCommand{ + Config: &config.Config{GitlabUrl: url}, + ReadWriter: &readwriter.ReadWriter{Out: output, In: input}, + Response: &accessverifier.Response{ + Payload: accessverifier.CustomPayload{ + Data: accessverifier.CustomPayloadData{PrimaryRepo: url}, + }, + }, + } + + err := cmd.Execute(context.Background()) + require.Error(t, err) + require.Equal(t, "Internal API error (403)", err.Error()) +} + +func setup(t *testing.T, receivePackStatusCode int) (string, io.Reader) { + infoRefs := "001f# service=git-receive-pack\n" + flush + infoRefsWithoutPrefix + receivePackPrefix := "00ab4c9d98d7750fa65db8ddcc60a89ef919f7a179f9 df505c066e4e63a801268a84627d7e8f7e033c7a " + + "refs/heads/main123 report-status-v2 side-band-64k object-format=sha1 agent=git/2.39.1" + receivePackData := "PACK some data" + + // Imitate sending data via multiple packets + input := io.MultiReader( + strings.NewReader(receivePackPrefix), + strings.NewReader(flush), + strings.NewReader(receivePackData), + ) + + requests := []testserver.TestRequestHandler{ + { + Path: "/info/refs", + Handler: func(w http.ResponseWriter, r *http.Request) { + require.Equal(t, "git-receive-pack", r.URL.Query().Get("service")) + + w.Write([]byte(infoRefs)) + }, + }, + { + Path: "/git-receive-pack", + Handler: func(w http.ResponseWriter, r *http.Request) { + body, err := io.ReadAll(r.Body) + require.NoError(t, err) + defer r.Body.Close() + + require.Equal(t, receivePackPrefix+flush+receivePackData, string(body)) + w.WriteHeader(receivePackStatusCode) + }, + }, + } + + return testserver.StartHttpServer(t, requests), input +} |