mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-31 03:25:11 +01:00 
			
		
		
		
	Inclusion of rename organization api (#33303)
This adds an endpoint (`/orgs/{org}/rename`) to rename organizations.
I've modeled the endpoint using the rename user endpoint --
`/admin/users/{username}/rename` -- as base.
It is the 1st time I wrote a new API endpoint (I've tried to follow the
rename users endpoint code while writing it). So feel free to ping me if
there is something wrong or missing.
Resolves #32995
---------
Signed-off-by: Bruno Sofiato <bruno.sofiato@gmail.com>
Co-authored-by: delvh <dev.lh@web.de>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
			
			
This commit is contained in:
		
							parent
							
								
									5b83203f37
								
							
						
					
					
						commit
						040c830dec
					
				| @ -57,3 +57,12 @@ type EditOrgOption struct { | ||||
| 	Visibility                string `json:"visibility" binding:"In(,public,limited,private)"` | ||||
| 	RepoAdminChangeTeamAccess *bool  `json:"repo_admin_change_team_access"` | ||||
| } | ||||
| 
 | ||||
| // RenameOrgOption options when renaming an organization | ||||
| type RenameOrgOption struct { | ||||
| 	// New username for this org. This name cannot be in use yet by any other user. | ||||
| 	// | ||||
| 	// required: true | ||||
| 	// unique: true | ||||
| 	NewName string `json:"new_name" binding:"Required"` | ||||
| } | ||||
|  | ||||
| @ -477,26 +477,16 @@ func RenameUser(ctx *context.APIContext) { | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	oldName := ctx.ContextUser.Name | ||||
| 	newName := web.GetForm(ctx).(*api.RenameUserOption).NewName | ||||
| 
 | ||||
| 	// Check if user name has been changed | ||||
| 	// Check if username has been changed | ||||
| 	if err := user_service.RenameUser(ctx, ctx.ContextUser, newName); err != nil { | ||||
| 		switch { | ||||
| 		case user_model.IsErrUserAlreadyExist(err): | ||||
| 			ctx.Error(http.StatusUnprocessableEntity, "", ctx.Tr("form.username_been_taken")) | ||||
| 		case db.IsErrNameReserved(err): | ||||
| 			ctx.Error(http.StatusUnprocessableEntity, "", ctx.Tr("user.form.name_reserved", newName)) | ||||
| 		case db.IsErrNamePatternNotAllowed(err): | ||||
| 			ctx.Error(http.StatusUnprocessableEntity, "", ctx.Tr("user.form.name_pattern_not_allowed", newName)) | ||||
| 		case db.IsErrNameCharsNotAllowed(err): | ||||
| 			ctx.Error(http.StatusUnprocessableEntity, "", ctx.Tr("user.form.name_chars_not_allowed", newName)) | ||||
| 		default: | ||||
| 		if user_model.IsErrUserAlreadyExist(err) || db.IsErrNameReserved(err) || db.IsErrNamePatternNotAllowed(err) || db.IsErrNameCharsNotAllowed(err) { | ||||
| 			ctx.Error(http.StatusUnprocessableEntity, "", err) | ||||
| 		} else { | ||||
| 			ctx.ServerError("ChangeUserName", err) | ||||
| 		} | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	log.Trace("User name changed: %s -> %s", oldName, newName) | ||||
| 	ctx.Status(http.StatusNoContent) | ||||
| } | ||||
|  | ||||
| @ -1530,6 +1530,7 @@ func Routes() *web.Router { | ||||
| 			m.Combo("").Get(org.Get). | ||||
| 				Patch(reqToken(), reqOrgOwnership(), bind(api.EditOrgOption{}), org.Edit). | ||||
| 				Delete(reqToken(), reqOrgOwnership(), org.Delete) | ||||
| 			m.Post("/rename", reqToken(), reqOrgOwnership(), bind(api.RenameOrgOption{}), org.Rename) | ||||
| 			m.Combo("/repos").Get(user.ListOrgRepos). | ||||
| 				Post(reqToken(), bind(api.CreateRepoOption{}), repo.CreateOrgRepo) | ||||
| 			m.Group("/members", func() { | ||||
|  | ||||
| @ -315,6 +315,44 @@ func Get(ctx *context.APIContext) { | ||||
| 	ctx.JSON(http.StatusOK, org) | ||||
| } | ||||
| 
 | ||||
| func Rename(ctx *context.APIContext) { | ||||
| 	// swagger:operation POST /orgs/{org}/rename organization renameOrg | ||||
| 	// --- | ||||
| 	// summary: Rename an organization | ||||
| 	// produces: | ||||
| 	// - application/json | ||||
| 	// parameters: | ||||
| 	// - name: org | ||||
| 	//   in: path | ||||
| 	//   description: existing org name | ||||
| 	//   type: string | ||||
| 	//   required: true | ||||
| 	// - name: body | ||||
| 	//   in: body | ||||
| 	//   required: true | ||||
| 	//   schema: | ||||
| 	//     "$ref": "#/definitions/RenameOrgOption" | ||||
| 	// responses: | ||||
| 	//   "204": | ||||
| 	//     "$ref": "#/responses/empty" | ||||
| 	//   "403": | ||||
| 	//     "$ref": "#/responses/forbidden" | ||||
| 	//   "422": | ||||
| 	//     "$ref": "#/responses/validationError" | ||||
| 
 | ||||
| 	form := web.GetForm(ctx).(*api.RenameOrgOption) | ||||
| 	orgUser := ctx.Org.Organization.AsUser() | ||||
| 	if err := user_service.RenameUser(ctx, orgUser, form.NewName); err != nil { | ||||
| 		if user_model.IsErrUserAlreadyExist(err) || db.IsErrNameReserved(err) || db.IsErrNamePatternNotAllowed(err) || db.IsErrNameCharsNotAllowed(err) { | ||||
| 			ctx.Error(http.StatusUnprocessableEntity, "RenameOrg", err) | ||||
| 		} else { | ||||
| 			ctx.ServerError("RenameOrg", err) | ||||
| 		} | ||||
| 		return | ||||
| 	} | ||||
| 	ctx.Status(http.StatusNoContent) | ||||
| } | ||||
| 
 | ||||
| // Edit change an organization's information | ||||
| func Edit(ctx *context.APIContext) { | ||||
| 	// swagger:operation PATCH /orgs/{org} organization orgEdit | ||||
|  | ||||
| @ -208,6 +208,9 @@ type swaggerParameterBodies struct { | ||||
| 	// in:body | ||||
| 	CreateVariableOption api.CreateVariableOption | ||||
| 
 | ||||
| 	// in:body | ||||
| 	RenameOrgOption api.RenameOrgOption | ||||
| 
 | ||||
| 	// in:body | ||||
| 	UpdateVariableOption api.UpdateVariableOption | ||||
| } | ||||
|  | ||||
							
								
								
									
										56
									
								
								templates/swagger/v1_json.tmpl
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										56
									
								
								templates/swagger/v1_json.tmpl
									
									
									
										generated
									
									
									
								
							| @ -2991,6 +2991,46 @@ | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "/orgs/{org}/rename": { | ||||
|       "post": { | ||||
|         "produces": [ | ||||
|           "application/json" | ||||
|         ], | ||||
|         "tags": [ | ||||
|           "organization" | ||||
|         ], | ||||
|         "summary": "Rename an organization", | ||||
|         "operationId": "renameOrg", | ||||
|         "parameters": [ | ||||
|           { | ||||
|             "type": "string", | ||||
|             "description": "existing org name", | ||||
|             "name": "org", | ||||
|             "in": "path", | ||||
|             "required": true | ||||
|           }, | ||||
|           { | ||||
|             "name": "body", | ||||
|             "in": "body", | ||||
|             "required": true, | ||||
|             "schema": { | ||||
|               "$ref": "#/definitions/RenameOrgOption" | ||||
|             } | ||||
|           } | ||||
|         ], | ||||
|         "responses": { | ||||
|           "204": { | ||||
|             "$ref": "#/responses/empty" | ||||
|           }, | ||||
|           "403": { | ||||
|             "$ref": "#/responses/forbidden" | ||||
|           }, | ||||
|           "422": { | ||||
|             "$ref": "#/responses/validationError" | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "/orgs/{org}/repos": { | ||||
|       "get": { | ||||
|         "produces": [ | ||||
| @ -24207,6 +24247,22 @@ | ||||
|       }, | ||||
|       "x-go-package": "code.gitea.io/gitea/modules/structs" | ||||
|     }, | ||||
|     "RenameOrgOption": { | ||||
|       "description": "RenameOrgOption options when renaming an organization", | ||||
|       "type": "object", | ||||
|       "required": [ | ||||
|         "new_name" | ||||
|       ], | ||||
|       "properties": { | ||||
|         "new_name": { | ||||
|           "description": "New username for this org. This name cannot be in use yet by any other user.", | ||||
|           "type": "string", | ||||
|           "uniqueItems": true, | ||||
|           "x-go-name": "NewName" | ||||
|         } | ||||
|       }, | ||||
|       "x-go-package": "code.gitea.io/gitea/modules/structs" | ||||
|     }, | ||||
|     "RenameUserOption": { | ||||
|       "description": "RenameUserOption options when renaming a user", | ||||
|       "type": "object", | ||||
|  | ||||
| @ -6,7 +6,6 @@ package integration | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"net/http" | ||||
| 	"net/url" | ||||
| 	"strings" | ||||
| 	"testing" | ||||
| 
 | ||||
| @ -19,46 +18,52 @@ import ( | ||||
| 	user_model "code.gitea.io/gitea/models/user" | ||||
| 	"code.gitea.io/gitea/modules/setting" | ||||
| 	api "code.gitea.io/gitea/modules/structs" | ||||
| 	"code.gitea.io/gitea/modules/test" | ||||
| 	"code.gitea.io/gitea/tests" | ||||
| 
 | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| ) | ||||
| 
 | ||||
| func TestAPIOrgCreate(t *testing.T) { | ||||
| 	onGiteaRun(t, func(*testing.T, *url.URL) { | ||||
| 		token := getUserToken(t, "user1", auth_model.AccessTokenScopeWriteOrganization) | ||||
| func TestAPIOrgCreateRename(t *testing.T) { | ||||
| 	defer tests.PrepareTestEnv(t)() | ||||
| 	token := getUserToken(t, "user1", auth_model.AccessTokenScopeWriteOrganization) | ||||
| 
 | ||||
| 		org := api.CreateOrgOption{ | ||||
| 			UserName:    "user1_org", | ||||
| 			FullName:    "User1's organization", | ||||
| 			Description: "This organization created by user1", | ||||
| 			Website:     "https://try.gitea.io", | ||||
| 			Location:    "Shanghai", | ||||
| 			Visibility:  "limited", | ||||
| 		} | ||||
| 		req := NewRequestWithJSON(t, "POST", "/api/v1/orgs", &org). | ||||
| 			AddTokenAuth(token) | ||||
| 		resp := MakeRequest(t, req, http.StatusCreated) | ||||
| 	org := api.CreateOrgOption{ | ||||
| 		UserName:    "user1_org", | ||||
| 		FullName:    "User1's organization", | ||||
| 		Description: "This organization created by user1", | ||||
| 		Website:     "https://try.gitea.io", | ||||
| 		Location:    "Shanghai", | ||||
| 		Visibility:  "limited", | ||||
| 	} | ||||
| 	req := NewRequestWithJSON(t, "POST", "/api/v1/orgs", &org).AddTokenAuth(token) | ||||
| 	resp := MakeRequest(t, req, http.StatusCreated) | ||||
| 
 | ||||
| 		var apiOrg api.Organization | ||||
| 		DecodeJSON(t, resp, &apiOrg) | ||||
| 	var apiOrg api.Organization | ||||
| 	DecodeJSON(t, resp, &apiOrg) | ||||
| 
 | ||||
| 		assert.Equal(t, org.UserName, apiOrg.Name) | ||||
| 		assert.Equal(t, org.FullName, apiOrg.FullName) | ||||
| 		assert.Equal(t, org.Description, apiOrg.Description) | ||||
| 		assert.Equal(t, org.Website, apiOrg.Website) | ||||
| 		assert.Equal(t, org.Location, apiOrg.Location) | ||||
| 		assert.Equal(t, org.Visibility, apiOrg.Visibility) | ||||
| 	assert.Equal(t, org.UserName, apiOrg.Name) | ||||
| 	assert.Equal(t, org.FullName, apiOrg.FullName) | ||||
| 	assert.Equal(t, org.Description, apiOrg.Description) | ||||
| 	assert.Equal(t, org.Website, apiOrg.Website) | ||||
| 	assert.Equal(t, org.Location, apiOrg.Location) | ||||
| 	assert.Equal(t, org.Visibility, apiOrg.Visibility) | ||||
| 
 | ||||
| 		unittest.AssertExistsAndLoadBean(t, &user_model.User{ | ||||
| 			Name:      org.UserName, | ||||
| 			LowerName: strings.ToLower(org.UserName), | ||||
| 			FullName:  org.FullName, | ||||
| 		}) | ||||
| 	unittest.AssertExistsAndLoadBean(t, &user_model.User{ | ||||
| 		Name:      org.UserName, | ||||
| 		LowerName: strings.ToLower(org.UserName), | ||||
| 		FullName:  org.FullName, | ||||
| 	}) | ||||
| 
 | ||||
| 	// check org name | ||||
| 	req = NewRequestf(t, "GET", "/api/v1/orgs/%s", org.UserName).AddTokenAuth(token) | ||||
| 	resp = MakeRequest(t, req, http.StatusOK) | ||||
| 	DecodeJSON(t, resp, &apiOrg) | ||||
| 	assert.EqualValues(t, org.UserName, apiOrg.Name) | ||||
| 
 | ||||
| 	t.Run("CheckPermission", func(t *testing.T) { | ||||
| 		// Check owner team permission | ||||
| 		ownerTeam, _ := org_model.GetOwnerTeam(db.DefaultContext, apiOrg.ID) | ||||
| 
 | ||||
| 		for _, ut := range unit_model.AllRepoUnitTypes { | ||||
| 			up := perm.AccessModeOwner | ||||
| 			if ut == unit_model.TypeExternalTracker || ut == unit_model.TypeExternalWiki { | ||||
| @ -71,25 +76,10 @@ func TestAPIOrgCreate(t *testing.T) { | ||||
| 				AccessMode: up, | ||||
| 			}) | ||||
| 		} | ||||
| 	}) | ||||
| 
 | ||||
| 		req = NewRequestf(t, "GET", "/api/v1/orgs/%s", org.UserName). | ||||
| 			AddTokenAuth(token) | ||||
| 		resp = MakeRequest(t, req, http.StatusOK) | ||||
| 		DecodeJSON(t, resp, &apiOrg) | ||||
| 		assert.EqualValues(t, org.UserName, apiOrg.Name) | ||||
| 
 | ||||
| 		req = NewRequestf(t, "GET", "/api/v1/orgs/%s/repos", org.UserName). | ||||
| 			AddTokenAuth(token) | ||||
| 		resp = MakeRequest(t, req, http.StatusOK) | ||||
| 
 | ||||
| 		var repos []*api.Repository | ||||
| 		DecodeJSON(t, resp, &repos) | ||||
| 		for _, repo := range repos { | ||||
| 			assert.False(t, repo.Private) | ||||
| 		} | ||||
| 
 | ||||
| 		req = NewRequestf(t, "GET", "/api/v1/orgs/%s/members", org.UserName). | ||||
| 			AddTokenAuth(token) | ||||
| 	t.Run("CheckMembers", func(t *testing.T) { | ||||
| 		req = NewRequestf(t, "GET", "/api/v1/orgs/%s/members", org.UserName).AddTokenAuth(token) | ||||
| 		resp = MakeRequest(t, req, http.StatusOK) | ||||
| 
 | ||||
| 		// user1 on this org is public | ||||
| @ -98,76 +88,89 @@ func TestAPIOrgCreate(t *testing.T) { | ||||
| 		assert.Len(t, users, 1) | ||||
| 		assert.EqualValues(t, "user1", users[0].UserName) | ||||
| 	}) | ||||
| 
 | ||||
| 	t.Run("RenameOrg", func(t *testing.T) { | ||||
| 		req = NewRequestWithJSON(t, "POST", "/api/v1/orgs/user1_org/rename", &api.RenameOrgOption{ | ||||
| 			NewName: "renamed_org", | ||||
| 		}).AddTokenAuth(token) | ||||
| 		MakeRequest(t, req, http.StatusNoContent) | ||||
| 		unittest.AssertExistsAndLoadBean(t, &org_model.Organization{Name: "renamed_org"}) | ||||
| 		org.UserName = "renamed_org" // update the variable so the following tests could still use it | ||||
| 	}) | ||||
| 
 | ||||
| 	t.Run("ListRepos", func(t *testing.T) { | ||||
| 		// FIXME: this test is wrong, there is no repository at all, so the for-loop is empty | ||||
| 		req = NewRequestf(t, "GET", "/api/v1/orgs/%s/repos", org.UserName).AddTokenAuth(token) | ||||
| 		resp = MakeRequest(t, req, http.StatusOK) | ||||
| 		var repos []*api.Repository | ||||
| 		DecodeJSON(t, resp, &repos) | ||||
| 		for _, repo := range repos { | ||||
| 			assert.False(t, repo.Private) | ||||
| 		} | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| func TestAPIOrgEdit(t *testing.T) { | ||||
| 	onGiteaRun(t, func(*testing.T, *url.URL) { | ||||
| 		session := loginUser(t, "user1") | ||||
| 	defer tests.PrepareTestEnv(t)() | ||||
| 	session := loginUser(t, "user1") | ||||
| 
 | ||||
| 		token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteOrganization) | ||||
| 		org := api.EditOrgOption{ | ||||
| 			FullName:    "Org3 organization new full name", | ||||
| 			Description: "A new description", | ||||
| 			Website:     "https://try.gitea.io/new", | ||||
| 			Location:    "Beijing", | ||||
| 			Visibility:  "private", | ||||
| 		} | ||||
| 		req := NewRequestWithJSON(t, "PATCH", "/api/v1/orgs/org3", &org). | ||||
| 			AddTokenAuth(token) | ||||
| 		resp := MakeRequest(t, req, http.StatusOK) | ||||
| 	token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteOrganization) | ||||
| 	org := api.EditOrgOption{ | ||||
| 		FullName:    "Org3 organization new full name", | ||||
| 		Description: "A new description", | ||||
| 		Website:     "https://try.gitea.io/new", | ||||
| 		Location:    "Beijing", | ||||
| 		Visibility:  "private", | ||||
| 	} | ||||
| 	req := NewRequestWithJSON(t, "PATCH", "/api/v1/orgs/org3", &org). | ||||
| 		AddTokenAuth(token) | ||||
| 	resp := MakeRequest(t, req, http.StatusOK) | ||||
| 
 | ||||
| 		var apiOrg api.Organization | ||||
| 		DecodeJSON(t, resp, &apiOrg) | ||||
| 	var apiOrg api.Organization | ||||
| 	DecodeJSON(t, resp, &apiOrg) | ||||
| 
 | ||||
| 		assert.Equal(t, "org3", apiOrg.Name) | ||||
| 		assert.Equal(t, org.FullName, apiOrg.FullName) | ||||
| 		assert.Equal(t, org.Description, apiOrg.Description) | ||||
| 		assert.Equal(t, org.Website, apiOrg.Website) | ||||
| 		assert.Equal(t, org.Location, apiOrg.Location) | ||||
| 		assert.Equal(t, org.Visibility, apiOrg.Visibility) | ||||
| 	}) | ||||
| 	assert.Equal(t, "org3", apiOrg.Name) | ||||
| 	assert.Equal(t, org.FullName, apiOrg.FullName) | ||||
| 	assert.Equal(t, org.Description, apiOrg.Description) | ||||
| 	assert.Equal(t, org.Website, apiOrg.Website) | ||||
| 	assert.Equal(t, org.Location, apiOrg.Location) | ||||
| 	assert.Equal(t, org.Visibility, apiOrg.Visibility) | ||||
| } | ||||
| 
 | ||||
| func TestAPIOrgEditBadVisibility(t *testing.T) { | ||||
| 	onGiteaRun(t, func(*testing.T, *url.URL) { | ||||
| 		session := loginUser(t, "user1") | ||||
| 	defer tests.PrepareTestEnv(t)() | ||||
| 	session := loginUser(t, "user1") | ||||
| 
 | ||||
| 		token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteOrganization) | ||||
| 		org := api.EditOrgOption{ | ||||
| 			FullName:    "Org3 organization new full name", | ||||
| 			Description: "A new description", | ||||
| 			Website:     "https://try.gitea.io/new", | ||||
| 			Location:    "Beijing", | ||||
| 			Visibility:  "badvisibility", | ||||
| 		} | ||||
| 		req := NewRequestWithJSON(t, "PATCH", "/api/v1/orgs/org3", &org). | ||||
| 			AddTokenAuth(token) | ||||
| 		MakeRequest(t, req, http.StatusUnprocessableEntity) | ||||
| 	}) | ||||
| 	token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteOrganization) | ||||
| 	org := api.EditOrgOption{ | ||||
| 		FullName:    "Org3 organization new full name", | ||||
| 		Description: "A new description", | ||||
| 		Website:     "https://try.gitea.io/new", | ||||
| 		Location:    "Beijing", | ||||
| 		Visibility:  "badvisibility", | ||||
| 	} | ||||
| 	req := NewRequestWithJSON(t, "PATCH", "/api/v1/orgs/org3", &org). | ||||
| 		AddTokenAuth(token) | ||||
| 	MakeRequest(t, req, http.StatusUnprocessableEntity) | ||||
| } | ||||
| 
 | ||||
| func TestAPIOrgDeny(t *testing.T) { | ||||
| 	onGiteaRun(t, func(*testing.T, *url.URL) { | ||||
| 		setting.Service.RequireSignInView = true | ||||
| 		defer func() { | ||||
| 			setting.Service.RequireSignInView = false | ||||
| 		}() | ||||
| 	defer tests.PrepareTestEnv(t)() | ||||
| 	defer test.MockVariableValue(&setting.Service.RequireSignInView, true)() | ||||
| 
 | ||||
| 		orgName := "user1_org" | ||||
| 		req := NewRequestf(t, "GET", "/api/v1/orgs/%s", orgName) | ||||
| 		MakeRequest(t, req, http.StatusNotFound) | ||||
| 	orgName := "user1_org" | ||||
| 	req := NewRequestf(t, "GET", "/api/v1/orgs/%s", orgName) | ||||
| 	MakeRequest(t, req, http.StatusNotFound) | ||||
| 
 | ||||
| 		req = NewRequestf(t, "GET", "/api/v1/orgs/%s/repos", orgName) | ||||
| 		MakeRequest(t, req, http.StatusNotFound) | ||||
| 	req = NewRequestf(t, "GET", "/api/v1/orgs/%s/repos", orgName) | ||||
| 	MakeRequest(t, req, http.StatusNotFound) | ||||
| 
 | ||||
| 		req = NewRequestf(t, "GET", "/api/v1/orgs/%s/members", orgName) | ||||
| 		MakeRequest(t, req, http.StatusNotFound) | ||||
| 	}) | ||||
| 	req = NewRequestf(t, "GET", "/api/v1/orgs/%s/members", orgName) | ||||
| 	MakeRequest(t, req, http.StatusNotFound) | ||||
| } | ||||
| 
 | ||||
| func TestAPIGetAll(t *testing.T) { | ||||
| 	defer tests.PrepareTestEnv(t)() | ||||
| 
 | ||||
| 	token := getUserToken(t, "user1", auth_model.AccessTokenScopeReadOrganization) | ||||
| 
 | ||||
| 	// accessing with a token will return all orgs | ||||
| @ -192,37 +195,36 @@ func TestAPIGetAll(t *testing.T) { | ||||
| } | ||||
| 
 | ||||
| func TestAPIOrgSearchEmptyTeam(t *testing.T) { | ||||
| 	onGiteaRun(t, func(*testing.T, *url.URL) { | ||||
| 		token := getUserToken(t, "user1", auth_model.AccessTokenScopeWriteOrganization) | ||||
| 		orgName := "org_with_empty_team" | ||||
| 	defer tests.PrepareTestEnv(t)() | ||||
| 	token := getUserToken(t, "user1", auth_model.AccessTokenScopeWriteOrganization) | ||||
| 	orgName := "org_with_empty_team" | ||||
| 
 | ||||
| 		// create org | ||||
| 		req := NewRequestWithJSON(t, "POST", "/api/v1/orgs", &api.CreateOrgOption{ | ||||
| 			UserName: orgName, | ||||
| 		}).AddTokenAuth(token) | ||||
| 		MakeRequest(t, req, http.StatusCreated) | ||||
| 	// create org | ||||
| 	req := NewRequestWithJSON(t, "POST", "/api/v1/orgs", &api.CreateOrgOption{ | ||||
| 		UserName: orgName, | ||||
| 	}).AddTokenAuth(token) | ||||
| 	MakeRequest(t, req, http.StatusCreated) | ||||
| 
 | ||||
| 		// create team with no member | ||||
| 		req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/orgs/%s/teams", orgName), &api.CreateTeamOption{ | ||||
| 			Name:                    "Empty", | ||||
| 			IncludesAllRepositories: true, | ||||
| 			Permission:              "read", | ||||
| 			Units:                   []string{"repo.code", "repo.issues", "repo.ext_issues", "repo.wiki", "repo.pulls"}, | ||||
| 		}).AddTokenAuth(token) | ||||
| 		MakeRequest(t, req, http.StatusCreated) | ||||
| 	// create team with no member | ||||
| 	req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/orgs/%s/teams", orgName), &api.CreateTeamOption{ | ||||
| 		Name:                    "Empty", | ||||
| 		IncludesAllRepositories: true, | ||||
| 		Permission:              "read", | ||||
| 		Units:                   []string{"repo.code", "repo.issues", "repo.ext_issues", "repo.wiki", "repo.pulls"}, | ||||
| 	}).AddTokenAuth(token) | ||||
| 	MakeRequest(t, req, http.StatusCreated) | ||||
| 
 | ||||
| 		// case-insensitive search for teams that have no members | ||||
| 		req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/orgs/%s/teams/search?q=%s", orgName, "empty")). | ||||
| 			AddTokenAuth(token) | ||||
| 		resp := MakeRequest(t, req, http.StatusOK) | ||||
| 		data := struct { | ||||
| 			Ok   bool | ||||
| 			Data []*api.Team | ||||
| 		}{} | ||||
| 		DecodeJSON(t, resp, &data) | ||||
| 		assert.True(t, data.Ok) | ||||
| 		if assert.Len(t, data.Data, 1) { | ||||
| 			assert.EqualValues(t, "Empty", data.Data[0].Name) | ||||
| 		} | ||||
| 	}) | ||||
| 	// case-insensitive search for teams that have no members | ||||
| 	req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/orgs/%s/teams/search?q=%s", orgName, "empty")). | ||||
| 		AddTokenAuth(token) | ||||
| 	resp := MakeRequest(t, req, http.StatusOK) | ||||
| 	data := struct { | ||||
| 		Ok   bool | ||||
| 		Data []*api.Team | ||||
| 	}{} | ||||
| 	DecodeJSON(t, resp, &data) | ||||
| 	assert.True(t, data.Ok) | ||||
| 	if assert.Len(t, data.Data, 1) { | ||||
| 		assert.EqualValues(t, "Empty", data.Data[0].Name) | ||||
| 	} | ||||
| } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user