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