diff --git a/scm/github/app_transport.go b/scm/github/app_transport.go index ca0234535..34ebb0742 100644 --- a/scm/github/app_transport.go +++ b/scm/github/app_transport.go @@ -335,6 +335,7 @@ func WithSigner(signer Signer) AppsTransportOption { // NewTestAppsTransport creates a new AppsTransport for testing purposes. func NewTestAppsTransport(baseURL string) *AppsTransport { pk, _ := rsa.GenerateKey(rand.Reader, 2048) + return &AppsTransport{ BaseURL: baseURL, Client: &http.Client{Transport: http.DefaultTransport}, diff --git a/scm/github/app_client.go b/scm/github/github_client.go similarity index 100% rename from scm/github/app_client.go rename to scm/github/github_client.go diff --git a/scm/github/github_client_test.go b/scm/github/github_client_test.go new file mode 100644 index 000000000..5d289f874 --- /dev/null +++ b/scm/github/github_client_test.go @@ -0,0 +1,125 @@ +// SPDX-License-Identifier: Apache-2.0 + +package github + +import ( + "context" + "net/http" + "net/http/httptest" + "testing" + + "github.com/gin-gonic/gin" + api "github.com/go-vela/server/api/types" + "github.com/go-vela/server/constants" + "github.com/google/go-github/v65/github" +) + +func TestClient_installationCanReadRepo(t *testing.T) { + // setup types + accessibleRepo := new(api.Repo) + accessibleRepo.SetOrg("octocat") + accessibleRepo.SetName("Hello-World") + accessibleRepo.SetFullName("octocat/Hello-World") + accessibleRepo.SetInstallID(0) + + inaccessibleRepo := new(api.Repo) + inaccessibleRepo.SetOrg("octocat") + inaccessibleRepo.SetName("Hello-World") + inaccessibleRepo.SetFullName("octocat/Hello-World2") + inaccessibleRepo.SetInstallID(4) + + resp := httptest.NewRecorder() + _, engine := gin.CreateTestContext(resp) + + // setup mock server + engine.POST("/api/v3/app/installations/:id/access_tokens", func(c *gin.Context) { + c.Header("Content-Type", "application/json") + c.Status(http.StatusOK) + c.File("testdata/installations_access_tokens.json") + }) + engine.GET("/api/v3/installation/repositories", func(c *gin.Context) { + c.Header("Content-Type", "application/json") + c.Status(http.StatusOK) + c.File("testdata/installation_repositories.json") + }) + + s := httptest.NewServer(engine) + defer s.Close() + + oauthClient, _ := NewTest(s.URL) + + appsClient, err := NewTest(s.URL) + if err != nil { + t.Errorf("unable to create GitHub App client: %v", err) + } + + appsClient.AppsTransport = NewTestAppsTransport("") + + // setup tests + tests := []struct { + name string + client *client + repo *api.Repo + installation *github.Installation + appsTransport bool + want bool + wantErr bool + }{ + { + name: "installation can read repo", + client: appsClient, + repo: accessibleRepo, + installation: &github.Installation{ + ID: github.Int64(1), + Account: &github.User{ + Login: github.String("github"), + }, + RepositorySelection: github.String(constants.AppInstallRepositoriesSelectionSelected), + }, + want: true, + wantErr: false, + }, + { + name: "installation cannot read repo", + client: appsClient, + repo: inaccessibleRepo, + installation: &github.Installation{ + ID: github.Int64(2), + Account: &github.User{ + Login: github.String("github"), + }, + RepositorySelection: github.String(constants.AppInstallRepositoriesSelectionSelected), + }, + want: false, + wantErr: false, + }, + { + name: "no GitHub App client", + client: oauthClient, + repo: accessibleRepo, + installation: &github.Installation{ + ID: github.Int64(1), + Account: &github.User{ + Login: github.String("github"), + }, + RepositorySelection: github.String(constants.AppInstallRepositoriesSelectionSelected), + }, + want: false, + wantErr: true, + }, + } + + // run tests + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := tt.client.installationCanReadRepo(context.Background(), tt.repo, tt.installation) + if (err != nil) != tt.wantErr { + t.Errorf("installationCanReadRepo() error = %v, wantErr %v", err, tt.wantErr) + return + } + if got != tt.want { + t.Errorf("installationCanReadRepo() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/scm/github/repo_test.go b/scm/github/repo_test.go index f10907ab7..898f072ac 100644 --- a/scm/github/repo_test.go +++ b/scm/github/repo_test.go @@ -1810,13 +1810,13 @@ func TestGithub_GetNetrcPassword(t *testing.T) { u.SetToken("bar") tests := []struct { - name string - repo *api.Repo - user *api.User - git yaml.Git - appTransport bool - wantToken string - wantErr bool + name string + repo *api.Repo + user *api.User + git yaml.Git + appsTransport bool + wantToken string + wantErr bool }{ { name: "installation token", @@ -1828,9 +1828,9 @@ func TestGithub_GetNetrcPassword(t *testing.T) { Permissions: map[string]string{"contents": "read"}, }, }, - appTransport: true, - wantToken: "ghs_16C7e42F292c6912E7710c838347Ae178B4a", - wantErr: false, + appsTransport: true, + wantToken: "ghs_16C7e42F292c6912E7710c838347Ae178B4a", + wantErr: false, }, { name: "no app configured returns user oauth token", @@ -1842,9 +1842,9 @@ func TestGithub_GetNetrcPassword(t *testing.T) { Permissions: map[string]string{"contents": "read"}, }, }, - appTransport: false, - wantToken: "bar", - wantErr: false, + appsTransport: false, + wantToken: "bar", + wantErr: false, }, { name: "repo not installed returns user oauth token", @@ -1856,9 +1856,9 @@ func TestGithub_GetNetrcPassword(t *testing.T) { Permissions: map[string]string{"contents": "read"}, }, }, - appTransport: true, - wantToken: "bar", - wantErr: false, + appsTransport: true, + wantToken: "bar", + wantErr: false, }, { name: "invalid permission resource", @@ -1870,9 +1870,9 @@ func TestGithub_GetNetrcPassword(t *testing.T) { Permissions: map[string]string{"invalid": "read"}, }, }, - appTransport: true, - wantToken: "bar", - wantErr: true, + appsTransport: true, + wantToken: "bar", + wantErr: true, }, { name: "invalid permission level", @@ -1884,16 +1884,16 @@ func TestGithub_GetNetrcPassword(t *testing.T) { Permissions: map[string]string{"contents": "invalid"}, }, }, - appTransport: true, - wantToken: "bar", - wantErr: true, + appsTransport: true, + wantToken: "bar", + wantErr: true, }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { client, _ := NewTest(s.URL) - if test.appTransport { + if test.appsTransport { client.AppsTransport = NewTestAppsTransport(s.URL) }