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.

action_test.go 15KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516
  1. package models
  2. import (
  3. "fmt"
  4. "path"
  5. "strings"
  6. "testing"
  7. "code.gitea.io/gitea/modules/setting"
  8. "github.com/stretchr/testify/assert"
  9. )
  10. func TestAction_GetRepoPath(t *testing.T) {
  11. assert.NoError(t, PrepareTestDatabase())
  12. repo := AssertExistsAndLoadBean(t, &Repository{}).(*Repository)
  13. owner := AssertExistsAndLoadBean(t, &User{ID: repo.OwnerID}).(*User)
  14. action := &Action{RepoID: repo.ID}
  15. assert.Equal(t, path.Join(owner.Name, repo.Name), action.GetRepoPath())
  16. }
  17. func TestAction_GetRepoLink(t *testing.T) {
  18. assert.NoError(t, PrepareTestDatabase())
  19. repo := AssertExistsAndLoadBean(t, &Repository{}).(*Repository)
  20. owner := AssertExistsAndLoadBean(t, &User{ID: repo.OwnerID}).(*User)
  21. action := &Action{RepoID: repo.ID}
  22. setting.AppSubURL = "/suburl/"
  23. expected := path.Join(setting.AppSubURL, owner.Name, repo.Name)
  24. assert.Equal(t, expected, action.GetRepoLink())
  25. }
  26. func TestNewRepoAction(t *testing.T) {
  27. assert.NoError(t, PrepareTestDatabase())
  28. user := AssertExistsAndLoadBean(t, &User{ID: 2}).(*User)
  29. repo := AssertExistsAndLoadBean(t, &Repository{OwnerID: user.ID}).(*Repository)
  30. repo.Owner = user
  31. actionBean := &Action{
  32. OpType: ActionCreateRepo,
  33. ActUserID: user.ID,
  34. RepoID: repo.ID,
  35. ActUser: user,
  36. Repo: repo,
  37. IsPrivate: repo.IsPrivate,
  38. }
  39. AssertNotExistsBean(t, actionBean)
  40. assert.NoError(t, NewRepoAction(user, repo))
  41. AssertExistsAndLoadBean(t, actionBean)
  42. CheckConsistencyFor(t, &Action{})
  43. }
  44. func TestRenameRepoAction(t *testing.T) {
  45. assert.NoError(t, PrepareTestDatabase())
  46. user := AssertExistsAndLoadBean(t, &User{ID: 2}).(*User)
  47. repo := AssertExistsAndLoadBean(t, &Repository{OwnerID: user.ID}).(*Repository)
  48. repo.Owner = user
  49. oldRepoName := repo.Name
  50. const newRepoName = "newRepoName"
  51. repo.Name = newRepoName
  52. repo.LowerName = strings.ToLower(newRepoName)
  53. actionBean := &Action{
  54. OpType: ActionRenameRepo,
  55. ActUserID: user.ID,
  56. ActUser: user,
  57. RepoID: repo.ID,
  58. Repo: repo,
  59. IsPrivate: repo.IsPrivate,
  60. Content: oldRepoName,
  61. }
  62. AssertNotExistsBean(t, actionBean)
  63. assert.NoError(t, RenameRepoAction(user, oldRepoName, repo))
  64. AssertExistsAndLoadBean(t, actionBean)
  65. _, err := x.ID(repo.ID).Cols("name", "lower_name").Update(repo)
  66. assert.NoError(t, err)
  67. CheckConsistencyFor(t, &Action{})
  68. }
  69. func TestPushCommits_ToAPIPayloadCommits(t *testing.T) {
  70. pushCommits := NewPushCommits()
  71. pushCommits.Commits = []*PushCommit{
  72. {
  73. Sha1: "abcdef1",
  74. CommitterEmail: "user2@example.com",
  75. CommitterName: "User Two",
  76. AuthorEmail: "user4@example.com",
  77. AuthorName: "User Four",
  78. Message: "message1",
  79. },
  80. {
  81. Sha1: "abcdef2",
  82. CommitterEmail: "user2@example.com",
  83. CommitterName: "User Two",
  84. AuthorEmail: "user2@example.com",
  85. AuthorName: "User Two",
  86. Message: "message2",
  87. },
  88. }
  89. pushCommits.Len = len(pushCommits.Commits)
  90. payloadCommits := pushCommits.ToAPIPayloadCommits("/username/reponame")
  91. if assert.Len(t, payloadCommits, 2) {
  92. assert.Equal(t, "abcdef1", payloadCommits[0].ID)
  93. assert.Equal(t, "message1", payloadCommits[0].Message)
  94. assert.Equal(t, "/username/reponame/commit/abcdef1", payloadCommits[0].URL)
  95. assert.Equal(t, "User Two", payloadCommits[0].Committer.Name)
  96. assert.Equal(t, "user2", payloadCommits[0].Committer.UserName)
  97. assert.Equal(t, "User Four", payloadCommits[0].Author.Name)
  98. assert.Equal(t, "user4", payloadCommits[0].Author.UserName)
  99. assert.Equal(t, "abcdef2", payloadCommits[1].ID)
  100. assert.Equal(t, "message2", payloadCommits[1].Message)
  101. assert.Equal(t, "/username/reponame/commit/abcdef2", payloadCommits[1].URL)
  102. assert.Equal(t, "User Two", payloadCommits[1].Committer.Name)
  103. assert.Equal(t, "user2", payloadCommits[1].Committer.UserName)
  104. assert.Equal(t, "User Two", payloadCommits[1].Author.Name)
  105. assert.Equal(t, "user2", payloadCommits[1].Author.UserName)
  106. }
  107. }
  108. func TestPushCommits_AvatarLink(t *testing.T) {
  109. pushCommits := NewPushCommits()
  110. pushCommits.Commits = []*PushCommit{
  111. {
  112. Sha1: "abcdef1",
  113. CommitterEmail: "user2@example.com",
  114. CommitterName: "User Two",
  115. AuthorEmail: "user4@example.com",
  116. AuthorName: "User Four",
  117. Message: "message1",
  118. },
  119. {
  120. Sha1: "abcdef2",
  121. CommitterEmail: "user2@example.com",
  122. CommitterName: "User Two",
  123. AuthorEmail: "user2@example.com",
  124. AuthorName: "User Two",
  125. Message: "message2",
  126. },
  127. }
  128. pushCommits.Len = len(pushCommits.Commits)
  129. assert.Equal(t,
  130. "https://secure.gravatar.com/avatar/ab53a2911ddf9b4817ac01ddcd3d975f?d=identicon",
  131. pushCommits.AvatarLink("user2@example.com"))
  132. assert.Equal(t,
  133. "https://secure.gravatar.com/avatar/19ade630b94e1e0535b3df7387434154?d=identicon",
  134. pushCommits.AvatarLink("nonexistent@example.com"))
  135. }
  136. func TestRegExp_issueReferenceKeywordsPat(t *testing.T) {
  137. trueTestCases := []string{
  138. "#2",
  139. "[#2]",
  140. "please see go-gitea/gitea#5",
  141. }
  142. falseTestCases := []string{
  143. "kb#2",
  144. "#2xy",
  145. }
  146. for _, testCase := range trueTestCases {
  147. assert.True(t, issueReferenceKeywordsPat.MatchString(testCase))
  148. }
  149. for _, testCase := range falseTestCases {
  150. assert.False(t, issueReferenceKeywordsPat.MatchString(testCase))
  151. }
  152. }
  153. func Test_getIssueFromRef(t *testing.T) {
  154. assert.NoError(t, PrepareTestDatabase())
  155. repo := AssertExistsAndLoadBean(t, &Repository{ID: 1}).(*Repository)
  156. for _, test := range []struct {
  157. Ref string
  158. ExpectedIssueID int64
  159. }{
  160. {"#2", 2},
  161. {"reopen #2", 2},
  162. {"user2/repo2#1", 4},
  163. {"fixes user2/repo2#1", 4},
  164. {"fixes: user2/repo2#1", 4},
  165. } {
  166. issue, err := getIssueFromRef(repo, test.Ref)
  167. assert.NoError(t, err)
  168. if assert.NotNil(t, issue) {
  169. assert.EqualValues(t, test.ExpectedIssueID, issue.ID)
  170. }
  171. }
  172. for _, badRef := range []string{
  173. "doesnotexist/doesnotexist#1",
  174. fmt.Sprintf("#%d", NonexistentID),
  175. } {
  176. issue, err := getIssueFromRef(repo, badRef)
  177. assert.NoError(t, err)
  178. assert.Nil(t, issue)
  179. }
  180. }
  181. func TestUpdateIssuesCommit(t *testing.T) {
  182. assert.NoError(t, PrepareTestDatabase())
  183. pushCommits := []*PushCommit{
  184. {
  185. Sha1: "abcdef1",
  186. CommitterEmail: "user2@example.com",
  187. CommitterName: "User Two",
  188. AuthorEmail: "user4@example.com",
  189. AuthorName: "User Four",
  190. Message: "start working on #FST-1, #1",
  191. },
  192. {
  193. Sha1: "abcdef2",
  194. CommitterEmail: "user2@example.com",
  195. CommitterName: "User Two",
  196. AuthorEmail: "user2@example.com",
  197. AuthorName: "User Two",
  198. Message: "a plain message",
  199. },
  200. {
  201. Sha1: "abcdef2",
  202. CommitterEmail: "user2@example.com",
  203. CommitterName: "User Two",
  204. AuthorEmail: "user2@example.com",
  205. AuthorName: "User Two",
  206. Message: "close #2",
  207. },
  208. }
  209. user := AssertExistsAndLoadBean(t, &User{ID: 2}).(*User)
  210. repo := AssertExistsAndLoadBean(t, &Repository{ID: 1}).(*Repository)
  211. repo.Owner = user
  212. commentBean := &Comment{
  213. Type: CommentTypeCommitRef,
  214. CommitSHA: "abcdef1",
  215. PosterID: user.ID,
  216. IssueID: 1,
  217. }
  218. issueBean := &Issue{RepoID: repo.ID, Index: 2}
  219. AssertNotExistsBean(t, commentBean)
  220. AssertNotExistsBean(t, &Issue{RepoID: repo.ID, Index: 2}, "is_closed=1")
  221. assert.NoError(t, UpdateIssuesCommit(user, repo, pushCommits, repo.DefaultBranch))
  222. AssertExistsAndLoadBean(t, commentBean)
  223. AssertExistsAndLoadBean(t, issueBean, "is_closed=1")
  224. CheckConsistencyFor(t, &Action{})
  225. // Test that push to a non-default branch closes no issue.
  226. pushCommits = []*PushCommit{
  227. {
  228. Sha1: "abcdef1",
  229. CommitterEmail: "user2@example.com",
  230. CommitterName: "User Two",
  231. AuthorEmail: "user4@example.com",
  232. AuthorName: "User Four",
  233. Message: "close #1",
  234. },
  235. }
  236. repo = AssertExistsAndLoadBean(t, &Repository{ID: 3}).(*Repository)
  237. commentBean = &Comment{
  238. Type: CommentTypeCommitRef,
  239. CommitSHA: "abcdef1",
  240. PosterID: user.ID,
  241. IssueID: 6,
  242. }
  243. issueBean = &Issue{RepoID: repo.ID, Index: 1}
  244. AssertNotExistsBean(t, commentBean)
  245. AssertNotExistsBean(t, &Issue{RepoID: repo.ID, Index: 1}, "is_closed=1")
  246. assert.NoError(t, UpdateIssuesCommit(user, repo, pushCommits, "non-existing-branch"))
  247. AssertExistsAndLoadBean(t, commentBean)
  248. AssertNotExistsBean(t, issueBean, "is_closed=1")
  249. CheckConsistencyFor(t, &Action{})
  250. }
  251. func TestUpdateIssuesCommit_Colon(t *testing.T) {
  252. assert.NoError(t, PrepareTestDatabase())
  253. pushCommits := []*PushCommit{
  254. {
  255. Sha1: "abcdef2",
  256. CommitterEmail: "user2@example.com",
  257. CommitterName: "User Two",
  258. AuthorEmail: "user2@example.com",
  259. AuthorName: "User Two",
  260. Message: "close: #2",
  261. },
  262. }
  263. user := AssertExistsAndLoadBean(t, &User{ID: 2}).(*User)
  264. repo := AssertExistsAndLoadBean(t, &Repository{ID: 1}).(*Repository)
  265. repo.Owner = user
  266. issueBean := &Issue{RepoID: repo.ID, Index: 2}
  267. AssertNotExistsBean(t, &Issue{RepoID: repo.ID, Index: 2}, "is_closed=1")
  268. assert.NoError(t, UpdateIssuesCommit(user, repo, pushCommits, repo.DefaultBranch))
  269. AssertExistsAndLoadBean(t, issueBean, "is_closed=1")
  270. CheckConsistencyFor(t, &Action{})
  271. }
  272. func TestUpdateIssuesCommit_Issue5957(t *testing.T) {
  273. assert.NoError(t, PrepareTestDatabase())
  274. user := AssertExistsAndLoadBean(t, &User{ID: 2}).(*User)
  275. // Test that push to a non-default branch closes an issue.
  276. pushCommits := []*PushCommit{
  277. {
  278. Sha1: "abcdef1",
  279. CommitterEmail: "user2@example.com",
  280. CommitterName: "User Two",
  281. AuthorEmail: "user4@example.com",
  282. AuthorName: "User Four",
  283. Message: "close #2",
  284. },
  285. }
  286. repo := AssertExistsAndLoadBean(t, &Repository{ID: 2}).(*Repository)
  287. commentBean := &Comment{
  288. Type: CommentTypeCommitRef,
  289. CommitSHA: "abcdef1",
  290. PosterID: user.ID,
  291. IssueID: 7,
  292. }
  293. issueBean := &Issue{RepoID: repo.ID, Index: 2, ID: 7}
  294. AssertNotExistsBean(t, commentBean)
  295. AssertNotExistsBean(t, issueBean, "is_closed=1")
  296. assert.NoError(t, UpdateIssuesCommit(user, repo, pushCommits, "non-existing-branch"))
  297. AssertExistsAndLoadBean(t, commentBean)
  298. AssertExistsAndLoadBean(t, issueBean, "is_closed=1")
  299. CheckConsistencyFor(t, &Action{})
  300. }
  301. func TestUpdateIssuesCommit_AnotherRepo(t *testing.T) {
  302. assert.NoError(t, PrepareTestDatabase())
  303. user := AssertExistsAndLoadBean(t, &User{ID: 2}).(*User)
  304. // Test that a push to default branch closes issue in another repo
  305. // If the user also has push permissions to that repo
  306. pushCommits := []*PushCommit{
  307. {
  308. Sha1: "abcdef1",
  309. CommitterEmail: "user2@example.com",
  310. CommitterName: "User Two",
  311. AuthorEmail: "user2@example.com",
  312. AuthorName: "User Two",
  313. Message: "close user2/repo1#1",
  314. },
  315. }
  316. repo := AssertExistsAndLoadBean(t, &Repository{ID: 2}).(*Repository)
  317. commentBean := &Comment{
  318. Type: CommentTypeCommitRef,
  319. CommitSHA: "abcdef1",
  320. PosterID: user.ID,
  321. IssueID: 1,
  322. }
  323. issueBean := &Issue{RepoID: 1, Index: 1, ID: 1}
  324. AssertNotExistsBean(t, commentBean)
  325. AssertNotExistsBean(t, issueBean, "is_closed=1")
  326. assert.NoError(t, UpdateIssuesCommit(user, repo, pushCommits, repo.DefaultBranch))
  327. AssertExistsAndLoadBean(t, commentBean)
  328. AssertExistsAndLoadBean(t, issueBean, "is_closed=1")
  329. CheckConsistencyFor(t, &Action{})
  330. }
  331. func TestUpdateIssuesCommit_AnotherRepoNoPermission(t *testing.T) {
  332. assert.NoError(t, PrepareTestDatabase())
  333. user := AssertExistsAndLoadBean(t, &User{ID: 10}).(*User)
  334. // Test that a push with close reference *can not* close issue
  335. // If the commiter doesn't have push rights in that repo
  336. pushCommits := []*PushCommit{
  337. {
  338. Sha1: "abcdef3",
  339. CommitterEmail: "user10@example.com",
  340. CommitterName: "User Ten",
  341. AuthorEmail: "user10@example.com",
  342. AuthorName: "User Ten",
  343. Message: "close user3/repo3#1",
  344. },
  345. }
  346. repo := AssertExistsAndLoadBean(t, &Repository{ID: 6}).(*Repository)
  347. commentBean := &Comment{
  348. Type: CommentTypeCommitRef,
  349. CommitSHA: "abcdef3",
  350. PosterID: user.ID,
  351. IssueID: 6,
  352. }
  353. issueBean := &Issue{RepoID: 3, Index: 1, ID: 6}
  354. AssertNotExistsBean(t, commentBean)
  355. AssertNotExistsBean(t, issueBean, "is_closed=1")
  356. assert.NoError(t, UpdateIssuesCommit(user, repo, pushCommits, repo.DefaultBranch))
  357. AssertExistsAndLoadBean(t, commentBean)
  358. AssertNotExistsBean(t, issueBean, "is_closed=1")
  359. CheckConsistencyFor(t, &Action{})
  360. }
  361. func TestTransferRepoAction(t *testing.T) {
  362. assert.NoError(t, PrepareTestDatabase())
  363. user2 := AssertExistsAndLoadBean(t, &User{ID: 2}).(*User)
  364. user4 := AssertExistsAndLoadBean(t, &User{ID: 4}).(*User)
  365. repo := AssertExistsAndLoadBean(t, &Repository{ID: 1, OwnerID: user2.ID}).(*Repository)
  366. repo.OwnerID = user4.ID
  367. repo.Owner = user4
  368. actionBean := &Action{
  369. OpType: ActionTransferRepo,
  370. ActUserID: user2.ID,
  371. ActUser: user2,
  372. RepoID: repo.ID,
  373. Repo: repo,
  374. IsPrivate: repo.IsPrivate,
  375. }
  376. AssertNotExistsBean(t, actionBean)
  377. assert.NoError(t, TransferRepoAction(user2, user2, repo))
  378. AssertExistsAndLoadBean(t, actionBean)
  379. _, err := x.ID(repo.ID).Cols("owner_id").Update(repo)
  380. assert.NoError(t, err)
  381. CheckConsistencyFor(t, &Action{})
  382. }
  383. func TestMergePullRequestAction(t *testing.T) {
  384. assert.NoError(t, PrepareTestDatabase())
  385. user := AssertExistsAndLoadBean(t, &User{ID: 2}).(*User)
  386. repo := AssertExistsAndLoadBean(t, &Repository{ID: 1, OwnerID: user.ID}).(*Repository)
  387. repo.Owner = user
  388. issue := AssertExistsAndLoadBean(t, &Issue{ID: 3, RepoID: repo.ID}).(*Issue)
  389. actionBean := &Action{
  390. OpType: ActionMergePullRequest,
  391. ActUserID: user.ID,
  392. ActUser: user,
  393. RepoID: repo.ID,
  394. Repo: repo,
  395. IsPrivate: repo.IsPrivate,
  396. }
  397. AssertNotExistsBean(t, actionBean)
  398. assert.NoError(t, MergePullRequestAction(user, repo, issue))
  399. AssertExistsAndLoadBean(t, actionBean)
  400. CheckConsistencyFor(t, &Action{})
  401. }
  402. func TestGetFeeds(t *testing.T) {
  403. // test with an individual user
  404. assert.NoError(t, PrepareTestDatabase())
  405. user := AssertExistsAndLoadBean(t, &User{ID: 2}).(*User)
  406. actions, err := GetFeeds(GetFeedsOptions{
  407. RequestedUser: user,
  408. RequestingUserID: user.ID,
  409. IncludePrivate: true,
  410. OnlyPerformedBy: false,
  411. IncludeDeleted: true,
  412. })
  413. assert.NoError(t, err)
  414. if assert.Len(t, actions, 1) {
  415. assert.EqualValues(t, 1, actions[0].ID)
  416. assert.EqualValues(t, user.ID, actions[0].UserID)
  417. }
  418. actions, err = GetFeeds(GetFeedsOptions{
  419. RequestedUser: user,
  420. RequestingUserID: user.ID,
  421. IncludePrivate: false,
  422. OnlyPerformedBy: false,
  423. })
  424. assert.NoError(t, err)
  425. assert.Len(t, actions, 0)
  426. }
  427. func TestGetFeeds2(t *testing.T) {
  428. // test with an organization user
  429. assert.NoError(t, PrepareTestDatabase())
  430. org := AssertExistsAndLoadBean(t, &User{ID: 3}).(*User)
  431. const userID = 2 // user2 is an owner of the organization
  432. actions, err := GetFeeds(GetFeedsOptions{
  433. RequestedUser: org,
  434. RequestingUserID: userID,
  435. IncludePrivate: true,
  436. OnlyPerformedBy: false,
  437. IncludeDeleted: true,
  438. })
  439. assert.NoError(t, err)
  440. assert.Len(t, actions, 1)
  441. if assert.Len(t, actions, 1) {
  442. assert.EqualValues(t, 2, actions[0].ID)
  443. assert.EqualValues(t, org.ID, actions[0].UserID)
  444. }
  445. actions, err = GetFeeds(GetFeedsOptions{
  446. RequestedUser: org,
  447. RequestingUserID: userID,
  448. IncludePrivate: false,
  449. OnlyPerformedBy: false,
  450. IncludeDeleted: true,
  451. })
  452. assert.NoError(t, err)
  453. assert.Len(t, actions, 0)
  454. }