From 1a58fbc1e2482feda995617ed96c83e0f19da02c Mon Sep 17 00:00:00 2001 From: Pablo Santiago Blum de Aguiar Date: Wed, 27 Aug 2014 16:10:53 -0300 Subject: [PATCH] Change API's pattern muxer and improve tests --- Godeps/Godeps.json | 12 ++- api/handler.go | 27 +++++++ api/handler_test.go | 178 ++++++++++++++++++++++---------------------- api/utils_test.go | 3 + webserver/main.go | 27 +------ 5 files changed, 130 insertions(+), 117 deletions(-) diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index c750ec2..0fa3c0a 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -11,8 +11,16 @@ "Rev": "23b39e4e860172e1983ded00a9d2f7e42b7683d0" }, { - "ImportPath": "github.com/bmizerany/pat", - "Rev": "51b7af73e39f6dc59846b22d56ca886d105ef0c3" + "ImportPath": "github.com/gorilla/context", + "Rev": "708054d61e5a2918b9f4e9700000ee611dcf03f5" + }, + { + "ImportPath": "github.com/gorilla/mux", + "Rev": "4b8fbc56f3b2400a7c7ea3dba9b3539787c486b6" + }, + { + "ImportPath": "github.com/gorilla/pat", + "Rev": "ae2e162c4b2ae96aa66b596b2c18f17834299ed0" }, { "ImportPath": "github.com/howeyc/fsnotify", diff --git a/api/handler.go b/api/handler.go index 9ce9439..2e113fb 100644 --- a/api/handler.go +++ b/api/handler.go @@ -17,6 +17,7 @@ import ( "strconv" "strings" + "github.com/gorilla/pat" "github.com/tsuru/config" "github.com/tsuru/gandalf/db" "github.com/tsuru/gandalf/hook" @@ -55,6 +56,32 @@ func accessParameters(body io.ReadCloser) (repositories, users []string, err err return repositories, users, nil } +func SetupRouter() *pat.Router { + router := pat.New() + router.Post("/user/{name}/key", http.HandlerFunc(AddKey)) + router.Delete("/user/{name}/key/{keyname}", http.HandlerFunc(RemoveKey)) + router.Get("/user/{name}/keys", http.HandlerFunc(ListKeys)) + router.Post("/user", http.HandlerFunc(NewUser)) + router.Delete("/user/{name}", http.HandlerFunc(RemoveUser)) + router.Post("/repository/grant", http.HandlerFunc(GrantAccess)) + router.Post("/repository", http.HandlerFunc(NewRepository)) + router.Delete("/repository/revoke", http.HandlerFunc(RevokeAccess)) + router.Delete("/repository/{name}", http.HandlerFunc(RemoveRepository)) + router.Get("/repository/{name}", http.HandlerFunc(GetRepository)) + router.Put("/repository/{name}", http.HandlerFunc(RenameRepository)) + router.Get("/repository/{name}/archive", http.HandlerFunc(GetArchive)) + router.Get("/repository/{name}/contents", http.HandlerFunc(GetFileContents)) + router.Get("/repository/{name}/tree", http.HandlerFunc(GetTree)) + router.Get("/repository/{name}/branches", http.HandlerFunc(GetBranches)) + router.Get("/repository/{name}/tags", http.HandlerFunc(GetTags)) + router.Get("/repository/{name}/diff/commits", http.HandlerFunc(GetDiff)) + router.Post("/repository/{name}/commit", http.HandlerFunc(Commit)) + router.Get("/repository/{name}/logs", http.HandlerFunc(GetLog)) + router.Get("/healthcheck", http.HandlerFunc(HealthCheck)) + router.Post("/hook/{name}", http.HandlerFunc(AddHook)) + return router +} + func GrantAccess(w http.ResponseWriter, r *http.Request) { // TODO: update README repositories, users, err := accessParameters(r.Body) diff --git a/api/handler_test.go b/api/handler_test.go index 499092a..8c2c2ea 100644 --- a/api/handler_test.go +++ b/api/handler_test.go @@ -119,7 +119,7 @@ func (s *S) TestAccessParametersShouldReturnErrorWhenNoRepositoryListProvided(c func (s *S) TestNewUser(c *gocheck.C) { b := strings.NewReader(fmt.Sprintf(`{"name": "brain", "keys": {"keyname": %q}}`, rawKey)) recorder, request := post("/user", b, c) - NewUser(recorder, request) + s.router.ServeHTTP(recorder, request) conn, err := db.Conn() c.Assert(err, gocheck.IsNil) defer conn.Close() @@ -134,7 +134,7 @@ func (s *S) TestNewUser(c *gocheck.C) { func (s *S) TestNewUserShouldSaveInDB(c *gocheck.C) { b := strings.NewReader(`{"name": "brain", "keys": {"content": "some id_rsa.pub key.. use your imagination!", "name": "somekey"}}`) recorder, request := post("/user", b, c) - NewUser(recorder, request) + s.router.ServeHTTP(recorder, request) conn, err := db.Conn() c.Assert(err, gocheck.IsNil) defer conn.Close() @@ -149,7 +149,7 @@ func (s *S) TestNewUserShouldSaveInDB(c *gocheck.C) { func (s *S) TestNewUserShouldRepassParseBodyErrors(c *gocheck.C) { b := strings.NewReader("{]9afe}") recorder, request := post("/user", b, c) - NewUser(recorder, request) + s.router.ServeHTTP(recorder, request) body := readBody(recorder.Body, c) expected := "Got error while parsing body: Could not parse json: invalid character ']' looking for beginning of object key string" got := strings.Replace(body, "\n", "", -1) @@ -159,7 +159,7 @@ func (s *S) TestNewUserShouldRepassParseBodyErrors(c *gocheck.C) { func (s *S) TestNewUserShouldRequireUserName(c *gocheck.C) { b := strings.NewReader(`{"name": ""}`) recorder, request := post("/user", b, c) - NewUser(recorder, request) + s.router.ServeHTTP(recorder, request) body := readBody(recorder.Body, c) expected := "Got error while creating user: Validation Error: user name is not valid" got := strings.Replace(body, "\n", "", -1) @@ -169,7 +169,7 @@ func (s *S) TestNewUserShouldRequireUserName(c *gocheck.C) { func (s *S) TestNewUserWihoutKeys(c *gocheck.C) { b := strings.NewReader(`{"name": "brain"}`) recorder, request := post("/user", b, c) - NewUser(recorder, request) + s.router.ServeHTTP(recorder, request) conn, err := db.Conn() c.Assert(err, gocheck.IsNil) defer conn.Close() @@ -185,8 +185,8 @@ func (s *S) TestGetRepository(c *gocheck.C) { err = conn.Repository().Insert(&r) c.Assert(err, gocheck.IsNil) defer conn.Repository().Remove(bson.M{"_id": r.Name}) - recorder, request := get("/repository/onerepo?:name=onerepo", nil, c) - GetRepository(recorder, request) + recorder, request := get("/repository/onerepo", nil, c) + s.router.ServeHTTP(recorder, request) body, err := ioutil.ReadAll(recorder.Body) c.Assert(err, gocheck.IsNil) var data map[string]interface{} @@ -202,8 +202,8 @@ func (s *S) TestGetRepository(c *gocheck.C) { } func (s *S) TestGetRepositoryDoesNotExist(c *gocheck.C) { - recorder, request := get("/repository/doesnotexists?:name=doesnotexists", nil, c) - GetRepository(recorder, request) + recorder, request := get("/repository/doesnotexists", nil, c) + s.router.ServeHTTP(recorder, request) c.Assert(recorder.Code, gocheck.Equals, 500) } @@ -214,7 +214,7 @@ func (s *S) TestNewRepository(c *gocheck.C) { defer conn.Repository().Remove(bson.M{"_id": "some_repository"}) b := strings.NewReader(`{"name": "some_repository", "users": ["r2d2"]}`) recorder, request := post("/repository", b, c) - NewRepository(recorder, request) + s.router.ServeHTTP(recorder, request) got := readBody(recorder.Body, c) expected := "Repository \"some_repository\" successfully created\n" c.Assert(got, gocheck.Equals, expected) @@ -223,7 +223,7 @@ func (s *S) TestNewRepository(c *gocheck.C) { func (s *S) TestNewRepositoryShouldSaveInDB(c *gocheck.C) { b := strings.NewReader(`{"name": "myRepository", "users": ["r2d2"]}`) recorder, request := post("/repository", b, c) - NewRepository(recorder, request) + s.router.ServeHTTP(recorder, request) conn, err := db.Conn() c.Assert(err, gocheck.IsNil) defer conn.Close() @@ -237,7 +237,7 @@ func (s *S) TestNewRepositoryShouldSaveInDB(c *gocheck.C) { func (s *S) TestNewRepositoryShouldSaveUserIdInRepository(c *gocheck.C) { b := strings.NewReader(`{"name": "myRepository", "users": ["r2d2", "brain"]}`) recorder, request := post("/repository", b, c) - NewRepository(recorder, request) + s.router.ServeHTTP(recorder, request) conn, err := db.Conn() c.Assert(err, gocheck.IsNil) defer conn.Close() @@ -252,7 +252,7 @@ func (s *S) TestNewRepositoryShouldSaveUserIdInRepository(c *gocheck.C) { func (s *S) TestNewRepositoryShouldReturnErrorWhenNoUserIsPassed(c *gocheck.C) { b := strings.NewReader(`{"name": "myRepository"}`) recorder, request := post("/repository", b, c) - NewRepository(recorder, request) + s.router.ServeHTTP(recorder, request) c.Assert(recorder.Code, gocheck.Equals, 400) body := readBody(recorder.Body, c) expected := "Validation Error: repository should have at least one user" @@ -263,7 +263,7 @@ func (s *S) TestNewRepositoryShouldReturnErrorWhenNoUserIsPassed(c *gocheck.C) { func (s *S) TestNewRepositoryShouldReturnErrorWhenNoParametersArePassed(c *gocheck.C) { b := strings.NewReader("{}") recorder, request := post("/repository", b, c) - NewRepository(recorder, request) + s.router.ServeHTTP(recorder, request) c.Assert(recorder.Code, gocheck.Equals, 400) body := readBody(recorder.Body, c) expected := "Validation Error: repository name is not valid" @@ -309,7 +309,7 @@ func (s *S) TestParseBodyShouldReturnErrorWhenResultParamIsNotAPointer(c *gochec func (s *S) TestNewRepositoryShouldReturnErrorWhenBodyIsEmpty(c *gocheck.C) { b := strings.NewReader("") recorder, request := post("/repository", b, c) - NewRepository(recorder, request) + s.router.ServeHTTP(recorder, request) c.Assert(recorder.Code, gocheck.Equals, 400) } @@ -329,8 +329,8 @@ func (s *S) TestGrantAccessUpdatesReposDocument(c *gocheck.C) { c.Assert(err, gocheck.IsNil) defer conn.Repository().Remove(bson.M{"_id": r2.Name}) b := bytes.NewBufferString(fmt.Sprintf(`{"repositories": ["%s", "%s"], "users": ["%s"]}`, r.Name, r2.Name, u.Name)) - rec, req := del("/repository/grant", b, c) - GrantAccess(rec, req) + rec, req := post("/repository/grant", b, c) + s.router.ServeHTTP(rec, req) var repos []repository.Repository err = conn.Repository().Find(bson.M{"_id": bson.M{"$in": []string{r.Name, r2.Name}}}).All(&repos) c.Assert(err, gocheck.IsNil) @@ -354,7 +354,7 @@ func (s *S) TestRevokeAccessUpdatesReposDocument(c *gocheck.C) { defer conn.Repository().Remove(bson.M{"_id": r2.Name}) b := bytes.NewBufferString(fmt.Sprintf(`{"repositories": ["%s", "%s"], "users": ["Umi"]}`, r.Name, r2.Name)) rec, req := del("/repository/revoke", b, c) - RevokeAccess(rec, req) + s.router.ServeHTTP(rec, req) var repos []repository.Repository err = conn.Repository().Find(bson.M{"_id": bson.M{"$in": []string{r.Name, r2.Name}}}).All(&repos) c.Assert(err, gocheck.IsNil) @@ -368,8 +368,8 @@ func (s *S) TestAddKey(c *gocheck.C) { c.Assert(err, gocheck.IsNil) defer user.Remove(usr.Name) b := strings.NewReader(fmt.Sprintf(`{"keyname": %q}`, rawKey)) - recorder, request := post(fmt.Sprintf("/user/%s/key?:name=%s", usr.Name, usr.Name), b, c) - AddKey(recorder, request) + recorder, request := post(fmt.Sprintf("/user/%s/key", usr.Name), b, c) + s.router.ServeHTTP(recorder, request) got := readBody(recorder.Body, c) expected := "Key(s) successfully created" c.Assert(got, gocheck.Equals, expected) @@ -386,8 +386,8 @@ func (s *S) TestAddKey(c *gocheck.C) { func (s *S) TestAddPostReceiveHookRepository(c *gocheck.C) { b := strings.NewReader(`{"repositories": ["some-repo"], "content": "some content"}`) - recorder, request := post("repository/hook/post-receive?:name=post-receive", b, c) - AddHook(recorder, request) + recorder, request := post("/hook/post-receive", b, c) + s.router.ServeHTTP(recorder, request) got := readBody(recorder.Body, c) expected := "hook post-receive successfully created for [some-repo]\n" c.Assert(got, gocheck.Equals, expected) @@ -401,8 +401,8 @@ func (s *S) TestAddPostReceiveHookRepository(c *gocheck.C) { func (s *S) TestAddPreReceiveHookRepository(c *gocheck.C) { b := strings.NewReader(`{"repositories": ["some-repo"], "content": "some content"}`) - recorder, request := post("repository/hook/pre-receive?:name=pre-receive", b, c) - AddHook(recorder, request) + recorder, request := post("/hook/pre-receive", b, c) + s.router.ServeHTTP(recorder, request) got := readBody(recorder.Body, c) expected := "hook pre-receive successfully created for [some-repo]\n" c.Assert(got, gocheck.Equals, expected) @@ -416,8 +416,8 @@ func (s *S) TestAddPreReceiveHookRepository(c *gocheck.C) { func (s *S) TestAddUpdateReceiveHookRepository(c *gocheck.C) { b := strings.NewReader(`{"repositories": ["some-repo"], "content": "some content"}`) - recorder, request := post("repository/hook/update?:name=update", b, c) - AddHook(recorder, request) + recorder, request := post("/hook/update", b, c) + s.router.ServeHTTP(recorder, request) got := readBody(recorder.Body, c) expected := "hook update successfully created for [some-repo]\n" c.Assert(got, gocheck.Equals, expected) @@ -431,8 +431,8 @@ func (s *S) TestAddUpdateReceiveHookRepository(c *gocheck.C) { func (s *S) TestAddInvalidHookRepository(c *gocheck.C) { b := strings.NewReader(`{"repositories": ["some-repo"], "content": "some content"}`) - recorder, request := post("repository/hook/invalid-hook?:name=invalid-hook", b, c) - AddHook(recorder, request) + recorder, request := post("/hook/invalid-hook", b, c) + s.router.ServeHTTP(recorder, request) got := readBody(recorder.Body, c) expected := "Unsupported hook, valid options are: post-receive, pre-receive or update\n" c.Assert(got, gocheck.Equals, expected) @@ -441,8 +441,8 @@ func (s *S) TestAddInvalidHookRepository(c *gocheck.C) { func (s *S) TestAddPostReceiveHook(c *gocheck.C) { b := strings.NewReader(`{"content": "some content"}`) - recorder, request := post("/hook/post-receive?:name=post-receive", b, c) - AddHook(recorder, request) + recorder, request := post("/hook/post-receive", b, c) + s.router.ServeHTTP(recorder, request) got := readBody(recorder.Body, c) expected := "hook post-receive successfully created\n" c.Assert(got, gocheck.Equals, expected) @@ -456,8 +456,8 @@ func (s *S) TestAddPostReceiveHook(c *gocheck.C) { func (s *S) TestAddPreReceiveHook(c *gocheck.C) { b := strings.NewReader(`{"content": "some content"}`) - recorder, request := post("/hook/pre-receive?:name=pre-receive", b, c) - AddHook(recorder, request) + recorder, request := post("/hook/pre-receive", b, c) + s.router.ServeHTTP(recorder, request) got := readBody(recorder.Body, c) expected := "hook pre-receive successfully created\n" c.Assert(got, gocheck.Equals, expected) @@ -471,8 +471,8 @@ func (s *S) TestAddPreReceiveHook(c *gocheck.C) { func (s *S) TestAddUpdateHook(c *gocheck.C) { b := strings.NewReader(`{"content": "some content"}`) - recorder, request := post("/hook/update?:name=update", b, c) - AddHook(recorder, request) + recorder, request := post("/hook/update", b, c) + s.router.ServeHTTP(recorder, request) got := readBody(recorder.Body, c) expected := "hook update successfully created\n" c.Assert(got, gocheck.Equals, expected) @@ -486,8 +486,8 @@ func (s *S) TestAddUpdateHook(c *gocheck.C) { func (s *S) TestAddInvalidHook(c *gocheck.C) { b := strings.NewReader(`{"content": "some content"}`) - recorder, request := post("/hook/invalid-hook?:name=invalid-hook", b, c) - AddHook(recorder, request) + recorder, request := post("/hook/invalid-hook", b, c) + s.router.ServeHTTP(recorder, request) got := readBody(recorder.Body, c) expected := "Unsupported hook, valid options are: post-receive, pre-receive or update\n" c.Assert(got, gocheck.Equals, expected) @@ -496,8 +496,8 @@ func (s *S) TestAddInvalidHook(c *gocheck.C) { func (s *S) TestAddPostReceiveOldFormatHook(c *gocheck.C) { b := strings.NewReader("some content") - recorder, request := post("/hook/post-receive?:name=post-receive", b, c) - AddHook(recorder, request) + recorder, request := post("/hook/post-receive", b, c) + s.router.ServeHTTP(recorder, request) got := readBody(recorder.Body, c) expected := "hook post-receive successfully created\n" c.Assert(got, gocheck.Equals, expected) @@ -511,8 +511,8 @@ func (s *S) TestAddPostReceiveOldFormatHook(c *gocheck.C) { func (s *S) TestAddPreReceiveOldFormatHook(c *gocheck.C) { b := strings.NewReader("some content") - recorder, request := post("/hook/pre-receive?:name=pre-receive", b, c) - AddHook(recorder, request) + recorder, request := post("/hook/pre-receive", b, c) + s.router.ServeHTTP(recorder, request) got := readBody(recorder.Body, c) expected := "hook pre-receive successfully created\n" c.Assert(got, gocheck.Equals, expected) @@ -526,8 +526,8 @@ func (s *S) TestAddPreReceiveOldFormatHook(c *gocheck.C) { func (s *S) TestAddUpdateOldFormatHook(c *gocheck.C) { b := strings.NewReader("some content") - recorder, request := post("/hook/update?:name=update", b, c) - AddHook(recorder, request) + recorder, request := post("/hook/update", b, c) + s.router.ServeHTTP(recorder, request) got := readBody(recorder.Body, c) expected := "hook update successfully created\n" c.Assert(got, gocheck.Equals, expected) @@ -541,8 +541,8 @@ func (s *S) TestAddUpdateOldFormatHook(c *gocheck.C) { func (s *S) TestAddInvalidOldFormatHook(c *gocheck.C) { b := strings.NewReader("some content") - recorder, request := post("/hook/invalid-hook?:name=invalid-hook", b, c) - AddHook(recorder, request) + recorder, request := post("/hook/invalid-hook", b, c) + s.router.ServeHTTP(recorder, request) got := readBody(recorder.Body, c) expected := "Unsupported hook, valid options are: post-receive, pre-receive or update\n" c.Assert(got, gocheck.Equals, expected) @@ -551,8 +551,8 @@ func (s *S) TestAddInvalidOldFormatHook(c *gocheck.C) { func (s *S) TestAddKeyShouldReturnErrorWhenUserDoesNotExists(c *gocheck.C) { b := strings.NewReader(`{"key": "a public key"}`) - recorder, request := post("/user/Frodo/key?:name=Frodo", b, c) - AddKey(recorder, request) + recorder, request := post("/user/Frodo/key", b, c) + s.router.ServeHTTP(recorder, request) c.Assert(recorder.Code, gocheck.Equals, 404) body, err := ioutil.ReadAll(recorder.Body) c.Assert(err, gocheck.IsNil) @@ -564,8 +564,8 @@ func (s *S) TestAddKeyShouldReturnProperStatusCodeWhenKeyAlreadyExists(c *gochec c.Assert(err, gocheck.IsNil) defer user.Remove(usr.Name) b := strings.NewReader(fmt.Sprintf(`{"keyname": %q}`, rawKey)) - recorder, request := post(fmt.Sprintf("/user/%s/key?:name=%s", usr.Name, usr.Name), b, c) - AddKey(recorder, request) + recorder, request := post(fmt.Sprintf("/user/%s/key", usr.Name), b, c) + s.router.ServeHTTP(recorder, request) got := readBody(recorder.Body, c) expected := "Key already exists.\n" c.Assert(got, gocheck.Equals, expected) @@ -580,8 +580,8 @@ func (s *S) TestAddKeyShouldNotAcceptRepeatedKeysForDifferentUsers(c *gocheck.C) c.Assert(err, gocheck.IsNil) defer user.Remove(usr2.Name) b := strings.NewReader(fmt.Sprintf(`{"keyname": %q}`, rawKey)) - recorder, request := post(fmt.Sprintf("/user/%s/key?:name=%s", usr2.Name, usr2.Name), b, c) - AddKey(recorder, request) + recorder, request := post(fmt.Sprintf("/user/%s/key", usr2.Name), b, c) + s.router.ServeHTTP(recorder, request) got := readBody(recorder.Body, c) expected := "Key already exists.\n" c.Assert(got, gocheck.Equals, expected) @@ -597,8 +597,8 @@ func (s *S) TestAddKeyInvalidKey(c *gocheck.C) { c.Assert(err, gocheck.IsNil) defer conn.User().Remove(bson.M{"_id": "Frodo"}) b := strings.NewReader(`{"keyname":"invalid-rsa"}`) - recorder, request := post(fmt.Sprintf("/user/%s/key?:name=%s", u.Name, u.Name), b, c) - AddKey(recorder, request) + recorder, request := post(fmt.Sprintf("/user/%s/key", u.Name), b, c) + s.router.ServeHTTP(recorder, request) got := readBody(recorder.Body, c) expected := "Invalid key\n" c.Assert(got, gocheck.Equals, expected) @@ -614,8 +614,8 @@ func (s *S) TestAddKeyShouldRequireKey(c *gocheck.C) { c.Assert(err, gocheck.IsNil) defer conn.User().Remove(bson.M{"_id": "Frodo"}) b := strings.NewReader(`{}`) - recorder, request := post("/user/Frodo/key?:name=Frodo", b, c) - AddKey(recorder, request) + recorder, request := post("/user/Frodo/key", b, c) + s.router.ServeHTTP(recorder, request) body := readBody(recorder.Body, c) expected := "A key is needed" got := strings.Replace(body, "\n", "", -1) @@ -631,8 +631,8 @@ func (s *S) TestAddKeyShouldWriteKeyInAuthorizedKeysFile(c *gocheck.C) { c.Assert(err, gocheck.IsNil) defer conn.User().RemoveId("Frodo") b := strings.NewReader(fmt.Sprintf(`{"key": "%s"}`, rawKey)) - recorder, request := post("/user/Frodo/key?:name=Frodo", b, c) - AddKey(recorder, request) + recorder, request := post("/user/Frodo/key", b, c) + s.router.ServeHTTP(recorder, request) defer conn.Key().Remove(bson.M{"name": "key", "username": u.Name}) c.Assert(recorder.Code, gocheck.Equals, 200) content := s.authKeysContent(c) @@ -643,9 +643,9 @@ func (s *S) TestRemoveKeyGivesExpectedSuccessResponse(c *gocheck.C) { u, err := user.New("Gandalf", map[string]string{"keyname": rawKey}) c.Assert(err, gocheck.IsNil) defer user.Remove(u.Name) - url := "/user/Gandalf/key/keyname?:keyname=keyname&:name=Gandalf" + url := "/user/Gandalf/key/keyname" recorder, request := del(url, nil, c) - RemoveKey(recorder, request) + s.router.ServeHTTP(recorder, request) c.Assert(recorder.Code, gocheck.Equals, 200) b := readBody(recorder.Body, c) c.Assert(b, gocheck.Equals, `Key "keyname" successfully removed`) @@ -655,9 +655,9 @@ func (s *S) TestRemoveKeyRemovesKeyFromDatabase(c *gocheck.C) { u, err := user.New("Gandalf", map[string]string{"keyname": rawKey}) c.Assert(err, gocheck.IsNil) defer user.Remove(u.Name) - url := "/user/Gandalf/key/keyname?:keyname=keyname&:name=Gandalf" + url := "/user/Gandalf/key/keyname" recorder, request := del(url, nil, c) - RemoveKey(recorder, request) + s.router.ServeHTTP(recorder, request) conn, err := db.Conn() c.Assert(err, gocheck.IsNil) defer conn.Close() @@ -670,17 +670,17 @@ func (s *S) TestRemoveKeyShouldRemoveKeyFromAuthorizedKeysFile(c *gocheck.C) { u, err := user.New("Gandalf", map[string]string{"keyname": rawKey}) c.Assert(err, gocheck.IsNil) defer user.Remove(u.Name) - url := "/user/Gandalf/key/keyname?:keyname=keyname&:name=Gandalf" + url := "/user/Gandalf/key/keyname" recorder, request := del(url, nil, c) - RemoveKey(recorder, request) + s.router.ServeHTTP(recorder, request) content := s.authKeysContent(c) c.Assert(content, gocheck.Equals, "") } func (s *S) TestRemoveKeyShouldReturnErrorWithLineBreakAtEnd(c *gocheck.C) { - url := "/user/idiocracy/key/keyname?:keyname=keyname&:name=idiocracy" + url := "/user/idiocracy/key/keyname" recorder, request := del(url, nil, c) - RemoveKey(recorder, request) + s.router.ServeHTTP(recorder, request) b := readBody(recorder.Body, c) c.Assert(b, gocheck.Equals, "User not found\n") } @@ -690,11 +690,11 @@ func (s *S) TestListKeysGivesExpectedSuccessResponse(c *gocheck.C) { u, err := user.New("Gandalf", keys) c.Assert(err, gocheck.IsNil) defer user.Remove(u.Name) - url := "/user/Gandalf/keys?:name=Gandalf" + url := "/user/Gandalf/keys" request, err := http.NewRequest("GET", url, nil) c.Assert(err, gocheck.IsNil) recorder := httptest.NewRecorder() - ListKeys(recorder, request) + s.router.ServeHTTP(recorder, request) c.Assert(recorder.Code, gocheck.Equals, 200) body, err := ioutil.ReadAll(recorder.Body) c.Assert(err, gocheck.IsNil) @@ -708,22 +708,22 @@ func (s *S) TestListKeysWithoutKeysGivesEmptyJSON(c *gocheck.C) { u, err := user.New("Gandalf", map[string]string{}) c.Assert(err, gocheck.IsNil) defer user.Remove(u.Name) - url := "/user/Gandalf/keys?:name=Gandalf" + url := "/user/Gandalf/keys" request, err := http.NewRequest("GET", url, nil) c.Assert(err, gocheck.IsNil) recorder := httptest.NewRecorder() - ListKeys(recorder, request) + s.router.ServeHTTP(recorder, request) c.Assert(recorder.Code, gocheck.Equals, 200) b := readBody(recorder.Body, c) c.Assert(b, gocheck.Equals, "{}") } func (s *S) TestListKeysWithInvalidUserReturnsNotFound(c *gocheck.C) { - url := "/user/no-Gandalf/keys?:name=no-Gandalf" + url := "/user/no-Gandalf/keys" request, err := http.NewRequest("GET", url, nil) c.Assert(err, gocheck.IsNil) recorder := httptest.NewRecorder() - ListKeys(recorder, request) + s.router.ServeHTTP(recorder, request) c.Assert(recorder.Code, gocheck.Equals, 404) b := readBody(recorder.Body, c) c.Assert(b, gocheck.Equals, "User not found\n") @@ -732,11 +732,11 @@ func (s *S) TestListKeysWithInvalidUserReturnsNotFound(c *gocheck.C) { func (s *S) TestRemoveUser(c *gocheck.C) { u, err := user.New("username", map[string]string{}) c.Assert(err, gocheck.IsNil) - url := fmt.Sprintf("/user/%s/?:name=%s", u.Name, u.Name) + url := fmt.Sprintf("/user/%s", u.Name) request, err := http.NewRequest("DELETE", url, nil) c.Assert(err, gocheck.IsNil) recorder := httptest.NewRecorder() - RemoveUser(recorder, request) + s.router.ServeHTTP(recorder, request) c.Assert(recorder.Code, gocheck.Equals, 200) b, err := ioutil.ReadAll(recorder.Body) c.Assert(err, gocheck.IsNil) @@ -746,11 +746,11 @@ func (s *S) TestRemoveUser(c *gocheck.C) { func (s *S) TestRemoveUserShouldRemoveFromDB(c *gocheck.C) { u, err := user.New("anuser", map[string]string{}) c.Assert(err, gocheck.IsNil) - url := fmt.Sprintf("/user/%s/?:name=%s", u.Name, u.Name) + url := fmt.Sprintf("/user/%s", u.Name) request, err := http.NewRequest("DELETE", url, nil) c.Assert(err, gocheck.IsNil) recorder := httptest.NewRecorder() - RemoveUser(recorder, request) + s.router.ServeHTTP(recorder, request) conn, err := db.Conn() c.Assert(err, gocheck.IsNil) defer conn.Close() @@ -763,11 +763,11 @@ func (s *S) TestRemoveUserShouldRemoveFromDB(c *gocheck.C) { func (s *S) TestRemoveRepository(c *gocheck.C) { r, err := repository.New("myRepo", []string{"pippin"}, true) c.Assert(err, gocheck.IsNil) - url := fmt.Sprintf("repository/%s/?:name=%s", r.Name, r.Name) + url := fmt.Sprintf("/repository/%s", r.Name) request, err := http.NewRequest("DELETE", url, nil) c.Assert(err, gocheck.IsNil) recorder := httptest.NewRecorder() - RemoveRepository(recorder, request) + s.router.ServeHTTP(recorder, request) c.Assert(recorder.Code, gocheck.Equals, 200) b, err := ioutil.ReadAll(recorder.Body) c.Assert(err, gocheck.IsNil) @@ -777,11 +777,11 @@ func (s *S) TestRemoveRepository(c *gocheck.C) { func (s *S) TestRemoveRepositoryShouldRemoveFromDB(c *gocheck.C) { r, err := repository.New("myRepo", []string{"pippin"}, true) c.Assert(err, gocheck.IsNil) - url := fmt.Sprintf("repository/%s/?:name=%s", r.Name, r.Name) + url := fmt.Sprintf("/repository/%s", r.Name) request, err := http.NewRequest("DELETE", url, nil) c.Assert(err, gocheck.IsNil) recorder := httptest.NewRecorder() - RemoveRepository(recorder, request) + s.router.ServeHTTP(recorder, request) conn, err := db.Conn() c.Assert(err, gocheck.IsNil) defer conn.Close() @@ -790,20 +790,20 @@ func (s *S) TestRemoveRepositoryShouldRemoveFromDB(c *gocheck.C) { } func (s *S) TestRemoveRepositoryShouldReturn400OnFailure(c *gocheck.C) { - url := fmt.Sprintf("repository/%s/?:name=%s", "foo", "foo") + url := "/repository/foo" request, err := http.NewRequest("DELETE", url, nil) c.Assert(err, gocheck.IsNil) recorder := httptest.NewRecorder() - RemoveRepository(recorder, request) + s.router.ServeHTTP(recorder, request) c.Assert(recorder.Code, gocheck.Equals, 400) } func (s *S) TestRemoveRepositoryShouldReturnErrorMsgWhenRepoDoesNotExists(c *gocheck.C) { - url := fmt.Sprintf("repository/%s/?:name=%s", "foo", "foo") + url := "/repository/foo" request, err := http.NewRequest("DELETE", url, nil) c.Assert(err, gocheck.IsNil) recorder := httptest.NewRecorder() - RemoveRepository(recorder, request) + s.router.ServeHTTP(recorder, request) b, err := ioutil.ReadAll(recorder.Body) c.Assert(err, gocheck.IsNil) c.Assert(string(b), gocheck.Equals, "Could not remove repository: not found\n") @@ -812,12 +812,12 @@ func (s *S) TestRemoveRepositoryShouldReturnErrorMsgWhenRepoDoesNotExists(c *goc func (s *S) TestRenameRepository(c *gocheck.C) { r, err := repository.New("raising", []string{"guardian@what.com"}, true) c.Assert(err, gocheck.IsNil) - url := fmt.Sprintf("/repository/%s/?:name=%s", r.Name, r.Name) + url := fmt.Sprintf("/repository/%s", r.Name) body := strings.NewReader(`{"name":"freedom"}`) request, err := http.NewRequest("PUT", url, body) c.Assert(err, gocheck.IsNil) recorder := httptest.NewRecorder() - RenameRepository(recorder, request) + s.router.ServeHTTP(recorder, request) c.Assert(recorder.Code, gocheck.Equals, http.StatusOK) _, err = repository.Get("raising") c.Assert(err, gocheck.NotNil) @@ -828,22 +828,22 @@ func (s *S) TestRenameRepository(c *gocheck.C) { } func (s *S) TestRenameRepositoryInvalidJSON(c *gocheck.C) { - url := "/repository/foo/?:name=foo" + url := "/repository/foo" body := strings.NewReader(`{"name""`) request, err := http.NewRequest("PUT", url, body) c.Assert(err, gocheck.IsNil) recorder := httptest.NewRecorder() - RenameRepository(recorder, request) + s.router.ServeHTTP(recorder, request) c.Assert(recorder.Code, gocheck.Equals, http.StatusBadRequest) } func (s *S) TestRenameRepositoryNotfound(c *gocheck.C) { - url := "/repository/foo/?:name=foo" + url := "/repository/foo" body := strings.NewReader(`{"name":"freedom"}`) request, err := http.NewRequest("PUT", url, body) c.Assert(err, gocheck.IsNil) recorder := httptest.NewRecorder() - RenameRepository(recorder, request) + s.router.ServeHTTP(recorder, request) c.Assert(recorder.Code, gocheck.Equals, http.StatusNotFound) } @@ -852,7 +852,7 @@ func (s *S) TestHealthcheck(c *gocheck.C) { request, err := http.NewRequest("GET", url, nil) c.Assert(err, gocheck.IsNil) recorder := httptest.NewRecorder() - HealthCheck(recorder, request) + s.router.ServeHTTP(recorder, request) c.Assert(recorder.Code, gocheck.Equals, http.StatusOK) c.Assert(recorder.Body.String(), gocheck.Equals, "WORKING") } diff --git a/api/utils_test.go b/api/utils_test.go index 3b732c3..ec96442 100644 --- a/api/utils_test.go +++ b/api/utils_test.go @@ -7,6 +7,7 @@ package api import ( "testing" + "github.com/gorilla/pat" "github.com/tsuru/commandmocker" "github.com/tsuru/config" "github.com/tsuru/gandalf/db" @@ -22,6 +23,7 @@ func Test(t *testing.T) { gocheck.TestingT(t) } type S struct { tmpdir string rfs *testingfs.RecordingFs + router *pat.Router } var _ = gocheck.Suite(&S{}) @@ -33,6 +35,7 @@ func (s *S) SetUpSuite(c *gocheck.C) { config.Set("database:name", "gandalf_api_tests") s.tmpdir, err = commandmocker.Add("git", "") c.Assert(err, gocheck.IsNil) + s.router = SetupRouter() } func (s *S) SetUpTest(c *gocheck.C) { diff --git a/webserver/main.go b/webserver/main.go index df8c5cd..2604f5e 100644 --- a/webserver/main.go +++ b/webserver/main.go @@ -10,7 +10,6 @@ import ( "log" "net/http" - "github.com/bmizerany/pat" "github.com/tsuru/config" "github.com/tsuru/gandalf/api" ) @@ -22,41 +21,17 @@ func main() { configFile := flag.String("config", "/etc/gandalf.conf", "Gandalf configuration file") gVersion := flag.Bool("version", false, "Print version and exit") flag.Parse() - if *gVersion { fmt.Printf("gandalf-webserver version %s\n", version) return } - err := config.ReadAndWatchConfigFile(*configFile) if err != nil { msg := `Could not find gandalf config file. Searched on %s. For an example conf check gandalf/etc/gandalf.conf file.\n %s` log.Panicf(msg, *configFile, err) } - router := pat.New() - router.Post("/user/:name/key", http.HandlerFunc(api.AddKey)) - router.Del("/user/:name/key/:keyname", http.HandlerFunc(api.RemoveKey)) - router.Get("/user/:name/keys", http.HandlerFunc(api.ListKeys)) - router.Post("/user", http.HandlerFunc(api.NewUser)) - router.Del("/user/:name", http.HandlerFunc(api.RemoveUser)) - router.Post("/repository", http.HandlerFunc(api.NewRepository)) - router.Post("/repository/grant", http.HandlerFunc(api.GrantAccess)) - router.Del("/repository/revoke", http.HandlerFunc(api.RevokeAccess)) - router.Del("/repository/:name", http.HandlerFunc(api.RemoveRepository)) - router.Get("/repository/:name", http.HandlerFunc(api.GetRepository)) - router.Put("/repository/:name", http.HandlerFunc(api.RenameRepository)) - router.Get("/repository/:name/archive", http.HandlerFunc(api.GetArchive)) - router.Get("/repository/:name/contents", http.HandlerFunc(api.GetFileContents)) - router.Get("/repository/:name/tree", http.HandlerFunc(api.GetTree)) - router.Get("/repository/:name/branches", http.HandlerFunc(api.GetBranches)) - router.Get("/repository/:name/tags", http.HandlerFunc(api.GetTags)) - router.Get("/repository/:name/diff/commits", http.HandlerFunc(api.GetDiff)) - router.Post("/repository/:name/commit", http.HandlerFunc(api.Commit)) - router.Get("/repository/:name/logs", http.HandlerFunc(api.GetLog)) - router.Get("/healthcheck/", http.HandlerFunc(api.HealthCheck)) - router.Post("/hook/:name", http.HandlerFunc(api.AddHook)) - + router := api.SetupRouter() bind, err := config.GetString("bind") if err != nil { var perr error