Repository: openshift-pipelines/pipelines-as-code
Pull request #46 (2021-05-07 11:52:34)

Refactor test helpers and add more tests to runwrap 💫
Fix a bug along the way that would crash the binary if checkrunid wasnt set


Patch:
diff --git a/pkg/cmd/pipelineascode/pipelineascode.go b/pkg/cmd/pipelineascode/pipelineascode.go
index f60840eb..f07d33e8 100644
--- a/pkg/cmd/pipelineascode/pipelineascode.go
+++ b/pkg/cmd/pipelineascode/pipelineascode.go
@@ -40,8 +40,16 @@ func Command(p cli.Params) *cobra.Command {
 			if token == "" || err != nil {
 				return fmt.Errorf("token option is not set properly")
 			}
+			cs, err := p.Clients()
+			if err != nil {
+				return err
+			}
+			kinteract, err := kubeinteraction.NewKubernetesInteraction(cs)
+			if err != nil {
+				return err
+			}
 
-			return runWrap(p, opts)
+			return runWrap(opts, cs, kinteract)
 		},
 	}
 
@@ -80,12 +88,7 @@ func getRunInfoFromArgsOrPayload(cs *cli.Clients, payload string, runinfo *webvc
 }
 
 // Wrap around a Run, create a CheckStatusID if there is a failure.
