You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

pull_create_test.go 5.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. // Copyright 2017 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package integration
  4. import (
  5. "net/http"
  6. "net/http/httptest"
  7. "net/url"
  8. "path"
  9. "strings"
  10. "testing"
  11. "code.gitea.io/gitea/modules/test"
  12. "code.gitea.io/gitea/tests"
  13. "github.com/stretchr/testify/assert"
  14. )
  15. func testPullCreate(t *testing.T, session *TestSession, user, repo, branch, title string) *httptest.ResponseRecorder {
  16. req := NewRequest(t, "GET", path.Join(user, repo))
  17. resp := session.MakeRequest(t, req, http.StatusOK)
  18. // Click the PR button to create a pull
  19. htmlDoc := NewHTMLParser(t, resp.Body)
  20. link, exists := htmlDoc.doc.Find("#new-pull-request").Attr("href")
  21. assert.True(t, exists, "The template has changed")
  22. if branch != "master" {
  23. link = strings.Replace(link, ":master", ":"+branch, 1)
  24. }
  25. req = NewRequest(t, "GET", link)
  26. resp = session.MakeRequest(t, req, http.StatusOK)
  27. // Submit the form for creating the pull
  28. htmlDoc = NewHTMLParser(t, resp.Body)
  29. link, exists = htmlDoc.doc.Find("form.ui.form").Attr("action")
  30. assert.True(t, exists, "The template has changed")
  31. req = NewRequestWithValues(t, "POST", link, map[string]string{
  32. "_csrf": htmlDoc.GetCSRF(),
  33. "title": title,
  34. })
  35. resp = session.MakeRequest(t, req, http.StatusOK)
  36. return resp
  37. }
  38. func TestPullCreate(t *testing.T) {
  39. onGiteaRun(t, func(t *testing.T, u *url.URL) {
  40. session := loginUser(t, "user1")
  41. testRepoFork(t, session, "user2", "repo1", "user1", "repo1")
  42. testEditFile(t, session, "user1", "repo1", "master", "README.md", "Hello, World (Edited)\n")
  43. resp := testPullCreate(t, session, "user1", "repo1", "master", "This is a pull title")
  44. // check the redirected URL
  45. url := test.RedirectURL(resp)
  46. assert.Regexp(t, "^/user2/repo1/pulls/[0-9]*$", url)
  47. // check .diff can be accessed and matches performed change
  48. req := NewRequest(t, "GET", url+".diff")
  49. resp = session.MakeRequest(t, req, http.StatusOK)
  50. assert.Regexp(t, `\+Hello, World \(Edited\)`, resp.Body)
  51. assert.Regexp(t, "^diff", resp.Body)
  52. assert.NotRegexp(t, "diff.*diff", resp.Body) // not two diffs, just one
  53. // check .patch can be accessed and matches performed change
  54. req = NewRequest(t, "GET", url+".patch")
  55. resp = session.MakeRequest(t, req, http.StatusOK)
  56. assert.Regexp(t, `\+Hello, World \(Edited\)`, resp.Body)
  57. assert.Regexp(t, "diff", resp.Body)
  58. assert.Regexp(t, `Subject: \[PATCH\] Update README.md`, resp.Body)
  59. assert.NotRegexp(t, "diff.*diff", resp.Body) // not two diffs, just one
  60. })
  61. }
  62. func TestPullCreate_TitleEscape(t *testing.T) {
  63. onGiteaRun(t, func(t *testing.T, u *url.URL) {
  64. session := loginUser(t, "user1")
  65. testRepoFork(t, session, "user2", "repo1", "user1", "repo1")
  66. testEditFile(t, session, "user1", "repo1", "master", "README.md", "Hello, World (Edited)\n")
  67. resp := testPullCreate(t, session, "user1", "repo1", "master", "<i>XSS PR</i>")
  68. // check the redirected URL
  69. url := test.RedirectURL(resp)
  70. assert.Regexp(t, "^/user2/repo1/pulls/[0-9]*$", url)
  71. // Edit title
  72. req := NewRequest(t, "GET", url)
  73. resp = session.MakeRequest(t, req, http.StatusOK)
  74. htmlDoc := NewHTMLParser(t, resp.Body)
  75. editTestTitleURL, exists := htmlDoc.doc.Find("#save-edit-title").First().Attr("data-update-url")
  76. assert.True(t, exists, "The template has changed")
  77. req = NewRequestWithValues(t, "POST", editTestTitleURL, map[string]string{
  78. "_csrf": htmlDoc.GetCSRF(),
  79. "title": "<u>XSS PR</u>",
  80. })
  81. session.MakeRequest(t, req, http.StatusOK)
  82. req = NewRequest(t, "GET", url)
  83. resp = session.MakeRequest(t, req, http.StatusOK)
  84. htmlDoc = NewHTMLParser(t, resp.Body)
  85. titleHTML, err := htmlDoc.doc.Find(".comment-list .timeline-item.event .text b").First().Html()
  86. assert.NoError(t, err)
  87. assert.Equal(t, "<strike>&lt;i&gt;XSS PR&lt;/i&gt;</strike>", titleHTML)
  88. titleHTML, err = htmlDoc.doc.Find(".comment-list .timeline-item.event .text b").Next().Html()
  89. assert.NoError(t, err)
  90. assert.Equal(t, "&lt;u&gt;XSS PR&lt;/u&gt;", titleHTML)
  91. })
  92. }
  93. func testUIDeleteBranch(t *testing.T, session *TestSession, ownerName, repoName, branchName string) {
  94. relURL := "/" + path.Join(ownerName, repoName, "branches")
  95. req := NewRequest(t, "GET", relURL)
  96. resp := session.MakeRequest(t, req, http.StatusOK)
  97. htmlDoc := NewHTMLParser(t, resp.Body)
  98. req = NewRequestWithValues(t, "POST", relURL+"/delete", map[string]string{
  99. "_csrf": htmlDoc.GetCSRF(),
  100. "name": branchName,
  101. })
  102. session.MakeRequest(t, req, http.StatusOK)
  103. }
  104. func testDeleteRepository(t *testing.T, session *TestSession, ownerName, repoName string) {
  105. relURL := "/" + path.Join(ownerName, repoName, "settings")
  106. req := NewRequest(t, "GET", relURL)
  107. resp := session.MakeRequest(t, req, http.StatusOK)
  108. htmlDoc := NewHTMLParser(t, resp.Body)
  109. req = NewRequestWithValues(t, "POST", relURL+"?action=delete", map[string]string{
  110. "_csrf": htmlDoc.GetCSRF(),
  111. "repo_name": repoName,
  112. })
  113. session.MakeRequest(t, req, http.StatusSeeOther)
  114. }
  115. func TestPullBranchDelete(t *testing.T) {
  116. onGiteaRun(t, func(t *testing.T, u *url.URL) {
  117. defer tests.PrepareTestEnv(t)()
  118. session := loginUser(t, "user1")
  119. testRepoFork(t, session, "user2", "repo1", "user1", "repo1")
  120. testCreateBranch(t, session, "user1", "repo1", "branch/master", "master1", http.StatusSeeOther)
  121. testEditFile(t, session, "user1", "repo1", "master1", "README.md", "Hello, World (Edited)\n")
  122. resp := testPullCreate(t, session, "user1", "repo1", "master1", "This is a pull title")
  123. // check the redirected URL
  124. url := test.RedirectURL(resp)
  125. assert.Regexp(t, "^/user2/repo1/pulls/[0-9]*$", url)
  126. req := NewRequest(t, "GET", url)
  127. session.MakeRequest(t, req, http.StatusOK)
  128. // delete head branch and confirm pull page is ok
  129. testUIDeleteBranch(t, session, "user1", "repo1", "master1")
  130. req = NewRequest(t, "GET", url)
  131. session.MakeRequest(t, req, http.StatusOK)
  132. // delete head repository and confirm pull page is ok
  133. testDeleteRepository(t, session, "user1", "repo1")
  134. req = NewRequest(t, "GET", url)
  135. session.MakeRequest(t, req, http.StatusOK)
  136. })
  137. }