mirror of
				https://github.com/woodpecker-ci/woodpecker.git
				synced 2025-10-31 12:45:35 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			329 lines
		
	
	
		
			9.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			329 lines
		
	
	
		
			9.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package testing
 | |
| 
 | |
| import (
 | |
| 	"database/sql"
 | |
| 	"fmt"
 | |
| 	"net/http"
 | |
| 	"net/http/httptest"
 | |
| 	"net/url"
 | |
| 	"testing"
 | |
| 
 | |
| 	"github.com/drone/drone/pkg/database"
 | |
| 	"github.com/drone/drone/pkg/handler"
 | |
| 	"github.com/drone/drone/pkg/model"
 | |
| 	"github.com/drone/drone/pkg/queue"
 | |
| 
 | |
| 	dbtest "github.com/drone/drone/pkg/database/testing"
 | |
| 	. "github.com/smartystreets/goconvey/convey"
 | |
| )
 | |
| 
 | |
| // Tests the ability to create GitHub repositories.
 | |
| func Test_GitLabCreate(t *testing.T) {
 | |
| 	// seed the database with values
 | |
| 	SetupGitlabFixtures()
 | |
| 	defer TeardownGitlabFixtures()
 | |
| 
 | |
| 	q := &queue.Queue{}
 | |
| 	gl := handler.NewGitlabHandler(q)
 | |
| 
 | |
| 	// mock request
 | |
| 	req := http.Request{}
 | |
| 	req.Form = url.Values{}
 | |
| 
 | |
| 	// get user that will add repositories
 | |
| 	user, _ := database.GetUser(1)
 | |
| 	settings := database.SettingsMust()
 | |
| 
 | |
| 	Convey("Given request to setup gitlab repo", t, func() {
 | |
| 
 | |
| 		Convey("When repository is public", func() {
 | |
| 			req.Form.Set("owner", "example")
 | |
| 			req.Form.Set("name", "public")
 | |
| 			req.Form.Set("team", "")
 | |
| 			res := httptest.NewRecorder()
 | |
| 			err := gl.Create(res, &req, user)
 | |
| 			repo, _ := database.GetRepoSlug(settings.GitlabDomain + "/example/public")
 | |
| 
 | |
| 			Convey("The repository is created", func() {
 | |
| 				So(err, ShouldBeNil)
 | |
| 				So(repo, ShouldNotBeNil)
 | |
| 				So(repo.ID, ShouldNotEqual, 0)
 | |
| 				So(repo.Owner, ShouldEqual, "example")
 | |
| 				So(repo.Name, ShouldEqual, "public")
 | |
| 				So(repo.Host, ShouldEqual, settings.GitlabDomain)
 | |
| 				So(repo.TeamID, ShouldEqual, 0)
 | |
| 				So(repo.UserID, ShouldEqual, user.ID)
 | |
| 				So(repo.Private, ShouldEqual, false)
 | |
| 				So(repo.SCM, ShouldEqual, "git")
 | |
| 			})
 | |
| 			Convey("The repository is public", func() {
 | |
| 				So(repo.Private, ShouldEqual, false)
 | |
| 			})
 | |
| 		})
 | |
| 
 | |
| 		Convey("When repository is private", func() {
 | |
| 			req.Form.Set("owner", "example")
 | |
| 			req.Form.Set("name", "private")
 | |
| 			req.Form.Set("team", "")
 | |
| 			res := httptest.NewRecorder()
 | |
| 			err := gl.Create(res, &req, user)
 | |
| 			repo, _ := database.GetRepoSlug(settings.GitlabDomain + "/example/private")
 | |
| 
 | |
| 			Convey("The repository is created", func() {
 | |
| 				So(err, ShouldBeNil)
 | |
| 				So(repo, ShouldNotBeNil)
 | |
| 				So(repo.ID, ShouldNotEqual, 0)
 | |
| 			})
 | |
| 			Convey("The repository is private", func() {
 | |
| 				So(repo.Private, ShouldEqual, true)
 | |
| 			})
 | |
| 		})
 | |
| 
 | |
| 		Convey("When repository is not found", func() {
 | |
| 			req.Form.Set("owner", "example")
 | |
| 			req.Form.Set("name", "notfound")
 | |
| 			req.Form.Set("team", "")
 | |
| 			res := httptest.NewRecorder()
 | |
| 			err := gl.Create(res, &req, user)
 | |
| 
 | |
| 			Convey("The result is an error", func() {
 | |
| 				So(err, ShouldNotBeNil)
 | |
| 				So(err.Error(), ShouldStartWith, "*Gitlab.buildAndExecRequestRaw")
 | |
| 			})
 | |
| 
 | |
| 			Convey("The repository is not created", func() {
 | |
| 				_, err := database.GetRepoSlug("example/notfound")
 | |
| 				So(err, ShouldNotBeNil)
 | |
| 				So(err, ShouldEqual, sql.ErrNoRows)
 | |
| 			})
 | |
| 		})
 | |
| 
 | |
| 		Convey("When repository hook is not writable", func() {
 | |
| 			req.Form.Set("owner", "example")
 | |
| 			req.Form.Set("name", "hookerr")
 | |
| 			req.Form.Set("team", "")
 | |
| 			res := httptest.NewRecorder()
 | |
| 			err := gl.Create(res, &req, user)
 | |
| 
 | |
| 			Convey("The result is an error", func() {
 | |
| 				So(err, ShouldNotBeNil)
 | |
| 				So(err.Error(), ShouldEqual, "Unable to add Hook to your GitLab repository.")
 | |
| 			})
 | |
| 
 | |
| 			Convey("The repository is not created", func() {
 | |
| 				_, err := database.GetRepoSlug("example/hookerr")
 | |
| 				So(err, ShouldNotBeNil)
 | |
| 				So(err, ShouldEqual, sql.ErrNoRows)
 | |
| 			})
 | |
| 		})
 | |
| 
 | |
| 		Convey("When repository ssh key is not writable", func() {
 | |
| 			req.Form.Set("owner", "example")
 | |
| 			req.Form.Set("name", "keyerr")
 | |
| 			req.Form.Set("team", "")
 | |
| 			res := httptest.NewRecorder()
 | |
| 			err := gl.Create(res, &req, user)
 | |
| 
 | |
| 			Convey("The result is an error", func() {
 | |
| 				So(err, ShouldNotBeNil)
 | |
| 				So(err.Error(), ShouldEqual, "Unable to add Public Key to your GitLab repository.")
 | |
| 			})
 | |
| 
 | |
| 			Convey("The repository is not created", func() {
 | |
| 				_, err := database.GetRepoSlug("example/keyerr")
 | |
| 				So(err, ShouldNotBeNil)
 | |
| 				So(err, ShouldEqual, sql.ErrNoRows)
 | |
| 			})
 | |
| 		})
 | |
| 
 | |
| 		Convey("When a team is provided", func() {
 | |
| 			req.Form.Set("owner", "example")
 | |
| 			req.Form.Set("name", "team")
 | |
| 			req.Form.Set("team", "drone")
 | |
| 			res := httptest.NewRecorder()
 | |
| 
 | |
| 			// invoke handler
 | |
| 			err := gl.Create(res, &req, user)
 | |
| 			team, _ := database.GetTeamSlug("drone")
 | |
| 			repo, _ := database.GetRepoSlug(settings.GitlabDomain + "/example/team")
 | |
| 
 | |
| 			Convey("The repository is created", func() {
 | |
| 				So(err, ShouldBeNil)
 | |
| 				So(repo, ShouldNotBeNil)
 | |
| 				So(repo.ID, ShouldNotEqual, 0)
 | |
| 			})
 | |
| 
 | |
| 			Convey("The team should be set", func() {
 | |
| 				So(repo.TeamID, ShouldEqual, team.ID)
 | |
| 			})
 | |
| 		})
 | |
| 
 | |
| 		Convey("When a team is not found", func() {
 | |
| 			req.Form.Set("owner", "example")
 | |
| 			req.Form.Set("name", "public")
 | |
| 			req.Form.Set("team", "faketeam")
 | |
| 			res := httptest.NewRecorder()
 | |
| 			err := gl.Create(res, &req, user)
 | |
| 
 | |
| 			Convey("The result is an error", func() {
 | |
| 				So(err, ShouldNotBeNil)
 | |
| 				So(err.Error(), ShouldEqual, "Unable to find Team faketeam.")
 | |
| 			})
 | |
| 		})
 | |
| 
 | |
| 		Convey("When a team is forbidden", func() {
 | |
| 			req.Form.Set("owner", "example")
 | |
| 			req.Form.Set("name", "public")
 | |
| 			req.Form.Set("team", "golang")
 | |
| 			res := httptest.NewRecorder()
 | |
| 			err := gl.Create(res, &req, user)
 | |
| 
 | |
| 			Convey("The result is an error", func() {
 | |
| 				So(err, ShouldNotBeNil)
 | |
| 				So(err.Error(), ShouldEqual, "Invalid permission to access Team golang.")
 | |
| 			})
 | |
| 		})
 | |
| 	})
 | |
| }
 | |
