loading up the forgejo repo on tangled to test page performance
at forgejo 593 lines 23 kB view raw
1// Copyright 2017 The Gitea Authors. All rights reserved. 2// Copyright 2024 The Forgejo Authors c/o Codeberg e.V.. All rights reserved. 3// SPDX-License-Identifier: MIT 4 5package integration 6 7import ( 8 "fmt" 9 "net/http" 10 "net/http/httptest" 11 "net/url" 12 "path" 13 "regexp" 14 "strings" 15 "testing" 16 17 "forgejo.org/models/db" 18 repo_model "forgejo.org/models/repo" 19 unit_model "forgejo.org/models/unit" 20 "forgejo.org/models/unittest" 21 user_model "forgejo.org/models/user" 22 "forgejo.org/modules/git" 23 "forgejo.org/modules/graceful" 24 "forgejo.org/modules/test" 25 repo_service "forgejo.org/services/repository" 26 files_service "forgejo.org/services/repository/files" 27 "forgejo.org/tests" 28 29 "github.com/stretchr/testify/assert" 30 "github.com/stretchr/testify/require" 31) 32 33func testPullCreate(t *testing.T, session *TestSession, user, repo string, toSelf bool, targetBranch, sourceBranch, title string) *httptest.ResponseRecorder { 34 req := NewRequest(t, "GET", path.Join(user, repo)) 35 resp := session.MakeRequest(t, req, http.StatusOK) 36 37 // Click the PR button to create a pull 38 htmlDoc := NewHTMLParser(t, resp.Body) 39 link, exists := htmlDoc.doc.Find("#new-pull-request").Attr("href") 40 assert.True(t, exists, "The template has changed") 41 42 targetUser := strings.Split(link, "/")[1] 43 if toSelf && targetUser != user { 44 link = strings.Replace(link, targetUser, user, 1) 45 } 46 47 // get main out of /user/project/main...some:other/branch 48 defaultBranch := regexp.MustCompile(`^.*/(.*)\.\.\.`).FindStringSubmatch(link)[1] 49 if targetBranch != defaultBranch { 50 link = strings.Replace(link, defaultBranch+"...", targetBranch+"...", 1) 51 } 52 if sourceBranch != defaultBranch { 53 if targetUser == user { 54 link = strings.Replace(link, "..."+defaultBranch, "..."+sourceBranch, 1) 55 } else { 56 link = strings.Replace(link, ":"+defaultBranch, ":"+sourceBranch, 1) 57 } 58 } 59 60 req = NewRequest(t, "GET", link) 61 resp = session.MakeRequest(t, req, http.StatusOK) 62 63 // Submit the form for creating the pull 64 htmlDoc = NewHTMLParser(t, resp.Body) 65 link, exists = htmlDoc.doc.Find("form.ui.form").Attr("action") 66 assert.True(t, exists, "The template has changed") 67 req = NewRequestWithValues(t, "POST", link, map[string]string{ 68 "_csrf": htmlDoc.GetCSRF(), 69 "title": title, 70 }) 71 resp = session.MakeRequest(t, req, http.StatusOK) 72 return resp 73} 74 75func testPullCreateDirectly(t *testing.T, session *TestSession, baseRepoOwner, baseRepoName, baseBranch, headRepoOwner, headRepoName, headBranch, title string) *httptest.ResponseRecorder { 76 headCompare := headBranch 77 if headRepoOwner != "" { 78 if headRepoName != "" { 79 headCompare = fmt.Sprintf("%s/%s:%s", headRepoOwner, headRepoName, headBranch) 80 } else { 81 headCompare = fmt.Sprintf("%s:%s", headRepoOwner, headBranch) 82 } 83 } 84 req := NewRequest(t, "GET", fmt.Sprintf("/%s/%s/compare/%s...%s", baseRepoOwner, baseRepoName, baseBranch, headCompare)) 85 resp := session.MakeRequest(t, req, http.StatusOK) 86 87 // Submit the form for creating the pull 88 htmlDoc := NewHTMLParser(t, resp.Body) 89 link, exists := htmlDoc.doc.Find("form.ui.form").Attr("action") 90 assert.True(t, exists, "The template has changed") 91 req = NewRequestWithValues(t, "POST", link, map[string]string{ 92 "_csrf": htmlDoc.GetCSRF(), 93 "title": title, 94 }) 95 resp = session.MakeRequest(t, req, http.StatusOK) 96 return resp 97} 98 99func TestPullCreate(t *testing.T) { 100 onGiteaRun(t, func(t *testing.T, u *url.URL) { 101 session := loginUser(t, "user1") 102 testRepoFork(t, session, "user2", "repo1", "user1", "repo1") 103 testEditFile(t, session, "user1", "repo1", "master", "README.md", "Hello, World (Edited)\n") 104 resp := testPullCreate(t, session, "user1", "repo1", false, "master", "master", "This is a pull title") 105 106 // check the redirected URL 107 url := test.RedirectURL(resp) 108 assert.Regexp(t, "^/user2/repo1/pulls/[0-9]*$", url) 109 110 // check .diff can be accessed and matches performed change 111 req := NewRequest(t, "GET", url+".diff") 112 resp = session.MakeRequest(t, req, http.StatusOK) 113 assert.Regexp(t, `\+Hello, World \(Edited\)`, resp.Body) 114 assert.Regexp(t, "^diff", resp.Body) 115 assert.NotRegexp(t, "diff.*diff", resp.Body) // not two diffs, just one 116 117 // check .patch can be accessed and matches performed change 118 req = NewRequest(t, "GET", url+".patch") 119 resp = session.MakeRequest(t, req, http.StatusOK) 120 assert.Regexp(t, `\+Hello, World \(Edited\)`, resp.Body) 121 assert.Regexp(t, "diff", resp.Body) 122 assert.Regexp(t, `Subject: \[PATCH\] Update README.md`, resp.Body) 123 assert.NotRegexp(t, "diff.*diff", resp.Body) // not two diffs, just one 124 }) 125} 126 127func TestPullCreateWithPullTemplate(t *testing.T) { 128 onGiteaRun(t, func(t *testing.T, u *url.URL) { 129 baseUser := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) 130 forkUser := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) 131 132 templateCandidates := []string{ 133 ".forgejo/PULL_REQUEST_TEMPLATE.md", 134 ".forgejo/pull_request_template.md", 135 ".gitea/PULL_REQUEST_TEMPLATE.md", 136 ".gitea/pull_request_template.md", 137 ".github/PULL_REQUEST_TEMPLATE.md", 138 ".github/pull_request_template.md", 139 } 140 141 createBaseRepo := func(t *testing.T, templateFiles []string, message string) (*repo_model.Repository, func()) { 142 t.Helper() 143 144 changeOps := make([]*files_service.ChangeRepoFile, len(templateFiles)) 145 for i, template := range templateFiles { 146 changeOps[i] = &files_service.ChangeRepoFile{ 147 Operation: "create", 148 TreePath: template, 149 ContentReader: strings.NewReader(message + " " + template), 150 } 151 } 152 153 repo, _, deferrer := tests.CreateDeclarativeRepo(t, baseUser, "", nil, nil, changeOps) 154 155 return repo, deferrer 156 } 157 158 testPullPreview := func(t *testing.T, session *TestSession, user, repo, message string) { 159 t.Helper() 160 161 req := NewRequest(t, "GET", path.Join(user, repo)) 162 resp := session.MakeRequest(t, req, http.StatusOK) 163 164 // Click the PR button to create a pull 165 htmlDoc := NewHTMLParser(t, resp.Body) 166 link, exists := htmlDoc.doc.Find("#new-pull-request").Attr("href") 167 assert.True(t, exists, "The template has changed") 168 169 // Load the pull request preview 170 req = NewRequest(t, "GET", link) 171 resp = session.MakeRequest(t, req, http.StatusOK) 172 173 // Check that the message from the template is present. 174 htmlDoc = NewHTMLParser(t, resp.Body) 175 pullRequestMessage := htmlDoc.doc.Find("textarea[placeholder*='comment']").Text() 176 assert.Equal(t, message, pullRequestMessage) 177 } 178 179 for i, template := range templateCandidates { 180 t.Run(template, func(t *testing.T) { 181 defer tests.PrintCurrentTest(t)() 182 183 // Create the base repository, with the pull request template added. 184 message := fmt.Sprintf("TestPullCreateWithPullTemplate/%s", template) 185 baseRepo, deferrer := createBaseRepo(t, []string{template}, message) 186 defer deferrer() 187 188 // Fork the repository 189 session := loginUser(t, forkUser.Name) 190 testRepoFork(t, session, baseUser.Name, baseRepo.Name, forkUser.Name, baseRepo.Name) 191 forkedRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{OwnerID: forkUser.ID, Name: baseRepo.Name}) 192 193 // Apply a change to the fork 194 err := createOrReplaceFileInBranch(forkUser, forkedRepo, "README.md", forkedRepo.DefaultBranch, fmt.Sprintf("Hello, World (%d)\n", i)) 195 require.NoError(t, err) 196 197 testPullPreview(t, session, forkUser.Name, forkedRepo.Name, message+" "+template) 198 }) 199 } 200 201 t.Run("multiple template options", func(t *testing.T) { 202 defer tests.PrintCurrentTest(t)() 203 204 // Create the base repository, with the pull request template added. 205 message := "TestPullCreateWithPullTemplate/multiple" 206 baseRepo, deferrer := createBaseRepo(t, templateCandidates, message) 207 defer deferrer() 208 209 // Fork the repository 210 session := loginUser(t, forkUser.Name) 211 testRepoFork(t, session, baseUser.Name, baseRepo.Name, forkUser.Name, baseRepo.Name) 212 forkedRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{OwnerID: forkUser.ID, Name: baseRepo.Name}) 213 214 // Apply a change to the fork 215 err := createOrReplaceFileInBranch(forkUser, forkedRepo, "README.md", forkedRepo.DefaultBranch, "Hello, World (%d)\n") 216 require.NoError(t, err) 217 218 // Unlike issues, where all candidates are considered and shown, for 219 // pull request, there's a priority: if there are multiple 220 // templates, only the highest priority one is used. 221 testPullPreview(t, session, forkUser.Name, forkedRepo.Name, message+" .forgejo/PULL_REQUEST_TEMPLATE.md") 222 }) 223 }) 224} 225 226func TestPullCreate_TitleEscape(t *testing.T) { 227 onGiteaRun(t, func(t *testing.T, u *url.URL) { 228 session := loginUser(t, "user1") 229 testRepoFork(t, session, "user2", "repo1", "user1", "repo1") 230 testEditFile(t, session, "user1", "repo1", "master", "README.md", "Hello, World (Edited)\n") 231 resp := testPullCreate(t, session, "user1", "repo1", false, "master", "master", "<i>XSS PR</i>") 232 233 // check the redirected URL 234 url := test.RedirectURL(resp) 235 assert.Regexp(t, "^/user2/repo1/pulls/[0-9]*$", url) 236 237 // Edit title 238 req := NewRequest(t, "GET", url) 239 resp = session.MakeRequest(t, req, http.StatusOK) 240 htmlDoc := NewHTMLParser(t, resp.Body) 241 editTestTitleURL, exists := htmlDoc.doc.Find(".button-row button[data-update-url]").First().Attr("data-update-url") 242 assert.True(t, exists, "The template has changed") 243 244 req = NewRequestWithValues(t, "POST", editTestTitleURL, map[string]string{ 245 "_csrf": htmlDoc.GetCSRF(), 246 "title": "<u>XSS PR</u>", 247 }) 248 session.MakeRequest(t, req, http.StatusOK) 249 250 req = NewRequest(t, "GET", url) 251 resp = session.MakeRequest(t, req, http.StatusOK) 252 htmlDoc = NewHTMLParser(t, resp.Body) 253 titleHTML, err := htmlDoc.doc.Find(".comment-list .timeline-item.event .text b").First().Html() 254 require.NoError(t, err) 255 assert.Equal(t, "<strike>&lt;i&gt;XSS PR&lt;/i&gt;</strike>", titleHTML) 256 titleHTML, err = htmlDoc.doc.Find(".comment-list .timeline-item.event .text b").Next().Html() 257 require.NoError(t, err) 258 assert.Equal(t, "&lt;u&gt;XSS PR&lt;/u&gt;", titleHTML) 259 }) 260} 261 262func testUIDeleteBranch(t *testing.T, session *TestSession, ownerName, repoName, branchName string) { 263 relURL := "/" + path.Join(ownerName, repoName, "branches") 264 req := NewRequest(t, "GET", relURL) 265 resp := session.MakeRequest(t, req, http.StatusOK) 266 htmlDoc := NewHTMLParser(t, resp.Body) 267 268 req = NewRequestWithValues(t, "POST", relURL+"/delete", map[string]string{ 269 "_csrf": htmlDoc.GetCSRF(), 270 "name": branchName, 271 }) 272 session.MakeRequest(t, req, http.StatusOK) 273} 274 275func testDeleteRepository(t *testing.T, session *TestSession, ownerName, repoName string) { 276 relURL := "/" + path.Join(ownerName, repoName, "settings") 277 req := NewRequest(t, "GET", relURL) 278 resp := session.MakeRequest(t, req, http.StatusOK) 279 htmlDoc := NewHTMLParser(t, resp.Body) 280 281 req = NewRequestWithValues(t, "POST", relURL+"?action=delete", map[string]string{ 282 "_csrf": htmlDoc.GetCSRF(), 283 "repo_name": fmt.Sprintf("%s/%s", ownerName, repoName), 284 }) 285 session.MakeRequest(t, req, http.StatusSeeOther) 286} 287 288func TestPullBranchDelete(t *testing.T) { 289 onGiteaRun(t, func(t *testing.T, u *url.URL) { 290 defer tests.PrepareTestEnv(t)() 291 292 session := loginUser(t, "user1") 293 testRepoFork(t, session, "user2", "repo1", "user1", "repo1") 294 testCreateBranch(t, session, "user1", "repo1", "branch/master", "master1", http.StatusSeeOther) 295 testEditFile(t, session, "user1", "repo1", "master1", "README.md", "Hello, World (Edited)\n") 296 resp := testPullCreate(t, session, "user1", "repo1", false, "master", "master1", "This is a pull title") 297 298 // check the redirected URL 299 url := test.RedirectURL(resp) 300 assert.Regexp(t, "^/user2/repo1/pulls/[0-9]*$", url) 301 req := NewRequest(t, "GET", url) 302 session.MakeRequest(t, req, http.StatusOK) 303 304 // delete head branch and confirm pull page is ok 305 testUIDeleteBranch(t, session, "user1", "repo1", "master1") 306 req = NewRequest(t, "GET", url) 307 session.MakeRequest(t, req, http.StatusOK) 308 309 // delete head repository and confirm pull page is ok 310 testDeleteRepository(t, session, "user1", "repo1") 311 req = NewRequest(t, "GET", url) 312 session.MakeRequest(t, req, http.StatusOK) 313 }) 314} 315 316func TestRecentlyPushed(t *testing.T) { 317 onGiteaRun(t, func(t *testing.T, u *url.URL) { 318 session := loginUser(t, "user1") 319 testRepoFork(t, session, "user2", "repo1", "user1", "repo1") 320 321 testCreateBranch(t, session, "user1", "repo1", "branch/master", "recent-push", http.StatusSeeOther) 322 testEditFile(t, session, "user1", "repo1", "recent-push", "README.md", "Hello recently!\n") 323 324 testCreateBranch(t, session, "user2", "repo1", "branch/master", "recent-push-base", http.StatusSeeOther) 325 testEditFile(t, session, "user2", "repo1", "recent-push-base", "README.md", "Hello, recently, from base!\n") 326 327 baseRepo, err := repo_model.GetRepositoryByOwnerAndName(db.DefaultContext, "user2", "repo1") 328 require.NoError(t, err) 329 repo, err := repo_model.GetRepositoryByOwnerAndName(db.DefaultContext, "user1", "repo1") 330 require.NoError(t, err) 331 332 enablePRs := func(t *testing.T, repo *repo_model.Repository) { 333 t.Helper() 334 335 err := repo_service.UpdateRepositoryUnits(db.DefaultContext, repo, 336 []repo_model.RepoUnit{{ 337 RepoID: repo.ID, 338 Type: unit_model.TypePullRequests, 339 Config: &repo_model.PullRequestsConfig{ 340 AllowMerge: true, 341 AllowSquash: true, 342 }, 343 }}, 344 nil) 345 require.NoError(t, err) 346 } 347 348 disablePRs := func(t *testing.T, repo *repo_model.Repository) { 349 t.Helper() 350 351 err := repo_service.UpdateRepositoryUnits(db.DefaultContext, repo, nil, 352 []unit_model.Type{unit_model.TypePullRequests}) 353 require.NoError(t, err) 354 } 355 356 testBanner := func(t *testing.T) { 357 t.Helper() 358 359 req := NewRequest(t, "GET", "/user1/repo1") 360 resp := session.MakeRequest(t, req, http.StatusOK) 361 htmlDoc := NewHTMLParser(t, resp.Body) 362 363 message := strings.TrimSpace(htmlDoc.Find(".ui.message").Text()) 364 link, _ := htmlDoc.Find(".ui.message a").Attr("href") 365 expectedMessage := "You pushed on branch recent-push" 366 367 assert.Contains(t, message, expectedMessage) 368 assert.Equal(t, "/user1/repo1/src/branch/recent-push", link) 369 } 370 371 // Test that there's a recently pushed branches banner, and it contains 372 // a link to the branch. 373 t.Run("recently-pushed-banner", func(t *testing.T) { 374 defer tests.PrintCurrentTest(t)() 375 376 testBanner(t) 377 }) 378 379 // Test that it is still there if the fork has PRs disabled, but the 380 // base repo still has them enabled. 381 t.Run("with-fork-prs-disabled", func(t *testing.T) { 382 defer tests.PrintCurrentTest(t)() 383 defer func() { 384 enablePRs(t, repo) 385 }() 386 387 disablePRs(t, repo) 388 testBanner(t) 389 }) 390 391 // Test that it is still there if the fork has PRs enabled, but the base 392 // repo does not. 393 t.Run("with-base-prs-disabled", func(t *testing.T) { 394 defer tests.PrintCurrentTest(t)() 395 defer func() { 396 enablePRs(t, baseRepo) 397 }() 398 399 disablePRs(t, baseRepo) 400 testBanner(t) 401 }) 402 403 // Test that the banner is not present if both the base and current 404 // repo have PRs disabled. 405 t.Run("with-prs-disabled", func(t *testing.T) { 406 defer tests.PrintCurrentTest(t)() 407 defer func() { 408 enablePRs(t, baseRepo) 409 enablePRs(t, repo) 410 }() 411 412 disablePRs(t, repo) 413 disablePRs(t, baseRepo) 414 415 req := NewRequest(t, "GET", "/user1/repo1") 416 resp := session.MakeRequest(t, req, http.StatusOK) 417 htmlDoc := NewHTMLParser(t, resp.Body) 418 htmlDoc.AssertElement(t, ".ui.message", false) 419 }) 420 421 // Test that visiting the base repo has the banner too, and includes 422 // recent push notifications from both the fork, and the base repo. 423 t.Run("on the base repo", func(t *testing.T) { 424 defer tests.PrintCurrentTest(t)() 425 426 // Count recently pushed branches on the fork 427 req := NewRequest(t, "GET", "/user1/repo1") 428 resp := session.MakeRequest(t, req, http.StatusOK) 429 htmlDoc := NewHTMLParser(t, resp.Body) 430 htmlDoc.AssertElement(t, ".ui.message", true) 431 432 // Count recently pushed branches on the base repo 433 req = NewRequest(t, "GET", "/user2/repo1") 434 resp = session.MakeRequest(t, req, http.StatusOK) 435 htmlDoc = NewHTMLParser(t, resp.Body) 436 messageCountOnBase := htmlDoc.Find(".ui.message").Length() 437 438 // We have two messages on the base: one from the fork, one on the 439 // base itself. 440 assert.Equal(t, 2, messageCountOnBase) 441 }) 442 443 // Test that the banner's links point to the right repos 444 t.Run("link validity", func(t *testing.T) { 445 defer tests.PrintCurrentTest(t)() 446 447 // We're testing against the origin repo, because that has both 448 // local branches, and another from a fork, so we can test both in 449 // one test! 450 451 req := NewRequest(t, "GET", "/user2/repo1") 452 resp := session.MakeRequest(t, req, http.StatusOK) 453 htmlDoc := NewHTMLParser(t, resp.Body) 454 messages := htmlDoc.Find(".ui.message") 455 456 prButtons := messages.Find("a[role='button']") 457 branchLinks := messages.Find("a[href*='/src/branch/']") 458 459 // ** base repo tests ** 460 basePRLink, _ := prButtons.First().Attr("href") 461 baseBranchLink, _ := branchLinks.First().Attr("href") 462 baseBranchName := branchLinks.First().Text() 463 464 // branch in the same repo does not have a `user/repo:` qualifier. 465 assert.Equal(t, "recent-push-base", baseBranchName) 466 // branch link points to the same repo 467 assert.Equal(t, "/user2/repo1/src/branch/recent-push-base", baseBranchLink) 468 // PR link compares against the correct rep, and unqualified branch name 469 assert.Equal(t, "/user2/repo1/compare/master...recent-push-base", basePRLink) 470 471 // ** forked repo tests ** 472 forkPRLink, _ := prButtons.Last().Attr("href") 473 forkBranchLink, _ := branchLinks.Last().Attr("href") 474 forkBranchName := branchLinks.Last().Text() 475 476 // branch in the forked repo has a `user/repo:` qualifier. 477 assert.Equal(t, "user1/repo1:recent-push", forkBranchName) 478 // branch link points to the forked repo 479 assert.Equal(t, "/user1/repo1/src/branch/recent-push", forkBranchLink) 480 // PR link compares against the correct rep, and qualified branch name 481 assert.Equal(t, "/user2/repo1/compare/master...user1/repo1:recent-push", forkPRLink) 482 }) 483 484 t.Run("unrelated branches are not shown", func(t *testing.T) { 485 defer tests.PrintCurrentTest(t)() 486 487 // Create a new branch with no relation to the default branch. 488 // 1. Create a new Tree object 489 cmd := git.NewCommand(db.DefaultContext, "write-tree") 490 treeID, _, gitErr := cmd.RunStdString(&git.RunOpts{Dir: repo.RepoPath()}) 491 require.NoError(t, gitErr) 492 treeID = strings.TrimSpace(treeID) 493 // 2. Create a new (empty) commit 494 cmd = git.NewCommand(db.DefaultContext, "commit-tree", "-m", "Initial orphan commit").AddDynamicArguments(treeID) 495 commitID, _, gitErr := cmd.RunStdString(&git.RunOpts{Dir: repo.RepoPath()}) 496 require.NoError(t, gitErr) 497 commitID = strings.TrimSpace(commitID) 498 // 3. Create a new ref pointing to the orphaned commit 499 cmd = git.NewCommand(db.DefaultContext, "update-ref", "refs/heads/orphan1").AddDynamicArguments(commitID) 500 _, _, gitErr = cmd.RunStdString(&git.RunOpts{Dir: repo.RepoPath()}) 501 require.NoError(t, gitErr) 502 // 4. Sync the git repo to the database 503 syncErr := repo_service.AddAllRepoBranchesToSyncQueue(graceful.GetManager().ShutdownContext()) 504 require.NoError(t, syncErr) 505 // 5. Add a fresh commit, so that FindRecentlyPushedBranches has 506 // something to find. 507 owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "user1"}) 508 changeResp, err := files_service.ChangeRepoFiles(git.DefaultContext, repo, owner, 509 &files_service.ChangeRepoFilesOptions{ 510 Files: []*files_service.ChangeRepoFile{ 511 { 512 Operation: "create", 513 TreePath: "README.md", 514 ContentReader: strings.NewReader("a readme file"), 515 }, 516 }, 517 Message: "Add README.md", 518 OldBranch: "orphan1", 519 NewBranch: "orphan1", 520 }) 521 require.NoError(t, err) 522 assert.NotEmpty(t, changeResp) 523 524 // Check that we only have 1 message on the main repo, the orphaned 525 // one is not shown. 526 req := NewRequest(t, "GET", "/user1/repo1") 527 resp := session.MakeRequest(t, req, http.StatusOK) 528 htmlDoc := NewHTMLParser(t, resp.Body) 529 530 htmlDoc.AssertElement(t, ".ui.message", true) 531 link, _ := htmlDoc.Find(".ui.message a[href*='/src/branch/']").Attr("href") 532 assert.Equal(t, "/user1/repo1/src/branch/recent-push", link) 533 }) 534 535 // Test that visiting the base repo does not show any banner if 536 // the branches have corresponding PRs (open or merged) 537 t.Run("branches with merged or open PRs are not shown", func(t *testing.T) { 538 defer tests.PrintCurrentTest(t)() 539 540 respChildPR := testPullCreateDirectly(t, session, "user2", "repo1", "master", "user1", "repo1", "recent-push", "Child Pull Request") 541 elemChildPR := strings.Split(test.RedirectURL(respChildPR), "/") 542 assert.Equal(t, "user2", elemChildPR[1]) 543 assert.Equal(t, "repo1", elemChildPR[2]) 544 assert.Equal(t, "pulls", elemChildPR[3]) 545 session2 := loginUser(t, "user2") 546 // Merge the PR from the fork 547 testPullMerge(t, session2, elemChildPR[1], elemChildPR[2], elemChildPR[4], repo_model.MergeStyleSquash, false) 548 549 respBasePR := testPullCreate(t, session, "user2", "repo1", true, "master", "recent-push-base", "Base Pull Request") 550 elemBasePR := strings.Split(test.RedirectURL(respBasePR), "/") 551 assert.Equal(t, "pulls", elemBasePR[3]) 552 // Leave the PR from the base repo open (it conflicts with the PR from the fork anyway) 553 554 // Count recently pushed branches on the base repo 555 req := NewRequest(t, "GET", "/user2/repo1") 556 resp := session.MakeRequest(t, req, http.StatusOK) 557 htmlDoc := NewHTMLParser(t, resp.Body) 558 559 messages := htmlDoc.Find(".ui.message") 560 561 // None of the branches should be shown, as they have either already been merged already, 562 // or have an open PR, so it doesn't make sense to make a new PR for any of them. 563 assert.Equal(t, 0, messages.Length()) 564 }) 565 }) 566} 567 568/* 569Setup: 570The base repository is: user2/repo1 571Fork repository to: user1/repo1 572Push extra commit to: user2/repo1, which changes README.md 573Create a PR on user1/repo1 574 575Test checks: 576Check if pull request can be created from base to the fork repository. 577*/ 578func TestPullCreatePrFromBaseToFork(t *testing.T) { 579 onGiteaRun(t, func(t *testing.T, u *url.URL) { 580 sessionFork := loginUser(t, "user1") 581 testRepoFork(t, sessionFork, "user2", "repo1", "user1", "repo1") 582 583 // Edit base repository 584 sessionBase := loginUser(t, "user2") 585 testEditFile(t, sessionBase, "user2", "repo1", "master", "README.md", "Hello, World (Edited)\n") 586 587 // Create a PR 588 resp := testPullCreateDirectly(t, sessionFork, "user1", "repo1", "master", "user2", "repo1", "master", "This is a pull title") 589 // check the redirected URL 590 url := test.RedirectURL(resp) 591 assert.Regexp(t, "^/user1/repo1/pulls/[0-9]*$", url) 592 }) 593}