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 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. // Copyright 2020 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package activities_test
  4. import (
  5. "fmt"
  6. "path"
  7. "testing"
  8. activities_model "code.gitea.io/gitea/models/activities"
  9. "code.gitea.io/gitea/models/db"
  10. issue_model "code.gitea.io/gitea/models/issues"
  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/setting"
  15. "github.com/stretchr/testify/assert"
  16. )
  17. func TestAction_GetRepoPath(t *testing.T) {
  18. assert.NoError(t, unittest.PrepareTestDatabase())
  19. repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
  20. owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
  21. action := &activities_model.Action{RepoID: repo.ID}
  22. assert.Equal(t, path.Join(owner.Name, repo.Name), action.GetRepoPath(db.DefaultContext))
  23. }
  24. func TestAction_GetRepoLink(t *testing.T) {
  25. assert.NoError(t, unittest.PrepareTestDatabase())
  26. repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
  27. owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
  28. comment := unittest.AssertExistsAndLoadBean(t, &issue_model.Comment{ID: 2})
  29. action := &activities_model.Action{RepoID: repo.ID, CommentID: comment.ID}
  30. setting.AppSubURL = "/suburl"
  31. expected := path.Join(setting.AppSubURL, owner.Name, repo.Name)
  32. assert.Equal(t, expected, action.GetRepoLink(db.DefaultContext))
  33. assert.Equal(t, repo.HTMLURL(), action.GetRepoAbsoluteLink(db.DefaultContext))
  34. assert.Equal(t, comment.HTMLURL(db.DefaultContext), action.GetCommentHTMLURL(db.DefaultContext))
  35. }
  36. func TestGetFeeds(t *testing.T) {
  37. // test with an individual user
  38. assert.NoError(t, unittest.PrepareTestDatabase())
  39. user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
  40. actions, count, err := activities_model.GetFeeds(db.DefaultContext, activities_model.GetFeedsOptions{
  41. RequestedUser: user,
  42. Actor: user,
  43. IncludePrivate: true,
  44. OnlyPerformedBy: false,
  45. IncludeDeleted: true,
  46. })
  47. assert.NoError(t, err)
  48. if assert.Len(t, actions, 1) {
  49. assert.EqualValues(t, 1, actions[0].ID)
  50. assert.EqualValues(t, user.ID, actions[0].UserID)
  51. }
  52. assert.Equal(t, int64(1), count)
  53. actions, count, err = activities_model.GetFeeds(db.DefaultContext, activities_model.GetFeedsOptions{
  54. RequestedUser: user,
  55. Actor: user,
  56. IncludePrivate: false,
  57. OnlyPerformedBy: false,
  58. })
  59. assert.NoError(t, err)
  60. assert.Len(t, actions, 0)
  61. assert.Equal(t, int64(0), count)
  62. }
  63. func TestGetFeedsForRepos(t *testing.T) {
  64. assert.NoError(t, unittest.PrepareTestDatabase())
  65. user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
  66. privRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2})
  67. pubRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 8})
  68. // private repo & no login
  69. actions, count, err := activities_model.GetFeeds(db.DefaultContext, activities_model.GetFeedsOptions{
  70. RequestedRepo: privRepo,
  71. IncludePrivate: true,
  72. })
  73. assert.NoError(t, err)
  74. assert.Len(t, actions, 0)
  75. assert.Equal(t, int64(0), count)
  76. // public repo & no login
  77. actions, count, err = activities_model.GetFeeds(db.DefaultContext, activities_model.GetFeedsOptions{
  78. RequestedRepo: pubRepo,
  79. IncludePrivate: true,
  80. })
  81. assert.NoError(t, err)
  82. assert.Len(t, actions, 1)
  83. assert.Equal(t, int64(1), count)
  84. // private repo and login
  85. actions, count, err = activities_model.GetFeeds(db.DefaultContext, activities_model.GetFeedsOptions{
  86. RequestedRepo: privRepo,
  87. IncludePrivate: true,
  88. Actor: user,
  89. })
  90. assert.NoError(t, err)
  91. assert.Len(t, actions, 1)
  92. assert.Equal(t, int64(1), count)
  93. // public repo & login
  94. actions, count, err = activities_model.GetFeeds(db.DefaultContext, activities_model.GetFeedsOptions{
  95. RequestedRepo: pubRepo,
  96. IncludePrivate: true,
  97. Actor: user,
  98. })
  99. assert.NoError(t, err)
  100. assert.Len(t, actions, 1)
  101. assert.Equal(t, int64(1), count)
  102. }
  103. func TestGetFeeds2(t *testing.T) {
  104. // test with an organization user
  105. assert.NoError(t, unittest.PrepareTestDatabase())
  106. org := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3})
  107. user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
  108. actions, count, err := activities_model.GetFeeds(db.DefaultContext, activities_model.GetFeedsOptions{
  109. RequestedUser: org,
  110. Actor: user,
  111. IncludePrivate: true,
  112. OnlyPerformedBy: false,
  113. IncludeDeleted: true,
  114. })
  115. assert.NoError(t, err)
  116. assert.Len(t, actions, 1)
  117. if assert.Len(t, actions, 1) {
  118. assert.EqualValues(t, 2, actions[0].ID)
  119. assert.EqualValues(t, org.ID, actions[0].UserID)
  120. }
  121. assert.Equal(t, int64(1), count)
  122. actions, count, err = activities_model.GetFeeds(db.DefaultContext, activities_model.GetFeedsOptions{
  123. RequestedUser: org,
  124. Actor: user,
  125. IncludePrivate: false,
  126. OnlyPerformedBy: false,
  127. IncludeDeleted: true,
  128. })
  129. assert.NoError(t, err)
  130. assert.Len(t, actions, 0)
  131. assert.Equal(t, int64(0), count)
  132. }
  133. func TestActivityReadable(t *testing.T) {
  134. tt := []struct {
  135. desc string
  136. user *user_model.User
  137. doer *user_model.User
  138. result bool
  139. }{{
  140. desc: "user should see own activity",
  141. user: &user_model.User{ID: 1},
  142. doer: &user_model.User{ID: 1},
  143. result: true,
  144. }, {
  145. desc: "anon should see activity if public",
  146. user: &user_model.User{ID: 1},
  147. result: true,
  148. }, {
  149. desc: "anon should NOT see activity",
  150. user: &user_model.User{ID: 1, KeepActivityPrivate: true},
  151. result: false,
  152. }, {
  153. desc: "user should see own activity if private too",
  154. user: &user_model.User{ID: 1, KeepActivityPrivate: true},
  155. doer: &user_model.User{ID: 1},
  156. result: true,
  157. }, {
  158. desc: "other user should NOT see activity",
  159. user: &user_model.User{ID: 1, KeepActivityPrivate: true},
  160. doer: &user_model.User{ID: 2},
  161. result: false,
  162. }, {
  163. desc: "admin should see activity",
  164. user: &user_model.User{ID: 1, KeepActivityPrivate: true},
  165. doer: &user_model.User{ID: 2, IsAdmin: true},
  166. result: true,
  167. }}
  168. for _, test := range tt {
  169. assert.Equal(t, test.result, activities_model.ActivityReadable(test.user, test.doer), test.desc)
  170. }
  171. }
  172. func TestNotifyWatchers(t *testing.T) {
  173. assert.NoError(t, unittest.PrepareTestDatabase())
  174. action := &activities_model.Action{
  175. ActUserID: 8,
  176. RepoID: 1,
  177. OpType: activities_model.ActionStarRepo,
  178. }
  179. assert.NoError(t, activities_model.NotifyWatchers(db.DefaultContext, action))
  180. // One watchers are inactive, thus action is only created for user 8, 1, 4, 11
  181. unittest.AssertExistsAndLoadBean(t, &activities_model.Action{
  182. ActUserID: action.ActUserID,
  183. UserID: 8,
  184. RepoID: action.RepoID,
  185. OpType: action.OpType,
  186. })
  187. unittest.AssertExistsAndLoadBean(t, &activities_model.Action{
  188. ActUserID: action.ActUserID,
  189. UserID: 1,
  190. RepoID: action.RepoID,
  191. OpType: action.OpType,
  192. })
  193. unittest.AssertExistsAndLoadBean(t, &activities_model.Action{
  194. ActUserID: action.ActUserID,
  195. UserID: 4,
  196. RepoID: action.RepoID,
  197. OpType: action.OpType,
  198. })
  199. unittest.AssertExistsAndLoadBean(t, &activities_model.Action{
  200. ActUserID: action.ActUserID,
  201. UserID: 11,
  202. RepoID: action.RepoID,
  203. OpType: action.OpType,
  204. })
  205. }
  206. func TestGetFeedsCorrupted(t *testing.T) {
  207. assert.NoError(t, unittest.PrepareTestDatabase())
  208. user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
  209. unittest.AssertExistsAndLoadBean(t, &activities_model.Action{
  210. ID: 8,
  211. RepoID: 1700,
  212. })
  213. actions, count, err := activities_model.GetFeeds(db.DefaultContext, activities_model.GetFeedsOptions{
  214. RequestedUser: user,
  215. Actor: user,
  216. IncludePrivate: true,
  217. })
  218. assert.NoError(t, err)
  219. assert.Len(t, actions, 0)
  220. assert.Equal(t, int64(0), count)
  221. }
  222. func TestConsistencyUpdateAction(t *testing.T) {
  223. if !setting.Database.Type.IsSQLite3() {
  224. t.Skip("Test is only for SQLite database.")
  225. }
  226. assert.NoError(t, unittest.PrepareTestDatabase())
  227. id := 8
  228. unittest.AssertExistsAndLoadBean(t, &activities_model.Action{
  229. ID: int64(id),
  230. })
  231. _, err := db.GetEngine(db.DefaultContext).Exec(`UPDATE action SET created_unix = "" WHERE id = ?`, id)
  232. assert.NoError(t, err)
  233. actions := make([]*activities_model.Action, 0, 1)
  234. //
  235. // XORM returns an error when created_unix is a string
  236. //
  237. err = db.GetEngine(db.DefaultContext).Where("id = ?", id).Find(&actions)
  238. if assert.Error(t, err) {
  239. assert.Contains(t, err.Error(), "type string to a int64: invalid syntax")
  240. }
  241. //
  242. // Get rid of incorrectly set created_unix
  243. //
  244. count, err := activities_model.CountActionCreatedUnixString(db.DefaultContext)
  245. assert.NoError(t, err)
  246. assert.EqualValues(t, 1, count)
  247. count, err = activities_model.FixActionCreatedUnixString(db.DefaultContext)
  248. assert.NoError(t, err)
  249. assert.EqualValues(t, 1, count)
  250. count, err = activities_model.CountActionCreatedUnixString(db.DefaultContext)
  251. assert.NoError(t, err)
  252. assert.EqualValues(t, 0, count)
  253. count, err = activities_model.FixActionCreatedUnixString(db.DefaultContext)
  254. assert.NoError(t, err)
  255. assert.EqualValues(t, 0, count)
  256. //
  257. // XORM must be happy now
  258. //
  259. assert.NoError(t, db.GetEngine(db.DefaultContext).Where("id = ?", id).Find(&actions))
  260. unittest.CheckConsistencyFor(t, &activities_model.Action{})
  261. }
  262. func TestDeleteIssueActions(t *testing.T) {
  263. assert.NoError(t, unittest.PrepareTestDatabase())
  264. // load an issue
  265. issue := unittest.AssertExistsAndLoadBean(t, &issue_model.Issue{ID: 4})
  266. assert.NotEqualValues(t, issue.ID, issue.Index) // it needs to use different ID/Index to test the DeleteIssueActions to delete some actions by IssueIndex
  267. // insert a comment
  268. err := db.Insert(db.DefaultContext, &issue_model.Comment{Type: issue_model.CommentTypeComment, IssueID: issue.ID})
  269. assert.NoError(t, err)
  270. comment := unittest.AssertExistsAndLoadBean(t, &issue_model.Comment{Type: issue_model.CommentTypeComment, IssueID: issue.ID})
  271. // truncate action table and insert some actions
  272. err = db.TruncateBeans(db.DefaultContext, &activities_model.Action{})
  273. assert.NoError(t, err)
  274. err = db.Insert(db.DefaultContext, &activities_model.Action{
  275. OpType: activities_model.ActionCommentIssue,
  276. CommentID: comment.ID,
  277. })
  278. assert.NoError(t, err)
  279. err = db.Insert(db.DefaultContext, &activities_model.Action{
  280. OpType: activities_model.ActionCreateIssue,
  281. RepoID: issue.RepoID,
  282. Content: fmt.Sprintf("%d|content...", issue.Index),
  283. })
  284. assert.NoError(t, err)
  285. // assert that the actions exist, then delete them
  286. unittest.AssertCount(t, &activities_model.Action{}, 2)
  287. assert.NoError(t, activities_model.DeleteIssueActions(db.DefaultContext, issue.RepoID, issue.ID, issue.Index))
  288. unittest.AssertCount(t, &activities_model.Action{}, 0)
  289. }