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.

340 lines
10 KiB

  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 repofiles
  5. import (
  6. "testing"
  7. "code.gitea.io/gitea/models"
  8. "code.gitea.io/gitea/modules/git"
  9. "code.gitea.io/gitea/modules/repository"
  10. "github.com/stretchr/testify/assert"
  11. )
  12. func testCorrectRepoAction(t *testing.T, opts *CommitRepoActionOptions, actionBean *models.Action) {
  13. models.AssertNotExistsBean(t, actionBean)
  14. assert.NoError(t, CommitRepoAction(opts))
  15. models.AssertExistsAndLoadBean(t, actionBean)
  16. models.CheckConsistencyFor(t, &models.Action{})
  17. }
  18. func TestCommitRepoAction(t *testing.T) {
  19. samples := []struct {
  20. userID int64
  21. repositoryID int64
  22. commitRepoActionOptions CommitRepoActionOptions
  23. action models.Action
  24. }{
  25. {
  26. userID: 2,
  27. repositoryID: 16,
  28. commitRepoActionOptions: CommitRepoActionOptions{
  29. PushUpdateOptions: PushUpdateOptions{
  30. RefFullName: "refName",
  31. OldCommitID: "oldCommitID",
  32. NewCommitID: "newCommitID",
  33. },
  34. Commits: &repository.PushCommits{
  35. Commits: []*repository.PushCommit{
  36. {
  37. Sha1: "69554a6",
  38. CommitterEmail: "user2@example.com",
  39. CommitterName: "User2",
  40. AuthorEmail: "user2@example.com",
  41. AuthorName: "User2",
  42. Message: "not signed commit",
  43. },
  44. {
  45. Sha1: "27566bd",
  46. CommitterEmail: "user2@example.com",
  47. CommitterName: "User2",
  48. AuthorEmail: "user2@example.com",
  49. AuthorName: "User2",
  50. Message: "good signed commit (with not yet validated email)",
  51. },
  52. },
  53. Len: 2,
  54. },
  55. },
  56. action: models.Action{
  57. OpType: models.ActionCommitRepo,
  58. RefName: "refName",
  59. },
  60. },
  61. {
  62. userID: 2,
  63. repositoryID: 1,
  64. commitRepoActionOptions: CommitRepoActionOptions{
  65. PushUpdateOptions: PushUpdateOptions{
  66. RefFullName: git.TagPrefix + "v1.1",
  67. OldCommitID: git.EmptySHA,
  68. NewCommitID: "newCommitID",
  69. },
  70. Commits: &repository.PushCommits{},
  71. },
  72. action: models.Action{
  73. OpType: models.ActionPushTag,
  74. RefName: "v1.1",
  75. },
  76. },
  77. {
  78. userID: 2,
  79. repositoryID: 1,
  80. commitRepoActionOptions: CommitRepoActionOptions{
  81. PushUpdateOptions: PushUpdateOptions{
  82. RefFullName: git.TagPrefix + "v1.1",
  83. OldCommitID: "oldCommitID",
  84. NewCommitID: git.EmptySHA,
  85. },
  86. Commits: &repository.PushCommits{},
  87. },
  88. action: models.Action{
  89. OpType: models.ActionDeleteTag,
  90. RefName: "v1.1",
  91. },
  92. },
  93. {
  94. userID: 2,
  95. repositoryID: 1,
  96. commitRepoActionOptions: CommitRepoActionOptions{
  97. PushUpdateOptions: PushUpdateOptions{
  98. RefFullName: git.BranchPrefix + "feature/1",
  99. OldCommitID: "oldCommitID",
  100. NewCommitID: git.EmptySHA,
  101. },
  102. Commits: &repository.PushCommits{},
  103. },
  104. action: models.Action{
  105. OpType: models.ActionDeleteBranch,
  106. RefName: "feature/1",
  107. },
  108. },
  109. }
  110. for _, s := range samples {
  111. models.PrepareTestEnv(t)
  112. user := models.AssertExistsAndLoadBean(t, &models.User{ID: s.userID}).(*models.User)
  113. repo := models.AssertExistsAndLoadBean(t, &models.Repository{ID: s.repositoryID, OwnerID: user.ID}).(*models.Repository)
  114. repo.Owner = user
  115. s.commitRepoActionOptions.PusherName = user.Name
  116. s.commitRepoActionOptions.RepoOwnerID = user.ID
  117. s.commitRepoActionOptions.RepoName = repo.Name
  118. s.action.ActUserID = user.ID
  119. s.action.RepoID = repo.ID
  120. s.action.Repo = repo
  121. s.action.IsPrivate = repo.IsPrivate
  122. testCorrectRepoAction(t, &s.commitRepoActionOptions, &s.action)
  123. }
  124. }
  125. func TestUpdateIssuesCommit(t *testing.T) {
  126. assert.NoError(t, models.PrepareTestDatabase())
  127. pushCommits := []*repository.PushCommit{
  128. {
  129. Sha1: "abcdef1",
  130. CommitterEmail: "user2@example.com",
  131. CommitterName: "User Two",
  132. AuthorEmail: "user4@example.com",
  133. AuthorName: "User Four",
  134. Message: "start working on #FST-1, #1",
  135. },
  136. {
  137. Sha1: "abcdef2",
  138. CommitterEmail: "user2@example.com",
  139. CommitterName: "User Two",
  140. AuthorEmail: "user2@example.com",
  141. AuthorName: "User Two",
  142. Message: "a plain message",
  143. },
  144. {
  145. Sha1: "abcdef2",
  146. CommitterEmail: "user2@example.com",
  147. CommitterName: "User Two",
  148. AuthorEmail: "user2@example.com",
  149. AuthorName: "User Two",
  150. Message: "close #2",
  151. },
  152. }
  153. user := models.AssertExistsAndLoadBean(t, &models.User{ID: 2}).(*models.User)
  154. repo := models.AssertExistsAndLoadBean(t, &models.Repository{ID: 1}).(*models.Repository)
  155. repo.Owner = user
  156. commentBean := &models.Comment{
  157. Type: models.CommentTypeCommitRef,
  158. CommitSHA: "abcdef1",
  159. PosterID: user.ID,
  160. IssueID: 1,
  161. }
  162. issueBean := &models.Issue{RepoID: repo.ID, Index: 4}
  163. models.AssertNotExistsBean(t, commentBean)
  164. models.AssertNotExistsBean(t, &models.Issue{RepoID: repo.ID, Index: 2}, "is_closed=1")
  165. assert.NoError(t, UpdateIssuesCommit(user, repo, pushCommits, repo.DefaultBranch))
  166. models.AssertExistsAndLoadBean(t, commentBean)
  167. models.AssertExistsAndLoadBean(t, issueBean, "is_closed=1")
  168. models.CheckConsistencyFor(t, &models.Action{})
  169. // Test that push to a non-default branch closes no issue.
  170. pushCommits = []*repository.PushCommit{
  171. {
  172. Sha1: "abcdef1",
  173. CommitterEmail: "user2@example.com",
  174. CommitterName: "User Two",
  175. AuthorEmail: "user4@example.com",
  176. AuthorName: "User Four",
  177. Message: "close #1",
  178. },
  179. }
  180. repo = models.AssertExistsAndLoadBean(t, &models.Repository{ID: 3}).(*models.Repository)
  181. commentBean = &models.Comment{
  182. Type: models.CommentTypeCommitRef,
  183. CommitSHA: "abcdef1",
  184. PosterID: user.ID,
  185. IssueID: 6,
  186. }
  187. issueBean = &models.Issue{RepoID: repo.ID, Index: 1}
  188. models.AssertNotExistsBean(t, commentBean)
  189. models.AssertNotExistsBean(t, &models.Issue{RepoID: repo.ID, Index: 1}, "is_closed=1")
  190. assert.NoError(t, UpdateIssuesCommit(user, repo, pushCommits, "non-existing-branch"))
  191. models.AssertExistsAndLoadBean(t, commentBean)
  192. models.AssertNotExistsBean(t, issueBean, "is_closed=1")
  193. models.CheckConsistencyFor(t, &models.Action{})
  194. }
  195. func TestUpdateIssuesCommit_Colon(t *testing.T) {
  196. assert.NoError(t, models.PrepareTestDatabase())
  197. pushCommits := []*repository.PushCommit{
  198. {
  199. Sha1: "abcdef2",
  200. CommitterEmail: "user2@example.com",
  201. CommitterName: "User Two",
  202. AuthorEmail: "user2@example.com",
  203. AuthorName: "User Two",
  204. Message: "close: #2",
  205. },
  206. }
  207. user := models.AssertExistsAndLoadBean(t, &models.User{ID: 2}).(*models.User)
  208. repo := models.AssertExistsAndLoadBean(t, &models.Repository{ID: 1}).(*models.Repository)
  209. repo.Owner = user
  210. issueBean := &models.Issue{RepoID: repo.ID, Index: 4}
  211. models.AssertNotExistsBean(t, &models.Issue{RepoID: repo.ID, Index: 2}, "is_closed=1")
  212. assert.NoError(t, UpdateIssuesCommit(user, repo, pushCommits, repo.DefaultBranch))
  213. models.AssertExistsAndLoadBean(t, issueBean, "is_closed=1")
  214. models.CheckConsistencyFor(t, &models.Action{})
  215. }
  216. func TestUpdateIssuesCommit_Issue5957(t *testing.T) {
  217. assert.NoError(t, models.PrepareTestDatabase())
  218. user := models.AssertExistsAndLoadBean(t, &models.User{ID: 2}).(*models.User)
  219. // Test that push to a non-default branch closes an issue.
  220. pushCommits := []*repository.PushCommit{
  221. {
  222. Sha1: "abcdef1",
  223. CommitterEmail: "user2@example.com",
  224. CommitterName: "User Two",
  225. AuthorEmail: "user4@example.com",
  226. AuthorName: "User Four",
  227. Message: "close #2",
  228. },
  229. }
  230. repo := models.AssertExistsAndLoadBean(t, &models.Repository{ID: 2}).(*models.Repository)
  231. commentBean := &models.Comment{
  232. Type: models.CommentTypeCommitRef,
  233. CommitSHA: "abcdef1",
  234. PosterID: user.ID,
  235. IssueID: 7,
  236. }
  237. issueBean := &models.Issue{RepoID: repo.ID, Index: 2, ID: 7}
  238. models.AssertNotExistsBean(t, commentBean)
  239. models.AssertNotExistsBean(t, issueBean, "is_closed=1")
  240. assert.NoError(t, UpdateIssuesCommit(user, repo, pushCommits, "non-existing-branch"))
  241. models.AssertExistsAndLoadBean(t, commentBean)
  242. models.AssertExistsAndLoadBean(t, issueBean, "is_closed=1")
  243. models.CheckConsistencyFor(t, &models.Action{})
  244. }
  245. func TestUpdateIssuesCommit_AnotherRepo(t *testing.T) {
  246. assert.NoError(t, models.PrepareTestDatabase())
  247. user := models.AssertExistsAndLoadBean(t, &models.User{ID: 2}).(*models.User)
  248. // Test that a push to default branch closes issue in another repo
  249. // If the user also has push permissions to that repo
  250. pushCommits := []*repository.PushCommit{
  251. {
  252. Sha1: "abcdef1",
  253. CommitterEmail: "user2@example.com",
  254. CommitterName: "User Two",
  255. AuthorEmail: "user2@example.com",
  256. AuthorName: "User Two",
  257. Message: "close user2/repo1#1",
  258. },
  259. }
  260. repo := models.AssertExistsAndLoadBean(t, &models.Repository{ID: 2}).(*models.Repository)
  261. commentBean := &models.Comment{
  262. Type: models.CommentTypeCommitRef,
  263. CommitSHA: "abcdef1",
  264. PosterID: user.ID,
  265. IssueID: 1,
  266. }
  267. issueBean := &models.Issue{RepoID: 1, Index: 1, ID: 1}
  268. models.AssertNotExistsBean(t, commentBean)
  269. models.AssertNotExistsBean(t, issueBean, "is_closed=1")
  270. assert.NoError(t, UpdateIssuesCommit(user, repo, pushCommits, repo.DefaultBranch))
  271. models.AssertExistsAndLoadBean(t, commentBean)
  272. models.AssertExistsAndLoadBean(t, issueBean, "is_closed=1")
  273. models.CheckConsistencyFor(t, &models.Action{})
  274. }
  275. func TestUpdateIssuesCommit_AnotherRepoNoPermission(t *testing.T) {
  276. assert.NoError(t, models.PrepareTestDatabase())
  277. user := models.AssertExistsAndLoadBean(t, &models.User{ID: 10}).(*models.User)
  278. // Test that a push with close reference *can not* close issue
  279. // If the commiter doesn't have push rights in that repo
  280. pushCommits := []*repository.PushCommit{
  281. {
  282. Sha1: "abcdef3",
  283. CommitterEmail: "user10@example.com",
  284. CommitterName: "User Ten",
  285. AuthorEmail: "user10@example.com",
  286. AuthorName: "User Ten",
  287. Message: "close user3/repo3#1",
  288. },
  289. }
  290. repo := models.AssertExistsAndLoadBean(t, &models.Repository{ID: 6}).(*models.Repository)
  291. commentBean := &models.Comment{
  292. Type: models.CommentTypeCommitRef,
  293. CommitSHA: "abcdef3",
  294. PosterID: user.ID,
  295. IssueID: 6,
  296. }
  297. issueBean := &models.Issue{RepoID: 3, Index: 1, ID: 6}
  298. models.AssertNotExistsBean(t, commentBean)
  299. models.AssertNotExistsBean(t, issueBean, "is_closed=1")
  300. assert.NoError(t, UpdateIssuesCommit(user, repo, pushCommits, repo.DefaultBranch))
  301. models.AssertNotExistsBean(t, commentBean)
  302. models.AssertNotExistsBean(t, issueBean, "is_closed=1")
  303. models.CheckConsistencyFor(t, &models.Action{})
  304. }