-func runWrap(p cli.Params, opts *pacpkg.Options) error {
-	cs, err := p.Clients()
-	if err != nil {
-		return err
-	}
-
+func runWrap(opts *pacpkg.Options, cs *cli.Clients, kinteract cli.KubeInteractionIntf) error {
 	if opts.PayloadFile != "" {
 		_, err := os.Stat(opts.PayloadFile)
 		if err != nil {
@@ -104,11 +107,6 @@ func runWrap(p cli.Params, opts *pacpkg.Options) error {
 		return err
 	}
 
-	kinteract, err := kubeinteraction.NewKubernetesInteraction(cs)
-	if err != nil {
-		return err
-	}
-
 	// Get webconsole url as soon as possible to have a link to click there
 	url, err := kinteract.GetConsoleUI("", "")
 	if err != nil {
@@ -118,7 +116,7 @@ func runWrap(p cli.Params, opts *pacpkg.Options) error {
 	runinfo.WebConsoleURL = url
 
 	err = pacpkg.Run(cs, kinteract, runinfo)
-	if err != nil && !strings.Contains(err.Error(), "403 Resource not accessible by integration") {
+	if err != nil && runinfo.CheckRunID != nil && !strings.Contains(err.Error(), "403 Resource not accessible by integration") {
 		_, _ = cs.GithubClient.CreateStatus(runinfo, "completed", "failure",
 			fmt.Sprintf("There was an issue validating the commit: %q", err),
 			runinfo.WebConsoleURL)
diff --git a/pkg/consoleui/consoleui.go b/pkg/consoleui/consoleui.go
index 318b9122..7809d12c 100644
--- a/pkg/consoleui/consoleui.go
+++ b/pkg/consoleui/consoleui.go
@@ -56,6 +56,6 @@ func GetConsoleUI(cs *cli.Clients, ns, pr string) (string, error) {
 	if err != nil {
 		return "", err
 	}
-	cs.Log.Info("Console view url: %s", url)
+	cs.Log.Infof("Web Console PR url: %s", url)
 	return url, nil
 }
diff --git a/pkg/kubeinteraction/namespace.go b/pkg/kubeinteraction/namespace.go
index 8032e93d..0497b438 100644
--- a/pkg/kubeinteraction/namespace.go
+++ b/pkg/kubeinteraction/namespace.go
@@ -10,9 +10,9 @@ import (
 func (k Interaction) GetNamespace(namespace string) error {
 	_, err := k.Clients.Kube.CoreV1().Namespaces().Get(context.Background(), namespace, v1.GetOptions{})
 	if err != nil {
-		k.Clients.Log.Infof("Namespace: \"%s\" cannot be found")
+		k.Clients.Log.Infof("Namespace: %s cannot be found")
 		return err
 	}
-	k.Clients.Log.Infof("Namespace is: \"%s\"", namespace)
+	k.Clients.Log.Infof("Namespace is: %s", namespace)
 	return nil
 }
diff --git a/pkg/pipelineascode/pipelineascode.go b/pkg/pipelineascode/pipelineascode.go
index d90c0931..e350562e 100644
--- a/pkg/pipelineascode/pipelineascode.go
+++ b/pkg/pipelineascode/pipelineascode.go
@@ -36,14 +36,14 @@ func getRepoByCR(cs *cli.Clients, url, branch, forceNamespace string) (apipac.Re
 		if value.Spec.URL == url && value.Spec.Branch == branch {
 			if forceNamespace != "" && value.Namespace != forceNamespace {
 				return repository, fmt.Errorf(
-					"repo CR matches but should be installed in \"%s\" as configured from tekton.yaml on the main branch",
+					"repo CR matches but should be installed in %s as configured from tekton.yaml on the main branch",
 					forceNamespace)
 			}
 
 			// Disallow attempts for hijacks. If the installed CR is not configured on the
 			// Namespace the Spec is targeting then disallow it.
 			if value.Namespace != value.Spec.Namespace {
-				return repository, fmt.Errorf("repo CR %s matches but belongs to \"%s\" while it should be in \"%s\"",
+				return repository, fmt.Errorf("repo CR %s matches but belongs to %s while it should be in %s",
 					value.Name,
 					value.Namespace,
 					value.Spec.Namespace)
diff --git a/pkg/webvcs/github.go b/pkg/webvcs/github.go
index a8f60ccc..0d7d6315 100644
--- a/pkg/webvcs/github.go
+++ b/pkg/webvcs/github.go
@@ -205,7 +205,7 @@ func (v GithubVCS) GetFileFromDefaultBranch(path string, runinfo *RunInfo) (stri
 
 	tektonyaml, err := v.GetFileInsideRepo(path, true, runInfoOnMain)
 	if err != nil {
-		return "", fmt.Errorf("cannot find %s inside the \"%s\" branch: %s", path, runInfoOnMain.Branch, err)
+		return "", fmt.Errorf("cannot find %s inside the %s branch: %s", path, runInfoOnMain.Branch, err)
 	}
 	return tektonyaml, err
 }


Test patch:
diff --git a/pkg/cmd/pipelineascode/pipelineascode_test.go b/pkg/cmd/pipelineascode/pipelineascode_test.go
index 1199d780..5ebe9336 100644
--- a/pkg/cmd/pipelineascode/pipelineascode_test.go
+++ b/pkg/cmd/pipelineascode/pipelineascode_test.go
@@ -4,16 +4,65 @@ import (
 	"fmt"
 	"io/ioutil"
 	"net/http"
+	"os"
 	"testing"
 
+	"github.com/davecgh/go-spew/spew"
 	"github.com/openshift-pipelines/pipelines-as-code/pkg/cli"
-	testhelper "github.com/openshift-pipelines/pipelines-as-code/pkg/test"
+	pacpkg "github.com/openshift-pipelines/pipelines-as-code/pkg/pipelineascode"
+	testclient "github.com/openshift-pipelines/pipelines-as-code/pkg/test/clients"
+	ghtesthelper "github.com/openshift-pipelines/pipelines-as-code/pkg/test/github"
+	kitesthelper "github.com/openshift-pipelines/pipelines-as-code/pkg/test/kubernetestint"
 	"github.com/openshift-pipelines/pipelines-as-code/pkg/webvcs"
+	"go.uber.org/zap"
+	zapobserver "go.uber.org/zap/zaptest/observer"
 	"gotest.tools/v3/assert"
+	rtesting "knative.dev/pkg/reconciler/testing"
 )
 
+func TestRunWrapOld(t *testing.T) {
+	fakectx, _ := rtesting.SetupFakeContext(t)
+	fakeghclient, mux, _, teardown := ghtesthelper.SetupGH()
+	stdata, _ := testclient.SeedTestData(t, fakectx, testclient.Data{})
+	observer, _ := zapobserver.New(zap.InfoLevel)
+	fakelogger := zap.New(observer).Sugar()
+	checkid := 1234
+	defer teardown()
+
+	mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
+		fmt.Fprintf(os.Stderr, `
+		============================================
+		%s
+		============================================
+		`, spew.Sdump(r.URL))
+	})
+	mux.HandleFunc("/repos/chmouel/scratchmyback/check-runs", func(w http.ResponseWriter, r *http.Request) {
+		fmt.Fprintf(w, `{"id": %d}`, checkid)
+	})
+	cs := &cli.Clients{
+		GithubClient: webvcs.GithubVCS{
+			Client:  fakeghclient,
+			Context: fakectx,
+		},
+		Log:            fakelogger,
+		PipelineAsCode: stdata.PipelineAsCode,
+	}
+	k8int := &kitesthelper.KinterfaceTest{
+		ConsoleURL: "https://console.url",
+	}
+
+	options := &pacpkg.Options{}
+	err := runWrap(options, cs, k8int)
+	assert.ErrorContains(t, err, "no payload")
+
+	options.PayloadFile = "testdata/pull_request.json"
+	err = runWrap(options, cs, k8int)
+	assert.NilError(t, err)
+}
+
 func TestGetInfo(t *testing.T) {
-	fakeclient, mux, _, teardown := testhelper.SetupGH()
+	fakeclient, mux, _, teardown := ghtesthelper.SetupGH()
+
 	defer teardown()
 	mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
 		fmt.Fprint(w, ``)
@@ -120,3 +169,61 @@ func TestGetInfo(t *testing.T) {
 		})
 	}
 }
+
+func TestRunWrap(t *testing.T) {
+	fakectx, _ := rtesting.SetupFakeContext(t)
+	fakeghclient, mux, _, teardown := ghtesthelper.SetupGH()
+	stdata, _ := testclient.SeedTestData(t, fakectx, testclient.Data{})
+	observer, _ := zapobserver.New(zap.InfoLevel)
+	fakelogger := zap.New(observer).Sugar()
+	checkid := 1234
+	mux.HandleFunc("/repos/chmouel/scratchmyback/check-runs", func(w http.ResponseWriter, r *http.Request) {
+		fmt.Fprintf(w, `{"id": %d}`, checkid)
+	})
+	kinteract := &kitesthelper.KinterfaceTest{
+		ConsoleURL: "https://console.url",
+	}
+
+	defer teardown()
+	cs := &cli.Clients{
+		GithubClient: webvcs.GithubVCS{
+			Client:  fakeghclient,
+			Context: fakectx,
+		},
+		Log:            fakelogger,
+		PipelineAsCode: stdata.PipelineAsCode,
+	}
+
+	tests := []struct {
+		name      string
+		opts      *pacpkg.Options
+		substrErr string
+	}{
+		{
+			name: "good",
+			opts: &pacpkg.Options{
+				PayloadFile: "testdata/pull_request.json",
+			},
+		},
+		{
+			name:      "bad",
+			opts:      &pacpkg.Options{},
+			substrErr: "no payload",
+		},
+		{
+			name:      "file 404",
+			opts:      &pacpkg.Options{PayloadFile: "/nowhere"},
+			substrErr: "no such file or directory",
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			err := runWrap(tt.opts, cs, kinteract)
+			if tt.substrErr != "" {
+				assert.ErrorContains(t, err, tt.substrErr)
+			} else {
+				assert.NilError(t, err)
+			}
+		})
+	}
+}
diff --git a/pkg/pipelineascode/acl_test.go b/pkg/pipelineascode/acl_test.go
index 024ffdfa..31de985f 100644
--- a/pkg/pipelineascode/acl_test.go
+++ b/pkg/pipelineascode/acl_test.go
@@ -7,12 +7,12 @@ import (
 	"testing"
 
 	"github.com/openshift-pipelines/pipelines-as-code/pkg/cli"
-	testhelper "github.com/openshift-pipelines/pipelines-as-code/pkg/test"
+	ghtesthelper "github.com/openshift-pipelines/pipelines-as-code/pkg/test/github"
 	"github.com/openshift-pipelines/pipelines-as-code/pkg/webvcs"
 )
 
 func TestAclCheck(t *testing.T) {
-	fakeclient, mux, _, teardown := testhelper.SetupGH()
+	fakeclient, mux, _, teardown := ghtesthelper.SetupGH()
 	defer teardown()
 
 	orgallowed := "allowed"
diff --git a/pkg/pipelineascode/pipelineascode_test.go b/pkg/pipelineascode/pipelineascode_test.go
index 8720d572..ae8855c6 100644
--- a/pkg/pipelineascode/pipelineascode_test.go
+++ b/pkg/pipelineascode/pipelineascode_test.go
@@ -15,7 +15,9 @@ import (
 	"github.com/jonboulle/clockwork"
 	"github.com/openshift-pipelines/pipelines-as-code/pkg/apis/pipelinesascode/v1alpha1"
 	"github.com/openshift-pipelines/pipelines-as-code/pkg/cli"
-	testhelper "github.com/openshift-pipelines/pipelines-as-code/pkg/test"
+	testclient "github.com/openshift-pipelines/pipelines-as-code/pkg/test/clients"
+	ghtesthelper "github.com/openshift-pipelines/pipelines-as-code/pkg/test/github"
+	kitesthelper "github.com/openshift-pipelines/pipelines-as-code/pkg/test/kubernetestint"
 	"github.com/openshift-pipelines/pipelines-as-code/pkg/webvcs"
 	"go.uber.org/zap"
 	zapobserver "go.uber.org/zap/zaptest/observer"
@@ -87,12 +89,12 @@ func TestFilterByGood(t *testing.T) {
 	branch := "mainone"
 	targetNamespace := "namespace"
 	url := "https://psg.fr"
-	d := testhelper.Data{
+	d := testclient.Data{
 		Repositories: []*v1alpha1.Repository{
 			newRepo("test-good", url, branch, targetNamespace, targetNamespace),
 		},
 	}
-	cs, _ := testhelper.SeedTestData(t, ctx, d)
+	cs, _ := testclient.SeedTestData(t, ctx, d)
 	client := &cli.Clients{PipelineAsCode: cs.PipelineAsCode}
 	repo, err := getRepoByCR(client, url, branch, "")
 	assert.NilError(t, err)
@@ -107,12 +109,12 @@ func TestFilterByNotMatch(t *testing.T) {
 	targetNamespace := "namespace"
 	url := "https://psg.com"
 	otherurl := "https://marseille.com"
-	d := testhelper.Data{
+	d := testclient.Data{
 		Repositories: []*v1alpha1.Repository{
 			newRepo("test-notmatch", url, branch, targetNamespace, targetNamespace),
 		},
 	}
-	cs, _ := testhelper.SeedTestData(t, ctx, d)
+	cs, _ := testclient.SeedTestData(t, ctx, d)
 	client := &cli.Clients{PipelineAsCode: cs.PipelineAsCode}
 	repo, err := getRepoByCR(client, otherurl, branch, "")
 	assert.NilError(t, err)
@@ -127,12 +129,12 @@ func TestFilterByNotInItsNamespace(t *testing.T) {
 	targetNamespace := "namespace"
 	installNamespace := "olympiquelyon"
 	url := "https://psg.fr"
-	d := testhelper.Data{
+	d := testclient.Data{
 		Repositories: []*v1alpha1.Repository{
 			newRepo(testname, url, branch, installNamespace, targetNamespace),
 		},
 	}
-	cs, _ := testhelper.SeedTestData(t, ctx, d)
+	cs, _ := testclient.SeedTestData(t, ctx, d)
 	client := &cli.Clients{PipelineAsCode: cs.PipelineAsCode}
 	repo, err := getRepoByCR(client, url, branch, "")
 	assert.ErrorContains(t, err, fmt.Sprintf("repo CR %s matches but belongs to", testname))
@@ -148,12 +150,12 @@ func TestFilterForceNamespace(t *testing.T) {
 	forcedNamespace := "asmonaco"
 
 	url := "https://psg.fr"
-	d := testhelper.Data{
+	d := testclient.Data{
 		Repositories: []*v1alpha1.Repository{
 			newRepo(testname, url, branch, targetNamespace, targetNamespace),
 		},
 	}
-	cs, _ := testhelper.SeedTestData(t, ctx, d)
+	cs, _ := testclient.SeedTestData(t, ctx, d)
 	client := &cli.Clients{PipelineAsCode: cs.PipelineAsCode}
 	_, err := getRepoByCR(client, url, branch, forcedNamespace)
 	assert.ErrorContains(t, err, "as configured from tekton.yaml on the main branch")
@@ -161,7 +163,7 @@ func TestFilterForceNamespace(t *testing.T) {
 
 func TestRunDeniedFromForcedNamespace(t *testing.T) {
 	ctx, _ := rtesting.SetupFakeContext(t)
-	fakeclient, mux, _, teardown := testhelper.SetupGH()
+	fakeclient, mux, _, teardown := ghtesthelper.SetupGH()
 	defer teardown()
 	defaultBranch := "default"
 	forcedNamespace := "laotronamspace"
@@ -202,28 +204,28 @@ func TestRunDeniedFromForcedNamespace(t *testing.T) {
 		Client:  fakeclient,
 		Context: ctx,
 	}
-	datas := testhelper.Data{
+	datas := testclient.Data{
 		Repositories: []*v1alpha1.Repository{
 			newRepo("repo", runinfo.URL, runinfo.Branch, installedNamespace, installedNamespace),
 		},
 	}
-	stdata, _ := testhelper.SeedTestData(t, ctx, datas)
+	stdata, _ := testclient.SeedTestData(t, ctx, datas)
 	cs := &cli.Clients{
 		GithubClient:   gcvs,
 		PipelineAsCode: stdata.PipelineAsCode,
 	}
-	k8int := testhelper.KinterfaceTest{}
+	k8int := kitesthelper.KinterfaceTest{}
 
 	err := Run(cs, &k8int, runinfo)
 
 	assert.Error(t, err,
-		fmt.Sprintf("repo CR matches but should be installed in \"%s\" as configured from tekton.yaml on the main branch",
+		fmt.Sprintf("repo CR matches but should be installed in %s as configured from tekton.yaml on the main branch",
 			forcedNamespace))
 }
 
 func TestRun(t *testing.T) {
 	ctx, _ := rtesting.SetupFakeContext(t)
-	fakeclient, mux, _, teardown := testhelper.SetupGH()
+	fakeclient, mux, _, teardown := ghtesthelper.SetupGH()
 	defer teardown()
 	runinfo := &webvcs.RunInfo{
 		SHA:        "principale",
@@ -322,7 +324,7 @@ func TestRun(t *testing.T) {
 		Context: ctx,
 	}
 
-	repo := testhelper.Data{
+	repo := testclient.Data{
 		Namespaces: []*corev1.Namespace{
 			{
 				ObjectMeta: metav1.ObjectMeta{
@@ -339,7 +341,7 @@ func TestRun(t *testing.T) {
 				"namespace"),
 		},
 	}
-	stdata, _ := testhelper.SeedTestData(t, ctx, repo)
+	stdata, _ := testclient.SeedTestData(t, ctx, repo)
 
 	observer, log := zapobserver.New(zap.InfoLevel)
 	logger := zap.New(observer).Sugar()
@@ -356,7 +358,7 @@ func TestRun(t *testing.T) {
 		Dynamic:        dc,
 	}
 
-	k8int := testhelper.KinterfaceTest{
+	k8int := kitesthelper.KinterfaceTest{
 		ConsoleURL: "https://console.url",
 	}
 
diff --git a/pkg/pipelineascode/processconfig_test.go b/pkg/pipelineascode/processconfig_test.go
index c3f993d5..10978ba6 100644
--- a/pkg/pipelineascode/processconfig_test.go
+++ b/pkg/pipelineascode/processconfig_test.go
@@ -7,9 +7,11 @@ import (
 	"net/http"
 	"testing"
 
+	ghtesthelper "github.com/openshift-pipelines/pipelines-as-code/pkg/test/github"
+	httptesthelper "github.com/openshift-pipelines/pipelines-as-code/pkg/test/http"
+
 	"github.com/google/go-cmp/cmp"
 	"github.com/openshift-pipelines/pipelines-as-code/pkg/cli"
-	"github.com/openshift-pipelines/pipelines-as-code/pkg/test"
 	"github.com/openshift-pipelines/pipelines-as-code/pkg/webvcs"
 
 	// hubtest "github.com/tektoncd/hub/api/pkg/cli/test"
@@ -30,7 +32,7 @@ func TestProcessTektonYamlRemoteTask(t *testing.T) {
 - https://foo.bar
 - https://hello.moto
 `
-	httpTestClient := test.MakeHTTPTestClient(t, 200, "HELLO")
+	httpTestClient := httptesthelper.MakeHTTPTestClient(t, 200, "HELLO")
 	cs := cli.Clients{HTTPClient: *httpTestClient}
 	expected := `
 ---
@@ -53,7 +55,7 @@ func TestProcessTektonYamlRefInternal(t *testing.T) {
 	data := `tasks:
 - be/healthy
 `
-	fakeclient, mux, _, teardown := test.SetupGH()
+	fakeclient, mux, _, teardown := ghtesthelper.SetupGH()
 	defer teardown()
 
 	mux.HandleFunc("/repos/contents/be/healthy", func(w http.ResponseWriter, r *http.Request) {
diff --git a/pkg/test/helpers.go b/pkg/test/clients/clients.go
similarity index 51%
rename from pkg/test/helpers.go
rename to pkg/test/clients/clients.go
index 99fa1f72..e9e13978 100644
--- a/pkg/test/helpers.go
+++ b/pkg/test/clients/clients.go
@@ -1,17 +1,9 @@
-package test
+package clients
 
 import (
-	"bytes"
 	"context"
-	"fmt"
-	"io/ioutil"
-	"net/http"
-	"net/http/httptest"
-	"net/url"
-	"os"
 	"testing"
 
-	"github.com/google/go-github/v34/github"
 	"github.com/openshift-pipelines/pipelines-as-code/pkg/apis/pipelinesascode/v1alpha1"
 	fakepacclientset "github.com/openshift-pipelines/pipelines-as-code/pkg/generated/clientset/versioned/fake"
 	informersv1alpha1 "github.com/openshift-pipelines/pipelines-as-code/pkg/generated/informers/externalversions/pipelinesascode/v1alpha1"
@@ -46,45 +38,6 @@ type Data struct {
 	Namespaces   []*corev1.Namespace
 }
 
-const (
-	// baseURLPath is a non-empty Client.BaseURL path to use during tests,
-	// to ensure relative URLs are used for all endpoints. See issue #752.
-	githubBaseURLPath = "/api-v3"
-)
-
-// SetupGH Setup a GitHUB httptest connexion, from go-github test-suit
-func SetupGH() (client *github.Client, mux *http.ServeMux, serverURL string, teardown func()) {
-	// mux is the HTTP request multiplexer used with the test server.
-	mux = http.NewServeMux()
-
-	// We want to ensure that tests catch mistakes where the endpoint URL is
-	// specified as absolute rather than relative. It only makes a difference
-	// when there's a non-empty base URL path. So, use that. See issue #752.
-	apiHandler := http.NewServeMux()
-	apiHandler.Handle(githubBaseURLPath+"/", http.StripPrefix(githubBaseURLPath, mux))
-	apiHandler.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
-		fmt.Fprintln(os.Stderr, "FAIL: Client.BaseURL path prefix is not preserved in the request URL:")
-		fmt.Fprintln(os.Stderr)
-		fmt.Fprintln(os.Stderr, "\t"+req.URL.String())
-		fmt.Fprintln(os.Stderr)
-		fmt.Fprintln(os.Stderr, "\tDid you accidentally use an absolute endpoint URL rather than relative?")
-		fmt.Fprintln(os.Stderr, "\tSee https://github.com/google/go-github/issues/752 for information.")
-		http.Error(w, "Client.BaseURL path prefix is not preserved in the request URL.", http.StatusInternalServerError)
-	})
-
-	// server is a test HTTP server used to provide mock API responses.
-	server := httptest.NewServer(apiHandler)
-
-	// client is the GitHub client being tested and is
-	// configured to use test server.
-	client = github.NewClient(nil)
-	url, _ := url.Parse(server.URL + githubBaseURLPath + "/")
-	client.BaseURL = url
-	client.UploadURL = url
-
-	return client, mux, server.URL, server.Close
-}
-
 // SeedTestData returns Clients and Informers populated with the
 // given Data.
 // nolint: golint, revive
@@ -121,32 +74,3 @@ func SeedTestData(t *testing.T, ctx context.Context, d Data) (Clients, Informers
 	c.PipelineAsCode.ClearActions()
 	return c, i
 }
-
-// roundTripFunc .
-type roundTripFunc func(req *http.Request) *http.Response
-
-// RoundTrip .
-func (f roundTripFunc) RoundTrip(req *http.Request) (*http.Response, error) {
-	return f(req), nil
-}
-
-// NewTestClient returns *http.Client with Transport replaced to avoid making real calls
-func newHTTPTestClient(fn roundTripFunc) *http.Client {
-	return &http.Client{
-		Transport: roundTripFunc(fn),
-	}
-}
-
-func MakeHTTPTestClient(t *testing.T, statusCode int, body string) *http.Client {
-	httpTestClient := newHTTPTestClient(func(req *http.Request) *http.Response {
-		// Test request parameters
-		return &http.Response{
-			StatusCode: statusCode,
-			// Send response to be tested
-			Body: ioutil.NopCloser(bytes.NewBufferString(body)),
-			// Must be set to non-nil value or it panics
-			Header: make(http.Header),
-		}
-	})
-	return httpTestClient
-}
diff --git a/pkg/test/github/github.go b/pkg/test/github/github.go
new file mode 100644
index 00000000..b26e503a
--- /dev/null
+++ b/pkg/test/github/github.go
@@ -0,0 +1,50 @@
+package github
+
+import (
+	"fmt"
+	"net/http"
+	"net/http/httptest"
+	"net/url"
+	"os"
+
+	"github.com/google/go-github/v34/github"
+)
+
+const (
+	// baseURLPath is a non-empty Client.BaseURL path to use during tests,
+	// to ensure relative URLs are used for all endpoints. See issue #752.
+	githubBaseURLPath = "/api-v3"
+)
+
+// SetupGH Setup a GitHUB httptest connexion, from go-github test-suit
+func SetupGH() (client *github.Client, mux *http.ServeMux, serverURL string, teardown func()) {
+	// mux is the HTTP request multiplexer used with the test server.
+	mux = http.NewServeMux()
+
+	// We want to ensure that tests catch mistakes where the endpoint URL is
+	// specified as absolute rather than relative. It only makes a difference
+	// when there's a non-empty base URL path. So, use that. See issue #752.
+	apiHandler := http.NewServeMux()
+	apiHandler.Handle(githubBaseURLPath+"/", http.StripPrefix(githubBaseURLPath, mux))
+	apiHandler.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
+		fmt.Fprintln(os.Stderr, "FAIL: Client.BaseURL path prefix is not preserved in the request URL:")
+		fmt.Fprintln(os.Stderr)
+		fmt.Fprintln(os.Stderr, "\t"+req.URL.String())
+		fmt.Fprintln(os.Stderr)
+		fmt.Fprintln(os.Stderr, "\tDid you accidentally use an absolute endpoint URL rather than relative?")
+		fmt.Fprintln(os.Stderr, "\tSee https://github.com/google/go-github/issues/752 for information.")
+		http.Error(w, "Client.BaseURL path prefix is not preserved in the request URL.", http.StatusInternalServerError)
+	})
+
+	// server is a test HTTP server used to provide mock API responses.
+	server := httptest.NewServer(apiHandler)
+
+	// client is the GitHub client being tested and is
+	// configured to use test server.
+	client = github.NewClient(nil)
+	url, _ := url.Parse(server.URL + githubBaseURLPath + "/")
+	client.BaseURL = url
+	client.UploadURL = url
+
+	return client, mux, server.URL, server.Close
+}
diff --git a/pkg/test/http/http.go b/pkg/test/http/http.go
new file mode 100644
index 00000000..4542b81d
--- /dev/null
+++ b/pkg/test/http/http.go
@@ -0,0 +1,37 @@
+package http
+
+import (
+	"bytes"
+	"io/ioutil"
+	"net/http"
+	"testing"
+)
+
+// NewTestClient returns *http.Client with Transport replaced to avoid making real calls
+func newHTTPTestClient(fn roundTripFunc) *http.Client {
+	return &http.Client{
+		Transport: roundTripFunc(fn),
+	}
+}
+
+func MakeHTTPTestClient(t *testing.T, statusCode int, body string) *http.Client {
+	httpTestClient := newHTTPTestClient(func(req *http.Request) *http.Response {
+		// Test request parameters
+		return &http.Response{
+			StatusCode: statusCode,
+			// Send response to be tested
+			Body: ioutil.NopCloser(bytes.NewBufferString(body)),
+			// Must be set to non-nil value or it panics
+			Header: make(http.Header),
+		}
+	})
+	return httpTestClient
+}
+
+// roundTripFunc .
+type roundTripFunc func(req *http.Request) *http.Response
+
+// RoundTrip .
+func (f roundTripFunc) RoundTrip(req *http.Request) (*http.Response, error) {
+	return f(req), nil
+}
diff --git a/pkg/test/kubernetesintf.go b/pkg/test/kubernetestint/kubernetesint.go
similarity index 96%
rename from pkg/test/kubernetesintf.go
rename to pkg/test/kubernetestint/kubernetesint.go
index f5863c44..c8d1eae6 100644
--- a/pkg/test/kubernetesintf.go
+++ b/pkg/test/kubernetestint/kubernetesint.go
@@ -1,4 +1,4 @@
-package test
+package kubernetestint
 
 import "errors"
 
diff --git a/pkg/test/params/params.go b/pkg/test/params/params.go
new file mode 100644
index 00000000..66d4e54e
--- /dev/null
+++ b/pkg/test/params/params.go
@@ -0,0 +1,27 @@
+package params
+
+import (
+	"github.com/openshift-pipelines/pipelines-as-code/pkg/cli"
+	"k8s.io/client-go/kubernetes"
+)
+
+type FakeParams struct {
+	Fakeclients *cli.Clients
+}
+
+// SetKubeConfigPath uses the kubeconfig path to instantiate tekton
+// returned by Clientset function
+func (p FakeParams) SetKubeConfigPath(string) {
+}
+
+// SetGitHubToken Set github token TODO: rename to a generic vcs
+func (p FakeParams) SetGitHubToken(string) {
+}
+
+func (p FakeParams) Clients() (*cli.Clients, error) {
+	return p.Fakeclients, nil
+}
+
+func (p FakeParams) KubeClient() (kubernetes.Interface, error) {
+	return nil, nil
+}
diff --git a/pkg/webvcs/github_test.go b/pkg/webvcs/github_test.go
index 02b76a57..138da23e 100644
--- a/pkg/webvcs/github_test.go
+++ b/pkg/webvcs/github_test.go
@@ -10,9 +10,10 @@ import (
 	"strings"
 	"testing"
 
+	ghtesthelper "github.com/openshift-pipelines/pipelines-as-code/pkg/test/github"
+
 	"github.com/google/go-cmp/cmp"
 	"github.com/google/go-github/v34/github"
-	testhelper "github.com/openshift-pipelines/pipelines-as-code/pkg/test"
 	"go.uber.org/zap"
 	zapobserver "go.uber.org/zap/zaptest/observer"
 	"gotest.tools/v3/assert"
@@ -45,7 +46,7 @@ func TestParsePayloadRerequest(t *testing.T) {
 	"check_run": {"check_suite": {"pull_requests": [{"number": %s}]}}, 
 	"repository": {"name": "%s", "owner": {"login": "%s"}}}`,
 		repoSender, prNumber, repoName, repoOwner)
-	fakeclient, mux, _, teardown := testhelper.SetupGH()
+	fakeclient, mux, _, teardown := ghtesthelper.SetupGH()
 	defer teardown()
 	mux.HandleFunc("/repos/"+repoOwner+"/"+repoName+"/pulls/"+prNumber, func(rw http.ResponseWriter, r *http.Request) {
 		fmt.Fprintf(rw, `{"repo": {"name": "%s", "owner": {"login": "%s"}}}`, repoName, repoOwner)
@@ -85,7 +86,7 @@ func TestParsePayload(t *testing.T) {
 }
 
 func setupFakesURLS() (client GithubVCS, teardown func()) {
-	fakeclient, mux, _, teardown := testhelper.SetupGH()
+	fakeclient, mux, _, teardown := ghtesthelper.SetupGH()
 
 	mux.HandleFunc("/repos/check/run/check-runs", func(w http.ResponseWriter, r *http.Request) {
 		fmt.Fprint(w, `{"id": 555}`)
@@ -525,7 +526,7 @@ func TestGithubVCS_CreateStatus(t *testing.T) {
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			fakeclient, mux, _, teardown := testhelper.SetupGH()
+			fakeclient, mux, _, teardown := ghtesthelper.SetupGH()
 			defer teardown()
 
 			ctx := context.Background()