add unit tests for launchpad bridge configuration

Amine Hilaly created

add tests for validateUsername in Github bridge
panic when compile regex fail

Change summary

bridge/github/config.go         |  2 
bridge/github/config_test.go    | 65 +++++++++++++++++++++++-
bridge/launchpad/config.go      | 23 +++++---
bridge/launchpad/config_test.go | 93 +++++++++++++++++++++++++++++++++++
4 files changed, 170 insertions(+), 13 deletions(-)

Detailed changes

bridge/github/config.go 🔗

@@ -418,7 +418,7 @@ func splitURL(url string) (owner string, project string, err error) {
 
 	re, err := regexp.Compile(`github\.com[/:]([a-zA-Z0-9\-_]+)/([a-zA-Z0-9\-_.]+)`)
 	if err != nil {
-		return "", "", err
+		panic("regexp compile:" + err.Error())
 	}
 
 	res := re.FindStringSubmatch(cleanURL)

bridge/github/config_test.go 🔗

@@ -32,7 +32,17 @@ func TestSplitURL(t *testing.T) {
 				err:     nil,
 			},
 		},
-
+		{
+			name: "default issues url",
+			args: args{
+				url: "https://github.com/MichaelMure/git-bug/issues",
+			},
+			want: want{
+				owner:   "MichaelMure",
+				project: "git-bug",
+				err:     nil,
+			},
+		},
 		{
 			name: "default url with git extension",
 			args: args{
@@ -87,6 +97,46 @@ func TestSplitURL(t *testing.T) {
 	}
 }
 
+func TestValidateUsername(t *testing.T) {
+	type args struct {
+		username string
+	}
+	tests := []struct {
+		name string
+		args args
+		want bool
+	}{
+		{
+			name: "existing username",
+			args: args{
+				username: "MichaelMure",
+			},
+			want: true,
+		},
+		{
+			name: "existing organisation name",
+			args: args{
+				username: "ipfs",
+			},
+			want: true,
+		},
+		{
+			name: "non existing username",
+			args: args{
+				username: "cant-find-this",
+			},
+			want: false,
+		},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			ok, _ := validateUsername(tt.args.username)
+			assert.Equal(t, tt.want, ok)
+		})
+	}
+}
+
 func TestValidateProject(t *testing.T) {
 	tokenPrivateScope := os.Getenv("GITHUB_TOKEN_PRIVATE")
 	if tokenPrivateScope == "" {
@@ -109,7 +159,7 @@ func TestValidateProject(t *testing.T) {
 		want bool
 	}{
 		{
-			name: "public repository and token with scope 'public_repo",
+			name: "public repository and token with scope 'public_repo'",
 			args: args{
 				project: "git-bug",
 				owner:   "MichaelMure",
@@ -118,7 +168,7 @@ func TestValidateProject(t *testing.T) {
 			want: true,
 		},
 		{
-			name: "private repository and token with scope 'repo",
+			name: "private repository and token with scope 'repo'",
 			args: args{
 				project: "git-bug-test-github-bridge",
 				owner:   "MichaelMure",
@@ -135,6 +185,15 @@ func TestValidateProject(t *testing.T) {
 			},
 			want: false,
 		},
+		{
+			name: "project not existing",
+			args: args{
+				project: "cant-find-this",
+				owner:   "organisation-not-found",
+				token:   tokenPublicScope,
+			},
+			want: false,
+		},
 	}
 
 	for _, tt := range tests {

bridge/launchpad/config.go 🔗

@@ -2,6 +2,7 @@ package launchpad
 
 import (
 	"bufio"
+	"errors"
 	"fmt"
 	"net/http"
 	"os"
@@ -13,15 +14,13 @@ import (
 	"github.com/MichaelMure/git-bug/repository"
 )
 
+var ErrBadProjectURL = errors.New("bad Launchpad project URL")
+
 const (
 	keyProject     = "project"
 	defaultTimeout = 60 * time.Second
 )
 
-var (
-	rxLaunchpadURL = regexp.MustCompile(`launchpad\.net[\/:]([^\/]*[a-z]+)`)
-)
-
 func (*Launchpad) Configure(repo repository.RepoCommon, params core.BridgeParams) (core.Configuration, error) {
 	if params.Token != "" {
 		fmt.Println("warning: --token is ineffective for a Launchpad bridge")
@@ -39,7 +38,7 @@ func (*Launchpad) Configure(repo repository.RepoCommon, params core.BridgeParams
 
 	} else if params.URL != "" {
 		// get project name from url
-		_, project, err = splitURL(params.URL)
+		project, err = splitURL(params.URL)
 		if err != nil {
 			return nil, err
 		}
@@ -108,11 +107,17 @@ func validateProject(project string) (bool, error) {
 	return resp.StatusCode == http.StatusOK, nil
 }
 
-func splitURL(url string) (string, string, error) {
-	res := rxLaunchpadURL.FindStringSubmatch(url)
+// extract project name from url
+func splitURL(url string) (string, error) {
+	re, err := regexp.Compile(`launchpad\.net[\/:]([^\/]*[a-z]+)`)
+	if err != nil {
+		panic("regexp compile:" + err.Error())
+	}
+
+	res := re.FindStringSubmatch(url)
 	if res == nil {
-		return "", "", fmt.Errorf("bad Launchpad project url")
+		return "", ErrBadProjectURL
 	}
 
-	return res[0], res[1], nil
+	return res[1], nil
 }

bridge/launchpad/config_test.go 🔗

@@ -0,0 +1,93 @@
+package launchpad
+
+import (
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+)
+
+func TestSplitURL(t *testing.T) {
+	type args struct {
+		url string
+	}
+	type want struct {
+		project string
+		err     error
+	}
+	tests := []struct {
+		name string
+		args args
+		want want
+	}{
+		{
+			name: "default project url",
+			args: args{
+				url: "https://launchpad.net/ubuntu",
+			},
+			want: want{
+				project: "ubuntu",
+				err:     nil,
+			},
+		},
+		{
+			name: "project bugs url",
+			args: args{
+				url: "https://bugs.launchpad.net/ubuntu",
+			},
+			want: want{
+				project: "ubuntu",
+				err:     nil,
+			},
+		},
+		{
+			name: "bad url",
+			args: args{
+				url: "https://launchpa.net/ubuntu",
+			},
+			want: want{
+				err: ErrBadProjectURL,
+			},
+		},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			project, err := splitURL(tt.args.url)
+			assert.Equal(t, tt.want.err, err)
+			assert.Equal(t, tt.want.project, project)
+		})
+	}
+}
+
+func TestValidateProject(t *testing.T) {
+	type args struct {
+		project string
+	}
+	tests := []struct {
+		name string
+		args args
+		want bool
+	}{
+		{
+			name: "public project",
+			args: args{
+				project: "ubuntu",
+			},
+			want: true,
+		},
+		{
+			name: "non existing project",
+			args: args{
+				project: "cant-find-this",
+			},
+			want: false,
+		},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			ok, _ := validateProject(tt.args.project)
+			assert.Equal(t, tt.want, ok)
+		})
+	}
+}