code.gitea.io/gitea@v1.22.3/tests/integration/pull_create_test.go (about)

     1  // Copyright 2017 The Gitea Authors. All rights reserved.
     2  // SPDX-License-Identifier: MIT
     3  
     4  package integration
     5  
     6  import (
     7  	"fmt"
     8  	"net/http"
     9  	"net/http/httptest"
    10  	"net/url"
    11  	"path"
    12  	"strings"
    13  	"testing"
    14  
    15  	"code.gitea.io/gitea/modules/test"
    16  	"code.gitea.io/gitea/tests"
    17  
    18  	"github.com/stretchr/testify/assert"
    19  )
    20  
    21  func testPullCreate(t *testing.T, session *TestSession, user, repo string, toSelf bool, targetBranch, sourceBranch, title string) *httptest.ResponseRecorder {
    22  	req := NewRequest(t, "GET", path.Join(user, repo))
    23  	resp := session.MakeRequest(t, req, http.StatusOK)
    24  
    25  	// Click the PR button to create a pull
    26  	htmlDoc := NewHTMLParser(t, resp.Body)
    27  	link, exists := htmlDoc.doc.Find("#new-pull-request").Attr("href")
    28  	assert.True(t, exists, "The template has changed")
    29  
    30  	targetUser := strings.Split(link, "/")[1]
    31  	if toSelf && targetUser != user {
    32  		link = strings.Replace(link, targetUser, user, 1)
    33  	}
    34  
    35  	if targetBranch != "master" {
    36  		link = strings.Replace(link, "master...", targetBranch+"...", 1)
    37  	}
    38  	if sourceBranch != "master" {
    39  		if targetUser == user {
    40  			link = strings.Replace(link, "...master", "..."+sourceBranch, 1)
    41  		} else {
    42  			link = strings.Replace(link, ":master", ":"+sourceBranch, 1)
    43  		}
    44  	}
    45  
    46  	req = NewRequest(t, "GET", link)
    47  	resp = session.MakeRequest(t, req, http.StatusOK)
    48  
    49  	// Submit the form for creating the pull
    50  	htmlDoc = NewHTMLParser(t, resp.Body)
    51  	link, exists = htmlDoc.doc.Find("form.ui.form").Attr("action")
    52  	assert.True(t, exists, "The template has changed")
    53  	req = NewRequestWithValues(t, "POST", link, map[string]string{
    54  		"_csrf": htmlDoc.GetCSRF(),
    55  		"title": title,
    56  	})
    57  	resp = session.MakeRequest(t, req, http.StatusOK)
    58  	return resp
    59  }
    60  
    61  func testPullCreateDirectly(t *testing.T, session *TestSession, baseRepoOwner, baseRepoName, baseBranch, headRepoOwner, headRepoName, headBranch, title string) *httptest.ResponseRecorder {
    62  	headCompare := headBranch
    63  	if headRepoOwner != "" {
    64  		if headRepoName != "" {
    65  			headCompare = fmt.Sprintf("%s/%s:%s", headRepoOwner, headRepoName, headBranch)
    66  		} else {
    67  			headCompare = fmt.Sprintf("%s:%s", headRepoOwner, headBranch)
    68  		}
    69  	}
    70  	req := NewRequest(t, "GET", fmt.Sprintf("/%s/%s/compare/%s...%s", baseRepoOwner, baseRepoName, baseBranch, headCompare))
    71  	resp := session.MakeRequest(t, req, http.StatusOK)
    72  
    73  	// Submit the form for creating the pull
    74  	htmlDoc := NewHTMLParser(t, resp.Body)
    75  	link, exists := htmlDoc.doc.Find("form.ui.form").Attr("action")
    76  	assert.True(t, exists, "The template has changed")
    77  	req = NewRequestWithValues(t, "POST", link, map[string]string{
    78  		"_csrf": htmlDoc.GetCSRF(),
    79  		"title": title,
    80  	})
    81  	resp = session.MakeRequest(t, req, http.StatusOK)
    82  	return resp
    83  }
    84  
    85  func TestPullCreate(t *testing.T) {
    86  	onGiteaRun(t, func(t *testing.T, u *url.URL) {
    87  		session := loginUser(t, "user1")
    88  		testRepoFork(t, session, "user2", "repo1", "user1", "repo1", "")
    89  		testEditFile(t, session, "user1", "repo1", "master", "README.md", "Hello, World (Edited)\n")
    90  		resp := testPullCreate(t, session, "user1", "repo1", false, "master", "master", "This is a pull title")
    91  
    92  		// check the redirected URL
    93  		url := test.RedirectURL(resp)
    94  		assert.Regexp(t, "^/user2/repo1/pulls/[0-9]*$", url)
    95  
    96  		// check .diff can be accessed and matches performed change
    97  		req := NewRequest(t, "GET", url+".diff")
    98  		resp = session.MakeRequest(t, req, http.StatusOK)
    99  		assert.Regexp(t, `\+Hello, World \(Edited\)`, resp.Body)
   100  		assert.Regexp(t, "^diff", resp.Body)
   101  		assert.NotRegexp(t, "diff.*diff", resp.Body) // not two diffs, just one
   102  
   103  		// check .patch can be accessed and matches performed change
   104  		req = NewRequest(t, "GET", url+".patch")
   105  		resp = session.MakeRequest(t, req, http.StatusOK)
   106  		assert.Regexp(t, `\+Hello, World \(Edited\)`, resp.Body)
   107  		assert.Regexp(t, "diff", resp.Body)
   108  		assert.Regexp(t, `Subject: \[PATCH\] Update README.md`, resp.Body)
   109  		assert.NotRegexp(t, "diff.*diff", resp.Body) // not two diffs, just one
   110  	})
   111  }
   112  
   113  func TestPullCreate_TitleEscape(t *testing.T) {
   114  	onGiteaRun(t, func(t *testing.T, u *url.URL) {
   115  		session := loginUser(t, "user1")
   116  		testRepoFork(t, session, "user2", "repo1", "user1", "repo1", "")
   117  		testEditFile(t, session, "user1", "repo1", "master", "README.md", "Hello, World (Edited)\n")
   118  		resp := testPullCreate(t, session, "user1", "repo1", false, "master", "master", "<i>XSS PR</i>")
   119  
   120  		// check the redirected URL
   121  		url := test.RedirectURL(resp)
   122  		assert.Regexp(t, "^/user2/repo1/pulls/[0-9]*$", url)
   123  
   124  		// Edit title
   125  		req := NewRequest(t, "GET", url)
   126  		resp = session.MakeRequest(t, req, http.StatusOK)
   127  		htmlDoc := NewHTMLParser(t, resp.Body)
   128  		editTestTitleURL, exists := htmlDoc.doc.Find(".issue-title-buttons button[data-update-url]").First().Attr("data-update-url")
   129  		assert.True(t, exists, "The template has changed")
   130  
   131  		req = NewRequestWithValues(t, "POST", editTestTitleURL, map[string]string{
   132  			"_csrf": htmlDoc.GetCSRF(),
   133  			"title": "<u>XSS PR</u>",
   134  		})
   135  		session.MakeRequest(t, req, http.StatusOK)
   136  
   137  		req = NewRequest(t, "GET", url)
   138  		resp = session.MakeRequest(t, req, http.StatusOK)
   139  		htmlDoc = NewHTMLParser(t, resp.Body)
   140  		titleHTML, err := htmlDoc.doc.Find(".comment-list .timeline-item.event .text b").First().Html()
   141  		assert.NoError(t, err)
   142  		assert.Equal(t, "<strike>&lt;i&gt;XSS PR&lt;/i&gt;</strike>", titleHTML)
   143  		titleHTML, err = htmlDoc.doc.Find(".comment-list .timeline-item.event .text b").Next().Html()
   144  		assert.NoError(t, err)
   145  		assert.Equal(t, "&lt;u&gt;XSS PR&lt;/u&gt;", titleHTML)
   146  	})
   147  }
   148  
   149  func testUIDeleteBranch(t *testing.T, session *TestSession, ownerName, repoName, branchName string) {
   150  	relURL := "/" + path.Join(ownerName, repoName, "branches")
   151  	req := NewRequest(t, "GET", relURL)
   152  	resp := session.MakeRequest(t, req, http.StatusOK)
   153  	htmlDoc := NewHTMLParser(t, resp.Body)
   154  
   155  	req = NewRequestWithValues(t, "POST", relURL+"/delete", map[string]string{
   156  		"_csrf": htmlDoc.GetCSRF(),
   157  		"name":  branchName,
   158  	})
   159  	session.MakeRequest(t, req, http.StatusOK)
   160  }
   161  
   162  func testDeleteRepository(t *testing.T, session *TestSession, ownerName, repoName string) {
   163  	relURL := "/" + path.Join(ownerName, repoName, "settings")
   164  	req := NewRequest(t, "GET", relURL)
   165  	resp := session.MakeRequest(t, req, http.StatusOK)
   166  	htmlDoc := NewHTMLParser(t, resp.Body)
   167  
   168  	req = NewRequestWithValues(t, "POST", relURL+"?action=delete", map[string]string{
   169  		"_csrf":     htmlDoc.GetCSRF(),
   170  		"repo_name": repoName,
   171  	})
   172  	session.MakeRequest(t, req, http.StatusSeeOther)
   173  }
   174  
   175  func TestPullBranchDelete(t *testing.T) {
   176  	onGiteaRun(t, func(t *testing.T, u *url.URL) {
   177  		defer tests.PrepareTestEnv(t)()
   178  
   179  		session := loginUser(t, "user1")
   180  		testRepoFork(t, session, "user2", "repo1", "user1", "repo1", "")
   181  		testCreateBranch(t, session, "user1", "repo1", "branch/master", "master1", http.StatusSeeOther)
   182  		testEditFile(t, session, "user1", "repo1", "master1", "README.md", "Hello, World (Edited)\n")
   183  		resp := testPullCreate(t, session, "user1", "repo1", false, "master", "master1", "This is a pull title")
   184  
   185  		// check the redirected URL
   186  		url := test.RedirectURL(resp)
   187  		assert.Regexp(t, "^/user2/repo1/pulls/[0-9]*$", url)
   188  		req := NewRequest(t, "GET", url)
   189  		session.MakeRequest(t, req, http.StatusOK)
   190  
   191  		// delete head branch and confirm pull page is ok
   192  		testUIDeleteBranch(t, session, "user1", "repo1", "master1")
   193  		req = NewRequest(t, "GET", url)
   194  		session.MakeRequest(t, req, http.StatusOK)
   195  
   196  		// delete head repository and confirm pull page is ok
   197  		testDeleteRepository(t, session, "user1", "repo1")
   198  		req = NewRequest(t, "GET", url)
   199  		session.MakeRequest(t, req, http.StatusOK)
   200  	})
   201  }