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 "net/url"
10 "strings"
11 "testing"
12 "time"
13
14 auth_model "forgejo.org/models/auth"
15 "forgejo.org/models/db"
16 issues_model "forgejo.org/models/issues"
17 "forgejo.org/models/unittest"
18 user_model "forgejo.org/models/user"
19 "forgejo.org/modules/git"
20 "forgejo.org/modules/setting"
21 api "forgejo.org/modules/structs"
22 "forgejo.org/modules/test"
23 pull_service "forgejo.org/services/pull"
24 repo_service "forgejo.org/services/repository"
25 files_service "forgejo.org/services/repository/files"
26 "forgejo.org/tests"
27
28 "github.com/stretchr/testify/assert"
29 "github.com/stretchr/testify/require"
30)
31
32func TestAPIPullUpdate(t *testing.T) {
33 onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) {
34 // Create PR to test
35 user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
36 org26 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 26})
37 pr := createOutdatedPR(t, user, org26)
38
39 // Test GetDiverging
40 diffCount, err := pull_service.GetDiverging(git.DefaultContext, pr)
41 require.NoError(t, err)
42 assert.Equal(t, 1, diffCount.Behind)
43 assert.Equal(t, 1, diffCount.Ahead)
44 require.NoError(t, pr.LoadBaseRepo(db.DefaultContext))
45 require.NoError(t, pr.LoadIssue(db.DefaultContext))
46
47 session := loginUser(t, "user2")
48 token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository)
49 req := NewRequestf(t, "POST", "/api/v1/repos/%s/%s/pulls/%d/update", pr.BaseRepo.OwnerName, pr.BaseRepo.Name, pr.Issue.Index).
50 AddTokenAuth(token)
51 session.MakeRequest(t, req, http.StatusOK)
52
53 // Test GetDiverging after update
54 diffCount, err = pull_service.GetDiverging(git.DefaultContext, pr)
55 require.NoError(t, err)
56 assert.Equal(t, 0, diffCount.Behind)
57 assert.Equal(t, 2, diffCount.Ahead)
58 })
59}
60
61func TestAPIPullUpdateByRebase(t *testing.T) {
62 onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) {
63 // Create PR to test
64 user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
65 org26 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 26})
66 pr := createOutdatedPR(t, user, org26)
67
68 // Test GetDiverging
69 diffCount, err := pull_service.GetDiverging(git.DefaultContext, pr)
70 require.NoError(t, err)
71 assert.Equal(t, 1, diffCount.Behind)
72 assert.Equal(t, 1, diffCount.Ahead)
73 require.NoError(t, pr.LoadBaseRepo(db.DefaultContext))
74 require.NoError(t, pr.LoadIssue(db.DefaultContext))
75
76 session := loginUser(t, "user2")
77 token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository)
78 req := NewRequestf(t, "POST", "/api/v1/repos/%s/%s/pulls/%d/update?style=rebase", pr.BaseRepo.OwnerName, pr.BaseRepo.Name, pr.Issue.Index).
79 AddTokenAuth(token)
80 session.MakeRequest(t, req, http.StatusOK)
81
82 // Test GetDiverging after update
83 diffCount, err = pull_service.GetDiverging(git.DefaultContext, pr)
84 require.NoError(t, err)
85 assert.Equal(t, 0, diffCount.Behind)
86 assert.Equal(t, 1, diffCount.Ahead)
87 })
88}
89
90func TestAPIViewUpdateSettings(t *testing.T) {
91 onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) {
92 defer tests.PrepareTestEnv(t)()
93 // Create PR to test
94 user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
95 org26 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 26})
96 pr := createOutdatedPR(t, user, org26)
97
98 // Test GetDiverging
99 diffCount, err := pull_service.GetDiverging(git.DefaultContext, pr)
100 require.NoError(t, err)
101 assert.Equal(t, 1, diffCount.Behind)
102 assert.Equal(t, 1, diffCount.Ahead)
103 require.NoError(t, pr.LoadBaseRepo(db.DefaultContext))
104 require.NoError(t, pr.LoadIssue(db.DefaultContext))
105
106 session := loginUser(t, "user2")
107 token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeAll)
108
109 defaultUpdateStyle := "rebase"
110 editOption := api.EditRepoOption{
111 DefaultUpdateStyle: &defaultUpdateStyle,
112 }
113
114 req := NewRequestWithJSON(t, "PATCH", fmt.Sprintf("/api/v1/repos/%s/%s", pr.BaseRepo.OwnerName, pr.BaseRepo.Name), editOption).AddTokenAuth(token)
115 session.MakeRequest(t, req, http.StatusOK)
116 assertViewPullUpdate(t, pr, session, "rebase", true)
117
118 defaultUpdateStyle = "merge"
119 req = NewRequestWithJSON(t, "PATCH", fmt.Sprintf("/api/v1/repos/%s/%s", pr.BaseRepo.OwnerName, pr.BaseRepo.Name), editOption).AddTokenAuth(token)
120 session.MakeRequest(t, req, http.StatusOK)
121 assertViewPullUpdate(t, pr, session, "merge", true)
122 })
123}
124
125func TestViewPullUpdateByMerge(t *testing.T) {
126 onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) {
127 testViewPullUpdate(t, "merge")
128 })
129}
130
131func TestViewPullUpdateByRebase(t *testing.T) {
132 onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) {
133 testViewPullUpdate(t, "rebase")
134 })
135}
136
137func testViewPullUpdate(t *testing.T, updateStyle string) {
138 defer test.MockVariableValue(&setting.Repository.PullRequest.DefaultUpdateStyle, updateStyle)()
139 defer tests.PrepareTestEnv(t)()
140 // Create PR to test
141 user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
142 org26 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 26})
143 pr := createOutdatedPR(t, user, org26)
144
145 // Test GetDiverging
146 diffCount, err := pull_service.GetDiverging(git.DefaultContext, pr)
147 require.NoError(t, err)
148 assert.Equal(t, 1, diffCount.Behind)
149 assert.Equal(t, 1, diffCount.Ahead)
150 require.NoError(t, pr.LoadBaseRepo(db.DefaultContext))
151 require.NoError(t, pr.LoadIssue(db.DefaultContext))
152
153 session := loginUser(t, "user2")
154 assertViewPullUpdate(t, pr, session, updateStyle, true)
155}
156
157func assertViewPullUpdate(t *testing.T, pr *issues_model.PullRequest, session *TestSession, expectedStyle string, dropdownExpected bool) {
158 req := NewRequest(t, "GET", fmt.Sprintf("%s/%s/pulls/%d", pr.BaseRepo.OwnerName, pr.BaseRepo.Name, pr.Issue.Index))
159 resp := session.MakeRequest(t, req, http.StatusOK)
160
161 htmlDoc := NewHTMLParser(t, resp.Body)
162 // Verify that URL of the update button is shown correctly.
163 var mainExpectedURL string
164 mergeExpectedURL := fmt.Sprintf("/%s/%s/pulls/%d/update?style=merge", pr.BaseRepo.OwnerName, pr.BaseRepo.Name, pr.Issue.Index)
165 rebaseExpectedURL := fmt.Sprintf("/%s/%s/pulls/%d/update?style=rebase", pr.BaseRepo.OwnerName, pr.BaseRepo.Name, pr.Issue.Index)
166 if expectedStyle == "rebase" {
167 mainExpectedURL = rebaseExpectedURL
168 if dropdownExpected {
169 htmlDoc.AssertElement(t, fmt.Sprintf(".update-button .dropdown .menu .item[data-do=\"%s\"]:not(.active.selected)", mergeExpectedURL), true)
170 htmlDoc.AssertElement(t, fmt.Sprintf(".update-button .dropdown .menu .active.selected.item[data-do=\"%s\"]", rebaseExpectedURL), true)
171 }
172 } else {
173 mainExpectedURL = mergeExpectedURL
174 if dropdownExpected {
175 htmlDoc.AssertElement(t, fmt.Sprintf(".update-button .dropdown .menu .active.selected.item[data-do=\"%s\"]", mergeExpectedURL), true)
176 htmlDoc.AssertElement(t, fmt.Sprintf(".update-button .dropdown .menu .item[data-do=\"%s\"]:not(.active.selected)", rebaseExpectedURL), true)
177 }
178 }
179 if dropdownExpected {
180 htmlDoc.AssertElement(t, fmt.Sprintf(".update-button .button[data-do=\"%s\"]", mainExpectedURL), true)
181 } else {
182 htmlDoc.AssertElement(t, fmt.Sprintf("form[action=\"%s\"]", mainExpectedURL), true)
183 }
184}
185
186func createOutdatedPR(t *testing.T, actor, forkOrg *user_model.User) *issues_model.PullRequest {
187 baseRepo, _, _ := tests.CreateDeclarativeRepo(t, actor, "repo-pr-update", nil, nil, nil)
188
189 headRepo, err := repo_service.ForkRepositoryAndUpdates(git.DefaultContext, actor, forkOrg, repo_service.ForkRepoOptions{
190 BaseRepo: baseRepo,
191 Name: "repo-pr-update",
192 Description: "desc",
193 })
194 require.NoError(t, err)
195 assert.NotEmpty(t, headRepo)
196
197 // create a commit on base Repo
198 _, err = files_service.ChangeRepoFiles(git.DefaultContext, baseRepo, actor, &files_service.ChangeRepoFilesOptions{
199 Files: []*files_service.ChangeRepoFile{
200 {
201 Operation: "create",
202 TreePath: "File_A",
203 ContentReader: strings.NewReader("File A"),
204 },
205 },
206 Message: "Add File A",
207 OldBranch: "main",
208 NewBranch: "main",
209 Author: &files_service.IdentityOptions{
210 Name: actor.Name,
211 Email: actor.Email,
212 },
213 Committer: &files_service.IdentityOptions{
214 Name: actor.Name,
215 Email: actor.Email,
216 },
217 Dates: &files_service.CommitDateOptions{
218 Author: time.Now(),
219 Committer: time.Now(),
220 },
221 })
222 require.NoError(t, err)
223
224 // create a commit on head Repo
225 _, err = files_service.ChangeRepoFiles(git.DefaultContext, headRepo, actor, &files_service.ChangeRepoFilesOptions{
226 Files: []*files_service.ChangeRepoFile{
227 {
228 Operation: "create",
229 TreePath: "File_B",
230 ContentReader: strings.NewReader("File B"),
231 },
232 },
233 Message: "Add File on PR branch",
234 OldBranch: "main",
235 NewBranch: "newBranch",
236 Author: &files_service.IdentityOptions{
237 Name: actor.Name,
238 Email: actor.Email,
239 },
240 Committer: &files_service.IdentityOptions{
241 Name: actor.Name,
242 Email: actor.Email,
243 },
244 Dates: &files_service.CommitDateOptions{
245 Author: time.Now(),
246 Committer: time.Now(),
247 },
248 })
249 require.NoError(t, err)
250
251 // create Pull
252 pullIssue := &issues_model.Issue{
253 RepoID: baseRepo.ID,
254 Title: "Test Pull -to-update-",
255 PosterID: actor.ID,
256 Poster: actor,
257 IsPull: true,
258 }
259 pullRequest := &issues_model.PullRequest{
260 HeadRepoID: headRepo.ID,
261 BaseRepoID: baseRepo.ID,
262 HeadBranch: "newBranch",
263 BaseBranch: "main",
264 HeadRepo: headRepo,
265 BaseRepo: baseRepo,
266 Type: issues_model.PullRequestGitea,
267 }
268 err = pull_service.NewPullRequest(git.DefaultContext, baseRepo, pullIssue, nil, nil, pullRequest, nil)
269 require.NoError(t, err)
270
271 issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{Title: "Test Pull -to-update-"})
272 require.NoError(t, issue.LoadPullRequest(db.DefaultContext))
273
274 return issue.PullRequest
275}