github.com/kvattikuti/drone@v0.2.1-0.20140603034306-d400229a327a/pkg/handler/testing/gitlab_test.go (about)

     1  package testing
     2  
     3  import (
     4  	"database/sql"
     5  	"fmt"
     6  	"net/http"
     7  	"net/http/httptest"
     8  	"net/url"
     9  	"testing"
    10  
    11  	"github.com/drone/drone/pkg/database"
    12  	"github.com/drone/drone/pkg/handler"
    13  	"github.com/drone/drone/pkg/model"
    14  	"github.com/drone/drone/pkg/queue"
    15  
    16  	dbtest "github.com/drone/drone/pkg/database/testing"
    17  	. "github.com/smartystreets/goconvey/convey"
    18  )
    19  
    20  // Tests the ability to create GitHub repositories.
    21  func Test_GitLabCreate(t *testing.T) {
    22  	// seed the database with values
    23  	SetupGitlabFixtures()
    24  	defer TeardownGitlabFixtures()
    25  
    26  	q := &queue.Queue{}
    27  	gl := handler.NewGitlabHandler(q)
    28  
    29  	// mock request
    30  	req := http.Request{}
    31  	req.Form = url.Values{}
    32  
    33  	// get user that will add repositories
    34  	user, _ := database.GetUser(1)
    35  	settings := database.SettingsMust()
    36  
    37  	Convey("Given request to setup gitlab repo", t, func() {
    38  
    39  		Convey("When repository is public", func() {
    40  			req.Form.Set("owner", "example")
    41  			req.Form.Set("name", "public")
    42  			req.Form.Set("team", "")
    43  			res := httptest.NewRecorder()
    44  			err := gl.Create(res, &req, user)
    45  			repo, _ := database.GetRepoSlug(settings.GitlabDomain + "/example/public")
    46  
    47  			Convey("The repository is created", func() {
    48  				So(err, ShouldBeNil)
    49  				So(repo, ShouldNotBeNil)
    50  				So(repo.ID, ShouldNotEqual, 0)
    51  				So(repo.Owner, ShouldEqual, "example")
    52  				So(repo.Name, ShouldEqual, "public")
    53  				So(repo.Host, ShouldEqual, settings.GitlabDomain)
    54  				So(repo.TeamID, ShouldEqual, 0)
    55  				So(repo.UserID, ShouldEqual, user.ID)
    56  				So(repo.Private, ShouldEqual, false)
    57  				So(repo.SCM, ShouldEqual, "git")
    58  			})
    59  			Convey("The repository is public", func() {
    60  				So(repo.Private, ShouldEqual, false)
    61  			})
    62  		})
    63  
    64  		Convey("When repository is private", func() {
    65  			req.Form.Set("owner", "example")
    66  			req.Form.Set("name", "private")
    67  			req.Form.Set("team", "")
    68  			res := httptest.NewRecorder()
    69  			err := gl.Create(res, &req, user)
    70  			repo, _ := database.GetRepoSlug(settings.GitlabDomain + "/example/private")
    71  
    72  			Convey("The repository is created", func() {
    73  				So(err, ShouldBeNil)
    74  				So(repo, ShouldNotBeNil)
    75  				So(repo.ID, ShouldNotEqual, 0)
    76  			})
    77  			Convey("The repository is private", func() {
    78  				So(repo.Private, ShouldEqual, true)
    79  			})
    80  		})
    81  
    82  		Convey("When repository is not found", func() {
    83  			req.Form.Set("owner", "example")
    84  			req.Form.Set("name", "notfound")
    85  			req.Form.Set("team", "")
    86  			res := httptest.NewRecorder()
    87  			err := gl.Create(res, &req, user)
    88  
    89  			Convey("The result is an error", func() {
    90  				So(err, ShouldNotBeNil)
    91  				So(err.Error(), ShouldStartWith, "*Gitlab.buildAndExecRequestRaw")
    92  			})
    93  
    94  			Convey("The repository is not created", func() {
    95  				_, err := database.GetRepoSlug("example/notfound")
    96  				So(err, ShouldNotBeNil)
    97  				So(err, ShouldEqual, sql.ErrNoRows)
    98  			})
    99  		})
   100  
   101  		Convey("When repository hook is not writable", func() {
   102  			req.Form.Set("owner", "example")
   103  			req.Form.Set("name", "hookerr")
   104  			req.Form.Set("team", "")
   105  			res := httptest.NewRecorder()
   106  			err := gl.Create(res, &req, user)
   107  
   108  			Convey("The result is an error", func() {
   109  				So(err, ShouldNotBeNil)
   110  				So(err.Error(), ShouldEqual, "Unable to add Hook to your GitLab repository.")
   111  			})
   112  
   113  			Convey("The repository is not created", func() {
   114  				_, err := database.GetRepoSlug("example/hookerr")
   115  				So(err, ShouldNotBeNil)
   116  				So(err, ShouldEqual, sql.ErrNoRows)
   117  			})
   118  		})
   119  
   120  		Convey("When repository ssh key is not writable", func() {
   121  			req.Form.Set("owner", "example")
   122  			req.Form.Set("name", "keyerr")
   123  			req.Form.Set("team", "")
   124  			res := httptest.NewRecorder()
   125  			err := gl.Create(res, &req, user)
   126  
   127  			Convey("The result is an error", func() {
   128  				So(err, ShouldNotBeNil)
   129  				So(err.Error(), ShouldEqual, "Unable to add Public Key to your GitLab repository.")
   130  			})
   131  
   132  			Convey("The repository is not created", func() {
   133  				_, err := database.GetRepoSlug("example/keyerr")
   134  				So(err, ShouldNotBeNil)
   135  				So(err, ShouldEqual, sql.ErrNoRows)
   136  			})
   137  		})
   138  
   139  		Convey("When a team is provided", func() {
   140  			req.Form.Set("owner", "example")
   141  			req.Form.Set("name", "team")
   142  			req.Form.Set("team", "drone")
   143  			res := httptest.NewRecorder()
   144  
   145  			// invoke handler
   146  			err := gl.Create(res, &req, user)
   147  			team, _ := database.GetTeamSlug("drone")
   148  			repo, _ := database.GetRepoSlug(settings.GitlabDomain + "/example/team")
   149  
   150  			Convey("The repository is created", func() {
   151  				So(err, ShouldBeNil)
   152  				So(repo, ShouldNotBeNil)
   153  				So(repo.ID, ShouldNotEqual, 0)
   154  			})
   155  
   156  			Convey("The team should be set", func() {
   157  				So(repo.TeamID, ShouldEqual, team.ID)
   158  			})
   159  		})
   160  
   161  		Convey("When a team is not found", func() {
   162  			req.Form.Set("owner", "example")
   163  			req.Form.Set("name", "public")
   164  			req.Form.Set("team", "faketeam")
   165  			res := httptest.NewRecorder()
   166  			err := gl.Create(res, &req, user)
   167  
   168  			Convey("The result is an error", func() {
   169  				So(err, ShouldNotBeNil)
   170  				So(err.Error(), ShouldEqual, "Unable to find Team faketeam.")
   171  			})
   172  		})
   173  
   174  		Convey("When a team is forbidden", func() {
   175  			req.Form.Set("owner", "example")
   176  			req.Form.Set("name", "public")
   177  			req.Form.Set("team", "golang")
   178  			res := httptest.NewRecorder()
   179  			err := gl.Create(res, &req, user)
   180  
   181  			Convey("The result is an error", func() {
   182  				So(err, ShouldNotBeNil)
   183  				So(err.Error(), ShouldEqual, "Invalid permission to access Team golang.")
   184  			})
   185  		})
   186  	})
   187  }
   188  
   189  // this code should be refactored and centralized, but for now
   190  // it is just proof-of-concepting a testing strategy, so we'll
   191  // revisit later.
   192  
   193  // server is a test HTTP server used to provide mock API responses.
   194  var glServer *httptest.Server
   195  
   196  func SetupGitlabFixtures() {
   197  	dbtest.Setup()
   198  
   199  	// test server
   200  	mux := http.NewServeMux()
   201  	glServer = httptest.NewServer(mux)
   202  	url, _ := url.Parse(glServer.URL)
   203  
   204  	// set database to use a localhost url for GitHub
   205  	settings := model.Settings{}
   206  	settings.GitlabApiUrl = url.String() // normall would be "https://api.github.com"
   207  	settings.GitlabDomain = url.Host     // normally would be "github.com"
   208  	settings.Scheme = url.Scheme
   209  	settings.Domain = "localhost"
   210  	database.SaveSettings(&settings)
   211  
   212  	// -----------------------------------------------------------------------------------
   213  	// fixture to return a public repository and successfully
   214  	// create a commit hook.
   215  
   216  	mux.HandleFunc("/api/v3/projects/example/public", func(w http.ResponseWriter, r *http.Request) {
   217  		fmt.Fprint(w, `{
   218  			"name": "public",
   219  			"path_with_namespace": "example/public",
   220  			"public": true
   221  		}`)
   222  	})
   223  
   224  	mux.HandleFunc("/api/v3/projects/example/public/hooks", func(w http.ResponseWriter, r *http.Request) {
   225  		fmt.Fprintf(w, `{
   226  			"url": "https://example.com/example/public/hooks/1",
   227  			"id": 1
   228  		}`)
   229  	})
   230  
   231  	// -----------------------------------------------------------------------------------
   232  	// fixture to return a private repository and successfully
   233  	// create a commit hook and ssh deploy key
   234  
   235  	mux.HandleFunc("/api/v3/projects/example/private", func(w http.ResponseWriter, r *http.Request) {
   236  		fmt.Fprint(w, `{
   237  			"name": "private",
   238  			"path_with_namespace": "example/private",
   239  			"public": false
   240  		}`)
   241  	})
   242  
   243  	mux.HandleFunc("/api/v3/projects/example/private/hooks", func(w http.ResponseWriter, r *http.Request) {
   244  		fmt.Fprintf(w, `{
   245  			"url": "https://example.com/example/private/hooks/1",
   246  			"id": 1
   247  		}`)
   248  	})
   249  
   250  	mux.HandleFunc("/api/v3/projects/example/private/keys", func(w http.ResponseWriter, r *http.Request) {
   251  		fmt.Fprintf(w, `{
   252  			"id": 1,
   253  			"key": "ssh-rsa AAA...",
   254  			"url": "https://api.github.com/user/keys/1",
   255  			"title": "octocat@octomac"
   256  		}`)
   257  	})
   258  
   259  	// -----------------------------------------------------------------------------------
   260  	// fixture to return a not found when accessing a github repository.
   261  
   262  	mux.HandleFunc("/api/v3/projects/example/notfound", func(w http.ResponseWriter, r *http.Request) {
   263  		http.NotFound(w, r)
   264  	})
   265  
   266  	// -----------------------------------------------------------------------------------
   267  	// fixture to return a public repository and successfully
   268  	// create a commit hook.
   269  
   270  	mux.HandleFunc("/api/v3/projects/example/hookerr", func(w http.ResponseWriter, r *http.Request) {
   271  		fmt.Fprint(w, `{
   272  			"name": "hookerr",
   273  			"path_with_namespace": "example/hookerr",
   274  			"public": true
   275  		}`)
   276  	})
   277  
   278  	mux.HandleFunc("/api/v3/projects/example/hookerr/hooks", func(w http.ResponseWriter, r *http.Request) {
   279  		http.Error(w, "Forbidden", http.StatusForbidden)
   280  	})
   281  
   282  	// -----------------------------------------------------------------------------------
   283  	// fixture to return a private repository and successfully
   284  	// create a commit hook and ssh deploy key
   285  
   286  	mux.HandleFunc("/api/v3/projects/example/keyerr", func(w http.ResponseWriter, r *http.Request) {
   287  		fmt.Fprint(w, `{
   288  			"name": "keyerr",
   289  			"path_with_namespace": "example/keyerr",
   290  			"public": false
   291  		}`)
   292  	})
   293  
   294  	mux.HandleFunc("/api/v3/projects/example/keyerr/hooks", func(w http.ResponseWriter, r *http.Request) {
   295  		fmt.Fprintf(w, `{
   296  			"url": "https://api.github.com/api/v3/projects/example/keyerr/hooks/1",
   297  			"id": 1
   298  		}`)
   299  	})
   300  
   301  	mux.HandleFunc("/api/v3/projects/example/keyerr/keys", func(w http.ResponseWriter, r *http.Request) {
   302  		http.Error(w, "Forbidden", http.StatusForbidden)
   303  	})
   304  
   305  	// -----------------------------------------------------------------------------------
   306  	// fixture to return a public repository and successfully to
   307  	// test adding a team.
   308  
   309  	mux.HandleFunc("/api/v3/projects/example/team", func(w http.ResponseWriter, r *http.Request) {
   310  		fmt.Fprint(w, `{
   311  			"name": "team",
   312  			"path_with_namespace": "example/team",
   313  			"public": true
   314  		}`)
   315  	})
   316  
   317  	mux.HandleFunc("/api/v3/projects/example/team/hooks", func(w http.ResponseWriter, r *http.Request) {
   318  		fmt.Fprintf(w, `{
   319  			"url": "https://api.github.com/api/v3/projects/example/team/hooks/1",
   320  			"id": 1
   321  		}`)
   322  	})
   323  }
   324  
   325  func TeardownGitlabFixtures() {
   326  	dbtest.Teardown()
   327  	glServer.Close()
   328  }