You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

api_repo_edit_test.go 9.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. // Copyright 2019 The Gitea Authors. All rights reserved.
  2. // Use of this source code is governed by a MIT-style
  3. // license that can be found in the LICENSE file.
  4. package integrations
  5. import (
  6. "fmt"
  7. "net/http"
  8. "net/url"
  9. "testing"
  10. "code.gitea.io/gitea/models"
  11. api "code.gitea.io/gitea/modules/structs"
  12. "github.com/stretchr/testify/assert"
  13. )
  14. // getRepoEditOptionFromRepo gets the options for an existing repo exactly as is
  15. func getRepoEditOptionFromRepo(repo *models.Repository) *api.EditRepoOption {
  16. name := repo.Name
  17. description := repo.Description
  18. website := repo.Website
  19. private := repo.IsPrivate
  20. hasIssues := false
  21. if _, err := repo.GetUnit(models.UnitTypeIssues); err == nil {
  22. hasIssues = true
  23. }
  24. hasWiki := false
  25. if _, err := repo.GetUnit(models.UnitTypeWiki); err == nil {
  26. hasWiki = true
  27. }
  28. defaultBranch := repo.DefaultBranch
  29. hasPullRequests := false
  30. ignoreWhitespaceConflicts := false
  31. allowMerge := false
  32. allowRebase := false
  33. allowRebaseMerge := false
  34. allowSquash := false
  35. if unit, err := repo.GetUnit(models.UnitTypePullRequests); err == nil {
  36. config := unit.PullRequestsConfig()
  37. hasPullRequests = true
  38. ignoreWhitespaceConflicts = config.IgnoreWhitespaceConflicts
  39. allowMerge = config.AllowMerge
  40. allowRebase = config.AllowRebase
  41. allowRebaseMerge = config.AllowRebaseMerge
  42. allowSquash = config.AllowSquash
  43. }
  44. archived := repo.IsArchived
  45. return &api.EditRepoOption{
  46. Name: &name,
  47. Description: &description,
  48. Website: &website,
  49. Private: &private,
  50. HasIssues: &hasIssues,
  51. HasWiki: &hasWiki,
  52. DefaultBranch: &defaultBranch,
  53. HasPullRequests: &hasPullRequests,
  54. IgnoreWhitespaceConflicts: &ignoreWhitespaceConflicts,
  55. AllowMerge: &allowMerge,
  56. AllowRebase: &allowRebase,
  57. AllowRebaseMerge: &allowRebaseMerge,
  58. AllowSquash: &allowSquash,
  59. Archived: &archived,
  60. }
  61. }
  62. // getNewRepoEditOption Gets the options to change everything about an existing repo by adding to strings or changing
  63. // the boolean
  64. func getNewRepoEditOption(opts *api.EditRepoOption) *api.EditRepoOption {
  65. // Gives a new property to everything
  66. name := *opts.Name + "renamed"
  67. description := "new description"
  68. website := "http://wwww.newwebsite.com"
  69. private := !*opts.Private
  70. hasIssues := !*opts.HasIssues
  71. hasWiki := !*opts.HasWiki
  72. defaultBranch := "master"
  73. hasPullRequests := !*opts.HasPullRequests
  74. ignoreWhitespaceConflicts := !*opts.IgnoreWhitespaceConflicts
  75. allowMerge := !*opts.AllowMerge
  76. allowRebase := !*opts.AllowRebase
  77. allowRebaseMerge := !*opts.AllowRebaseMerge
  78. allowSquash := !*opts.AllowSquash
  79. archived := !*opts.Archived
  80. return &api.EditRepoOption{
  81. Name: &name,
  82. Description: &description,
  83. Website: &website,
  84. Private: &private,
  85. DefaultBranch: &defaultBranch,
  86. HasIssues: &hasIssues,
  87. HasWiki: &hasWiki,
  88. HasPullRequests: &hasPullRequests,
  89. IgnoreWhitespaceConflicts: &ignoreWhitespaceConflicts,
  90. AllowMerge: &allowMerge,
  91. AllowRebase: &allowRebase,
  92. AllowRebaseMerge: &allowRebaseMerge,
  93. AllowSquash: &allowSquash,
  94. Archived: &archived,
  95. }
  96. }
  97. func TestAPIRepoEdit(t *testing.T) {
  98. onGiteaRun(t, func(t *testing.T, u *url.URL) {
  99. user2 := models.AssertExistsAndLoadBean(t, &models.User{ID: 2}).(*models.User) // owner of the repo1 & repo16
  100. user3 := models.AssertExistsAndLoadBean(t, &models.User{ID: 3}).(*models.User) // owner of the repo3, is an org
  101. user4 := models.AssertExistsAndLoadBean(t, &models.User{ID: 4}).(*models.User) // owner of neither repos
  102. repo1 := models.AssertExistsAndLoadBean(t, &models.Repository{ID: 1}).(*models.Repository) // public repo
  103. repo3 := models.AssertExistsAndLoadBean(t, &models.Repository{ID: 3}).(*models.Repository) // public repo
  104. repo16 := models.AssertExistsAndLoadBean(t, &models.Repository{ID: 16}).(*models.Repository) // private repo
  105. // Get user2's token
  106. session := loginUser(t, user2.Name)
  107. token2 := getTokenForLoggedInUser(t, session)
  108. session = emptyTestSession(t)
  109. // Get user4's token
  110. session = loginUser(t, user4.Name)
  111. token4 := getTokenForLoggedInUser(t, session)
  112. session = emptyTestSession(t)
  113. // Test editing a repo1 which user2 owns, changing name and many properties
  114. origRepoEditOption := getRepoEditOptionFromRepo(repo1)
  115. repoEditOption := getNewRepoEditOption(origRepoEditOption)
  116. url := fmt.Sprintf("/api/v1/repos/%s/%s?token=%s", user2.Name, repo1.Name, token2)
  117. req := NewRequestWithJSON(t, "PATCH", url, &repoEditOption)
  118. resp := session.MakeRequest(t, req, http.StatusOK)
  119. var repo api.Repository
  120. DecodeJSON(t, resp, &repo)
  121. assert.NotNil(t, repo)
  122. // check response
  123. assert.Equal(t, *repoEditOption.Name, repo.Name)
  124. assert.Equal(t, *repoEditOption.Description, repo.Description)
  125. assert.Equal(t, *repoEditOption.Website, repo.Website)
  126. assert.Equal(t, *repoEditOption.Archived, repo.Archived)
  127. // check repo1 from database
  128. repo1edited := models.AssertExistsAndLoadBean(t, &models.Repository{ID: 1}).(*models.Repository)
  129. repo1editedOption := getRepoEditOptionFromRepo(repo1edited)
  130. assert.Equal(t, *repoEditOption.Name, *repo1editedOption.Name)
  131. assert.Equal(t, *repoEditOption.Description, *repo1editedOption.Description)
  132. assert.Equal(t, *repoEditOption.Website, *repo1editedOption.Website)
  133. assert.Equal(t, *repoEditOption.Archived, *repo1editedOption.Archived)
  134. assert.Equal(t, *repoEditOption.Private, *repo1editedOption.Private)
  135. assert.Equal(t, *repoEditOption.HasWiki, *repo1editedOption.HasWiki)
  136. // reset repo in db
  137. url = fmt.Sprintf("/api/v1/repos/%s/%s?token=%s", user2.Name, *repoEditOption.Name, token2)
  138. req = NewRequestWithJSON(t, "PATCH", url, &origRepoEditOption)
  139. resp = session.MakeRequest(t, req, http.StatusOK)
  140. // Test editing a non-existing repo
  141. name := "repodoesnotexist"
  142. url = fmt.Sprintf("/api/v1/repos/%s/%s?token=%s", user2.Name, name, token2)
  143. req = NewRequestWithJSON(t, "PATCH", url, &api.EditRepoOption{Name: &name})
  144. resp = session.MakeRequest(t, req, http.StatusNotFound)
  145. // Test editing repo16 by user4 who does not have write access
  146. origRepoEditOption = getRepoEditOptionFromRepo(repo16)
  147. repoEditOption = getNewRepoEditOption(origRepoEditOption)
  148. url = fmt.Sprintf("/api/v1/repos/%s/%s?token=%s", user2.Name, repo16.Name, token4)
  149. req = NewRequestWithJSON(t, "PATCH", url, &repoEditOption)
  150. session.MakeRequest(t, req, http.StatusNotFound)
  151. // Tests a repo with no token given so will fail
  152. origRepoEditOption = getRepoEditOptionFromRepo(repo16)
  153. repoEditOption = getNewRepoEditOption(origRepoEditOption)
  154. url = fmt.Sprintf("/api/v1/repos/%s/%s", user2.Name, repo16.Name)
  155. req = NewRequestWithJSON(t, "PATCH", url, &repoEditOption)
  156. resp = session.MakeRequest(t, req, http.StatusNotFound)
  157. // Test using access token for a private repo that the user of the token owns
  158. origRepoEditOption = getRepoEditOptionFromRepo(repo16)
  159. repoEditOption = getNewRepoEditOption(origRepoEditOption)
  160. url = fmt.Sprintf("/api/v1/repos/%s/%s?token=%s", user2.Name, repo16.Name, token2)
  161. req = NewRequestWithJSON(t, "PATCH", url, &repoEditOption)
  162. resp = session.MakeRequest(t, req, http.StatusOK)
  163. // reset repo in db
  164. url = fmt.Sprintf("/api/v1/repos/%s/%s?token=%s", user2.Name, *repoEditOption.Name, token2)
  165. req = NewRequestWithJSON(t, "PATCH", url, &origRepoEditOption)
  166. resp = session.MakeRequest(t, req, http.StatusOK)
  167. // Test making a repo public that is private
  168. repo16 = models.AssertExistsAndLoadBean(t, &models.Repository{ID: 16}).(*models.Repository)
  169. assert.True(t, repo16.IsPrivate)
  170. private := false
  171. repoEditOption = &api.EditRepoOption{
  172. Private: &private,
  173. }
  174. url = fmt.Sprintf("/api/v1/repos/%s/%s?token=%s", user2.Name, repo16.Name, token2)
  175. req = NewRequestWithJSON(t, "PATCH", url, &repoEditOption)
  176. resp = session.MakeRequest(t, req, http.StatusOK)
  177. repo16 = models.AssertExistsAndLoadBean(t, &models.Repository{ID: 16}).(*models.Repository)
  178. assert.False(t, repo16.IsPrivate)
  179. // Make it private again
  180. private = true
  181. repoEditOption.Private = &private
  182. req = NewRequestWithJSON(t, "PATCH", url, &repoEditOption)
  183. resp = session.MakeRequest(t, req, http.StatusOK)
  184. // Test using org repo "user3/repo3" where user2 is a collaborator
  185. origRepoEditOption = getRepoEditOptionFromRepo(repo3)
  186. repoEditOption = getNewRepoEditOption(origRepoEditOption)
  187. url = fmt.Sprintf("/api/v1/repos/%s/%s?token=%s", user3.Name, repo3.Name, token2)
  188. req = NewRequestWithJSON(t, "PATCH", url, &repoEditOption)
  189. session.MakeRequest(t, req, http.StatusOK)
  190. // reset repo in db
  191. url = fmt.Sprintf("/api/v1/repos/%s/%s?token=%s", user3.Name, *repoEditOption.Name, token2)
  192. req = NewRequestWithJSON(t, "PATCH", url, &origRepoEditOption)
  193. resp = session.MakeRequest(t, req, http.StatusOK)
  194. // Test using org repo "user3/repo3" with no user token
  195. origRepoEditOption = getRepoEditOptionFromRepo(repo3)
  196. repoEditOption = getNewRepoEditOption(origRepoEditOption)
  197. url = fmt.Sprintf("/api/v1/repos/%s/%s", user3.Name, repo3.Name)
  198. req = NewRequestWithJSON(t, "PATCH", url, &repoEditOption)
  199. session.MakeRequest(t, req, http.StatusNotFound)
  200. // Test using repo "user2/repo1" where user4 is a NOT collaborator
  201. origRepoEditOption = getRepoEditOptionFromRepo(repo1)
  202. repoEditOption = getNewRepoEditOption(origRepoEditOption)
  203. url = fmt.Sprintf("/api/v1/repos/%s/%s?token=%s", user2.Name, repo1.Name, token4)
  204. req = NewRequestWithJSON(t, "PATCH", url, &repoEditOption)
  205. session.MakeRequest(t, req, http.StatusForbidden)
  206. })
  207. }