mirror of
				https://codeberg.org/forgejo/forgejo.git
				synced 2025-10-31 14:31:02 +00:00 
			
		
		
		
	chore: improve test quality
- Merge tests together. - Remove unecessary usage of `onGiteaRun`. - Make proper use of `unittest`. - Make proper use of `test.MockVariable`. - I have not checked all of the testing files yet.
This commit is contained in:
		
					parent
					
						
							
								ab36ab57e4
							
						
					
				
			
			
				commit
				
					
						582ab21bc3
					
				
			
		
					 18 changed files with 620 additions and 784 deletions
				
			
		|  | @ -14,6 +14,7 @@ import ( | |||
| 	"code.gitea.io/gitea/models/unittest" | ||||
| 	user_model "code.gitea.io/gitea/models/user" | ||||
| 	"code.gitea.io/gitea/modules/setting" | ||||
| 	"code.gitea.io/gitea/modules/test" | ||||
| 	"code.gitea.io/gitea/services/actions" | ||||
| 	"code.gitea.io/gitea/services/automerge" | ||||
| 
 | ||||
|  | @ -23,7 +24,7 @@ import ( | |||
| 
 | ||||
| func TestActionsAutomerge(t *testing.T) { | ||||
| 	onGiteaRun(t, func(t *testing.T, u *url.URL) { | ||||
| 		assert.True(t, setting.Actions.Enabled, "Actions should be enabled") | ||||
| 		defer test.MockVariableValue(&setting.Actions.Enabled, true)() | ||||
| 
 | ||||
| 		ctx := db.DefaultContext | ||||
| 
 | ||||
|  |  | |||
|  | @ -5,7 +5,6 @@ package integration | |||
| 
 | ||||
| import ( | ||||
| 	"net/http" | ||||
| 	"net/url" | ||||
| 	"strings" | ||||
| 	"testing" | ||||
| 
 | ||||
|  | @ -19,57 +18,55 @@ import ( | |||
| ) | ||||
| 
 | ||||
| func TestAPIAdminOrgCreate(t *testing.T) { | ||||
| 	onGiteaRun(t, func(*testing.T, *url.URL) { | ||||
| 		session := loginUser(t, "user1") | ||||
| 		token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteAdmin) | ||||
| 	defer tests.PrepareTestEnv(t)() | ||||
| 	session := loginUser(t, "user1") | ||||
| 	token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteAdmin) | ||||
| 
 | ||||
| 		org := api.CreateOrgOption{ | ||||
| 			UserName:    "user2_org", | ||||
| 			FullName:    "User2's organization", | ||||
| 			Description: "This organization created by admin for user2", | ||||
| 			Website:     "https://try.gitea.io", | ||||
| 			Location:    "Shanghai", | ||||
| 			Visibility:  "private", | ||||
| 		} | ||||
| 		req := NewRequestWithJSON(t, "POST", "/api/v1/admin/users/user2/orgs", &org). | ||||
| 			AddTokenAuth(token) | ||||
| 		resp := MakeRequest(t, req, http.StatusCreated) | ||||
| 	org := api.CreateOrgOption{ | ||||
| 		UserName:    "user2_org", | ||||
| 		FullName:    "User2's organization", | ||||
| 		Description: "This organization created by admin for user2", | ||||
| 		Website:     "https://try.gitea.io", | ||||
| 		Location:    "Shanghai", | ||||
| 		Visibility:  "private", | ||||
| 	} | ||||
| 	req := NewRequestWithJSON(t, "POST", "/api/v1/admin/users/user2/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, | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| func TestAPIAdminOrgCreateBadVisibility(t *testing.T) { | ||||
| 	onGiteaRun(t, func(*testing.T, *url.URL) { | ||||
| 		session := loginUser(t, "user1") | ||||
| 		token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteAdmin) | ||||
| 	defer tests.PrepareTestEnv(t)() | ||||
| 	session := loginUser(t, "user1") | ||||
| 	token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteAdmin) | ||||
| 
 | ||||
| 		org := api.CreateOrgOption{ | ||||
| 			UserName:    "user2_org", | ||||
| 			FullName:    "User2's organization", | ||||
| 			Description: "This organization created by admin for user2", | ||||
| 			Website:     "https://try.gitea.io", | ||||
| 			Location:    "Shanghai", | ||||
| 			Visibility:  "notvalid", | ||||
| 		} | ||||
| 		req := NewRequestWithJSON(t, "POST", "/api/v1/admin/users/user2/orgs", &org). | ||||
| 			AddTokenAuth(token) | ||||
| 		MakeRequest(t, req, http.StatusUnprocessableEntity) | ||||
| 	}) | ||||
| 	org := api.CreateOrgOption{ | ||||
| 		UserName:    "user2_org", | ||||
| 		FullName:    "User2's organization", | ||||
| 		Description: "This organization created by admin for user2", | ||||
| 		Website:     "https://try.gitea.io", | ||||
| 		Location:    "Shanghai", | ||||
| 		Visibility:  "notvalid", | ||||
| 	} | ||||
| 	req := NewRequestWithJSON(t, "POST", "/api/v1/admin/users/user2/orgs", &org). | ||||
| 		AddTokenAuth(token) | ||||
| 	MakeRequest(t, req, http.StatusUnprocessableEntity) | ||||
| } | ||||
| 
 | ||||
| func TestAPIAdminOrgCreateNotAdmin(t *testing.T) { | ||||
|  |  | |||
|  | @ -9,14 +9,13 @@ import ( | |||
| 	"testing" | ||||
| 
 | ||||
| 	auth_model "code.gitea.io/gitea/models/auth" | ||||
| 	"code.gitea.io/gitea/models/db" | ||||
| 	git_model "code.gitea.io/gitea/models/git" | ||||
| 	"code.gitea.io/gitea/models/unittest" | ||||
| 	"code.gitea.io/gitea/modules/git" | ||||
| 	api "code.gitea.io/gitea/modules/structs" | ||||
| 	"code.gitea.io/gitea/tests" | ||||
| 
 | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| 	"github.com/stretchr/testify/require" | ||||
| ) | ||||
| 
 | ||||
| func testAPIGetBranch(t *testing.T, branchName string, exists bool) { | ||||
|  | @ -234,35 +233,17 @@ func TestAPIBranchProtection(t *testing.T) { | |||
| } | ||||
| 
 | ||||
| func TestAPICreateBranchWithSyncBranches(t *testing.T) { | ||||
| 	defer tests.PrepareTestEnv(t)() | ||||
| 
 | ||||
| 	branches, err := db.Find[git_model.Branch](db.DefaultContext, git_model.FindBranchOptions{ | ||||
| 		RepoID: 1, | ||||
| 	}) | ||||
| 	require.NoError(t, err) | ||||
| 	assert.Len(t, branches, 4) | ||||
| 
 | ||||
| 	// make a broke repository with no branch on database | ||||
| 	_, err = db.DeleteByBean(db.DefaultContext, git_model.Branch{RepoID: 1}) | ||||
| 	require.NoError(t, err) | ||||
| 
 | ||||
| 	onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) { | ||||
| 		unittest.AssertCount(t, &git_model.Branch{RepoID: 1}, 4) | ||||
| 
 | ||||
| 		// make a broke repository with no branch on database | ||||
| 		unittest.AssertSuccessfulDelete(t, &git_model.Branch{RepoID: 1}) | ||||
| 
 | ||||
| 		ctx := NewAPITestContext(t, "user2", "repo1", auth_model.AccessTokenScopeWriteRepository, auth_model.AccessTokenScopeWriteUser) | ||||
| 		giteaURL.Path = ctx.GitPath() | ||||
| 
 | ||||
| 		testAPICreateBranch(t, ctx.Session, "user2", "repo1", "", "new_branch", http.StatusCreated) | ||||
| 	}) | ||||
| 
 | ||||
| 	branches, err = db.Find[git_model.Branch](db.DefaultContext, git_model.FindBranchOptions{ | ||||
| 		RepoID: 1, | ||||
| 		unittest.AssertExistsIf(t, true, &git_model.Branch{RepoID: 1, Name: "new_branch"}) | ||||
| 	}) | ||||
| 	require.NoError(t, err) | ||||
| 	assert.Len(t, branches, 5) | ||||
| 
 | ||||
| 	branches, err = db.Find[git_model.Branch](db.DefaultContext, git_model.FindBranchOptions{ | ||||
| 		RepoID:  1, | ||||
| 		Keyword: "new_branch", | ||||
| 	}) | ||||
| 	require.NoError(t, err) | ||||
| 	assert.Len(t, branches, 1) | ||||
| } | ||||
|  |  | |||
|  | @ -7,7 +7,6 @@ package integration | |||
| import ( | ||||
| 	"fmt" | ||||
| 	"net/http" | ||||
| 	"net/url" | ||||
| 	"testing" | ||||
| 
 | ||||
| 	auth_model "code.gitea.io/gitea/models/auth" | ||||
|  | @ -86,25 +85,24 @@ func TestCreateForkNoLogin(t *testing.T) { | |||
| } | ||||
| 
 | ||||
| func TestAPIDisabledForkRepo(t *testing.T) { | ||||
| 	onGiteaRun(t, func(t *testing.T, u *url.URL) { | ||||
| 		defer test.MockVariableValue(&setting.Repository.DisableForks, true)() | ||||
| 		defer test.MockVariableValue(&testWebRoutes, routers.NormalRoutes())() | ||||
| 	defer test.MockVariableValue(&setting.Repository.DisableForks, true)() | ||||
| 	defer test.MockVariableValue(&testWebRoutes, routers.NormalRoutes())() | ||||
| 	defer tests.PrepareTestEnv(t)() | ||||
| 
 | ||||
| 		t.Run("fork listing", func(t *testing.T) { | ||||
| 			defer tests.PrintCurrentTest(t)() | ||||
| 	t.Run("fork listing", func(t *testing.T) { | ||||
| 		defer tests.PrintCurrentTest(t)() | ||||
| 
 | ||||
| 			req := NewRequest(t, "GET", "/api/v1/repos/user2/repo1/forks") | ||||
| 			MakeRequest(t, req, http.StatusNotFound) | ||||
| 		}) | ||||
| 		req := NewRequest(t, "GET", "/api/v1/repos/user2/repo1/forks") | ||||
| 		MakeRequest(t, req, http.StatusNotFound) | ||||
| 	}) | ||||
| 
 | ||||
| 		t.Run("forking", func(t *testing.T) { | ||||
| 			defer tests.PrintCurrentTest(t)() | ||||
| 	t.Run("forking", func(t *testing.T) { | ||||
| 		defer tests.PrintCurrentTest(t)() | ||||
| 
 | ||||
| 			session := loginUser(t, "user5") | ||||
| 			token := getTokenForLoggedInUser(t, session) | ||||
| 		session := loginUser(t, "user5") | ||||
| 		token := getTokenForLoggedInUser(t, session) | ||||
| 
 | ||||
| 			req := NewRequestWithJSON(t, "POST", "/api/v1/repos/user2/repo1/forks", &api.CreateForkOption{}).AddTokenAuth(token) | ||||
| 			session.MakeRequest(t, req, http.StatusNotFound) | ||||
| 		}) | ||||
| 		req := NewRequestWithJSON(t, "POST", "/api/v1/repos/user2/repo1/forks", &api.CreateForkOption{}).AddTokenAuth(token) | ||||
| 		session.MakeRequest(t, req, http.StatusNotFound) | ||||
| 	}) | ||||
| } | ||||
|  |  | |||
|  | @ -5,35 +5,31 @@ package integration | |||
| 
 | ||||
| import ( | ||||
| 	"net/http" | ||||
| 	"net/url" | ||||
| 	"testing" | ||||
| 
 | ||||
| 	"code.gitea.io/gitea/modules/setting" | ||||
| 	api "code.gitea.io/gitea/modules/structs" | ||||
| 	"code.gitea.io/gitea/modules/test" | ||||
| 	"code.gitea.io/gitea/routers" | ||||
| 	"code.gitea.io/gitea/tests" | ||||
| 
 | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| ) | ||||
| 
 | ||||
| func TestNodeinfo(t *testing.T) { | ||||
| 	setting.Federation.Enabled = true | ||||
| 	testWebRoutes = routers.NormalRoutes() | ||||
| 	defer func() { | ||||
| 		setting.Federation.Enabled = false | ||||
| 		testWebRoutes = routers.NormalRoutes() | ||||
| 	}() | ||||
| 	defer test.MockVariableValue(&setting.Federation.Enabled, true)() | ||||
| 	defer test.MockVariableValue(&testWebRoutes, routers.NormalRoutes())() | ||||
| 	defer tests.PrepareTestEnv(t)() | ||||
| 
 | ||||
| 	onGiteaRun(t, func(*testing.T, *url.URL) { | ||||
| 		req := NewRequest(t, "GET", "/api/v1/nodeinfo") | ||||
| 		resp := MakeRequest(t, req, http.StatusOK) | ||||
| 		VerifyJSONSchema(t, resp, "nodeinfo_2.1.json") | ||||
| 	req := NewRequest(t, "GET", "/api/v1/nodeinfo") | ||||
| 	resp := MakeRequest(t, req, http.StatusOK) | ||||
| 	VerifyJSONSchema(t, resp, "nodeinfo_2.1.json") | ||||
| 
 | ||||
| 		var nodeinfo api.NodeInfo | ||||
| 		DecodeJSON(t, resp, &nodeinfo) | ||||
| 		assert.True(t, nodeinfo.OpenRegistrations) | ||||
| 		assert.Equal(t, "forgejo", nodeinfo.Software.Name) | ||||
| 		assert.Equal(t, 29, nodeinfo.Usage.Users.Total) | ||||
| 		assert.Equal(t, 22, nodeinfo.Usage.LocalPosts) | ||||
| 		assert.Equal(t, 4, nodeinfo.Usage.LocalComments) | ||||
| 	}) | ||||
| 	var nodeinfo api.NodeInfo | ||||
| 	DecodeJSON(t, resp, &nodeinfo) | ||||
| 	assert.True(t, nodeinfo.OpenRegistrations) | ||||
| 	assert.Equal(t, "forgejo", nodeinfo.Software.Name) | ||||
| 	assert.Equal(t, 29, nodeinfo.Usage.Users.Total) | ||||
| 	assert.Equal(t, 22, nodeinfo.Usage.LocalPosts) | ||||
| 	assert.Equal(t, 4, nodeinfo.Usage.LocalComments) | ||||
| } | ||||
|  |  | |||
|  | @ -6,7 +6,6 @@ package integration | |||
| import ( | ||||
| 	"fmt" | ||||
| 	"net/http" | ||||
| 	"net/url" | ||||
| 	"strings" | ||||
| 	"testing" | ||||
| 
 | ||||
|  | @ -19,150 +18,144 @@ 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) | ||||
| 	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, | ||||
| 		}) | ||||
| 
 | ||||
| 		// 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 { | ||||
| 				up = perm.AccessModeRead | ||||
| 			} | ||||
| 			unittest.AssertExistsAndLoadBean(t, &org_model.TeamUnit{ | ||||
| 				OrgID:      apiOrg.ID, | ||||
| 				TeamID:     ownerTeam.ID, | ||||
| 				Type:       ut, | ||||
| 				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) | ||||
| 		resp = MakeRequest(t, req, http.StatusOK) | ||||
| 
 | ||||
| 		// user1 on this org is public | ||||
| 		var users []*api.User | ||||
| 		DecodeJSON(t, resp, &users) | ||||
| 		assert.Len(t, users, 1) | ||||
| 		assert.EqualValues(t, "user1", users[0].UserName) | ||||
| 	unittest.AssertExistsAndLoadBean(t, &user_model.User{ | ||||
| 		Name:      org.UserName, | ||||
| 		LowerName: strings.ToLower(org.UserName), | ||||
| 		FullName:  org.FullName, | ||||
| 	}) | ||||
| 
 | ||||
| 	// 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 { | ||||
| 			up = perm.AccessModeRead | ||||
| 		} | ||||
| 		unittest.AssertExistsAndLoadBean(t, &org_model.TeamUnit{ | ||||
| 			OrgID:      apiOrg.ID, | ||||
| 			TeamID:     ownerTeam.ID, | ||||
| 			Type:       ut, | ||||
| 			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) | ||||
| 	resp = MakeRequest(t, req, http.StatusOK) | ||||
| 
 | ||||
| 	// user1 on this org is public | ||||
| 	var users []*api.User | ||||
| 	DecodeJSON(t, resp, &users) | ||||
| 	assert.Len(t, users, 1) | ||||
| 	assert.EqualValues(t, "user1", users[0].UserName) | ||||
| } | ||||
| 
 | ||||
| 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) { | ||||
|  | @ -192,37 +185,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) | ||||
| 	} | ||||
| } | ||||
|  |  | |||
|  | @ -2,60 +2,59 @@ package integration | |||
| 
 | ||||
| import ( | ||||
| 	"net/http" | ||||
| 	"net/url" | ||||
| 	"path" | ||||
| 	"strings" | ||||
| 	"testing" | ||||
| 
 | ||||
| 	"code.gitea.io/gitea/tests" | ||||
| 
 | ||||
| 	"github.com/PuerkitoBio/goquery" | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| ) | ||||
| 
 | ||||
| func TestRepoLastUpdatedTime(t *testing.T) { | ||||
| 	onGiteaRun(t, func(t *testing.T, u *url.URL) { | ||||
| 		user := "user2" | ||||
| 		session := loginUser(t, user) | ||||
| 	defer tests.PrepareTestEnv(t)() | ||||
| 	user := "user2" | ||||
| 	session := loginUser(t, user) | ||||
| 
 | ||||
| 		req := NewRequest(t, "GET", "/explore/repos?q=repo1") | ||||
| 		resp := session.MakeRequest(t, req, http.StatusOK) | ||||
| 		doc := NewHTMLParser(t, resp.Body) | ||||
| 		node := doc.doc.Find(".flex-item-body").First() | ||||
| 		{ | ||||
| 			buf := "" | ||||
| 			findTextNonNested(t, node, &buf) | ||||
| 			assert.Equal(t, "Updated", strings.TrimSpace(buf)) | ||||
| 		} | ||||
| 	req := NewRequest(t, "GET", "/explore/repos?q=repo1") | ||||
| 	resp := session.MakeRequest(t, req, http.StatusOK) | ||||
| 	doc := NewHTMLParser(t, resp.Body) | ||||
| 	node := doc.doc.Find(".flex-item-body").First() | ||||
| 	{ | ||||
| 		buf := "" | ||||
| 		findTextNonNested(t, node, &buf) | ||||
| 		assert.Equal(t, "Updated", strings.TrimSpace(buf)) | ||||
| 	} | ||||
| 
 | ||||
| 		// Relative time should be present as a descendent | ||||
| 		{ | ||||
| 			relativeTime := node.Find("relative-time").Text() | ||||
| 			assert.True(t, strings.HasPrefix(relativeTime, "19")) // ~1970, might underflow with timezone | ||||
| 		} | ||||
| 	}) | ||||
| 	// Relative time should be present as a descendent | ||||
| 	{ | ||||
| 		relativeTime := node.Find("relative-time").Text() | ||||
| 		assert.True(t, strings.HasPrefix(relativeTime, "19")) // ~1970, might underflow with timezone | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func TestBranchLastUpdatedTime(t *testing.T) { | ||||
| 	onGiteaRun(t, func(t *testing.T, u *url.URL) { | ||||
| 		user := "user2" | ||||
| 		repo := "repo1" | ||||
| 		session := loginUser(t, user) | ||||
| 	defer tests.PrepareTestEnv(t)() | ||||
| 	user := "user2" | ||||
| 	repo := "repo1" | ||||
| 	session := loginUser(t, user) | ||||
| 
 | ||||
| 		req := NewRequest(t, "GET", path.Join(user, repo, "branches")) | ||||
| 		resp := session.MakeRequest(t, req, http.StatusOK) | ||||
| 		doc := NewHTMLParser(t, resp.Body) | ||||
| 		node := doc.doc.Find("p:has(span.commit-message)") | ||||
| 	req := NewRequest(t, "GET", path.Join(user, repo, "branches")) | ||||
| 	resp := session.MakeRequest(t, req, http.StatusOK) | ||||
| 	doc := NewHTMLParser(t, resp.Body) | ||||
| 	node := doc.doc.Find("p:has(span.commit-message)") | ||||
| 
 | ||||
| 		{ | ||||
| 			buf := "" | ||||
| 			findTextNonNested(t, node, &buf) | ||||
| 			assert.True(t, strings.Contains(buf, "Updated")) | ||||
| 		} | ||||
| 	{ | ||||
| 		buf := "" | ||||
| 		findTextNonNested(t, node, &buf) | ||||
| 		assert.True(t, strings.Contains(buf, "Updated")) | ||||
| 	} | ||||
| 
 | ||||
| 		{ | ||||
| 			relativeTime := node.Find("relative-time").Text() | ||||
| 			assert.True(t, strings.HasPrefix(relativeTime, "2017")) | ||||
| 		} | ||||
| 	}) | ||||
| 	{ | ||||
| 		relativeTime := node.Find("relative-time").Text() | ||||
| 		assert.True(t, strings.HasPrefix(relativeTime, "2017")) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // Find all text that are direct descendents | ||||
|  |  | |||
|  | @ -5,30 +5,29 @@ package integration | |||
| 
 | ||||
| import ( | ||||
| 	"net/http" | ||||
| 	"net/url" | ||||
| 	"testing" | ||||
| 
 | ||||
| 	pull_service "code.gitea.io/gitea/services/pull" | ||||
| 	"code.gitea.io/gitea/tests" | ||||
| 
 | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| ) | ||||
| 
 | ||||
| func TestListPullCommits(t *testing.T) { | ||||
| 	onGiteaRun(t, func(t *testing.T, u *url.URL) { | ||||
| 		session := loginUser(t, "user5") | ||||
| 		req := NewRequest(t, "GET", "/user2/repo1/pulls/3/commits/list") | ||||
| 		resp := session.MakeRequest(t, req, http.StatusOK) | ||||
| 	defer tests.PrepareTestEnv(t)() | ||||
| 	session := loginUser(t, "user5") | ||||
| 	req := NewRequest(t, "GET", "/user2/repo1/pulls/3/commits/list") | ||||
| 	resp := session.MakeRequest(t, req, http.StatusOK) | ||||
| 
 | ||||
| 		var pullCommitList struct { | ||||
| 			Commits             []pull_service.CommitInfo `json:"commits"` | ||||
| 			LastReviewCommitSha string                    `json:"last_review_commit_sha"` | ||||
| 		} | ||||
| 		DecodeJSON(t, resp, &pullCommitList) | ||||
| 	var pullCommitList struct { | ||||
| 		Commits             []pull_service.CommitInfo `json:"commits"` | ||||
| 		LastReviewCommitSha string                    `json:"last_review_commit_sha"` | ||||
| 	} | ||||
| 	DecodeJSON(t, resp, &pullCommitList) | ||||
| 
 | ||||
| 		if assert.Len(t, pullCommitList.Commits, 2) { | ||||
| 			assert.Equal(t, "5f22f7d0d95d614d25a5b68592adb345a4b5c7fd", pullCommitList.Commits[0].ID) | ||||
| 			assert.Equal(t, "4a357436d925b5c974181ff12a994538ddc5a269", pullCommitList.Commits[1].ID) | ||||
| 		} | ||||
| 		assert.Equal(t, "4a357436d925b5c974181ff12a994538ddc5a269", pullCommitList.LastReviewCommitSha) | ||||
| 	}) | ||||
| 	if assert.Len(t, pullCommitList.Commits, 2) { | ||||
| 		assert.Equal(t, "5f22f7d0d95d614d25a5b68592adb345a4b5c7fd", pullCommitList.Commits[0].ID) | ||||
| 		assert.Equal(t, "4a357436d925b5c974181ff12a994538ddc5a269", pullCommitList.Commits[1].ID) | ||||
| 	} | ||||
| 	assert.Equal(t, "4a357436d925b5c974181ff12a994538ddc5a269", pullCommitList.LastReviewCommitSha) | ||||
| } | ||||
|  |  | |||
|  | @ -18,7 +18,6 @@ import ( | |||
| 	repo_model "code.gitea.io/gitea/models/repo" | ||||
| 	"code.gitea.io/gitea/models/unittest" | ||||
| 	user_model "code.gitea.io/gitea/models/user" | ||||
| 	"code.gitea.io/gitea/modules/git" | ||||
| 	"code.gitea.io/gitea/modules/gitrepo" | ||||
| 	"code.gitea.io/gitea/modules/test" | ||||
| 	issue_service "code.gitea.io/gitea/services/issue" | ||||
|  | @ -283,32 +282,18 @@ func TestPullView_CodeOwner(t *testing.T) { | |||
| 	onGiteaRun(t, func(t *testing.T, u *url.URL) { | ||||
| 		user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) | ||||
| 
 | ||||
| 		// Create the repo. | ||||
| 		repo, err := repo_service.CreateRepositoryDirectly(db.DefaultContext, user2, user2, repo_service.CreateRepoOptions{ | ||||
| 			Name:             "test_codeowner", | ||||
| 			Readme:           "Default", | ||||
| 			AutoInit:         true, | ||||
| 			ObjectFormatName: git.Sha1ObjectFormat.Name(), | ||||
| 			DefaultBranch:    "master", | ||||
| 		}) | ||||
| 		require.NoError(t, err) | ||||
| 
 | ||||
| 		// add CODEOWNERS to default branch | ||||
| 		_, err = files_service.ChangeRepoFiles(db.DefaultContext, repo, user2, &files_service.ChangeRepoFilesOptions{ | ||||
| 			OldBranch: repo.DefaultBranch, | ||||
| 			Files: []*files_service.ChangeRepoFile{ | ||||
| 				{ | ||||
| 					Operation:     "create", | ||||
| 					TreePath:      "CODEOWNERS", | ||||
| 					ContentReader: strings.NewReader("README.md @user5\n"), | ||||
| 				}, | ||||
| 		repo, _, f := tests.CreateDeclarativeRepo(t, user2, "test_codeowner", nil, nil, []*files_service.ChangeRepoFile{ | ||||
| 			{ | ||||
| 				Operation:     "create", | ||||
| 				TreePath:      "CODEOWNERS", | ||||
| 				ContentReader: strings.NewReader("README.md @user5\n"), | ||||
| 			}, | ||||
| 		}) | ||||
| 		require.NoError(t, err) | ||||
| 		defer f() | ||||
| 
 | ||||
| 		t.Run("First Pull Request", func(t *testing.T) { | ||||
| 			// create a new branch to prepare for pull request | ||||
| 			_, err = files_service.ChangeRepoFiles(db.DefaultContext, repo, user2, &files_service.ChangeRepoFilesOptions{ | ||||
| 			_, err := files_service.ChangeRepoFiles(db.DefaultContext, repo, user2, &files_service.ChangeRepoFilesOptions{ | ||||
| 				NewBranch: "codeowner-basebranch", | ||||
| 				Files: []*files_service.ChangeRepoFile{ | ||||
| 					{ | ||||
|  | @ -328,7 +313,7 @@ func TestPullView_CodeOwner(t *testing.T) { | |||
| 			unittest.AssertExistsIf(t, true, &issues_model.Review{IssueID: pr.IssueID, Type: issues_model.ReviewTypeRequest, ReviewerID: 5}) | ||||
| 			require.NoError(t, pr.LoadIssue(db.DefaultContext)) | ||||
| 
 | ||||
| 			err := issue_service.ChangeTitle(db.DefaultContext, pr.Issue, user2, "[WIP] Test Pull Request") | ||||
| 			err = issue_service.ChangeTitle(db.DefaultContext, pr.Issue, user2, "[WIP] Test Pull Request") | ||||
| 			require.NoError(t, err) | ||||
| 			prUpdated1 := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: pr.ID}) | ||||
| 			require.NoError(t, prUpdated1.LoadIssue(db.DefaultContext)) | ||||
|  | @ -342,7 +327,7 @@ func TestPullView_CodeOwner(t *testing.T) { | |||
| 		}) | ||||
| 
 | ||||
| 		// change the default branch CODEOWNERS file to change README.md's codeowner | ||||
| 		_, err = files_service.ChangeRepoFiles(db.DefaultContext, repo, user2, &files_service.ChangeRepoFilesOptions{ | ||||
| 		_, err := files_service.ChangeRepoFiles(db.DefaultContext, repo, user2, &files_service.ChangeRepoFilesOptions{ | ||||
| 			Files: []*files_service.ChangeRepoFile{ | ||||
| 				{ | ||||
| 					Operation:     "update", | ||||
|  |  | |||
|  | @ -22,8 +22,6 @@ func TestRenameBranch(t *testing.T) { | |||
| } | ||||
| 
 | ||||
| func testRenameBranch(t *testing.T, u *url.URL) { | ||||
| 	defer tests.PrepareTestEnv(t)() | ||||
| 
 | ||||
| 	repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) | ||||
| 	unittest.AssertExistsAndLoadBean(t, &git_model.Branch{RepoID: repo.ID, Name: "master"}) | ||||
| 
 | ||||
|  |  | |||
|  | @ -5,33 +5,33 @@ package integration | |||
| 
 | ||||
| import ( | ||||
| 	"net/http" | ||||
| 	"net/url" | ||||
| 	"strings" | ||||
| 	"testing" | ||||
| 
 | ||||
| 	"code.gitea.io/gitea/tests" | ||||
| 
 | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| ) | ||||
| 
 | ||||
| // TestRepoCollaborators is a test for contents of Collaborators tab in the repo settings | ||||
| // It only covers a few elements and can be extended as needed | ||||
| func TestRepoCollaborators(t *testing.T) { | ||||
| 	onGiteaRun(t, func(t *testing.T, u *url.URL) { | ||||
| 		session := loginUser(t, "user2") | ||||
| 	defer tests.PrepareTestEnv(t)() | ||||
| 	session := loginUser(t, "user2") | ||||
| 
 | ||||
| 		// Visit Collaborators tab of repo settings | ||||
| 		response := session.MakeRequest(t, NewRequest(t, "GET", "/user2/repo1/settings/collaboration"), http.StatusOK) | ||||
| 		page := NewHTMLParser(t, response.Body).Find(".repo-setting-content") | ||||
| 	// Visit Collaborators tab of repo settings | ||||
| 	response := session.MakeRequest(t, NewRequest(t, "GET", "/user2/repo1/settings/collaboration"), http.StatusOK) | ||||
| 	page := NewHTMLParser(t, response.Body).Find(".repo-setting-content") | ||||
| 
 | ||||
| 		// Veirfy header | ||||
| 		assert.EqualValues(t, "Collaborators", strings.TrimSpace(page.Find("h4").Text())) | ||||
| 	// Veirfy header | ||||
| 	assert.EqualValues(t, "Collaborators", strings.TrimSpace(page.Find("h4").Text())) | ||||
| 
 | ||||
| 		// Veirfy button text | ||||
| 		page = page.Find("#repo-collab-form") | ||||
| 		assert.EqualValues(t, "Add collaborator", strings.TrimSpace(page.Find("button.primary").Text())) | ||||
| 	// Veirfy button text | ||||
| 	page = page.Find("#repo-collab-form") | ||||
| 	assert.EqualValues(t, "Add collaborator", strings.TrimSpace(page.Find("button.primary").Text())) | ||||
| 
 | ||||
| 		// Veirfy placeholder | ||||
| 		placeholder, exists := page.Find("#search-user-box input").Attr("placeholder") | ||||
| 		assert.True(t, exists) | ||||
| 		assert.EqualValues(t, "Search users...", placeholder) | ||||
| 	}) | ||||
| 	// Veirfy placeholder | ||||
| 	placeholder, exists := page.Find("#search-user-box input").Attr("placeholder") | ||||
| 	assert.True(t, exists) | ||||
| 	assert.EqualValues(t, "Search users...", placeholder) | ||||
| } | ||||
|  |  | |||
|  | @ -5,26 +5,26 @@ package integration | |||
| 
 | ||||
| import ( | ||||
| 	"net/http" | ||||
| 	"net/url" | ||||
| 	"testing" | ||||
| 
 | ||||
| 	"code.gitea.io/gitea/tests" | ||||
| 
 | ||||
| 	"github.com/PuerkitoBio/goquery" | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| ) | ||||
| 
 | ||||
| func TestRepoMigrationUI(t *testing.T) { | ||||
| 	onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) { | ||||
| 		sessionUser1 := loginUser(t, "user1") | ||||
| 		// Nothing is tested in plain Git migration form right now | ||||
| 		testRepoMigrationFormGitHub(t, sessionUser1) | ||||
| 		testRepoMigrationFormGitea(t, sessionUser1) | ||||
| 		testRepoMigrationFormGitLab(t, sessionUser1) | ||||
| 		testRepoMigrationFormGogs(t, sessionUser1) | ||||
| 		testRepoMigrationFormOneDev(t, sessionUser1) | ||||
| 		testRepoMigrationFormGitBucket(t, sessionUser1) | ||||
| 		testRepoMigrationFormCodebase(t, sessionUser1) | ||||
| 		testRepoMigrationFormForgejo(t, sessionUser1) | ||||
| 	}) | ||||
| 	defer tests.PrepareTestEnv(t)() | ||||
| 	sessionUser1 := loginUser(t, "user1") | ||||
| 	// Nothing is tested in plain Git migration form right now | ||||
| 	testRepoMigrationFormGitHub(t, sessionUser1) | ||||
| 	testRepoMigrationFormGitea(t, sessionUser1) | ||||
| 	testRepoMigrationFormGitLab(t, sessionUser1) | ||||
| 	testRepoMigrationFormGogs(t, sessionUser1) | ||||
| 	testRepoMigrationFormOneDev(t, sessionUser1) | ||||
| 	testRepoMigrationFormGitBucket(t, sessionUser1) | ||||
| 	testRepoMigrationFormCodebase(t, sessionUser1) | ||||
| 	testRepoMigrationFormForgejo(t, sessionUser1) | ||||
| } | ||||
| 
 | ||||
| func testRepoMigrationFormGitHub(t *testing.T, session *TestSession) { | ||||
|  |  | |||
|  | @ -11,8 +11,6 @@ import ( | |||
| 	"testing" | ||||
| 
 | ||||
| 	"code.gitea.io/gitea/models" | ||||
| 	"code.gitea.io/gitea/models/db" | ||||
| 	git_model "code.gitea.io/gitea/models/git" | ||||
| 	repo_model "code.gitea.io/gitea/models/repo" | ||||
| 	"code.gitea.io/gitea/models/unittest" | ||||
| 	user_model "code.gitea.io/gitea/models/user" | ||||
|  | @ -31,20 +29,6 @@ func TestTagViewWithoutRelease(t *testing.T) { | |||
| 	repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) | ||||
| 	owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) | ||||
| 
 | ||||
| 	defer func() { | ||||
| 		releases, err := db.Find[repo_model.Release](db.DefaultContext, repo_model.FindReleasesOptions{ | ||||
| 			IncludeTags: true, | ||||
| 			TagNames:    []string{"no-release"}, | ||||
| 			RepoID:      repo.ID, | ||||
| 		}) | ||||
| 		require.NoError(t, err) | ||||
| 
 | ||||
| 		for _, release := range releases { | ||||
| 			_, err = db.DeleteByID[repo_model.Release](db.DefaultContext, release.ID) | ||||
| 			require.NoError(t, err) | ||||
| 		} | ||||
| 	}() | ||||
| 
 | ||||
| 	err := release.CreateNewTag(git.DefaultContext, owner, repo, "master", "no-release", "release-less tag") | ||||
| 	require.NoError(t, err) | ||||
| 
 | ||||
|  | @ -70,27 +54,27 @@ func TestTagViewWithoutRelease(t *testing.T) { | |||
| } | ||||
| 
 | ||||
| func TestCreateNewTagProtected(t *testing.T) { | ||||
| 	defer tests.PrepareTestEnv(t)() | ||||
| 	onGiteaRun(t, func(t *testing.T, u *url.URL) { | ||||
| 		repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) | ||||
| 		owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) | ||||
| 
 | ||||
| 	repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) | ||||
| 	owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) | ||||
| 		t.Run("Code", func(t *testing.T) { | ||||
| 			defer tests.PrintCurrentTest(t)() | ||||
| 
 | ||||
| 	t.Run("Code", func(t *testing.T) { | ||||
| 		defer tests.PrintCurrentTest(t)() | ||||
| 			err := release.CreateNewTag(git.DefaultContext, owner, repo, "master", "t-first", "first tag") | ||||
| 			require.NoError(t, err) | ||||
| 
 | ||||
| 		err := release.CreateNewTag(git.DefaultContext, owner, repo, "master", "t-first", "first tag") | ||||
| 		require.NoError(t, err) | ||||
| 			err = release.CreateNewTag(git.DefaultContext, owner, repo, "master", "v-2", "second tag") | ||||
| 			require.Error(t, err) | ||||
| 			assert.True(t, models.IsErrProtectedTagName(err)) | ||||
| 
 | ||||
| 		err = release.CreateNewTag(git.DefaultContext, owner, repo, "master", "v-2", "second tag") | ||||
| 		require.Error(t, err) | ||||
| 		assert.True(t, models.IsErrProtectedTagName(err)) | ||||
| 			err = release.CreateNewTag(git.DefaultContext, owner, repo, "master", "v-1.1", "third tag") | ||||
| 			require.NoError(t, err) | ||||
| 		}) | ||||
| 
 | ||||
| 		err = release.CreateNewTag(git.DefaultContext, owner, repo, "master", "v-1.1", "third tag") | ||||
| 		require.NoError(t, err) | ||||
| 	}) | ||||
| 		t.Run("Git", func(t *testing.T) { | ||||
| 			defer tests.PrintCurrentTest(t)() | ||||
| 
 | ||||
| 	t.Run("Git", func(t *testing.T) { | ||||
| 		onGiteaRun(t, func(t *testing.T, u *url.URL) { | ||||
| 			httpContext := NewAPITestContext(t, owner.Name, repo.Name) | ||||
| 
 | ||||
| 			dstPath := t.TempDir() | ||||
|  | @ -107,10 +91,10 @@ func TestCreateNewTagProtected(t *testing.T) { | |||
| 			require.Error(t, err) | ||||
| 			assert.Contains(t, err.Error(), "Tag v-2 is protected") | ||||
| 		}) | ||||
| 	}) | ||||
| 
 | ||||
| 	t.Run("GitTagForce", func(t *testing.T) { | ||||
| 		onGiteaRun(t, func(t *testing.T, u *url.URL) { | ||||
| 		t.Run("GitTagForce", func(t *testing.T) { | ||||
| 			defer tests.PrintCurrentTest(t)() | ||||
| 
 | ||||
| 			httpContext := NewAPITestContext(t, owner.Name, repo.Name) | ||||
| 
 | ||||
| 			dstPath := t.TempDir() | ||||
|  | @ -120,13 +104,7 @@ func TestCreateNewTagProtected(t *testing.T) { | |||
| 
 | ||||
| 			doGitClone(dstPath, u)(t) | ||||
| 
 | ||||
| 			_, _, err := git.NewCommand(git.DefaultContext, "tag", "v-1.1", "-m", "force update", "--force").RunStdString(&git.RunOpts{Dir: dstPath}) | ||||
| 			require.NoError(t, err) | ||||
| 
 | ||||
| 			_, _, err = git.NewCommand(git.DefaultContext, "push", "--tags").RunStdString(&git.RunOpts{Dir: dstPath}) | ||||
| 			require.NoError(t, err) | ||||
| 
 | ||||
| 			_, _, err = git.NewCommand(git.DefaultContext, "tag", "v-1.1", "-m", "force update v2", "--force").RunStdString(&git.RunOpts{Dir: dstPath}) | ||||
| 			_, _, err := git.NewCommand(git.DefaultContext, "tag", "v-1.1", "-m", "force update v2", "--force").RunStdString(&git.RunOpts{Dir: dstPath}) | ||||
| 			require.NoError(t, err) | ||||
| 
 | ||||
| 			_, _, err = git.NewCommand(git.DefaultContext, "push", "--tags").RunStdString(&git.RunOpts{Dir: dstPath}) | ||||
|  | @ -142,27 +120,6 @@ func TestCreateNewTagProtected(t *testing.T) { | |||
| 			assert.Contains(t, tagsTab.Text(), "force update v2") | ||||
| 		}) | ||||
| 	}) | ||||
| 
 | ||||
| 	// Cleanup | ||||
| 	releases, err := db.Find[repo_model.Release](db.DefaultContext, repo_model.FindReleasesOptions{ | ||||
| 		IncludeTags: true, | ||||
| 		TagNames:    []string{"v-1", "v-1.1"}, | ||||
| 		RepoID:      repo.ID, | ||||
| 	}) | ||||
| 	require.NoError(t, err) | ||||
| 
 | ||||
| 	for _, release := range releases { | ||||
| 		_, err = db.DeleteByID[repo_model.Release](db.DefaultContext, release.ID) | ||||
| 		require.NoError(t, err) | ||||
| 	} | ||||
| 
 | ||||
| 	protectedTags, err := git_model.GetProtectedTags(db.DefaultContext, repo.ID) | ||||
| 	require.NoError(t, err) | ||||
| 
 | ||||
| 	for _, protectedTag := range protectedTags { | ||||
| 		err = git_model.DeleteProtectedTag(db.DefaultContext, protectedTag) | ||||
| 		require.NoError(t, err) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func TestSyncRepoTags(t *testing.T) { | ||||
|  | @ -200,18 +157,5 @@ func TestSyncRepoTags(t *testing.T) { | |||
| 			require.NoError(t, repo_module.SyncRepoTags(git.DefaultContext, repo.ID)) | ||||
| 			testTag(t) | ||||
| 		}) | ||||
| 
 | ||||
| 		// Cleanup | ||||
| 		releases, err := db.Find[repo_model.Release](db.DefaultContext, repo_model.FindReleasesOptions{ | ||||
| 			IncludeTags: true, | ||||
| 			TagNames:    []string{"v2"}, | ||||
| 			RepoID:      repo.ID, | ||||
| 		}) | ||||
| 		require.NoError(t, err) | ||||
| 
 | ||||
| 		for _, release := range releases { | ||||
| 			_, err = db.DeleteByID[repo_model.Release](db.DefaultContext, release.ID) | ||||
| 			require.NoError(t, err) | ||||
| 		} | ||||
| 	}) | ||||
| } | ||||
|  |  | |||
|  | @ -62,8 +62,9 @@ func createRepoAndGetContext(t *testing.T, files []string, deleteMdReadme bool) | |||
| } | ||||
| 
 | ||||
| func TestRepoView_FindReadme(t *testing.T) { | ||||
| 	t.Run("PrioOneLocalizedMdReadme", func(t *testing.T) { | ||||
| 		onGiteaRun(t, func(t *testing.T, u *url.URL) { | ||||
| 	onGiteaRun(t, func(t *testing.T, u *url.URL) { | ||||
| 		t.Run("PrioOneLocalizedMdReadme", func(t *testing.T) { | ||||
| 			defer tests.PrintCurrentTest(t)() | ||||
| 			ctx, f := createRepoAndGetContext(t, []string{"README.en.md", "README.en.org", "README.org", "README.txt", "README.tex"}, false) | ||||
| 			defer f() | ||||
| 
 | ||||
|  | @ -73,9 +74,8 @@ func TestRepoView_FindReadme(t *testing.T) { | |||
| 
 | ||||
| 			assert.Equal(t, "README.en.md", file.Name()) | ||||
| 		}) | ||||
| 	}) | ||||
| 	t.Run("PrioTwoMdReadme", func(t *testing.T) { | ||||
| 		onGiteaRun(t, func(t *testing.T, u *url.URL) { | ||||
| 		t.Run("PrioTwoMdReadme", func(t *testing.T) { | ||||
| 			defer tests.PrintCurrentTest(t)() | ||||
| 			ctx, f := createRepoAndGetContext(t, []string{"README.en.org", "README.org", "README.txt", "README.tex"}, false) | ||||
| 			defer f() | ||||
| 
 | ||||
|  | @ -85,9 +85,8 @@ func TestRepoView_FindReadme(t *testing.T) { | |||
| 
 | ||||
| 			assert.Equal(t, "README.md", file.Name()) | ||||
| 		}) | ||||
| 	}) | ||||
| 	t.Run("PrioThreeLocalizedOrgReadme", func(t *testing.T) { | ||||
| 		onGiteaRun(t, func(t *testing.T, u *url.URL) { | ||||
| 		t.Run("PrioThreeLocalizedOrgReadme", func(t *testing.T) { | ||||
| 			defer tests.PrintCurrentTest(t)() | ||||
| 			ctx, f := createRepoAndGetContext(t, []string{"README.en.org", "README.org", "README.txt", "README.tex"}, true) | ||||
| 			defer f() | ||||
| 
 | ||||
|  | @ -97,9 +96,8 @@ func TestRepoView_FindReadme(t *testing.T) { | |||
| 
 | ||||
| 			assert.Equal(t, "README.en.org", file.Name()) | ||||
| 		}) | ||||
| 	}) | ||||
| 	t.Run("PrioFourOrgReadme", func(t *testing.T) { | ||||
| 		onGiteaRun(t, func(t *testing.T, u *url.URL) { | ||||
| 		t.Run("PrioFourOrgReadme", func(t *testing.T) { | ||||
| 			defer tests.PrintCurrentTest(t)() | ||||
| 			ctx, f := createRepoAndGetContext(t, []string{"README.org", "README.txt", "README.tex"}, true) | ||||
| 			defer f() | ||||
| 
 | ||||
|  | @ -109,9 +107,8 @@ func TestRepoView_FindReadme(t *testing.T) { | |||
| 
 | ||||
| 			assert.Equal(t, "README.org", file.Name()) | ||||
| 		}) | ||||
| 	}) | ||||
| 	t.Run("PrioFiveTxtReadme", func(t *testing.T) { | ||||
| 		onGiteaRun(t, func(t *testing.T, u *url.URL) { | ||||
| 		t.Run("PrioFiveTxtReadme", func(t *testing.T) { | ||||
| 			defer tests.PrintCurrentTest(t)() | ||||
| 			ctx, f := createRepoAndGetContext(t, []string{"README.txt", "README", "README.tex"}, true) | ||||
| 			defer f() | ||||
| 
 | ||||
|  | @ -121,9 +118,8 @@ func TestRepoView_FindReadme(t *testing.T) { | |||
| 
 | ||||
| 			assert.Equal(t, "README.txt", file.Name()) | ||||
| 		}) | ||||
| 	}) | ||||
| 	t.Run("PrioSixWithoutExtensionReadme", func(t *testing.T) { | ||||
| 		onGiteaRun(t, func(t *testing.T, u *url.URL) { | ||||
| 		t.Run("PrioSixWithoutExtensionReadme", func(t *testing.T) { | ||||
| 			defer tests.PrintCurrentTest(t)() | ||||
| 			ctx, f := createRepoAndGetContext(t, []string{"README", "README.tex"}, true) | ||||
| 			defer f() | ||||
| 
 | ||||
|  | @ -133,9 +129,8 @@ func TestRepoView_FindReadme(t *testing.T) { | |||
| 
 | ||||
| 			assert.Equal(t, "README", file.Name()) | ||||
| 		}) | ||||
| 	}) | ||||
| 	t.Run("PrioSevenAnyReadme", func(t *testing.T) { | ||||
| 		onGiteaRun(t, func(t *testing.T, u *url.URL) { | ||||
| 		t.Run("PrioSevenAnyReadme", func(t *testing.T) { | ||||
| 			defer tests.PrintCurrentTest(t)() | ||||
| 			ctx, f := createRepoAndGetContext(t, []string{"README.tex"}, true) | ||||
| 			defer f() | ||||
| 
 | ||||
|  | @ -145,9 +140,8 @@ func TestRepoView_FindReadme(t *testing.T) { | |||
| 
 | ||||
| 			assert.Equal(t, "README.tex", file.Name()) | ||||
| 		}) | ||||
| 	}) | ||||
| 	t.Run("DoNotPickReadmeIfNonPresent", func(t *testing.T) { | ||||
| 		onGiteaRun(t, func(t *testing.T, u *url.URL) { | ||||
| 		t.Run("DoNotPickReadmeIfNonPresent", func(t *testing.T) { | ||||
| 			defer tests.PrintCurrentTest(t)() | ||||
| 			ctx, f := createRepoAndGetContext(t, []string{}, true) | ||||
| 			defer f() | ||||
| 
 | ||||
|  |  | |||
|  | @ -18,6 +18,7 @@ import ( | |||
| 	"code.gitea.io/gitea/modules/setting" | ||||
| 	api "code.gitea.io/gitea/modules/structs" | ||||
| 	files_service "code.gitea.io/gitea/services/repository/files" | ||||
| 	"code.gitea.io/gitea/tests" | ||||
| 
 | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| 	"github.com/stretchr/testify/require" | ||||
|  | @ -63,8 +64,8 @@ func getDeleteRepoFilesOptions(repo *repo_model.Repository) *files_service.Chang | |||
| 		Files: []*files_service.ChangeRepoFile{ | ||||
| 			{ | ||||
| 				Operation: "delete", | ||||
| 				TreePath:  "README.md", | ||||
| 				SHA:       "4b4851ad51df6a7d9f25c979345979eaeb5b349f", | ||||
| 				TreePath:  "README_new.md", | ||||
| 				SHA:       "dbf8d00e022e05b7e5cf7e535de857de57925647", | ||||
| 			}, | ||||
| 		}, | ||||
| 		LastCommitID: "", | ||||
|  | @ -244,184 +245,142 @@ func getExpectedFileResponseForRepofilesUpdate(commitID, filename, lastCommitSHA | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| func TestChangeRepoFilesForCreate(t *testing.T) { | ||||
| 	// setup | ||||
| func TestChangeRepoFiles(t *testing.T) { | ||||
| 	onGiteaRun(t, func(t *testing.T, u *url.URL) { | ||||
| 		doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) | ||||
| 		repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) | ||||
| 		opts := getCreateRepoFilesOptions(repo) | ||||
| 
 | ||||
| 		// test | ||||
| 		filesResponse, err := files_service.ChangeRepoFiles(git.DefaultContext, repo, doer, opts) | ||||
| 
 | ||||
| 		// asserts | ||||
| 		gitRepo, err := gitrepo.OpenRepository(git.DefaultContext, repo) | ||||
| 		require.NoError(t, err) | ||||
| 		gitRepo, _ := gitrepo.OpenRepository(git.DefaultContext, repo) | ||||
| 		defer gitRepo.Close() | ||||
| 
 | ||||
| 		commitID, _ := gitRepo.GetBranchCommitID(opts.NewBranch) | ||||
| 		lastCommit, _ := gitRepo.GetCommitByPath("new/file.txt") | ||||
| 		expectedFileResponse := getExpectedFileResponseForRepofilesCreate(commitID, lastCommit.ID.String()) | ||||
| 		assert.NotNil(t, expectedFileResponse) | ||||
| 		if expectedFileResponse != nil { | ||||
| 		t.Run("Create", func(t *testing.T) { | ||||
| 			defer tests.PrintCurrentTest(t)() | ||||
| 			opts := getCreateRepoFilesOptions(repo) | ||||
| 			filesResponse, err := files_service.ChangeRepoFiles(git.DefaultContext, repo, doer, opts) | ||||
| 			require.NoError(t, err) | ||||
| 
 | ||||
| 			commitID, err := gitRepo.GetBranchCommitID(opts.NewBranch) | ||||
| 			require.NoError(t, err) | ||||
| 			lastCommit, err := gitRepo.GetCommitByPath("new/file.txt") | ||||
| 			require.NoError(t, err) | ||||
| 			expectedFileResponse := getExpectedFileResponseForRepofilesCreate(commitID, lastCommit.ID.String()) | ||||
| 			assert.EqualValues(t, expectedFileResponse.Content, filesResponse.Files[0]) | ||||
| 			assert.EqualValues(t, expectedFileResponse.Commit.SHA, filesResponse.Commit.SHA) | ||||
| 			assert.EqualValues(t, expectedFileResponse.Commit.HTMLURL, filesResponse.Commit.HTMLURL) | ||||
| 			assert.EqualValues(t, expectedFileResponse.Commit.Author.Email, filesResponse.Commit.Author.Email) | ||||
| 			assert.EqualValues(t, expectedFileResponse.Commit.Author.Name, filesResponse.Commit.Author.Name) | ||||
| 		} | ||||
| 	}) | ||||
| } | ||||
| 		}) | ||||
| 
 | ||||
| func TestChangeRepoFilesForUpdate(t *testing.T) { | ||||
| 	// setup | ||||
| 	onGiteaRun(t, func(t *testing.T, u *url.URL) { | ||||
| 		doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) | ||||
| 		repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) | ||||
| 		opts := getUpdateRepoFilesOptions(repo) | ||||
| 		t.Run("Update", func(t *testing.T) { | ||||
| 			defer tests.PrintCurrentTest(t)() | ||||
| 			opts := getUpdateRepoFilesOptions(repo) | ||||
| 			filesResponse, err := files_service.ChangeRepoFiles(git.DefaultContext, repo, doer, opts) | ||||
| 			require.NoError(t, err) | ||||
| 
 | ||||
| 		// test | ||||
| 		filesResponse, err := files_service.ChangeRepoFiles(git.DefaultContext, repo, doer, opts) | ||||
| 			commit, err := gitRepo.GetBranchCommit(opts.NewBranch) | ||||
| 			require.NoError(t, err) | ||||
| 			lastCommit, err := commit.GetCommitByPath(opts.Files[0].TreePath) | ||||
| 			require.NoError(t, err) | ||||
| 			expectedFileResponse := getExpectedFileResponseForRepofilesUpdate(commit.ID.String(), opts.Files[0].TreePath, lastCommit.ID.String()) | ||||
| 			assert.EqualValues(t, expectedFileResponse.Content, filesResponse.Files[0]) | ||||
| 			assert.EqualValues(t, expectedFileResponse.Commit.SHA, filesResponse.Commit.SHA) | ||||
| 			assert.EqualValues(t, expectedFileResponse.Commit.HTMLURL, filesResponse.Commit.HTMLURL) | ||||
| 			assert.EqualValues(t, expectedFileResponse.Commit.Author.Email, filesResponse.Commit.Author.Email) | ||||
| 			assert.EqualValues(t, expectedFileResponse.Commit.Author.Name, filesResponse.Commit.Author.Name) | ||||
| 		}) | ||||
| 
 | ||||
| 		// asserts | ||||
| 		require.NoError(t, err) | ||||
| 		gitRepo, _ := gitrepo.OpenRepository(git.DefaultContext, repo) | ||||
| 		defer gitRepo.Close() | ||||
| 		t.Run("Update and move", func(t *testing.T) { | ||||
| 			defer tests.PrintCurrentTest(t)() | ||||
| 			opts := getUpdateRepoFilesOptions(repo) | ||||
| 			opts.Files[0].SHA = "dbf8d00e022e05b7e5cf7e535de857de57925647" | ||||
| 			opts.Files[0].FromTreePath = "README.md" | ||||
| 			opts.Files[0].TreePath = "README_new.md" // new file name, README_new.md | ||||
| 			filesResponse, err := files_service.ChangeRepoFiles(git.DefaultContext, repo, doer, opts) | ||||
| 			require.NoError(t, err) | ||||
| 
 | ||||
| 		commit, _ := gitRepo.GetBranchCommit(opts.NewBranch) | ||||
| 		lastCommit, _ := commit.GetCommitByPath(opts.Files[0].TreePath) | ||||
| 		expectedFileResponse := getExpectedFileResponseForRepofilesUpdate(commit.ID.String(), opts.Files[0].TreePath, lastCommit.ID.String()) | ||||
| 		assert.EqualValues(t, expectedFileResponse.Content, filesResponse.Files[0]) | ||||
| 		assert.EqualValues(t, expectedFileResponse.Commit.SHA, filesResponse.Commit.SHA) | ||||
| 		assert.EqualValues(t, expectedFileResponse.Commit.HTMLURL, filesResponse.Commit.HTMLURL) | ||||
| 		assert.EqualValues(t, expectedFileResponse.Commit.Author.Email, filesResponse.Commit.Author.Email) | ||||
| 		assert.EqualValues(t, expectedFileResponse.Commit.Author.Name, filesResponse.Commit.Author.Name) | ||||
| 	}) | ||||
| } | ||||
| 			commit, err := gitRepo.GetBranchCommit(opts.NewBranch) | ||||
| 			require.NoError(t, err) | ||||
| 			lastCommit, err := commit.GetCommitByPath(opts.Files[0].TreePath) | ||||
| 			require.NoError(t, err) | ||||
| 			expectedFileResponse := getExpectedFileResponseForRepofilesUpdate(commit.ID.String(), opts.Files[0].TreePath, lastCommit.ID.String()) | ||||
| 
 | ||||
| func TestChangeRepoFilesForUpdateWithFileMove(t *testing.T) { | ||||
| 	// setup | ||||
| 	onGiteaRun(t, func(t *testing.T, u *url.URL) { | ||||
| 		doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) | ||||
| 		repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) | ||||
| 		opts := getUpdateRepoFilesOptions(repo) | ||||
| 		opts.Files[0].FromTreePath = "README.md" | ||||
| 		opts.Files[0].TreePath = "README_new.md" // new file name, README_new.md | ||||
| 			// assert that the old file no longer exists in the last commit of the branch | ||||
| 			fromEntry, err := commit.GetTreeEntryByPath(opts.Files[0].FromTreePath) | ||||
| 			switch err.(type) { | ||||
| 			case git.ErrNotExist: | ||||
| 				// correct, continue | ||||
| 			default: | ||||
| 				t.Fatalf("expected git.ErrNotExist, got:%v", err) | ||||
| 			} | ||||
| 			toEntry, err := commit.GetTreeEntryByPath(opts.Files[0].TreePath) | ||||
| 			require.NoError(t, err) | ||||
| 			assert.Nil(t, fromEntry)  // Should no longer exist here | ||||
| 			assert.NotNil(t, toEntry) // Should exist here | ||||
| 			// assert SHA has remained the same but paths use the new file name | ||||
| 			assert.EqualValues(t, expectedFileResponse.Content.SHA, filesResponse.Files[0].SHA) | ||||
| 			assert.EqualValues(t, expectedFileResponse.Content.Name, filesResponse.Files[0].Name) | ||||
| 			assert.EqualValues(t, expectedFileResponse.Content.Path, filesResponse.Files[0].Path) | ||||
| 			assert.EqualValues(t, expectedFileResponse.Content.URL, filesResponse.Files[0].URL) | ||||
| 			assert.EqualValues(t, expectedFileResponse.Commit.SHA, filesResponse.Commit.SHA) | ||||
| 			assert.EqualValues(t, expectedFileResponse.Commit.HTMLURL, filesResponse.Commit.HTMLURL) | ||||
| 		}) | ||||
| 
 | ||||
| 		// test | ||||
| 		filesResponse, err := files_service.ChangeRepoFiles(git.DefaultContext, repo, doer, opts) | ||||
| 		t.Run("Change without branch names", func(t *testing.T) { | ||||
| 			defer tests.PrintCurrentTest(t)() | ||||
| 			opts := getUpdateRepoFilesOptions(repo) | ||||
| 			opts.OldBranch = "" | ||||
| 			opts.NewBranch = "" | ||||
| 			opts.Files[0].TreePath = "README_new.md" | ||||
| 			opts.Files[0].SHA = "dbf8d00e022e05b7e5cf7e535de857de57925647" | ||||
| 
 | ||||
| 		// asserts | ||||
| 		require.NoError(t, err) | ||||
| 		gitRepo, _ := gitrepo.OpenRepository(git.DefaultContext, repo) | ||||
| 		defer gitRepo.Close() | ||||
| 			filesResponse, err := files_service.ChangeRepoFiles(git.DefaultContext, repo, doer, opts) | ||||
| 			require.NoError(t, err) | ||||
| 
 | ||||
| 		commit, _ := gitRepo.GetBranchCommit(opts.NewBranch) | ||||
| 		lastCommit, _ := commit.GetCommitByPath(opts.Files[0].TreePath) | ||||
| 		expectedFileResponse := getExpectedFileResponseForRepofilesUpdate(commit.ID.String(), opts.Files[0].TreePath, lastCommit.ID.String()) | ||||
| 		// assert that the old file no longer exists in the last commit of the branch | ||||
| 		fromEntry, err := commit.GetTreeEntryByPath(opts.Files[0].FromTreePath) | ||||
| 		switch err.(type) { | ||||
| 		case git.ErrNotExist: | ||||
| 			// correct, continue | ||||
| 		default: | ||||
| 			t.Fatalf("expected git.ErrNotExist, got:%v", err) | ||||
| 		} | ||||
| 		toEntry, err := commit.GetTreeEntryByPath(opts.Files[0].TreePath) | ||||
| 		require.NoError(t, err) | ||||
| 		assert.Nil(t, fromEntry)  // Should no longer exist here | ||||
| 		assert.NotNil(t, toEntry) // Should exist here | ||||
| 		// assert SHA has remained the same but paths use the new file name | ||||
| 		assert.EqualValues(t, expectedFileResponse.Content.SHA, filesResponse.Files[0].SHA) | ||||
| 		assert.EqualValues(t, expectedFileResponse.Content.Name, filesResponse.Files[0].Name) | ||||
| 		assert.EqualValues(t, expectedFileResponse.Content.Path, filesResponse.Files[0].Path) | ||||
| 		assert.EqualValues(t, expectedFileResponse.Content.URL, filesResponse.Files[0].URL) | ||||
| 		assert.EqualValues(t, expectedFileResponse.Commit.SHA, filesResponse.Commit.SHA) | ||||
| 		assert.EqualValues(t, expectedFileResponse.Commit.HTMLURL, filesResponse.Commit.HTMLURL) | ||||
| 	}) | ||||
| } | ||||
| 			commit, _ := gitRepo.GetBranchCommit(repo.DefaultBranch) | ||||
| 			lastCommit, _ := commit.GetCommitByPath(opts.Files[0].TreePath) | ||||
| 			expectedFileResponse := getExpectedFileResponseForRepofilesUpdate(commit.ID.String(), opts.Files[0].TreePath, lastCommit.ID.String()) | ||||
| 			assert.EqualValues(t, expectedFileResponse.Content, filesResponse.Files[0]) | ||||
| 		}) | ||||
| 
 | ||||
| // Test opts with branch names removed, should get same results as above test | ||||
| func TestChangeRepoFilesWithoutBranchNames(t *testing.T) { | ||||
| 	// setup | ||||
| 	onGiteaRun(t, func(t *testing.T, u *url.URL) { | ||||
| 		doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) | ||||
| 		repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) | ||||
| 		opts := getUpdateRepoFilesOptions(repo) | ||||
| 		opts.OldBranch = "" | ||||
| 		opts.NewBranch = "" | ||||
| 		t.Run("Delete files", func(t *testing.T) { | ||||
| 			defer tests.PrintCurrentTest(t)() | ||||
| 			opts := getDeleteRepoFilesOptions(repo) | ||||
| 
 | ||||
| 		// test | ||||
| 		filesResponse, err := files_service.ChangeRepoFiles(git.DefaultContext, repo, doer, opts) | ||||
| 			filesResponse, err := files_service.ChangeRepoFiles(git.DefaultContext, repo, doer, opts) | ||||
| 			require.NoError(t, err) | ||||
| 			expectedFileResponse := getExpectedFileResponseForRepofilesDelete() | ||||
| 			assert.NotNil(t, filesResponse) | ||||
| 			assert.Nil(t, filesResponse.Files[0]) | ||||
| 			assert.EqualValues(t, expectedFileResponse.Commit.Message, filesResponse.Commit.Message) | ||||
| 			assert.EqualValues(t, expectedFileResponse.Commit.Author.Identity, filesResponse.Commit.Author.Identity) | ||||
| 			assert.EqualValues(t, expectedFileResponse.Commit.Committer.Identity, filesResponse.Commit.Committer.Identity) | ||||
| 			assert.EqualValues(t, expectedFileResponse.Verification, filesResponse.Verification) | ||||
| 
 | ||||
| 		// asserts | ||||
| 		require.NoError(t, err) | ||||
| 		gitRepo, _ := gitrepo.OpenRepository(git.DefaultContext, repo) | ||||
| 		defer gitRepo.Close() | ||||
| 			filesResponse, err = files_service.ChangeRepoFiles(git.DefaultContext, repo, doer, opts) | ||||
| 			assert.Nil(t, filesResponse) | ||||
| 			expectedError := "repository file does not exist [path: " + opts.Files[0].TreePath + "]" | ||||
| 			assert.EqualError(t, err, expectedError) | ||||
| 		}) | ||||
| 
 | ||||
| 		commit, _ := gitRepo.GetBranchCommit(repo.DefaultBranch) | ||||
| 		lastCommit, _ := commit.GetCommitByPath(opts.Files[0].TreePath) | ||||
| 		expectedFileResponse := getExpectedFileResponseForRepofilesUpdate(commit.ID.String(), opts.Files[0].TreePath, lastCommit.ID.String()) | ||||
| 		assert.EqualValues(t, expectedFileResponse.Content, filesResponse.Files[0]) | ||||
| 	}) | ||||
| } | ||||
| 		t.Run("Delete without branch name", func(t *testing.T) { | ||||
| 			defer tests.PrintCurrentTest(t)() | ||||
| 			opts := getDeleteRepoFilesOptions(repo) | ||||
| 			opts.OldBranch = "" | ||||
| 			opts.NewBranch = "" | ||||
| 			opts.Files[0].SHA = "103ff9234cefeee5ec5361d22b49fbb04d385885" | ||||
| 			opts.Files[0].TreePath = "new/file.txt" | ||||
| 
 | ||||
| func TestChangeRepoFilesForDelete(t *testing.T) { | ||||
| 	onGiteaRun(t, testDeleteRepoFiles) | ||||
| } | ||||
| 
 | ||||
| func testDeleteRepoFiles(t *testing.T, u *url.URL) { | ||||
| 	// setup | ||||
| 	unittest.PrepareTestEnv(t) | ||||
| 	doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) | ||||
| 	repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) | ||||
| 	opts := getDeleteRepoFilesOptions(repo) | ||||
| 
 | ||||
| 	t.Run("Delete README.md file", func(t *testing.T) { | ||||
| 		filesResponse, err := files_service.ChangeRepoFiles(git.DefaultContext, repo, doer, opts) | ||||
| 		require.NoError(t, err) | ||||
| 		expectedFileResponse := getExpectedFileResponseForRepofilesDelete() | ||||
| 		assert.NotNil(t, filesResponse) | ||||
| 		assert.Nil(t, filesResponse.Files[0]) | ||||
| 		assert.EqualValues(t, expectedFileResponse.Commit.Message, filesResponse.Commit.Message) | ||||
| 		assert.EqualValues(t, expectedFileResponse.Commit.Author.Identity, filesResponse.Commit.Author.Identity) | ||||
| 		assert.EqualValues(t, expectedFileResponse.Commit.Committer.Identity, filesResponse.Commit.Committer.Identity) | ||||
| 		assert.EqualValues(t, expectedFileResponse.Verification, filesResponse.Verification) | ||||
| 	}) | ||||
| 
 | ||||
| 	t.Run("Verify README.md has been deleted", func(t *testing.T) { | ||||
| 		filesResponse, err := files_service.ChangeRepoFiles(git.DefaultContext, repo, doer, opts) | ||||
| 		assert.Nil(t, filesResponse) | ||||
| 		expectedError := "repository file does not exist [path: " + opts.Files[0].TreePath + "]" | ||||
| 		assert.EqualError(t, err, expectedError) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| // Test opts with branch names removed, same results | ||||
| func TestChangeRepoFilesForDeleteWithoutBranchNames(t *testing.T) { | ||||
| 	onGiteaRun(t, testDeleteRepoFilesWithoutBranchNames) | ||||
| } | ||||
| 
 | ||||
| func testDeleteRepoFilesWithoutBranchNames(t *testing.T, u *url.URL) { | ||||
| 	// setup | ||||
| 	unittest.PrepareTestEnv(t) | ||||
| 	doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) | ||||
| 	repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) | ||||
| 
 | ||||
| 	opts := getDeleteRepoFilesOptions(repo) | ||||
| 	opts.OldBranch = "" | ||||
| 	opts.NewBranch = "" | ||||
| 
 | ||||
| 	t.Run("Delete README.md without Branch Name", func(t *testing.T) { | ||||
| 		filesResponse, err := files_service.ChangeRepoFiles(git.DefaultContext, repo, doer, opts) | ||||
| 		require.NoError(t, err) | ||||
| 		expectedFileResponse := getExpectedFileResponseForRepofilesDelete() | ||||
| 		assert.NotNil(t, filesResponse) | ||||
| 		assert.Nil(t, filesResponse.Files[0]) | ||||
| 		assert.EqualValues(t, expectedFileResponse.Commit.Message, filesResponse.Commit.Message) | ||||
| 		assert.EqualValues(t, expectedFileResponse.Commit.Author.Identity, filesResponse.Commit.Author.Identity) | ||||
| 		assert.EqualValues(t, expectedFileResponse.Commit.Committer.Identity, filesResponse.Commit.Committer.Identity) | ||||
| 		assert.EqualValues(t, expectedFileResponse.Verification, filesResponse.Verification) | ||||
| 			filesResponse, err := files_service.ChangeRepoFiles(git.DefaultContext, repo, doer, opts) | ||||
| 			require.NoError(t, err) | ||||
| 			expectedFileResponse := getExpectedFileResponseForRepofilesDelete() | ||||
| 			assert.NotNil(t, filesResponse) | ||||
| 			assert.Nil(t, filesResponse.Files[0]) | ||||
| 			assert.EqualValues(t, expectedFileResponse.Commit.Message, filesResponse.Commit.Message) | ||||
| 			assert.EqualValues(t, expectedFileResponse.Commit.Author.Identity, filesResponse.Commit.Author.Identity) | ||||
| 			assert.EqualValues(t, expectedFileResponse.Commit.Committer.Identity, filesResponse.Commit.Committer.Identity) | ||||
| 			assert.EqualValues(t, expectedFileResponse.Verification, filesResponse.Verification) | ||||
| 		}) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -10,85 +10,78 @@ import ( | |||
| 	"io" | ||||
| 	"mime/multipart" | ||||
| 	"net/http" | ||||
| 	"net/url" | ||||
| 	"testing" | ||||
| 
 | ||||
| 	"code.gitea.io/gitea/models/db" | ||||
| 	"code.gitea.io/gitea/models/unittest" | ||||
| 	user_model "code.gitea.io/gitea/models/user" | ||||
| 	"code.gitea.io/gitea/modules/avatar" | ||||
| 	"code.gitea.io/gitea/tests" | ||||
| 
 | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| 	"github.com/stretchr/testify/require" | ||||
| ) | ||||
| 
 | ||||
| func TestUserAvatar(t *testing.T) { | ||||
| 	onGiteaRun(t, func(t *testing.T, u *url.URL) { | ||||
| 		user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) // owner of the repo3, is an org | ||||
| 	defer tests.PrepareTestEnv(t)() | ||||
| 	user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) // owner of the repo3, is an org | ||||
| 
 | ||||
| 		seed := user2.Email | ||||
| 		if len(seed) == 0 { | ||||
| 			seed = user2.Name | ||||
| 		} | ||||
| 	seed := user2.Email | ||||
| 	if len(seed) == 0 { | ||||
| 		seed = user2.Name | ||||
| 	} | ||||
| 
 | ||||
| 		img, err := avatar.RandomImage([]byte(seed)) | ||||
| 		if err != nil { | ||||
| 			require.NoError(t, err) | ||||
| 			return | ||||
| 		} | ||||
| 	img, err := avatar.RandomImage([]byte(seed)) | ||||
| 	if err != nil { | ||||
| 		require.NoError(t, err) | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 		session := loginUser(t, "user2") | ||||
| 		csrf := GetCSRF(t, session, "/user/settings") | ||||
| 	session := loginUser(t, "user2") | ||||
| 	csrf := GetCSRF(t, session, "/user/settings") | ||||
| 
 | ||||
| 		imgData := &bytes.Buffer{} | ||||
| 	imgData := &bytes.Buffer{} | ||||
| 
 | ||||
| 		body := &bytes.Buffer{} | ||||
| 	body := &bytes.Buffer{} | ||||
| 
 | ||||
| 		// Setup multi-part | ||||
| 		writer := multipart.NewWriter(body) | ||||
| 		writer.WriteField("source", "local") | ||||
| 		part, err := writer.CreateFormFile("avatar", "avatar-for-testuseravatar.png") | ||||
| 		if err != nil { | ||||
| 			require.NoError(t, err) | ||||
| 			return | ||||
| 		} | ||||
| 	// Setup multi-part | ||||
| 	writer := multipart.NewWriter(body) | ||||
| 	writer.WriteField("source", "local") | ||||
| 	part, err := writer.CreateFormFile("avatar", "avatar-for-testuseravatar.png") | ||||
| 	if err != nil { | ||||
| 		require.NoError(t, err) | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 		if err := png.Encode(imgData, img); err != nil { | ||||
| 			require.NoError(t, err) | ||||
| 			return | ||||
| 		} | ||||
| 	if err := png.Encode(imgData, img); err != nil { | ||||
| 		require.NoError(t, err) | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 		if _, err := io.Copy(part, imgData); err != nil { | ||||
| 			require.NoError(t, err) | ||||
| 			return | ||||
| 		} | ||||
| 	if _, err := io.Copy(part, imgData); err != nil { | ||||
| 		require.NoError(t, err) | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 		if err := writer.Close(); err != nil { | ||||
| 			require.NoError(t, err) | ||||
| 			return | ||||
| 		} | ||||
| 	if err := writer.Close(); err != nil { | ||||
| 		require.NoError(t, err) | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 		req := NewRequestWithBody(t, "POST", "/user/settings/avatar", body) | ||||
| 		req.Header.Add("X-Csrf-Token", csrf) | ||||
| 		req.Header.Add("Content-Type", writer.FormDataContentType()) | ||||
| 	req := NewRequestWithBody(t, "POST", "/user/settings/avatar", body) | ||||
| 	req.Header.Add("X-Csrf-Token", csrf) | ||||
| 	req.Header.Add("Content-Type", writer.FormDataContentType()) | ||||
| 
 | ||||
| 		session.MakeRequest(t, req, http.StatusSeeOther) | ||||
| 	session.MakeRequest(t, req, http.StatusSeeOther) | ||||
| 
 | ||||
| 		user2 = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) // owner of the repo3, is an org | ||||
| 	user2 = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) // owner of the repo3, is an org | ||||
| 
 | ||||
| 		req = NewRequest(t, "GET", user2.AvatarLinkWithSize(db.DefaultContext, 0)) | ||||
| 		_ = session.MakeRequest(t, req, http.StatusOK) | ||||
| 	req = NewRequest(t, "GET", user2.AvatarLinkWithSize(db.DefaultContext, 0)) | ||||
| 	_ = session.MakeRequest(t, req, http.StatusOK) | ||||
| 
 | ||||
| 		testGetAvatarRedirect(t, user2) | ||||
| 	req = NewRequestf(t, "GET", "/%s.png", user2.Name) | ||||
| 	resp := MakeRequest(t, req, http.StatusSeeOther) | ||||
| 	assert.EqualValues(t, fmt.Sprintf("/avatars/%s", user2.Avatar), resp.Header().Get("location")) | ||||
| 
 | ||||
| 		// Can't test if the response matches because the image is re-generated on upload but checking that this at least doesn't give a 404 should be enough. | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| func testGetAvatarRedirect(t *testing.T, user *user_model.User) { | ||||
| 	t.Run(fmt.Sprintf("getAvatarRedirect_%s", user.Name), func(t *testing.T) { | ||||
| 		req := NewRequestf(t, "GET", "/%s.png", user.Name) | ||||
| 		resp := MakeRequest(t, req, http.StatusSeeOther) | ||||
| 		assert.EqualValues(t, fmt.Sprintf("/avatars/%s", user.Avatar), resp.Header().Get("location")) | ||||
| 	}) | ||||
| 	// Can't test if the response matches because the image is re-generated on upload but checking that this at least doesn't give a 404 should be enough. | ||||
| } | ||||
|  |  | |||
|  | @ -5,11 +5,11 @@ package integration | |||
| 
 | ||||
| import ( | ||||
| 	"net/http" | ||||
| 	"net/url" | ||||
| 	"strconv" | ||||
| 	"testing" | ||||
| 
 | ||||
| 	"code.gitea.io/gitea/modules/structs" | ||||
| 	"code.gitea.io/gitea/tests" | ||||
| 
 | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| ) | ||||
|  | @ -23,70 +23,69 @@ import ( | |||
| // - Profile visibility | ||||
| // - Public activity visibility | ||||
| func TestUserProfileActivity(t *testing.T) { | ||||
| 	onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) { | ||||
| 		// This test needs multiple users with different access statuses to check for all possible states | ||||
| 		userAdmin := loginUser(t, "user1") | ||||
| 		userRegular := loginUser(t, "user2") | ||||
| 		// Activity availability should be the same for guest and another non-admin user, so this is not tested separately | ||||
| 		userGuest := emptyTestSession(t) | ||||
| 	defer tests.PrepareTestEnv(t)() | ||||
| 	// This test needs multiple users with different access statuses to check for all possible states | ||||
| 	userAdmin := loginUser(t, "user1") | ||||
| 	userRegular := loginUser(t, "user2") | ||||
| 	// Activity availability should be the same for guest and another non-admin user, so this is not tested separately | ||||
| 	userGuest := emptyTestSession(t) | ||||
| 
 | ||||
| 		// = Public profile, public activity = | ||||
| 	// = Public profile, public activity = | ||||
| 
 | ||||
| 		// Set activity visibility of user2 to public. This is the default, but won't hurt to set it before testing. | ||||
| 		testChangeUserActivityVisibility(t, userRegular, "off") | ||||
| 	// Set activity visibility of user2 to public. This is the default, but won't hurt to set it before testing. | ||||
| 	testChangeUserActivityVisibility(t, userRegular, "off") | ||||
| 
 | ||||
| 		// Verify availability of RSS button and activity tab | ||||
| 		testUser2ActivityButtonsAvailability(t, userAdmin, true) | ||||
| 		testUser2ActivityButtonsAvailability(t, userRegular, true) | ||||
| 		testUser2ActivityButtonsAvailability(t, userGuest, true) | ||||
| 	// Verify availability of RSS button and activity tab | ||||
| 	testUser2ActivityButtonsAvailability(t, userAdmin, true) | ||||
| 	testUser2ActivityButtonsAvailability(t, userRegular, true) | ||||
| 	testUser2ActivityButtonsAvailability(t, userGuest, true) | ||||
| 
 | ||||
| 		// Verify the hint for all types of users: admin, self, guest | ||||
| 		testUser2ActivityVisibility(t, userAdmin, "This activity is visible to everyone, but as an administrator you can also see interactions in private spaces.", true) | ||||
| 		hintLink := testUser2ActivityVisibility(t, userRegular, "Your activity is visible to everyone, except for interactions in private spaces. Configure.", true) | ||||
| 		testUser2ActivityVisibility(t, userGuest, "", true) | ||||
| 	// Verify the hint for all types of users: admin, self, guest | ||||
| 	testUser2ActivityVisibility(t, userAdmin, "This activity is visible to everyone, but as an administrator you can also see interactions in private spaces.", true) | ||||
| 	hintLink := testUser2ActivityVisibility(t, userRegular, "Your activity is visible to everyone, except for interactions in private spaces. Configure.", true) | ||||
| 	testUser2ActivityVisibility(t, userGuest, "", true) | ||||
| 
 | ||||
| 		// When viewing own profile, the user is offered to configure activity visibility. Verify that the link is correct and works, also check that it links back to the activity tab. | ||||
| 		linkCorrect := assert.EqualValues(t, "/user/settings#keep-activity-private", hintLink) | ||||
| 		if linkCorrect { | ||||
| 			page := NewHTMLParser(t, userRegular.MakeRequest(t, NewRequest(t, "GET", hintLink), http.StatusOK).Body) | ||||
| 			activityLink, exists := page.Find(".field:has(.checkbox#keep-activity-private) .help a").Attr("href") | ||||
| 			assert.True(t, exists) | ||||
| 			assert.EqualValues(t, "/user2?tab=activity", activityLink) | ||||
| 		} | ||||
| 	// When viewing own profile, the user is offered to configure activity visibility. Verify that the link is correct and works, also check that it links back to the activity tab. | ||||
| 	linkCorrect := assert.EqualValues(t, "/user/settings#keep-activity-private", hintLink) | ||||
| 	if linkCorrect { | ||||
| 		page := NewHTMLParser(t, userRegular.MakeRequest(t, NewRequest(t, "GET", hintLink), http.StatusOK).Body) | ||||
| 		activityLink, exists := page.Find(".field:has(.checkbox#keep-activity-private) .help a").Attr("href") | ||||
| 		assert.True(t, exists) | ||||
| 		assert.EqualValues(t, "/user2?tab=activity", activityLink) | ||||
| 	} | ||||
| 
 | ||||
| 		// = Private profile, but public activity = | ||||
| 	// = Private profile, but public activity = | ||||
| 
 | ||||
| 		// Set profile visibility of user2 to private | ||||
| 		testChangeUserProfileVisibility(t, userRegular, structs.VisibleTypePrivate) | ||||
| 	// Set profile visibility of user2 to private | ||||
| 	testChangeUserProfileVisibility(t, userRegular, structs.VisibleTypePrivate) | ||||
| 
 | ||||
| 		// When profile activity is configured as public, but the profile is private, tell the user about this and link to visibility settings. | ||||
| 		hintLink = testUser2ActivityVisibility(t, userRegular, "Your activity is only visible to you and the instance administrators because your profile is private. Configure.", true) | ||||
| 		assert.EqualValues(t, "/user/settings#visibility-setting", hintLink) | ||||
| 	// When profile activity is configured as public, but the profile is private, tell the user about this and link to visibility settings. | ||||
| 	hintLink = testUser2ActivityVisibility(t, userRegular, "Your activity is only visible to you and the instance administrators because your profile is private. Configure.", true) | ||||
| 	assert.EqualValues(t, "/user/settings#visibility-setting", hintLink) | ||||
| 
 | ||||
| 		// When the profile is private, tell the admin about this. | ||||
| 		testUser2ActivityVisibility(t, userAdmin, "This activity is visible to you because you're an administrator, but the user wants it to remain private.", true) | ||||
| 	// When the profile is private, tell the admin about this. | ||||
| 	testUser2ActivityVisibility(t, userAdmin, "This activity is visible to you because you're an administrator, but the user wants it to remain private.", true) | ||||
| 
 | ||||
| 		// Set profile visibility of user2 back to public | ||||
| 		testChangeUserProfileVisibility(t, userRegular, structs.VisibleTypePublic) | ||||
| 	// Set profile visibility of user2 back to public | ||||
| 	testChangeUserProfileVisibility(t, userRegular, structs.VisibleTypePublic) | ||||
| 
 | ||||
| 		// = Private acitivty = | ||||
| 	// = Private acitivty = | ||||
| 
 | ||||
| 		// Set activity visibility of user2 to private | ||||
| 		testChangeUserActivityVisibility(t, userRegular, "on") | ||||
| 	// Set activity visibility of user2 to private | ||||
| 	testChangeUserActivityVisibility(t, userRegular, "on") | ||||
| 
 | ||||
| 		// Verify availability of RSS button and activity tab | ||||
| 		testUser2ActivityButtonsAvailability(t, userAdmin, true) | ||||
| 		testUser2ActivityButtonsAvailability(t, userRegular, true) | ||||
| 		testUser2ActivityButtonsAvailability(t, userGuest, false) | ||||
| 	// Verify availability of RSS button and activity tab | ||||
| 	testUser2ActivityButtonsAvailability(t, userAdmin, true) | ||||
| 	testUser2ActivityButtonsAvailability(t, userRegular, true) | ||||
| 	testUser2ActivityButtonsAvailability(t, userGuest, false) | ||||
| 
 | ||||
| 		// Verify the hint for all types of users: admin, self, guest | ||||
| 		testUser2ActivityVisibility(t, userAdmin, "This activity is visible to you because you're an administrator, but the user wants it to remain private.", true) | ||||
| 		hintLink = testUser2ActivityVisibility(t, userRegular, "Your activity is only visible to you and the instance administrators. Configure.", true) | ||||
| 		testUser2ActivityVisibility(t, userGuest, "This user has disabled the public visibility of the activity.", false) | ||||
| 	// Verify the hint for all types of users: admin, self, guest | ||||
| 	testUser2ActivityVisibility(t, userAdmin, "This activity is visible to you because you're an administrator, but the user wants it to remain private.", true) | ||||
| 	hintLink = testUser2ActivityVisibility(t, userRegular, "Your activity is only visible to you and the instance administrators. Configure.", true) | ||||
| 	testUser2ActivityVisibility(t, userGuest, "This user has disabled the public visibility of the activity.", false) | ||||
| 
 | ||||
| 		// Verify that Configure link is correct | ||||
| 		assert.EqualValues(t, "/user/settings#keep-activity-private", hintLink) | ||||
| 	}) | ||||
| 	// Verify that Configure link is correct | ||||
| 	assert.EqualValues(t, "/user/settings#keep-activity-private", hintLink) | ||||
| } | ||||
| 
 | ||||
| // testChangeUserActivityVisibility allows to easily change visibility of public activity for a user | ||||
|  |  | |||
|  | @ -6,10 +6,11 @@ package integration | |||
| import ( | ||||
| 	"fmt" | ||||
| 	"net/http" | ||||
| 	"net/url" | ||||
| 	"strings" | ||||
| 	"testing" | ||||
| 
 | ||||
| 	"code.gitea.io/gitea/tests" | ||||
| 
 | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| ) | ||||
| 
 | ||||
|  | @ -19,92 +20,92 @@ import ( | |||
| // - Followers and Following lists have correct amounts of items | ||||
| // - %d followers and %following counters are always present and always have correct numbers and use correct plurals | ||||
| func TestUserProfileFollows(t *testing.T) { | ||||
| 	onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) { | ||||
| 		// This test needs 3 users to check for all possible states | ||||
| 		// The accounts of user3 and user4 are not functioning | ||||
| 		user1 := loginUser(t, "user1") | ||||
| 		user2 := loginUser(t, "user2") | ||||
| 		user5 := loginUser(t, "user5") | ||||
| 	defer tests.PrepareTestEnv(t)() | ||||
| 
 | ||||
| 		followersLink := "#profile-avatar-card a[href='/user1?tab=followers']" | ||||
| 		followingLink := "#profile-avatar-card a[href='/user1?tab=following']" | ||||
| 		listHeader := ".user-cards h2" | ||||
| 		listItems := ".user-cards .list" | ||||
| 	// This test needs 3 users to check for all possible states | ||||
| 	// The accounts of user3 and user4 are not functioning | ||||
| 	user1 := loginUser(t, "user1") | ||||
| 	user2 := loginUser(t, "user2") | ||||
| 	user5 := loginUser(t, "user5") | ||||
| 
 | ||||
| 		// = No follows = | ||||
| 	followersLink := "#profile-avatar-card a[href='/user1?tab=followers']" | ||||
| 	followingLink := "#profile-avatar-card a[href='/user1?tab=following']" | ||||
| 	listHeader := ".user-cards h2" | ||||
| 	listItems := ".user-cards .list" | ||||
| 
 | ||||
| 		var followCount int | ||||
| 	// = No follows = | ||||
| 
 | ||||
| 		// Request the profile of user1, the Followers tab | ||||
| 		response := user1.MakeRequest(t, NewRequest(t, "GET", "/user1?tab=followers"), http.StatusOK) | ||||
| 		page := NewHTMLParser(t, response.Body) | ||||
| 	var followCount int | ||||
| 
 | ||||
| 		// Verify that user1 has no followers | ||||
| 		testSelectorEquals(t, page, followersLink, "0 followers") | ||||
| 		testSelectorEquals(t, page, listHeader, "Followers") | ||||
| 		testListCount(t, page, listItems, followCount) | ||||
| 	// Request the profile of user1, the Followers tab | ||||
| 	response := user1.MakeRequest(t, NewRequest(t, "GET", "/user1?tab=followers"), http.StatusOK) | ||||
| 	page := NewHTMLParser(t, response.Body) | ||||
| 
 | ||||
| 		// Request the profile of user1, the Following tab | ||||
| 		response = user1.MakeRequest(t, NewRequest(t, "GET", "/user1?tab=following"), http.StatusOK) | ||||
| 		page = NewHTMLParser(t, response.Body) | ||||
| 	// Verify that user1 has no followers | ||||
| 	testSelectorEquals(t, page, followersLink, "0 followers") | ||||
| 	testSelectorEquals(t, page, listHeader, "Followers") | ||||
| 	testListCount(t, page, listItems, followCount) | ||||
| 
 | ||||
| 		// Verify that user1 does not follow anyone | ||||
| 		testSelectorEquals(t, page, followingLink, "0 following") | ||||
| 		testSelectorEquals(t, page, listHeader, "Following") | ||||
| 		testListCount(t, page, listItems, followCount) | ||||
| 	// Request the profile of user1, the Following tab | ||||
| 	response = user1.MakeRequest(t, NewRequest(t, "GET", "/user1?tab=following"), http.StatusOK) | ||||
| 	page = NewHTMLParser(t, response.Body) | ||||
| 
 | ||||
| 		// Make user1 and user2 follow each other | ||||
| 		testUserFollowUser(t, user1, "user2") | ||||
| 		testUserFollowUser(t, user2, "user1") | ||||
| 	// Verify that user1 does not follow anyone | ||||
| 	testSelectorEquals(t, page, followingLink, "0 following") | ||||
| 	testSelectorEquals(t, page, listHeader, "Following") | ||||
| 	testListCount(t, page, listItems, followCount) | ||||
| 
 | ||||
| 		// = 1 follow each = | ||||
| 	// Make user1 and user2 follow each other | ||||
| 	testUserFollowUser(t, user1, "user2") | ||||
| 	testUserFollowUser(t, user2, "user1") | ||||
| 
 | ||||
| 		followCount++ | ||||
| 	// = 1 follow each = | ||||
| 
 | ||||
| 		// Request the profile of user1, the Followers tab | ||||
| 		response = user1.MakeRequest(t, NewRequest(t, "GET", "/user1?tab=followers"), http.StatusOK) | ||||
| 		page = NewHTMLParser(t, response.Body) | ||||
| 	followCount++ | ||||
| 
 | ||||
| 		// Verify it is now followed by 1 user | ||||
| 		testSelectorEquals(t, page, followersLink, "1 follower") | ||||
| 		testSelectorEquals(t, page, listHeader, "Follower") | ||||
| 		testListCount(t, page, listItems, followCount) | ||||
| 	// Request the profile of user1, the Followers tab | ||||
| 	response = user1.MakeRequest(t, NewRequest(t, "GET", "/user1?tab=followers"), http.StatusOK) | ||||
| 	page = NewHTMLParser(t, response.Body) | ||||
| 
 | ||||
| 		// Request the profile of user1, the Following tab | ||||
| 		response = user1.MakeRequest(t, NewRequest(t, "GET", "/user1?tab=following"), http.StatusOK) | ||||
| 		page = NewHTMLParser(t, response.Body) | ||||
| 	// Verify it is now followed by 1 user | ||||
| 	testSelectorEquals(t, page, followersLink, "1 follower") | ||||
| 	testSelectorEquals(t, page, listHeader, "Follower") | ||||
| 	testListCount(t, page, listItems, followCount) | ||||
| 
 | ||||
| 		// Verify it now follows follows 1 user | ||||
| 		testSelectorEquals(t, page, followingLink, "1 following") | ||||
| 		testSelectorEquals(t, page, listHeader, "Following") | ||||
| 		testListCount(t, page, listItems, followCount) | ||||
| 	// Request the profile of user1, the Following tab | ||||
| 	response = user1.MakeRequest(t, NewRequest(t, "GET", "/user1?tab=following"), http.StatusOK) | ||||
| 	page = NewHTMLParser(t, response.Body) | ||||
| 
 | ||||
| 		// Make user1 and user3 follow each other | ||||
| 		testUserFollowUser(t, user1, "user5") | ||||
| 		testUserFollowUser(t, user5, "user1") | ||||
| 	// Verify it now follows follows 1 user | ||||
| 	testSelectorEquals(t, page, followingLink, "1 following") | ||||
| 	testSelectorEquals(t, page, listHeader, "Following") | ||||
| 	testListCount(t, page, listItems, followCount) | ||||
| 
 | ||||
| 		// = 2 follows = | ||||
| 	// Make user1 and user3 follow each other | ||||
| 	testUserFollowUser(t, user1, "user5") | ||||
| 	testUserFollowUser(t, user5, "user1") | ||||
| 
 | ||||
| 		followCount++ | ||||
| 	// = 2 follows = | ||||
| 
 | ||||
| 		// Request the profile of user1, the Followers tab | ||||
| 		response = user1.MakeRequest(t, NewRequest(t, "GET", "/user1?tab=followers"), http.StatusOK) | ||||
| 		page = NewHTMLParser(t, response.Body) | ||||
| 	followCount++ | ||||
| 
 | ||||
| 		// Verify it is now followed by 2 users | ||||
| 		testSelectorEquals(t, page, followersLink, "2 followers") | ||||
| 		testSelectorEquals(t, page, listHeader, "Followers") | ||||
| 		testListCount(t, page, listItems, followCount) | ||||
| 	// Request the profile of user1, the Followers tab | ||||
| 	response = user1.MakeRequest(t, NewRequest(t, "GET", "/user1?tab=followers"), http.StatusOK) | ||||
| 	page = NewHTMLParser(t, response.Body) | ||||
| 
 | ||||
| 		// Request the profile of user1, the Following tab | ||||
| 		response = user1.MakeRequest(t, NewRequest(t, "GET", "/user1?tab=following"), http.StatusOK) | ||||
| 		page = NewHTMLParser(t, response.Body) | ||||
| 	// Verify it is now followed by 2 users | ||||
| 	testSelectorEquals(t, page, followersLink, "2 followers") | ||||
| 	testSelectorEquals(t, page, listHeader, "Followers") | ||||
| 	testListCount(t, page, listItems, followCount) | ||||
| 
 | ||||
| 		// Verify it now follows follows 2 users | ||||
| 		testSelectorEquals(t, page, followingLink, "2 following") | ||||
| 		testSelectorEquals(t, page, listHeader, "Following") | ||||
| 		testListCount(t, page, listItems, followCount) | ||||
| 	}) | ||||
| 	// Request the profile of user1, the Following tab | ||||
| 	response = user1.MakeRequest(t, NewRequest(t, "GET", "/user1?tab=following"), http.StatusOK) | ||||
| 	page = NewHTMLParser(t, response.Body) | ||||
| 
 | ||||
| 	// Verify it now follows follows 2 users | ||||
| 	testSelectorEquals(t, page, followingLink, "2 following") | ||||
| 	testSelectorEquals(t, page, listHeader, "Following") | ||||
| 	testListCount(t, page, listItems, followCount) | ||||
| } | ||||
| 
 | ||||
| // testUserFollowUser simply follows a user `following` by session of user `follower` | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue