From ec83c9c997014a8d5e555e1524a4590de828a25b Mon Sep 17 00:00:00 2001 From: awwalker Date: Sat, 24 Jun 2017 00:55:19 -0400 Subject: [PATCH 1/9] API: support '/orgs/:org/repos' --- integrations/api_repo_test.go | 8 ++++++++ routers/api/v1/api.go | 3 +++ routers/api/v1/user/key.go | 5 +++++ routers/api/v1/user/repo.go | 22 ++++++++++++++++++++++ 4 files changed, 38 insertions(+) diff --git a/integrations/api_repo_test.go b/integrations/api_repo_test.go index 8073f773ac259..5896dd508db9b 100644 --- a/integrations/api_repo_test.go +++ b/integrations/api_repo_test.go @@ -63,3 +63,11 @@ func TestAPIViewRepo(t *testing.T) { assert.EqualValues(t, 1, repo.ID) assert.EqualValues(t, "repo1", repo.Name) } + +func TestAPIOrgReposNotLogin(t *testing.T) { + assert.NoError(t, models.LoadFixtures()) + + req := NewRequest(t, "GET", "/api/v1/orgs/org1/repos") + resp := MakeRequest(req) + assert.EqualValues(t, http.StatusOK, resp.HeaderCode) +} diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index 8dda892955653..d572d88f1e692 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -465,6 +465,9 @@ func RegisterRoutes(m *macaron.Macaron) { m.Combo("/:username").Get(org.IsMember). Delete(reqToken(), reqOrgOwnership(), org.DeleteMember) }) + m.Group("/repos", func() { + m.Get("", user.ListOrgRepos) + }) m.Group("/public_members", func() { m.Get("", org.ListPublicMembers) m.Combo("/:username").Get(org.IsPublicMember). diff --git a/routers/api/v1/user/key.go b/routers/api/v1/user/key.go index a53ed2f8c90ba..ab72ee12672d5 100644 --- a/routers/api/v1/user/key.go +++ b/routers/api/v1/user/key.go @@ -33,6 +33,11 @@ func GetUserByParams(ctx *context.APIContext) *models.User { return GetUserByParamsName(ctx, ":username") } +// GetOrgByParams returns org whose name is presented in URL parameter. +func GetOrgByParams(ctx *context.APIContext) *models.User { + return GetUserByParamsName(ctx, ":org") +} + func composePublicKeysAPILink() string { return setting.AppURL + "api/v1/user/keys/" } diff --git a/routers/api/v1/user/repo.go b/routers/api/v1/user/repo.go index c929da5e37531..0195c3fd29bdf 100644 --- a/routers/api/v1/user/repo.go +++ b/routers/api/v1/user/repo.go @@ -1,3 +1,7 @@ +// Copyright 2017 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + package user import ( @@ -80,3 +84,21 @@ func ListMyRepos(ctx *context.APIContext) { } ctx.JSON(200, &apiRepos) } + +// ListOrgRepos - list the repositories of an organization. +func ListOrgRepos(ctx *context.APIContext) { + // swagger:route GET /orgs/{org}/repos orgListRepos + // + // Produces: + // - application/json + // + // Responses: + // 200: RepositoryList + // 500: error + + org := GetOrgByParams(ctx) + if ctx.Written() { + return + } + listUserRepos(ctx, org) +} From f471e48ed21b675bfc4e403d5e0db0e3ebbf0757 Mon Sep 17 00:00:00 2001 From: awwalker Date: Sat, 24 Jun 2017 17:06:24 -0400 Subject: [PATCH 2/9] use ctx.Org instead of OrgFromParams --- routers/api/v1/user/key.go | 5 ----- routers/api/v1/user/repo.go | 6 +----- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/routers/api/v1/user/key.go b/routers/api/v1/user/key.go index ab72ee12672d5..a53ed2f8c90ba 100644 --- a/routers/api/v1/user/key.go +++ b/routers/api/v1/user/key.go @@ -33,11 +33,6 @@ func GetUserByParams(ctx *context.APIContext) *models.User { return GetUserByParamsName(ctx, ":username") } -// GetOrgByParams returns org whose name is presented in URL parameter. -func GetOrgByParams(ctx *context.APIContext) *models.User { - return GetUserByParamsName(ctx, ":org") -} - func composePublicKeysAPILink() string { return setting.AppURL + "api/v1/user/keys/" } diff --git a/routers/api/v1/user/repo.go b/routers/api/v1/user/repo.go index 0195c3fd29bdf..9c6dd62f9c724 100644 --- a/routers/api/v1/user/repo.go +++ b/routers/api/v1/user/repo.go @@ -96,9 +96,5 @@ func ListOrgRepos(ctx *context.APIContext) { // 200: RepositoryList // 500: error - org := GetOrgByParams(ctx) - if ctx.Written() { - return - } - listUserRepos(ctx, org) + listUserRepos(ctx, ctx.Org) } From bf8a45109b44f9dc8627a6b65206d2609a90f501 Mon Sep 17 00:00:00 2001 From: awwalker Date: Sun, 25 Jun 2017 21:23:39 -0400 Subject: [PATCH 3/9] login for test and use ctx.Org.Organization --- integrations/api_repo_test.go | 7 ++++--- routers/api/v1/user/repo.go | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/integrations/api_repo_test.go b/integrations/api_repo_test.go index 5896dd508db9b..77512d22c7efd 100644 --- a/integrations/api_repo_test.go +++ b/integrations/api_repo_test.go @@ -64,10 +64,11 @@ func TestAPIViewRepo(t *testing.T) { assert.EqualValues(t, "repo1", repo.Name) } -func TestAPIOrgReposNotLogin(t *testing.T) { - assert.NoError(t, models.LoadFixtures()) +func TestAPIOrgRepos(t *testing.T) { + prepareTestEnv(t) req := NewRequest(t, "GET", "/api/v1/orgs/org1/repos") - resp := MakeRequest(req) + session := loginUser(t, "user1") + resp := session.MakeRequest(t, req) assert.EqualValues(t, http.StatusOK, resp.HeaderCode) } diff --git a/routers/api/v1/user/repo.go b/routers/api/v1/user/repo.go index 9c6dd62f9c724..b4a4653faa2a6 100644 --- a/routers/api/v1/user/repo.go +++ b/routers/api/v1/user/repo.go @@ -96,5 +96,5 @@ func ListOrgRepos(ctx *context.APIContext) { // 200: RepositoryList // 500: error - listUserRepos(ctx, ctx.Org) + listUserRepos(ctx, ctx.Org.Organization) } From b7a1dfd02431078521bbbb47cc151e991fd9c873 Mon Sep 17 00:00:00 2001 From: awwalker Date: Tue, 4 Jul 2017 02:27:49 -0400 Subject: [PATCH 4/9] use proper org/user in test --- integrations/api_repo_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/integrations/api_repo_test.go b/integrations/api_repo_test.go index 77512d22c7efd..a21acd072df2c 100644 --- a/integrations/api_repo_test.go +++ b/integrations/api_repo_test.go @@ -67,8 +67,8 @@ func TestAPIViewRepo(t *testing.T) { func TestAPIOrgRepos(t *testing.T) { prepareTestEnv(t) - req := NewRequest(t, "GET", "/api/v1/orgs/org1/repos") - session := loginUser(t, "user1") + req := NewRequest(t, "GET", "/api/v1/orgs/user3/repos") + session := loginUser(t, "user2") resp := session.MakeRequest(t, req) assert.EqualValues(t, http.StatusOK, resp.HeaderCode) } From f4c83655c80ec0cdc4bcf73b387f87d4910774e3 Mon Sep 17 00:00:00 2001 From: awwalker Date: Thu, 6 Jul 2017 04:34:12 -0400 Subject: [PATCH 5/9] validate correct num of repos returned --- integrations/api_repo_test.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/integrations/api_repo_test.go b/integrations/api_repo_test.go index a21acd072df2c..286b500a4464a 100644 --- a/integrations/api_repo_test.go +++ b/integrations/api_repo_test.go @@ -71,4 +71,8 @@ func TestAPIOrgRepos(t *testing.T) { session := loginUser(t, "user2") resp := session.MakeRequest(t, req) assert.EqualValues(t, http.StatusOK, resp.HeaderCode) + + var repos []*api.Repository + DecodeJSON(t, resp, &repos) + assert.Len(t, repos, 1) // User3 has 1 public repo. } From b351b38a0f2c148c1b135fc90312b94e444fc812 Mon Sep 17 00:00:00 2001 From: awwalker Date: Thu, 6 Jul 2017 05:18:34 -0400 Subject: [PATCH 6/9] update swagger.json --- public/swagger.v1.json | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/public/swagger.v1.json b/public/swagger.v1.json index 68f8227933089..3ce534d44f6ba 100644 --- a/public/swagger.v1.json +++ b/public/swagger.v1.json @@ -187,6 +187,22 @@ } } }, + "/orgs/{org}/repos": { + "get": { + "produces": [ + "application/json" + ], + "operationId": "orgListRepos", + "responses": { + "200": { + "$ref": "#/responses/RepositoryList" + }, + "500": { + "$ref": "#/responses/error" + } + } + } + }, "/repos/search": { "get": { "produces": [ @@ -1357,4 +1373,4 @@ } } } -} \ No newline at end of file +} From 5a6522bb97ca5db28f682795cc3749c4a16ecbc5 Mon Sep 17 00:00:00 2001 From: awwalker Date: Fri, 7 Jul 2017 16:12:02 -0400 Subject: [PATCH 7/9] format imports/revise route --- routers/api/v1/api.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index d572d88f1e692..bac5af7be6699 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -458,6 +458,7 @@ func RegisterRoutes(m *macaron.Macaron) { m.Get("/user/orgs", reqToken(), org.ListMyOrgs) m.Get("/users/:username/orgs", org.ListUserOrgs) m.Group("/orgs/:orgname", func() { + m.Get("/repos", user.ListOrgRepos) m.Combo("").Get(org.Get). Patch(reqToken(), reqOrgOwnership(), bind(api.EditOrgOption{}), org.Edit) m.Group("/members", func() { @@ -465,9 +466,6 @@ func RegisterRoutes(m *macaron.Macaron) { m.Combo("/:username").Get(org.IsMember). Delete(reqToken(), reqOrgOwnership(), org.DeleteMember) }) - m.Group("/repos", func() { - m.Get("", user.ListOrgRepos) - }) m.Group("/public_members", func() { m.Get("", org.ListPublicMembers) m.Combo("/:username").Get(org.IsPublicMember). From a49fdeedfa0c02998869b590879a4d38f30ba5d5 Mon Sep 17 00:00:00 2001 From: awwalker Date: Sun, 9 Jul 2017 18:08:20 -0400 Subject: [PATCH 8/9] reformat integration test --- integrations/api_repo_test.go | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/integrations/api_repo_test.go b/integrations/api_repo_test.go index 286b500a4464a..cd07e8b28b0af 100644 --- a/integrations/api_repo_test.go +++ b/integrations/api_repo_test.go @@ -5,6 +5,7 @@ package integrations import ( + "fmt" "net/http" "strings" "testing" @@ -66,13 +67,24 @@ func TestAPIViewRepo(t *testing.T) { func TestAPIOrgRepos(t *testing.T) { prepareTestEnv(t) + user := models.AssertExistsAndLoadBean(t, &models.User{ID: 2}).(*models.User) + // User3 is an Org. Check their repos. + sourceOrg := models.AssertExistsAndLoadBean(t, &models.User{ID: 3}).(*models.User) + // Login as User2. + session := loginUser(t, user.Name) - req := NewRequest(t, "GET", "/api/v1/orgs/user3/repos") - session := loginUser(t, "user2") - resp := session.MakeRequest(t, req) - assert.EqualValues(t, http.StatusOK, resp.HeaderCode) + req := NewRequestf(t, "GET", "/api/v1/orgs/%s/repos", sourceOrg.Name) + resp := session.MakeRequest(t, req, http.StatusOK) - var repos []*api.Repository - DecodeJSON(t, resp, &repos) - assert.Len(t, repos, 1) // User3 has 1 public repo. + var apiRepos []*api.Repository + DecodeJSON(t, resp, &apiRepos) + expectedLen := models.GetCount(t, models.Repository{OwnerID: sourceOrg.ID}, + models.Cond("is_private = ?", false)) + fmt.Println(expectedLen) // 0 + fmt.Println(len(apiRepos)) // 1 + assert.Len(t, apiRepos, expectedLen) + for _, repo := range apiRepos { + fmt.Printf("%+v\n", repo) + assert.False(t, repo.Private) + } } From a0c2d773efc87b422e6d946ea2673c5c0c73fb90 Mon Sep 17 00:00:00 2001 From: awwalker Date: Tue, 11 Jul 2017 12:41:53 -0400 Subject: [PATCH 9/9] remove print statements --- integrations/api_repo_test.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/integrations/api_repo_test.go b/integrations/api_repo_test.go index cd07e8b28b0af..e89a6359ae34a 100644 --- a/integrations/api_repo_test.go +++ b/integrations/api_repo_test.go @@ -5,7 +5,6 @@ package integrations import ( - "fmt" "net/http" "strings" "testing" @@ -80,11 +79,8 @@ func TestAPIOrgRepos(t *testing.T) { DecodeJSON(t, resp, &apiRepos) expectedLen := models.GetCount(t, models.Repository{OwnerID: sourceOrg.ID}, models.Cond("is_private = ?", false)) - fmt.Println(expectedLen) // 0 - fmt.Println(len(apiRepos)) // 1 assert.Len(t, apiRepos, expectedLen) for _, repo := range apiRepos { - fmt.Printf("%+v\n", repo) assert.False(t, repo.Private) } }