Repository: lindell/multi-gitter
Pull request #103 (2021-04-10 11:17:50)

test: added GitHub tests


Patch:
diff --git a/cmd/root.go b/cmd/root.go
index 8017d09..6a514e7 100755
--- a/cmd/root.go
+++ b/cmd/root.go
@@ -9,6 +9,7 @@ import (
 	"time"
 
 	"github.com/lindell/multi-gitter/internal/domain"
+	"github.com/lindell/multi-gitter/internal/http"
 	"github.com/lindell/multi-gitter/internal/multigitter"
 	"github.com/lindell/multi-gitter/internal/scm/github"
 	"github.com/lindell/multi-gitter/internal/scm/gitlab"
@@ -250,7 +251,7 @@ func createGithubClient(flag *flag.FlagSet, verifyFlags bool) (multigitter.Versi
 		}
 	}
 
-	vc, err := github.New(token, gitBaseURL, github.RepositoryListing{
+	vc, err := github.New(token, gitBaseURL, http.NewLoggingRoundTripper, github.RepositoryListing{
 		Organizations: orgs,
 		Users:         users,
 		Repositories:  repoRefs,
diff --git a/internal/http/logging.go b/internal/http/logging.go
index 92a3830..2382932 100644
--- a/internal/http/logging.go
+++ b/internal/http/logging.go
@@ -8,6 +8,13 @@ import (
 	log "github.com/sirupsen/logrus"
 )
 
+// NewLoggingRoundTripper creates a new logging roundtripper
+func NewLoggingRoundTripper(rt http.RoundTripper) http.RoundTripper {
+	return LoggingRoundTripper{
+		Next: rt,
+	}
+}
+
 // LoggingRoundTripper logs a request-response
 type LoggingRoundTripper struct {
 	Next http.RoundTripper
diff --git a/internal/scm/github/github.go b/internal/scm/github/github.go
index 29e4df7..023f4f7 100755
--- a/internal/scm/github/github.go
+++ b/internal/scm/github/github.go
@@ -4,6 +4,7 @@ import (
 	"context"
 	"errors"
 	"fmt"
+	"net/http"
 	"net/url"
 	"sort"
 	"strings"
@@ -13,19 +14,22 @@ import (
 	"golang.org/x/oauth2"
 
 	"github.com/lindell/multi-gitter/internal/domain"
-	"github.com/lindell/multi-gitter/internal/http"
 )
 
 // New create a new Github client
-func New(token, baseURL string, repoListing RepositoryListing, mergeTypes []domain.MergeType) (*Github, error) {
+func New(
+	token string,
+	baseURL string,
+	transportMiddleware func(http.RoundTripper) http.RoundTripper,
+	repoListing RepositoryListing,
+	mergeTypes []domain.MergeType,
+) (*Github, error) {
 	ctx := context.Background()
 	ts := oauth2.StaticTokenSource(
 		&oauth2.Token{AccessToken: token},
 	)
 	tc := oauth2.NewClient(ctx, ts)
-	tc.Transport = http.LoggingRoundTripper{
-		Next: tc.Transport,
-	}
+	tc.Transport = transportMiddleware(tc.Transport)
 
 	var client *github.Client
 	if baseURL != "" {


Test patch:
diff --git a/internal/scm/github/github_test.go b/internal/scm/github/github_test.go
new file mode 100644
index 0000000..6629686
--- /dev/null
+++ b/internal/scm/github/github_test.go
@@ -0,0 +1,189 @@
+package github_test
+
+import (
+	"context"
+	"errors"
+	"io/ioutil"
+	"net/http"
+	"strings"
+	"testing"
+
+	"github.com/lindell/multi-gitter/internal/domain"
+	"github.com/lindell/multi-gitter/internal/scm/github"
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
+)
+
+type testTransport struct {
+	pathBodies map[string]string
+}
+
+func (tt testTransport) RoundTrip(req *http.Request) (*http.Response, error) {
+	body, ok := tt.pathBodies[req.URL.Path]
+	if !ok {
+		return nil, errors.New("could not find path")
+	}
+	return &http.Response{
+		Status:        "200 OK",
+		StatusCode:    200,
+		Proto:         "HTTP/1.1",
+		ProtoMajor:    1,
+		ProtoMinor:    1,
+		Body:          ioutil.NopCloser(strings.NewReader(body)),
+		ContentLength: int64(len(body)),
+		Request:       req,
+		Header:        make(http.Header),
+	}, nil
+}
+
+func (tt testTransport) Wrapper(http.RoundTripper) http.RoundTripper {
+	return tt
+}
+
+func Test_GetRepositories(t *testing.T) {
+	transport := testTransport{
+		pathBodies: map[string]string{
+			"/orgs/test-org/repos": `[
+				{
+					"id": 1,
+					"name": "test1",
+					"full_name": "test-org/test1",
+					"private": false,
+					"owner": {
+						"login": "test-org",
+						"type": "Organization",
+						"site_admin": false
+					},
+					"html_url": "https://github.com/test-org/test1",
+					"archived": false,
+					"disabled": false,
+					"default_branch": "master",
+					"permissions": {
+						"admin": true,
+						"push": true,
+						"pull": true
+					},
+					"created_at": "2020-01-01T16:49:16Z"
+				}
+			]`,
+			"/repos/test-org/test1": `{
+				"id": 2,
+				"name": "test1",
+				"full_name": "test-org/test1",
+				"private": false,
+				"owner": {
+					"login": "test-org",
+					"type": "Organization",
+					"site_admin": false
+				},
+				"html_url": "https://github.com/test-org/test1",
+				"archived": false,
+				"disabled": false,
+				"default_branch": "master",
+				"permissions": {
+					"admin": true,
+					"push": true,
+					"pull": true
+				},
+				"created_at": "2020-01-02T16:49:16Z"
+			}`,
+			"/users/test-user/repos": `[
+				{
+					"id": 3,
+					"name": "test2",
+					"full_name": "lindell/test2",
+					"private": false,
+					"owner": {
+						"login": "lindell",
+						"type": "User",
+						"site_admin": false
+					},
+					"html_url": "https://github.com/lindell/test2",
+					"archived": false,
+					"disabled": false,
+					"default_branch": "main",
+					"permissions": {
+						"admin": true,
+						"push": true,
+						"pull": true
+					},
+					"created_at": "2020-01-03T16:49:16Z"
+				}
+			]`,
+		},
+	}
+
+	// Organization
+	{
+		gh, err := github.New("", "", transport.Wrapper, github.RepositoryListing{
+			Organizations: []string{"test-org"},
+		}, []domain.MergeType{domain.MergeTypeMerge})
+		require.NoError(t, err)
+
+		repos, err := gh.GetRepositories(context.Background())
+		assert.NoError(t, err)
+		if assert.Len(t, repos, 1) {
+			assert.Equal(t, "master", repos[0].DefaultBranch())
+			assert.Equal(t, "test-org/test1", repos[0].FullName())
+		}
+	}
+
+	// Repository
+	{
+		gh, err := github.New("", "", transport.Wrapper, github.RepositoryListing{
+			Repositories: []github.RepositoryReference{
+				{
+					OwnerName: "test-org",
+					Name:      "test1",
+				},
+			},
+		}, []domain.MergeType{domain.MergeTypeMerge})
+		require.NoError(t, err)
+
+		repos, err := gh.GetRepositories(context.Background())
+		assert.NoError(t, err)
+		if assert.Len(t, repos, 1) {
+			assert.Equal(t, "master", repos[0].DefaultBranch())
+			assert.Equal(t, "test-org/test1", repos[0].FullName())
+		}
+	}
+
+	// User
+	{
+		gh, err := github.New("", "", transport.Wrapper, github.RepositoryListing{
+			Users: []string{"test-user"},
+		}, []domain.MergeType{domain.MergeTypeMerge})
+		require.NoError(t, err)
+
+		repos, err := gh.GetRepositories(context.Background())
+		assert.NoError(t, err)
+		if assert.Len(t, repos, 1) {
+			assert.Equal(t, "main", repos[0].DefaultBranch())
+			assert.Equal(t, "lindell/test2", repos[0].FullName())
+		}
+	}
+
+	// Multiple
+	{
+		gh, err := github.New("", "", transport.Wrapper, github.RepositoryListing{
+			Organizations: []string{"test-org"},
+			Users:         []string{"test-user"},
+			Repositories: []github.RepositoryReference{
+				{
+					OwnerName: "test-org",
+					Name:      "test1",
+				},
+			},
+		}, []domain.MergeType{domain.MergeTypeMerge})
+		require.NoError(t, err)
+
+		repos, err := gh.GetRepositories(context.Background())
+		assert.NoError(t, err)
+		if assert.Len(t, repos, 2) {
+			assert.Equal(t, "master", repos[0].DefaultBranch())
+			assert.Equal(t, "test-org/test1", repos[0].FullName())
+			assert.Equal(t, "main", repos[1].DefaultBranch())
+			assert.Equal(t, "lindell/test2", repos[1].FullName())
+		}
+	}
+}