gitea源码

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. // Copyright 2020 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package integration
  4. import (
  5. "fmt"
  6. "net/http"
  7. "testing"
  8. activities_model "code.gitea.io/gitea/models/activities"
  9. auth_model "code.gitea.io/gitea/models/auth"
  10. repo_model "code.gitea.io/gitea/models/repo"
  11. "code.gitea.io/gitea/models/unittest"
  12. user_model "code.gitea.io/gitea/models/user"
  13. api "code.gitea.io/gitea/modules/structs"
  14. "code.gitea.io/gitea/tests"
  15. "github.com/stretchr/testify/assert"
  16. )
  17. func TestAPINotification(t *testing.T) {
  18. defer tests.PrepareTestEnv(t)()
  19. user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
  20. repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
  21. thread5 := unittest.AssertExistsAndLoadBean(t, &activities_model.Notification{ID: 5})
  22. assert.NoError(t, thread5.LoadAttributes(t.Context()))
  23. session := loginUser(t, user2.Name)
  24. token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteNotification, auth_model.AccessTokenScopeWriteRepository)
  25. MakeRequest(t, NewRequest(t, "GET", "/api/v1/notifications"), http.StatusUnauthorized)
  26. // -- GET /notifications --
  27. // test filter
  28. since := "2000-01-01T00%3A50%3A01%2B00%3A00" // 946687801
  29. req := NewRequest(t, "GET", "/api/v1/notifications?since="+since).
  30. AddTokenAuth(token)
  31. resp := MakeRequest(t, req, http.StatusOK)
  32. var apiNL []api.NotificationThread
  33. DecodeJSON(t, resp, &apiNL)
  34. assert.Len(t, apiNL, 1)
  35. assert.EqualValues(t, 5, apiNL[0].ID)
  36. // test filter
  37. before := "2000-01-01T01%3A06%3A59%2B00%3A00" // 946688819
  38. req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/notifications?all=%s&before=%s", "true", before)).
  39. AddTokenAuth(token)
  40. resp = MakeRequest(t, req, http.StatusOK)
  41. DecodeJSON(t, resp, &apiNL)
  42. assert.Len(t, apiNL, 3)
  43. assert.EqualValues(t, 4, apiNL[0].ID)
  44. assert.True(t, apiNL[0].Unread)
  45. assert.False(t, apiNL[0].Pinned)
  46. assert.EqualValues(t, 3, apiNL[1].ID)
  47. assert.False(t, apiNL[1].Unread)
  48. assert.True(t, apiNL[1].Pinned)
  49. assert.EqualValues(t, 2, apiNL[2].ID)
  50. assert.False(t, apiNL[2].Unread)
  51. assert.False(t, apiNL[2].Pinned)
  52. // -- GET /repos/{owner}/{repo}/notifications --
  53. req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/%s/notifications?status-types=unread", user2.Name, repo1.Name)).
  54. AddTokenAuth(token)
  55. resp = MakeRequest(t, req, http.StatusOK)
  56. DecodeJSON(t, resp, &apiNL)
  57. assert.Len(t, apiNL, 1)
  58. assert.EqualValues(t, 4, apiNL[0].ID)
  59. // -- GET /repos/{owner}/{repo}/notifications -- multiple status-types
  60. req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/%s/notifications?status-types=unread&status-types=pinned", user2.Name, repo1.Name)).
  61. AddTokenAuth(token)
  62. resp = MakeRequest(t, req, http.StatusOK)
  63. DecodeJSON(t, resp, &apiNL)
  64. assert.Len(t, apiNL, 2)
  65. assert.EqualValues(t, 4, apiNL[0].ID)
  66. assert.True(t, apiNL[0].Unread)
  67. assert.False(t, apiNL[0].Pinned)
  68. assert.EqualValues(t, 3, apiNL[1].ID)
  69. assert.False(t, apiNL[1].Unread)
  70. assert.True(t, apiNL[1].Pinned)
  71. MakeRequest(t, NewRequest(t, "GET", fmt.Sprintf("/api/v1/notifications/threads/%d", 1)), http.StatusUnauthorized)
  72. // -- GET /notifications/threads/{id} --
  73. // get forbidden
  74. req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/notifications/threads/%d", 1)).
  75. AddTokenAuth(token)
  76. MakeRequest(t, req, http.StatusForbidden)
  77. // get own
  78. req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/notifications/threads/%d", thread5.ID)).
  79. AddTokenAuth(token)
  80. resp = MakeRequest(t, req, http.StatusOK)
  81. var apiN api.NotificationThread
  82. DecodeJSON(t, resp, &apiN)
  83. assert.EqualValues(t, 5, apiN.ID)
  84. assert.False(t, apiN.Pinned)
  85. assert.True(t, apiN.Unread)
  86. assert.Equal(t, "issue4", apiN.Subject.Title)
  87. assert.EqualValues(t, "Issue", apiN.Subject.Type)
  88. assert.Equal(t, thread5.Issue.APIURL(t.Context()), apiN.Subject.URL)
  89. assert.Equal(t, thread5.Repository.HTMLURL(), apiN.Repository.HTMLURL)
  90. MakeRequest(t, NewRequest(t, "GET", "/api/v1/notifications/new"), http.StatusUnauthorized)
  91. newStruct := struct {
  92. New int64 `json:"new"`
  93. }{}
  94. // -- check notifications --
  95. req = NewRequest(t, "GET", "/api/v1/notifications/new").
  96. AddTokenAuth(token)
  97. resp = MakeRequest(t, req, http.StatusOK)
  98. DecodeJSON(t, resp, &newStruct)
  99. assert.Positive(t, newStruct.New)
  100. // -- mark notifications as read --
  101. req = NewRequest(t, "GET", "/api/v1/notifications?status-types=unread").
  102. AddTokenAuth(token)
  103. resp = MakeRequest(t, req, http.StatusOK)
  104. DecodeJSON(t, resp, &apiNL)
  105. assert.Len(t, apiNL, 2)
  106. lastReadAt := "2000-01-01T00%3A50%3A01%2B00%3A00" // 946687801 <- only Notification 4 is in this filter ...
  107. req = NewRequest(t, "PUT", fmt.Sprintf("/api/v1/repos/%s/%s/notifications?last_read_at=%s", user2.Name, repo1.Name, lastReadAt)).
  108. AddTokenAuth(token)
  109. MakeRequest(t, req, http.StatusResetContent)
  110. req = NewRequest(t, "GET", "/api/v1/notifications?status-types=unread").
  111. AddTokenAuth(token)
  112. resp = MakeRequest(t, req, http.StatusOK)
  113. DecodeJSON(t, resp, &apiNL)
  114. assert.Len(t, apiNL, 1)
  115. // -- PATCH /notifications/threads/{id} --
  116. req = NewRequest(t, "PATCH", fmt.Sprintf("/api/v1/notifications/threads/%d", thread5.ID)).
  117. AddTokenAuth(token)
  118. MakeRequest(t, req, http.StatusResetContent)
  119. assert.Equal(t, activities_model.NotificationStatusUnread, thread5.Status)
  120. thread5 = unittest.AssertExistsAndLoadBean(t, &activities_model.Notification{ID: 5})
  121. assert.Equal(t, activities_model.NotificationStatusRead, thread5.Status)
  122. // -- check notifications --
  123. req = NewRequest(t, "GET", "/api/v1/notifications/new").
  124. AddTokenAuth(token)
  125. resp = MakeRequest(t, req, http.StatusOK)
  126. DecodeJSON(t, resp, &newStruct)
  127. assert.Zero(t, newStruct.New)
  128. }
  129. func TestAPINotificationPUT(t *testing.T) {
  130. defer tests.PrepareTestEnv(t)()
  131. user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
  132. thread5 := unittest.AssertExistsAndLoadBean(t, &activities_model.Notification{ID: 5})
  133. assert.NoError(t, thread5.LoadAttributes(t.Context()))
  134. session := loginUser(t, user2.Name)
  135. token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteNotification)
  136. // Check notifications are as expected
  137. req := NewRequest(t, "GET", "/api/v1/notifications?all=true").
  138. AddTokenAuth(token)
  139. resp := MakeRequest(t, req, http.StatusOK)
  140. var apiNL []api.NotificationThread
  141. DecodeJSON(t, resp, &apiNL)
  142. assert.Len(t, apiNL, 4)
  143. assert.EqualValues(t, 5, apiNL[0].ID)
  144. assert.True(t, apiNL[0].Unread)
  145. assert.False(t, apiNL[0].Pinned)
  146. assert.EqualValues(t, 4, apiNL[1].ID)
  147. assert.True(t, apiNL[1].Unread)
  148. assert.False(t, apiNL[1].Pinned)
  149. assert.EqualValues(t, 3, apiNL[2].ID)
  150. assert.False(t, apiNL[2].Unread)
  151. assert.True(t, apiNL[2].Pinned)
  152. assert.EqualValues(t, 2, apiNL[3].ID)
  153. assert.False(t, apiNL[3].Unread)
  154. assert.False(t, apiNL[3].Pinned)
  155. //
  156. // Notification ID 2 is the only one with status-type read & pinned
  157. // change it to unread.
  158. //
  159. req = NewRequest(t, "PUT", "/api/v1/notifications?status-types=read&status-type=pinned&to-status=unread").
  160. AddTokenAuth(token)
  161. resp = MakeRequest(t, req, http.StatusResetContent)
  162. DecodeJSON(t, resp, &apiNL)
  163. assert.Len(t, apiNL, 1)
  164. assert.EqualValues(t, 2, apiNL[0].ID)
  165. assert.True(t, apiNL[0].Unread)
  166. assert.False(t, apiNL[0].Pinned)
  167. //
  168. // Now nofication ID 2 is the first in the list and is unread.
  169. //
  170. req = NewRequest(t, "GET", "/api/v1/notifications?all=true").
  171. AddTokenAuth(token)
  172. resp = MakeRequest(t, req, http.StatusOK)
  173. DecodeJSON(t, resp, &apiNL)
  174. assert.Len(t, apiNL, 4)
  175. assert.EqualValues(t, 2, apiNL[0].ID)
  176. assert.True(t, apiNL[0].Unread)
  177. assert.False(t, apiNL[0].Pinned)
  178. }