Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

action_test.go 11KB

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