gitea源码

team_test.go 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. // Copyright 2017 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package org
  4. import (
  5. "fmt"
  6. "strings"
  7. "testing"
  8. "code.gitea.io/gitea/models/organization"
  9. "code.gitea.io/gitea/models/perm"
  10. access_model "code.gitea.io/gitea/models/perm/access"
  11. repo_model "code.gitea.io/gitea/models/repo"
  12. "code.gitea.io/gitea/models/unittest"
  13. user_model "code.gitea.io/gitea/models/user"
  14. "code.gitea.io/gitea/modules/structs"
  15. repo_service "code.gitea.io/gitea/services/repository"
  16. "github.com/stretchr/testify/assert"
  17. )
  18. func TestTeam_AddMember(t *testing.T) {
  19. assert.NoError(t, unittest.PrepareTestDatabase())
  20. test := func(team *organization.Team, user *user_model.User) {
  21. assert.NoError(t, AddTeamMember(t.Context(), team, user))
  22. unittest.AssertExistsAndLoadBean(t, &organization.TeamUser{UID: user.ID, TeamID: team.ID})
  23. unittest.CheckConsistencyFor(t, &organization.Team{ID: team.ID}, &user_model.User{ID: team.OrgID})
  24. }
  25. team1 := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 1})
  26. team3 := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 3})
  27. user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
  28. user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4})
  29. test(team1, user2)
  30. test(team1, user4)
  31. test(team3, user2)
  32. }
  33. func TestTeam_RemoveMember(t *testing.T) {
  34. assert.NoError(t, unittest.PrepareTestDatabase())
  35. testSuccess := func(team *organization.Team, user *user_model.User) {
  36. assert.NoError(t, RemoveTeamMember(t.Context(), team, user))
  37. unittest.AssertNotExistsBean(t, &organization.TeamUser{UID: user.ID, TeamID: team.ID})
  38. unittest.CheckConsistencyFor(t, &organization.Team{ID: team.ID})
  39. }
  40. team1 := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 1})
  41. team2 := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 2})
  42. team3 := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 3})
  43. user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
  44. user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4})
  45. testSuccess(team1, user4)
  46. testSuccess(team2, user2)
  47. testSuccess(team3, user2)
  48. err := RemoveTeamMember(t.Context(), team1, user2)
  49. assert.True(t, organization.IsErrLastOrgOwner(err))
  50. }
  51. func TestNewTeam(t *testing.T) {
  52. assert.NoError(t, unittest.PrepareTestDatabase())
  53. const teamName = "newTeamName"
  54. team := &organization.Team{Name: teamName, OrgID: 3}
  55. assert.NoError(t, NewTeam(t.Context(), team))
  56. unittest.AssertExistsAndLoadBean(t, &organization.Team{Name: teamName})
  57. unittest.CheckConsistencyFor(t, &organization.Team{}, &user_model.User{ID: team.OrgID})
  58. }
  59. func TestUpdateTeam(t *testing.T) {
  60. // successful update
  61. assert.NoError(t, unittest.PrepareTestDatabase())
  62. team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 2})
  63. team.LowerName = "newname"
  64. team.Name = "newName"
  65. team.Description = strings.Repeat("A long description!", 100)
  66. team.AccessMode = perm.AccessModeAdmin
  67. assert.NoError(t, UpdateTeam(t.Context(), team, true, false))
  68. team = unittest.AssertExistsAndLoadBean(t, &organization.Team{Name: "newName"})
  69. assert.True(t, strings.HasPrefix(team.Description, "A long description!"))
  70. access := unittest.AssertExistsAndLoadBean(t, &access_model.Access{UserID: 4, RepoID: 3})
  71. assert.Equal(t, perm.AccessModeAdmin, access.Mode)
  72. unittest.CheckConsistencyFor(t, &organization.Team{ID: team.ID})
  73. }
  74. func TestUpdateTeam2(t *testing.T) {
  75. // update to already-existing team
  76. assert.NoError(t, unittest.PrepareTestDatabase())
  77. team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 2})
  78. team.LowerName = "owners"
  79. team.Name = "Owners"
  80. team.Description = strings.Repeat("A long description!", 100)
  81. err := UpdateTeam(t.Context(), team, true, false)
  82. assert.True(t, organization.IsErrTeamAlreadyExist(err))
  83. unittest.CheckConsistencyFor(t, &organization.Team{ID: team.ID})
  84. }
  85. func TestDeleteTeam(t *testing.T) {
  86. assert.NoError(t, unittest.PrepareTestDatabase())
  87. team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 2})
  88. assert.NoError(t, DeleteTeam(t.Context(), team))
  89. unittest.AssertNotExistsBean(t, &organization.Team{ID: team.ID})
  90. unittest.AssertNotExistsBean(t, &organization.TeamRepo{TeamID: team.ID})
  91. unittest.AssertNotExistsBean(t, &organization.TeamUser{TeamID: team.ID})
  92. // check that team members don't have "leftover" access to repos
  93. user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4})
  94. repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3})
  95. accessMode, err := access_model.AccessLevel(t.Context(), user, repo)
  96. assert.NoError(t, err)
  97. assert.Less(t, accessMode, perm.AccessModeWrite)
  98. }
  99. func TestAddTeamMember(t *testing.T) {
  100. assert.NoError(t, unittest.PrepareTestDatabase())
  101. test := func(team *organization.Team, user *user_model.User) {
  102. assert.NoError(t, AddTeamMember(t.Context(), team, user))
  103. unittest.AssertExistsAndLoadBean(t, &organization.TeamUser{UID: user.ID, TeamID: team.ID})
  104. unittest.CheckConsistencyFor(t, &organization.Team{ID: team.ID}, &user_model.User{ID: team.OrgID})
  105. }
  106. team1 := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 1})
  107. team3 := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 3})
  108. user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
  109. user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4})
  110. test(team1, user2)
  111. test(team1, user4)
  112. test(team3, user2)
  113. }
  114. func TestRemoveTeamMember(t *testing.T) {
  115. assert.NoError(t, unittest.PrepareTestDatabase())
  116. testSuccess := func(team *organization.Team, user *user_model.User) {
  117. assert.NoError(t, RemoveTeamMember(t.Context(), team, user))
  118. unittest.AssertNotExistsBean(t, &organization.TeamUser{UID: user.ID, TeamID: team.ID})
  119. unittest.CheckConsistencyFor(t, &organization.Team{ID: team.ID})
  120. }
  121. team1 := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 1})
  122. team2 := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 2})
  123. team3 := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 3})
  124. user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
  125. user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4})
  126. testSuccess(team1, user4)
  127. testSuccess(team2, user2)
  128. testSuccess(team3, user2)
  129. err := RemoveTeamMember(t.Context(), team1, user2)
  130. assert.True(t, organization.IsErrLastOrgOwner(err))
  131. }
  132. func TestIncludesAllRepositoriesTeams(t *testing.T) {
  133. assert.NoError(t, unittest.PrepareTestDatabase())
  134. testTeamRepositories := func(teamID int64, repoIDs []int64) {
  135. team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID})
  136. repos, err := repo_model.GetTeamRepositories(t.Context(), &repo_model.SearchTeamRepoOptions{
  137. TeamID: team.ID,
  138. })
  139. assert.NoError(t, err, "%s: GetTeamRepositories", team.Name)
  140. assert.Len(t, repos, team.NumRepos, "%s: len repo", team.Name)
  141. assert.Len(t, repos, len(repoIDs), "%s: repo count", team.Name)
  142. for i, rid := range repoIDs {
  143. if rid > 0 {
  144. assert.True(t, repo_service.HasRepository(t.Context(), team, rid), "%s: HasRepository(%d) %d", rid, i)
  145. }
  146. }
  147. }
  148. // Get an admin user.
  149. user, err := user_model.GetUserByID(t.Context(), 1)
  150. assert.NoError(t, err, "GetUserByID")
  151. // Create org.
  152. org := &organization.Organization{
  153. Name: "All_repo",
  154. IsActive: true,
  155. Type: user_model.UserTypeOrganization,
  156. Visibility: structs.VisibleTypePublic,
  157. }
  158. assert.NoError(t, organization.CreateOrganization(t.Context(), org, user), "CreateOrganization")
  159. // Check Owner team.
  160. ownerTeam, err := org.GetOwnerTeam(t.Context())
  161. assert.NoError(t, err, "GetOwnerTeam")
  162. assert.True(t, ownerTeam.IncludesAllRepositories, "Owner team includes all repositories")
  163. // Create repos.
  164. repoIDs := make([]int64, 0)
  165. for i := range 3 {
  166. r, err := repo_service.CreateRepositoryDirectly(t.Context(), user, org.AsUser(),
  167. repo_service.CreateRepoOptions{Name: fmt.Sprintf("repo-%d", i)}, true)
  168. assert.NoError(t, err, "CreateRepository %d", i)
  169. if r != nil {
  170. repoIDs = append(repoIDs, r.ID)
  171. }
  172. }
  173. // Get fresh copy of Owner team after creating repos.
  174. ownerTeam, err = org.GetOwnerTeam(t.Context())
  175. assert.NoError(t, err, "GetOwnerTeam")
  176. // Create teams and check repositories.
  177. teams := []*organization.Team{
  178. ownerTeam,
  179. {
  180. OrgID: org.ID,
  181. Name: "team one",
  182. AccessMode: perm.AccessModeRead,
  183. IncludesAllRepositories: true,
  184. },
  185. {
  186. OrgID: org.ID,
  187. Name: "team 2",
  188. AccessMode: perm.AccessModeRead,
  189. IncludesAllRepositories: false,
  190. },
  191. {
  192. OrgID: org.ID,
  193. Name: "team three",
  194. AccessMode: perm.AccessModeWrite,
  195. IncludesAllRepositories: true,
  196. },
  197. {
  198. OrgID: org.ID,
  199. Name: "team 4",
  200. AccessMode: perm.AccessModeWrite,
  201. IncludesAllRepositories: false,
  202. },
  203. }
  204. teamRepos := [][]int64{
  205. repoIDs,
  206. repoIDs,
  207. {},
  208. repoIDs,
  209. {},
  210. }
  211. for i, team := range teams {
  212. if i > 0 { // first team is Owner.
  213. assert.NoError(t, NewTeam(t.Context(), team), "%s: NewTeam", team.Name)
  214. }
  215. testTeamRepositories(team.ID, teamRepos[i])
  216. }
  217. // Update teams and check repositories.
  218. teams[3].IncludesAllRepositories = false
  219. teams[4].IncludesAllRepositories = true
  220. teamRepos[4] = repoIDs
  221. for i, team := range teams {
  222. assert.NoError(t, UpdateTeam(t.Context(), team, false, true), "%s: UpdateTeam", team.Name)
  223. testTeamRepositories(team.ID, teamRepos[i])
  224. }
  225. // Create repo and check teams repositories.
  226. r, err := repo_service.CreateRepositoryDirectly(t.Context(), user, org.AsUser(), repo_service.CreateRepoOptions{Name: "repo-last"}, true)
  227. assert.NoError(t, err, "CreateRepository last")
  228. if r != nil {
  229. repoIDs = append(repoIDs, r.ID)
  230. }
  231. teamRepos[0] = repoIDs
  232. teamRepos[1] = repoIDs
  233. teamRepos[4] = repoIDs
  234. for i, team := range teams {
  235. testTeamRepositories(team.ID, teamRepos[i])
  236. }
  237. // Remove repo and check teams repositories.
  238. assert.NoError(t, repo_service.DeleteRepositoryDirectly(t.Context(), repoIDs[0]), "DeleteRepository")
  239. teamRepos[0] = repoIDs[1:]
  240. teamRepos[1] = repoIDs[1:]
  241. teamRepos[3] = repoIDs[1:3]
  242. teamRepos[4] = repoIDs[1:]
  243. for i, team := range teams {
  244. testTeamRepositories(team.ID, teamRepos[i])
  245. }
  246. // Wipe created items.
  247. for i, rid := range repoIDs {
  248. if i > 0 { // first repo already deleted.
  249. assert.NoError(t, repo_service.DeleteRepositoryDirectly(t.Context(), rid), "DeleteRepository %d", i)
  250. }
  251. }
  252. assert.NoError(t, DeleteOrganization(t.Context(), org, false), "DeleteOrganization")
  253. }