code.gitea.io/gitea@v1.21.7/tests/integration/nonascii_branches_test.go (about)

     1  // Copyright 2018 The Gitea Authors. All rights reserved.
     2  // SPDX-License-Identifier: MIT
     3  
     4  package integration
     5  
     6  import (
     7  	"net/http"
     8  	"net/url"
     9  	"path"
    10  	"testing"
    11  
    12  	"code.gitea.io/gitea/tests"
    13  
    14  	"github.com/stretchr/testify/assert"
    15  )
    16  
    17  func testSrcRouteRedirect(t *testing.T, session *TestSession, user, repo, route, expectedLocation string, expectedStatus int) {
    18  	prefix := path.Join("/", user, repo, "src")
    19  
    20  	// Make request
    21  	req := NewRequest(t, "GET", path.Join(prefix, route))
    22  	resp := session.MakeRequest(t, req, http.StatusSeeOther)
    23  
    24  	// Check Location header
    25  	location := resp.Header().Get("Location")
    26  	assert.Equal(t, path.Join(prefix, expectedLocation), location)
    27  
    28  	// Perform redirect
    29  	req = NewRequest(t, "GET", location)
    30  	session.MakeRequest(t, req, expectedStatus)
    31  }
    32  
    33  func setDefaultBranch(t *testing.T, session *TestSession, user, repo, branch string) {
    34  	location := path.Join("/", user, repo, "settings/branches")
    35  	csrf := GetCSRF(t, session, location)
    36  	req := NewRequestWithValues(t, "POST", location, map[string]string{
    37  		"_csrf":  csrf,
    38  		"action": "default_branch",
    39  		"branch": branch,
    40  	})
    41  	session.MakeRequest(t, req, http.StatusSeeOther)
    42  }
    43  
    44  func TestNonasciiBranches(t *testing.T) {
    45  	testRedirects := []struct {
    46  		from   string
    47  		to     string
    48  		status int
    49  	}{
    50  		// Branches
    51  		{
    52  			from:   "master",
    53  			to:     "branch/master",
    54  			status: http.StatusOK,
    55  		},
    56  		{
    57  			from:   "master/README.md",
    58  			to:     "branch/master/README.md",
    59  			status: http.StatusOK,
    60  		},
    61  		{
    62  			from:   "master/badfile",
    63  			to:     "branch/master/badfile",
    64  			status: http.StatusNotFound, // it does not exists
    65  		},
    66  		{
    67  			from:   "ГлавнаяВетка",
    68  			to:     "branch/%D0%93%D0%BB%D0%B0%D0%B2%D0%BD%D0%B0%D1%8F%D0%92%D0%B5%D1%82%D0%BA%D0%B0",
    69  			status: http.StatusOK,
    70  		},
    71  		{
    72  			from:   "а/б/в",
    73  			to:     "branch/%D0%B0/%D0%B1/%D0%B2",
    74  			status: http.StatusOK,
    75  		},
    76  		{
    77  			from:   "Grüßen/README.md",
    78  			to:     "branch/Gr%C3%BC%C3%9Fen/README.md",
    79  			status: http.StatusOK,
    80  		},
    81  		{
    82  			from:   "Plus+Is+Not+Space",
    83  			to:     "branch/Plus+Is+Not+Space",
    84  			status: http.StatusOK,
    85  		},
    86  		{
    87  			from:   "Plus+Is+Not+Space/Файл.md",
    88  			to:     "branch/Plus+Is+Not+Space/%D0%A4%D0%B0%D0%B9%D0%BB.md",
    89  			status: http.StatusOK,
    90  		},
    91  		{
    92  			from:   "Plus+Is+Not+Space/and+it+is+valid.md",
    93  			to:     "branch/Plus+Is+Not+Space/and+it+is+valid.md",
    94  			status: http.StatusOK,
    95  		},
    96  		{
    97  			from:   "ブランチ",
    98  			to:     "branch/%E3%83%96%E3%83%A9%E3%83%B3%E3%83%81",
    99  			status: http.StatusOK,
   100  		},
   101  		// Tags
   102  		{
   103  			from:   "Тэг",
   104  			to:     "tag/%D0%A2%D1%8D%D0%B3",
   105  			status: http.StatusOK,
   106  		},
   107  		{
   108  			from:   "Ё/人",
   109  			to:     "tag/%D0%81/%E4%BA%BA",
   110  			status: http.StatusOK,
   111  		},
   112  		{
   113  			from:   "タグ",
   114  			to:     "tag/%E3%82%BF%E3%82%B0",
   115  			status: http.StatusOK,
   116  		},
   117  		{
   118  			from:   "タグ/ファイル.md",
   119  			to:     "tag/%E3%82%BF%E3%82%B0/%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB.md",
   120  			status: http.StatusOK,
   121  		},
   122  		// Files
   123  		{
   124  			from:   "README.md",
   125  			to:     "branch/Plus+Is+Not+Space/README.md",
   126  			status: http.StatusOK,
   127  		},
   128  		{
   129  			from:   "Файл.md",
   130  			to:     "branch/Plus+Is+Not+Space/%D0%A4%D0%B0%D0%B9%D0%BB.md",
   131  			status: http.StatusOK,
   132  		},
   133  		{
   134  			from:   "ファイル.md",
   135  			to:     "branch/Plus+Is+Not+Space/%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB.md",
   136  			status: http.StatusNotFound, // it's not on default branch
   137  		},
   138  		// Same but url-encoded (few tests)
   139  		{
   140  			from:   "%E3%83%96%E3%83%A9%E3%83%B3%E3%83%81",
   141  			to:     "branch/%E3%83%96%E3%83%A9%E3%83%B3%E3%83%81",
   142  			status: http.StatusOK,
   143  		},
   144  		{
   145  			from:   "%E3%82%BF%E3%82%b0",
   146  			to:     "tag/%E3%82%BF%E3%82%B0",
   147  			status: http.StatusOK,
   148  		},
   149  		{
   150  			from:   "%D0%A4%D0%B0%D0%B9%D0%BB.md",
   151  			to:     "branch/Plus+Is+Not+Space/%D0%A4%D0%B0%D0%B9%D0%BB.md",
   152  			status: http.StatusOK,
   153  		},
   154  		{
   155  			from:   "%D0%81%2F%E4%BA%BA",
   156  			to:     "tag/%D0%81/%E4%BA%BA",
   157  			status: http.StatusOK,
   158  		},
   159  		{
   160  			from:   "Ё%2F%E4%BA%BA",
   161  			to:     "tag/%D0%81/%E4%BA%BA",
   162  			status: http.StatusOK,
   163  		},
   164  		{
   165  			from:   "Plus+Is+Not+Space/%25%252525mightnotplaywell",
   166  			to:     "branch/Plus+Is+Not+Space/%25%252525mightnotplaywell",
   167  			status: http.StatusOK,
   168  		},
   169  		{
   170  			from:   "Plus+Is+Not+Space/%25253Fisnotaquestion%25253F",
   171  			to:     "branch/Plus+Is+Not+Space/%25253Fisnotaquestion%25253F",
   172  			status: http.StatusOK,
   173  		},
   174  		{
   175  			from:   "Plus+Is+Not+Space/" + url.PathEscape("%3Fis?and#afile"),
   176  			to:     "branch/Plus+Is+Not+Space/" + url.PathEscape("%3Fis?and#afile"),
   177  			status: http.StatusOK,
   178  		},
   179  		{
   180  			from:   "Plus+Is+Not+Space/10%25.md",
   181  			to:     "branch/Plus+Is+Not+Space/10%25.md",
   182  			status: http.StatusOK,
   183  		},
   184  		{
   185  			from:   "Plus+Is+Not+Space/" + url.PathEscape("This+file%20has 1space"),
   186  			to:     "branch/Plus+Is+Not+Space/" + url.PathEscape("This+file%20has 1space"),
   187  			status: http.StatusOK,
   188  		},
   189  		{
   190  			from:   "Plus+Is+Not+Space/" + url.PathEscape("This+file%2520has 2 spaces"),
   191  			to:     "branch/Plus+Is+Not+Space/" + url.PathEscape("This+file%2520has 2 spaces"),
   192  			status: http.StatusOK,
   193  		},
   194  		{
   195  			from:   "Plus+Is+Not+Space/" + url.PathEscape("£15&$6.txt"),
   196  			to:     "branch/Plus+Is+Not+Space/" + url.PathEscape("£15&$6.txt"),
   197  			status: http.StatusOK,
   198  		},
   199  	}
   200  
   201  	defer tests.PrepareTestEnv(t)()
   202  
   203  	user := "user2"
   204  	repo := "utf8"
   205  	session := loginUser(t, user)
   206  
   207  	setDefaultBranch(t, session, user, repo, "Plus+Is+Not+Space")
   208  
   209  	for _, test := range testRedirects {
   210  		testSrcRouteRedirect(t, session, user, repo, test.from, test.to, test.status)
   211  	}
   212  
   213  	setDefaultBranch(t, session, user, repo, "master")
   214  }