| 
 | |
| // this code should be refactored and centralized, but for now
 | |
| // it is just proof-of-concepting a testing strategy, so we'll
 | |
| // revisit later.
 | |
| 
 | |
| // server is a test HTTP server used to provide mock API responses.
 | |
| var glServer *httptest.Server
 | |
| 
 | |
| func SetupGitlabFixtures() {
 | |
| 	dbtest.Setup()
 | |
| 
 | |
| 	// test server
 | |
| 	mux := http.NewServeMux()
 | |
| 	glServer = httptest.NewServer(mux)
 | |
| 	url, _ := url.Parse(glServer.URL)
 | |
| 
 | |
| 	// set database to use a localhost url for GitHub
 | |
| 	settings := model.Settings{}
 | |
| 	settings.GitlabApiUrl = url.String() // normall would be "https://api.github.com"
 | |
| 	settings.GitlabDomain = url.Host     // normally would be "github.com"
 | |
| 	settings.Scheme = url.Scheme
 | |
| 	settings.Domain = "localhost"
 | |
| 	database.SaveSettings(&settings)
 | |
| 
 | |
| 	// -----------------------------------------------------------------------------------
 | |
| 	// fixture to return a public repository and successfully
 | |
| 	// create a commit hook.
 | |
| 
 | |
| 	mux.HandleFunc("/api/v3/projects/example/public", func(w http.ResponseWriter, r *http.Request) {
 | |
| 		fmt.Fprint(w, `{
 | |
| 			"name": "public",
 | |
| 			"path_with_namespace": "example/public",
 | |
| 			"public": true
 | |
| 		}`)
 | |
| 	})
 | |
| 
 | |
| 	mux.HandleFunc("/api/v3/projects/example/public/hooks", func(w http.ResponseWriter, r *http.Request) {
 | |
| 		fmt.Fprintf(w, `{
 | |
| 			"url": "https://example.com/example/public/hooks/1",
 | |
| 			"id": 1
 | |
| 		}`)
 | |
| 	})
 | |
| 
 | |
| 	// -----------------------------------------------------------------------------------
 | |
| 	// fixture to return a private repository and successfully
 | |
| 	// create a commit hook and ssh deploy key
 | |
| 
 | |
| 	mux.HandleFunc("/api/v3/projects/example/private", func(w http.ResponseWriter, r *http.Request) {
 | |
| 		fmt.Fprint(w, `{
 | |
| 			"name": "private",
 | |
| 			"path_with_namespace": "example/private",
 | |
| 			"public": false
 | |
| 		}`)
 | |
| 	})
 | |
| 
 | |
| 	mux.HandleFunc("/api/v3/projects/example/private/hooks", func(w http.ResponseWriter, r *http.Request) {
 | |
| 		fmt.Fprintf(w, `{
 | |
| 			"url": "https://example.com/example/private/hooks/1",
 | |
| 			"id": 1
 | |
| 		}`)
 | |
| 	})
 | |
| 
 | |
| 	mux.HandleFunc("/api/v3/projects/example/private/keys", func(w http.ResponseWriter, r *http.Request) {
 | |
| 		fmt.Fprintf(w, `{
 | |
| 			"id": 1,
 | |
| 			"key": "ssh-rsa AAA...",
 | |
| 			"url": "https://api.github.com/user/keys/1",
 | |
| 			"title": "octocat@octomac"
 | |
| 		}`)
 | |
| 	})
 | |
| 
 | |
| 	// -----------------------------------------------------------------------------------
 | |
| 	// fixture to return a not found when accessing a github repository.
 | |
| 
 | |
| 	mux.HandleFunc("/api/v3/projects/example/notfound", func(w http.ResponseWriter, r *http.Request) {
 | |
| 		http.NotFound(w, r)
 | |
| 	})
 | |
| 
 | |
| 	// -----------------------------------------------------------------------------------
 | |
| 	// fixture to return a public repository and successfully
 | |
| 	// create a commit hook.
 | |
| 
 | |
| 	mux.HandleFunc("/api/v3/projects/example/hookerr", func(w http.ResponseWriter, r *http.Request) {
 | |
| 		fmt.Fprint(w, `{
 | |
| 			"name": "hookerr",
 | |
| 			"path_with_namespace": "example/hookerr",
 | |
| 			"public": true
 | |
| 		}`)
 | |
| 	})
 | |
| 
 | |
| 	mux.HandleFunc("/api/v3/projects/example/hookerr/hooks", func(w http.ResponseWriter, r *http.Request) {
 | |
| 		http.Error(w, "Forbidden", http.StatusForbidden)
 | |
| 	})
 | |
| 
 | |
| 	// -----------------------------------------------------------------------------------
 | |
| 	// fixture to return a private repository and successfully
 | |
| 	// create a commit hook and ssh deploy key
 | |
| 
 | |
| 	mux.HandleFunc("/api/v3/projects/example/keyerr", func(w http.ResponseWriter, r *http.Request) {
 | |
| 		fmt.Fprint(w, `{
 | |
| 			"name": "keyerr",
 | |
| 			"path_with_namespace": "example/keyerr",
 | |
| 			"public": false
 | |
| 		}`)
 | |
| 	})
 | |
| 
 | |
| 	mux.HandleFunc("/api/v3/projects/example/keyerr/hooks", func(w http.ResponseWriter, r *http.Request) {
 | |
| 		fmt.Fprintf(w, `{
 | |
| 			"url": "https://api.github.com/api/v3/projects/example/keyerr/hooks/1",
 | |
| 			"id": 1
 | |
| 		}`)
 | |
| 	})
 | |
| 
 | |
| 	mux.HandleFunc("/api/v3/projects/example/keyerr/keys", func(w http.ResponseWriter, r *http.Request) {
 | |
| 		http.Error(w, "Forbidden", http.StatusForbidden)
 | |
| 	})
 | |
| 
 | |
| 	// -----------------------------------------------------------------------------------
 | |
| 	// fixture to return a public repository and successfully to
 | |
| 	// test adding a team.
 | |
| 
 | |
| 	mux.HandleFunc("/api/v3/projects/example/team", func(w http.ResponseWriter, r *http.Request) {
 | |
| 		fmt.Fprint(w, `{
 | |
| 			"name": "team",
 | |
| 			"path_with_namespace": "example/team",
 | |
| 			"public": true
 | |
| 		}`)
 | |
| 	})
 | |
| 
 | |
| 	mux.HandleFunc("/api/v3/projects/example/team/hooks", func(w http.ResponseWriter, r *http.Request) {
 | |
| 		fmt.Fprintf(w, `{
 | |
| 			"url": "https://api.github.com/api/v3/projects/example/team/hooks/1",
 | |
| 			"id": 1
 | |
| 		}`)
 | |
| 	})
 | |
| }
 | |
| 
 | |
| func TeardownGitlabFixtures() {
 | |
| 	dbtest.Teardown()
 | |
| 	glServer.Close()
 | |
| }
 |