github.com/kvattikuti/drone@v0.2.1-0.20140603034306-d400229a327a/pkg/handler/testing/github_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  
    15  	dbtest "github.com/drone/drone/pkg/database/testing"
    16  	. "github.com/smartystreets/goconvey/convey"
    17  )
    18  
    19  // Tests the ability to create GitHub repositories.
    20  func Test_GitHubCreate(t *testing.T) {
    21  	// seed the database with values
    22  	SetupFixtures()
    23  	defer TeardownFixtures()
    24  
    25  	// mock request
    26  	req := http.Request{}
    27  	req.Form = url.Values{}
    28  
    29  	// get user that will add repositories
    30  	user, _ := database.GetUser(1)
    31  	settings := database.SettingsMust()
    32  
    33  	Convey("Given request to setup github repo", t, func() {
    34  
    35  		Convey("When repository is public", func() {
    36  			req.Form.Set("owner", "example")
    37  			req.Form.Set("name", "public")
    38  			req.Form.Set("team", "")
    39  			res := httptest.NewRecorder()
    40  			err := handler.RepoCreateGithub(res, &req, user)
    41  			repo, _ := database.GetRepoSlug(settings.GitHubDomain + "/example/public")
    42  
    43  			Convey("The repository is created", func() {
    44  				So(err, ShouldBeNil)
    45  				So(repo, ShouldNotBeNil)
    46  				So(repo.ID, ShouldNotEqual, 0)
    47  				So(repo.Owner, ShouldEqual, "example")
    48  				So(repo.Name, ShouldEqual, "public")
    49  				So(repo.Host, ShouldEqual, settings.GitHubDomain)
    50  				So(repo.TeamID, ShouldEqual, 0)
    51  				So(repo.UserID, ShouldEqual, user.ID)
    52  				So(repo.Private, ShouldEqual, false)
    53  				So(repo.SCM, ShouldEqual, "git")
    54  			})
    55  			Convey("The repository is public", func() {
    56  				So(repo.Private, ShouldEqual, false)
    57  			})
    58  		})
    59  
    60  		Convey("When repository is private", func() {
    61  			req.Form.Set("owner", "example")
    62  			req.Form.Set("name", "private")
    63  			req.Form.Set("team", "")
    64  			res := httptest.NewRecorder()
    65  			err := handler.RepoCreateGithub(res, &req, user)
    66  			repo, _ := database.GetRepoSlug(settings.GitHubDomain + "/example/private")
    67  
    68  			Convey("The repository is created", func() {
    69  				So(err, ShouldBeNil)
    70  				So(repo, ShouldNotBeNil)
    71  				So(repo.ID, ShouldNotEqual, 0)
    72  			})
    73  			Convey("The repository is private", func() {
    74  				So(repo.Private, ShouldEqual, true)
    75  			})
    76  		})
    77  
    78  		Convey("When repository is not found", func() {
    79  			req.Form.Set("owner", "example")
    80  			req.Form.Set("name", "notfound")
    81  			req.Form.Set("team", "")
    82  			res := httptest.NewRecorder()
    83  			err := handler.RepoCreateGithub(res, &req, user)
    84  
    85  			Convey("The result is an error", func() {
    86  				So(err, ShouldNotBeNil)
    87  				So(err.Error(), ShouldEqual, "Unable to find GitHub repository example/notfound.")
    88  			})
    89  
    90  			Convey("The repository is not created", func() {
    91  				_, err := database.GetRepoSlug("example/notfound")
    92  				So(err, ShouldNotBeNil)
    93  				So(err, ShouldEqual, sql.ErrNoRows)
    94  			})
    95  		})
    96  
    97  		Convey("When repository hook is not writable", func() {
    98  			req.Form.Set("owner", "example")
    99  			req.Form.Set("name", "hookerr")
   100  			req.Form.Set("team", "")
   101  			res := httptest.NewRecorder()
   102  			err := handler.RepoCreateGithub(res, &req, user)
   103  
   104  			Convey("The result is an error", func() {
   105  				So(err, ShouldNotBeNil)
   106  				So(err.Error(), ShouldEqual, "Unable to add Hook to your GitHub repository.")
   107  			})
   108  
   109  			Convey("The repository is not created", func() {
   110  				_, err := database.GetRepoSlug("example/hookerr")
   111  				So(err, ShouldNotBeNil)
   112  				So(err, ShouldEqual, sql.ErrNoRows)
   113  			})
   114  		})
   115  
   116  		Convey("When repository ssh key is not writable", func() {
   117  			req.Form.Set("owner", "example")
   118  			req.Form.Set("name", "keyerr")
   119  			req.Form.Set("team", "")
   120  			res := httptest.NewRecorder()
   121  			err := handler.RepoCreateGithub(res, &req, user)
   122  
   123  			Convey("The result is an error", func() {
   124  				So(err, ShouldNotBeNil)
   125  				So(err.Error(), ShouldEqual, "Unable to add Public Key to your GitHub repository.")
   126  			})
   127  
   128  			Convey("The repository is not created", func() {
   129  				_, err := database.GetRepoSlug("example/keyerr")
   130  				So(err, ShouldNotBeNil)
   131  				So(err, ShouldEqual, sql.ErrNoRows)
   132  			})
   133  		})
   134  
   135  		Convey("When a team is provided", func() {
   136  			req.Form.Set("owner", "example")
   137  			req.Form.Set("name", "team")
   138  			req.Form.Set("team", "drone")
   139  			res := httptest.NewRecorder()
   140  
   141  			// invoke handler
   142  			err := handler.RepoCreateGithub(res, &req, user)
   143  			team, _ := database.GetTeamSlug("drone")
   144  			repo, _ := database.GetRepoSlug(settings.GitHubDomain + "/example/team")
   145  
   146  			Convey("The repository is created", func() {
   147  				So(err, ShouldBeNil)
   148  				So(repo, ShouldNotBeNil)
   149  				So(repo.ID, ShouldNotEqual, 0)
   150  			})
   151  
   152  			Convey("The team should be set", func() {
   153  				So(repo.TeamID, ShouldEqual, team.ID)
   154  			})
   155  		})
   156  
   157  		Convey("When a team is not found", func() {
   158  			req.Form.Set("owner", "example")
   159  			req.Form.Set("name", "public")
   160  			req.Form.Set("team", "faketeam")
   161  			res := httptest.NewRecorder()
   162  			err := handler.RepoCreateGithub(res, &req, user)
   163  
   164  			Convey("The result is an error", func() {
   165  				So(err, ShouldNotBeNil)
   166  				So(err.Error(), ShouldEqual, "Unable to find Team faketeam.")
   167  			})
   168  		})
   169  
   170  		Convey("When a team is forbidden", func() {
   171  			req.Form.Set("owner", "example")
   172  			req.Form.Set("name", "public")
   173  			req.Form.Set("team", "golang")
   174  			res := httptest.NewRecorder()
   175  			err := handler.RepoCreateGithub(res, &req, user)
   176  
   177  			Convey("The result is an error", func() {
   178  				So(err, ShouldNotBeNil)
   179  				So(err.Error(), ShouldEqual, "Invalid permission to access Team golang.")
   180  			})
   181  		})
   182  	})
   183  }
   184  
   185  // this code should be refactored and centralized, but for now
   186  // it is just proof-of-concepting a testing strategy, so we'll
   187  // revisit later.
   188  
   189  // mux is the HTTP request multiplexer used with the test server.
   190  var mux *http.ServeMux
   191  
   192  // server is a test HTTP server used to provide mock API responses.
   193  var server *httptest.Server
   194  
   195  func SetupFixtures() {
   196  	dbtest.Setup()
   197  
   198  	// test server
   199  	mux = http.NewServeMux()
   200  	server = httptest.NewServer(mux)
   201  	url, _ := url.Parse(server.URL)
   202  
   203  	// set database to use a localhost url for GitHub
   204  	settings := model.Settings{}
   205  	settings.GitHubKey = "123"
   206  	settings.GitHubSecret = "abc"
   207  	settings.GitHubApiUrl = url.String() // normall would be "https://api.github.com"
   208  	settings.GitHubDomain = url.Host     // normally would be "github.com"
   209  	settings.Scheme = url.Scheme
   210  	settings.Domain = "localhost"
   211  	database.SaveSettings(&settings)
   212  
   213  	// -----------------------------------------------------------------------------------
   214  	// fixture to return a public repository and successfully
   215  	// create a commit hook.
   216  
   217  	mux.HandleFunc("/repos/example/public", func(w http.ResponseWriter, r *http.Request) {
   218  		fmt.Fprint(w, `{
   219  			"name": "public",
   220  			"full_name": "example/public",
   221  			"private": false
   222  		}`)
   223  	})
   224  
   225  	mux.HandleFunc("/repos/example/public/hooks", func(w http.ResponseWriter, r *http.Request) {
   226  		fmt.Fprintf(w, `{
   227  			"url": "https://api.github.com/repos/example/public/hooks/1",
   228  			"name": "web",
   229  			"events": [ "push", "pull_request" ],
   230  			"id": 1
   231  		}`)
   232  	})
   233  
   234  	// -----------------------------------------------------------------------------------
   235  	// fixture to return a private repository and successfully
   236  	// create a commit hook and ssh deploy key
   237  
   238  	mux.HandleFunc("/repos/example/private", func(w http.ResponseWriter, r *http.Request) {
   239  		fmt.Fprint(w, `{
   240  			"name": "private",
   241  			"full_name": "example/private",
   242  			"private": true
   243  		}`)
   244  	})
   245  
   246  	mux.HandleFunc("/repos/example/private/hooks", func(w http.ResponseWriter, r *http.Request) {
   247  		fmt.Fprintf(w, `{
   248  			"url": "https://api.github.com/repos/example/private/hooks/1",
   249  			"name": "web",
   250  			"events": [ "push", "pull_request" ],
   251  			"id": 1
   252  		}`)
   253  	})
   254  
   255  	mux.HandleFunc("/repos/example/private/keys", func(w http.ResponseWriter, r *http.Request) {
   256  		fmt.Fprintf(w, `{
   257  			"id": 1,
   258  			"key": "ssh-rsa AAA...",
   259  			"url": "https://api.github.com/user/keys/1",
   260  			"title": "octocat@octomac"
   261  		}`)
   262  	})
   263  
   264  	// -----------------------------------------------------------------------------------
   265  	// fixture to return a not found when accessing a github repository.
   266  
   267  	mux.HandleFunc("/repos/example/notfound", func(w http.ResponseWriter, r *http.Request) {
   268  		http.NotFound(w, r)
   269  	})
   270  
   271  	// -----------------------------------------------------------------------------------
   272  	// fixture to return a public repository and successfully
   273  	// create a commit hook.
   274  
   275  	mux.HandleFunc("/repos/example/hookerr", func(w http.ResponseWriter, r *http.Request) {
   276  		fmt.Fprint(w, `{
   277  			"name": "hookerr",
   278  			"full_name": "example/hookerr",
   279  			"private": false
   280  		}`)
   281  	})
   282  
   283  	mux.HandleFunc("/repos/example/hookerr/hooks", func(w http.ResponseWriter, r *http.Request) {
   284  		http.Error(w, "Forbidden", http.StatusForbidden)
   285  	})
   286  
   287  	// -----------------------------------------------------------------------------------
   288  	// fixture to return a private repository and successfully
   289  	// create a commit hook and ssh deploy key
   290  
   291  	mux.HandleFunc("/repos/example/keyerr", func(w http.ResponseWriter, r *http.Request) {
   292  		fmt.Fprint(w, `{
   293  			"name": "keyerr",
   294  			"full_name": "example/keyerr",
   295  			"private": true
   296  		}`)
   297  	})
   298  
   299  	mux.HandleFunc("/repos/example/keyerr/hooks", func(w http.ResponseWriter, r *http.Request) {
   300  		fmt.Fprintf(w, `{
   301  			"url": "https://api.github.com/repos/example/keyerr/hooks/1",
   302  			"name": "web",
   303  			"events": [ "push", "pull_request" ],
   304  			"id": 1
   305  		}`)
   306  	})
   307  
   308  	mux.HandleFunc("/repos/example/keyerr/keys", func(w http.ResponseWriter, r *http.Request) {
   309  		http.Error(w, "Forbidden", http.StatusForbidden)
   310  	})
   311  
   312  	// -----------------------------------------------------------------------------------
   313  	// fixture to return a public repository and successfully to
   314  	// test adding a team.
   315  
   316  	mux.HandleFunc("/repos/example/team", func(w http.ResponseWriter, r *http.Request) {
   317  		fmt.Fprint(w, `{
   318  			"name": "team",
   319  			"full_name": "example/team",
   320  			"private": false
   321  		}`)
   322  	})
   323  
   324  	mux.HandleFunc("/repos/example/team/hooks", func(w http.ResponseWriter, r *http.Request) {
   325  		fmt.Fprintf(w, `{
   326  			"url": "https://api.github.com/repos/example/team/hooks/1",
   327  			"name": "web",
   328  			"events": [ "push", "pull_request" ],
   329  			"id": 1
   330  		}`)
   331  	})
   332  }
   333  
   334  func TeardownFixtures() {
   335  	dbtest.Teardown()
   336  	server.Close()
   337  }
   338  
   339  /*
   340  
   341  // response for querying a repo
   342  var repoGet = `{
   343    "name": "Hello-World",
   344    "full_name": "octocat/Hello-World",
   345    "owner": {
   346      "login": "octocat"
   347    },
   348    "private": false,
   349    "git_url": "git://github.com/octocat/Hello-World.git",
   350    "ssh_url": "git@github.com:octocat/Hello-World.git",
   351    "clone_url": "https://github.com/octocat/Hello-World.git"
   352  }`
   353  
   354  // response for querying a private repo
   355  var repoPrivateGet = `{
   356    "name": "Hello-World",
   357    "full_name": "octocat/Hello-World",
   358    "owner": {
   359      "login": "octocat"
   360    },
   361    "private": true,
   362    "git_url": "git://github.com/octocat/Hello-World.git",
   363    "ssh_url": "git@github.com:octocat/Hello-World.git",
   364    "clone_url": "https://github.com/octocat/Hello-World.git"
   365  }`
   366  
   367  // response for creating a key
   368  var keyAdd = `
   369  {
   370    "id": 1,
   371    "key": "ssh-rsa AAA...",
   372    "url": "https://api.github.com/user/keys/1",
   373    "title": "octocat@octomac"
   374  }
   375  `
   376  
   377  // response for creating a hook
   378  var hookAdd = `
   379  {
   380    "url": "https://api.github.com/repos/octocat/Hello-World/hooks/1",
   381    "updated_at": "2011-09-06T20:39:23Z",
   382    "created_at": "2011-09-06T17:26:27Z",
   383    "name": "web",
   384    "events": [
   385      "push",
   386      "pull_request"
   387    ],
   388    "active": true,
   389    "config": {
   390      "url": "http://example.com",
   391      "content_type": "json"
   392    },
   393    "id": 1
   394  }
   395  `
   396  */