gitea源码

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461
  1. // Copyright 2017 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package integration
  4. import (
  5. "bytes"
  6. "fmt"
  7. "io"
  8. "maps"
  9. "mime/multipart"
  10. "net/http"
  11. "net/http/httptest"
  12. "net/url"
  13. "path"
  14. "strings"
  15. "testing"
  16. repo_model "code.gitea.io/gitea/models/repo"
  17. "code.gitea.io/gitea/models/unittest"
  18. user_model "code.gitea.io/gitea/models/user"
  19. "code.gitea.io/gitea/modules/git"
  20. "code.gitea.io/gitea/modules/test"
  21. "code.gitea.io/gitea/modules/translation"
  22. "code.gitea.io/gitea/modules/util"
  23. "code.gitea.io/gitea/tests"
  24. "github.com/stretchr/testify/assert"
  25. "github.com/stretchr/testify/require"
  26. )
  27. func TestEditor(t *testing.T) {
  28. onGiteaRun(t, func(t *testing.T, u *url.URL) {
  29. sessionUser2 := loginUser(t, "user2")
  30. t.Run("EditFileNotAllowed", testEditFileNotAllowed)
  31. t.Run("DiffPreview", testEditorDiffPreview)
  32. t.Run("CreateFile", testEditorCreateFile)
  33. t.Run("EditFile", func(t *testing.T) {
  34. testEditFile(t, sessionUser2, "user2", "repo1", "master", "README.md", "Hello, World (direct)\n")
  35. testEditFileToNewBranch(t, sessionUser2, "user2", "repo1", "master", "feature/test", "README.md", "Hello, World (commit-to-new-branch)\n")
  36. })
  37. t.Run("PatchFile", testEditorPatchFile)
  38. t.Run("DeleteFile", func(t *testing.T) {
  39. viewLink := "/user2/repo1/src/branch/branch2/README.md"
  40. sessionUser2.MakeRequest(t, NewRequest(t, "GET", viewLink), http.StatusOK)
  41. testEditorActionPostRequest(t, sessionUser2, "/user2/repo1/_delete/branch2/README.md", map[string]string{"commit_choice": "direct"})
  42. sessionUser2.MakeRequest(t, NewRequest(t, "GET", viewLink), http.StatusNotFound)
  43. })
  44. t.Run("ForkToEditFile", func(t *testing.T) {
  45. testForkToEditFile(t, loginUser(t, "user4"), "user4", "user2", "repo1", "master", "README.md")
  46. })
  47. t.Run("WebGitCommitEmail", testEditorWebGitCommitEmail)
  48. t.Run("ProtectedBranch", testEditorProtectedBranch)
  49. })
  50. }
  51. func testEditorCreateFile(t *testing.T) {
  52. session := loginUser(t, "user2")
  53. testCreateFile(t, session, "user2", "repo1", "master", "", "test.txt", "Content")
  54. testEditorActionPostRequestError(t, session, "/user2/repo1/_new/master/", map[string]string{
  55. "tree_path": "test.txt",
  56. "commit_choice": "direct",
  57. "new_branch_name": "master",
  58. }, `A file named "test.txt" already exists in this repository.`)
  59. testEditorActionPostRequestError(t, session, "/user2/repo1/_new/master/", map[string]string{
  60. "tree_path": "test.txt",
  61. "commit_choice": "commit-to-new-branch",
  62. "new_branch_name": "master",
  63. }, `Branch "master" already exists in this repository.`)
  64. }
  65. func testCreateFile(t *testing.T, session *TestSession, user, repo, baseBranchName, newBranchName, filePath, content string) {
  66. commitChoice := "direct"
  67. if newBranchName != "" && newBranchName != baseBranchName {
  68. commitChoice = "commit-to-new-branch"
  69. }
  70. testEditorActionEdit(t, session, user, repo, "_new", baseBranchName, "", map[string]string{
  71. "tree_path": filePath,
  72. "content": content,
  73. "commit_choice": commitChoice,
  74. "new_branch_name": newBranchName,
  75. })
  76. }
  77. func testEditorProtectedBranch(t *testing.T) {
  78. session := loginUser(t, "user2")
  79. // Change the "master" branch to "protected"
  80. req := NewRequestWithValues(t, "POST", "/user2/repo1/settings/branches/edit", map[string]string{
  81. "_csrf": GetUserCSRFToken(t, session),
  82. "rule_name": "master",
  83. "enable_push": "true",
  84. })
  85. session.MakeRequest(t, req, http.StatusSeeOther)
  86. flashMsg := session.GetCookieFlashMessage()
  87. assert.Equal(t, `Branch protection for rule "master" has been updated.`, flashMsg.SuccessMsg)
  88. // Try to commit a file to the "master" branch and it should fail
  89. resp := testEditorActionPostRequest(t, session, "/user2/repo1/_new/master/", map[string]string{"tree_path": "test-protected-branch.txt", "commit_choice": "direct"})
  90. assert.Equal(t, http.StatusBadRequest, resp.Code)
  91. assert.Equal(t, `Cannot commit to protected branch "master".`, test.ParseJSONError(resp.Body.Bytes()).ErrorMessage)
  92. }
  93. func testEditorActionPostRequest(t *testing.T, session *TestSession, requestPath string, params map[string]string) *httptest.ResponseRecorder {
  94. req := NewRequest(t, "GET", requestPath)
  95. resp := session.MakeRequest(t, req, http.StatusOK)
  96. htmlDoc := NewHTMLParser(t, resp.Body)
  97. form := map[string]string{
  98. "_csrf": htmlDoc.GetCSRF(),
  99. "last_commit": htmlDoc.GetInputValueByName("last_commit"),
  100. }
  101. maps.Copy(form, params)
  102. req = NewRequestWithValues(t, "POST", requestPath, form)
  103. return session.MakeRequest(t, req, NoExpectedStatus)
  104. }
  105. func testEditorActionPostRequestError(t *testing.T, session *TestSession, requestPath string, params map[string]string, errorMessage string) {
  106. resp := testEditorActionPostRequest(t, session, requestPath, params)
  107. assert.Equal(t, http.StatusBadRequest, resp.Code)
  108. assert.Equal(t, errorMessage, test.ParseJSONError(resp.Body.Bytes()).ErrorMessage)
  109. }
  110. func testEditorActionEdit(t *testing.T, session *TestSession, user, repo, editorAction, branch, filePath string, params map[string]string) *httptest.ResponseRecorder {
  111. params["tree_path"] = util.IfZero(params["tree_path"], filePath)
  112. newBranchName := util.Iif(params["commit_choice"] == "direct", branch, params["new_branch_name"])
  113. resp := testEditorActionPostRequest(t, session, fmt.Sprintf("/%s/%s/%s/%s/%s", user, repo, editorAction, branch, filePath), params)
  114. assert.Equal(t, http.StatusOK, resp.Code)
  115. assert.NotEmpty(t, test.RedirectURL(resp))
  116. req := NewRequest(t, "GET", path.Join(user, repo, "raw/branch", newBranchName, params["tree_path"]))
  117. resp = session.MakeRequest(t, req, http.StatusOK)
  118. assert.Equal(t, params["content"], resp.Body.String())
  119. return resp
  120. }
  121. func testEditFile(t *testing.T, session *TestSession, user, repo, branch, filePath, newContent string) {
  122. testEditorActionEdit(t, session, user, repo, "_edit", branch, filePath, map[string]string{
  123. "content": newContent,
  124. "commit_choice": "direct",
  125. })
  126. }
  127. func testEditFileToNewBranch(t *testing.T, session *TestSession, user, repo, branch, targetBranch, filePath, newContent string) {
  128. testEditorActionEdit(t, session, user, repo, "_edit", branch, filePath, map[string]string{
  129. "content": newContent,
  130. "commit_choice": "commit-to-new-branch",
  131. "new_branch_name": targetBranch,
  132. })
  133. }
  134. func testEditorDiffPreview(t *testing.T) {
  135. session := loginUser(t, "user2")
  136. req := NewRequestWithValues(t, "POST", "/user2/repo1/_preview/master/README.md", map[string]string{
  137. "_csrf": GetUserCSRFToken(t, session),
  138. "content": "Hello, World (Edited)\n",
  139. })
  140. resp := session.MakeRequest(t, req, http.StatusOK)
  141. assert.Contains(t, resp.Body.String(), `<span class="added-code">Hello, World (Edited)</span>`)
  142. }
  143. func testEditorPatchFile(t *testing.T) {
  144. session := loginUser(t, "user2")
  145. pathContentCommon := `diff --git a/patch-file-1.txt b/patch-file-1.txt
  146. new file mode 100644
  147. index 0000000000..aaaaaaaaaa
  148. --- /dev/null
  149. +++ b/patch-file-1.txt
  150. @@ -0,0 +1 @@
  151. +`
  152. testEditorActionPostRequest(t, session, "/user2/repo1/_diffpatch/master/", map[string]string{
  153. "content": pathContentCommon + "patched content\n",
  154. "commit_choice": "commit-to-new-branch",
  155. "new_branch_name": "patched-branch",
  156. })
  157. resp := MakeRequest(t, NewRequest(t, "GET", "/user2/repo1/raw/branch/patched-branch/patch-file-1.txt"), http.StatusOK)
  158. assert.Equal(t, "patched content\n", resp.Body.String())
  159. // patch again, it should fail
  160. resp = testEditorActionPostRequest(t, session, "/user2/repo1/_diffpatch/patched-branch/", map[string]string{
  161. "content": pathContentCommon + "another patched content\n",
  162. "commit_choice": "commit-to-new-branch",
  163. "new_branch_name": "patched-branch-1",
  164. })
  165. assert.Equal(t, "Unable to apply patch", test.ParseJSONError(resp.Body.Bytes()).ErrorMessage)
  166. }
  167. func testEditorWebGitCommitEmail(t *testing.T) {
  168. user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
  169. require.True(t, user.KeepEmailPrivate)
  170. repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
  171. gitRepo, _ := git.OpenRepository(t.Context(), repo1.RepoPath())
  172. defer gitRepo.Close()
  173. getLastCommit := func(t *testing.T) *git.Commit {
  174. c, err := gitRepo.GetBranchCommit("master")
  175. require.NoError(t, err)
  176. return c
  177. }
  178. session := loginUser(t, user.Name)
  179. makeReq := func(t *testing.T, link string, params map[string]string, expectedUserName, expectedEmail string) *httptest.ResponseRecorder {
  180. lastCommit := getLastCommit(t)
  181. params["_csrf"] = GetUserCSRFToken(t, session)
  182. params["last_commit"] = lastCommit.ID.String()
  183. params["commit_choice"] = "direct"
  184. req := NewRequestWithValues(t, "POST", link, params)
  185. resp := session.MakeRequest(t, req, NoExpectedStatus)
  186. newCommit := getLastCommit(t)
  187. if expectedUserName == "" {
  188. require.Equal(t, lastCommit.ID.String(), newCommit.ID.String())
  189. respErr := test.ParseJSONError(resp.Body.Bytes())
  190. assert.Equal(t, translation.NewLocale("en-US").TrString("repo.editor.invalid_commit_email"), respErr.ErrorMessage)
  191. } else {
  192. require.NotEqual(t, lastCommit.ID.String(), newCommit.ID.String())
  193. assert.Equal(t, expectedUserName, newCommit.Author.Name)
  194. assert.Equal(t, expectedEmail, newCommit.Author.Email)
  195. assert.Equal(t, expectedUserName, newCommit.Committer.Name)
  196. assert.Equal(t, expectedEmail, newCommit.Committer.Email)
  197. }
  198. return resp
  199. }
  200. uploadFile := func(t *testing.T, name, content string) string {
  201. body := &bytes.Buffer{}
  202. uploadForm := multipart.NewWriter(body)
  203. file, _ := uploadForm.CreateFormFile("file", name)
  204. _, _ = io.Copy(file, strings.NewReader(content))
  205. _ = uploadForm.WriteField("_csrf", GetUserCSRFToken(t, session))
  206. _ = uploadForm.Close()
  207. req := NewRequestWithBody(t, "POST", "/user2/repo1/upload-file", body)
  208. req.Header.Add("Content-Type", uploadForm.FormDataContentType())
  209. resp := session.MakeRequest(t, req, http.StatusOK)
  210. respMap := map[string]string{}
  211. DecodeJSON(t, resp, &respMap)
  212. return respMap["uuid"]
  213. }
  214. t.Run("EmailInactive", func(t *testing.T) {
  215. defer tests.PrintCurrentTest(t)()
  216. email := unittest.AssertExistsAndLoadBean(t, &user_model.EmailAddress{ID: 35, UID: user.ID})
  217. require.False(t, email.IsActivated)
  218. makeReq(t, "/user2/repo1/_edit/master/README.md", map[string]string{
  219. "tree_path": "README.md",
  220. "content": "test content",
  221. "commit_email": email.Email,
  222. }, "", "")
  223. })
  224. t.Run("EmailInvalid", func(t *testing.T) {
  225. defer tests.PrintCurrentTest(t)()
  226. email := unittest.AssertExistsAndLoadBean(t, &user_model.EmailAddress{ID: 1, IsActivated: true})
  227. require.NotEqual(t, email.UID, user.ID)
  228. makeReq(t, "/user2/repo1/_edit/master/README.md", map[string]string{
  229. "tree_path": "README.md",
  230. "content": "test content",
  231. "commit_email": email.Email,
  232. }, "", "")
  233. })
  234. testWebGit := func(t *testing.T, linkForKeepPrivate string, paramsForKeepPrivate map[string]string, linkForChosenEmail string, paramsForChosenEmail map[string]string) (resp1, resp2 *httptest.ResponseRecorder) {
  235. t.Run("DefaultEmailKeepPrivate", func(t *testing.T) {
  236. defer tests.PrintCurrentTest(t)()
  237. paramsForKeepPrivate["commit_email"] = ""
  238. resp1 = makeReq(t, linkForKeepPrivate, paramsForKeepPrivate, "User Two", "user2@noreply.example.org")
  239. })
  240. t.Run("ChooseEmail", func(t *testing.T) {
  241. defer tests.PrintCurrentTest(t)()
  242. paramsForChosenEmail["commit_email"] = "user2@example.com"
  243. resp2 = makeReq(t, linkForChosenEmail, paramsForChosenEmail, "User Two", "user2@example.com")
  244. })
  245. return resp1, resp2
  246. }
  247. t.Run("Edit", func(t *testing.T) {
  248. testWebGit(t,
  249. "/user2/repo1/_edit/master/README.md", map[string]string{"tree_path": "README.md", "content": "for keep private"},
  250. "/user2/repo1/_edit/master/README.md", map[string]string{"tree_path": "README.md", "content": "for chosen email"},
  251. )
  252. })
  253. t.Run("UploadDelete", func(t *testing.T) {
  254. file1UUID := uploadFile(t, "file1", "File 1")
  255. file2UUID := uploadFile(t, "file2", "File 2")
  256. testWebGit(t,
  257. "/user2/repo1/_upload/master", map[string]string{"files": file1UUID},
  258. "/user2/repo1/_upload/master", map[string]string{"files": file2UUID},
  259. )
  260. testWebGit(t,
  261. "/user2/repo1/_delete/master/file1", map[string]string{},
  262. "/user2/repo1/_delete/master/file2", map[string]string{},
  263. )
  264. })
  265. t.Run("ApplyPatchCherryPick", func(t *testing.T) {
  266. testWebGit(t,
  267. "/user2/repo1/_diffpatch/master", map[string]string{
  268. "tree_path": "__dummy__",
  269. "content": `diff --git a/patch-file-1.txt b/patch-file-1.txt
  270. new file mode 100644
  271. index 0000000000..aaaaaaaaaa
  272. --- /dev/null
  273. +++ b/patch-file-1.txt
  274. @@ -0,0 +1 @@
  275. +File 1
  276. `,
  277. },
  278. "/user2/repo1/_diffpatch/master", map[string]string{
  279. "tree_path": "__dummy__",
  280. "content": `diff --git a/patch-file-2.txt b/patch-file-2.txt
  281. new file mode 100644
  282. index 0000000000..bbbbbbbbbb
  283. --- /dev/null
  284. +++ b/patch-file-2.txt
  285. @@ -0,0 +1 @@
  286. +File 2
  287. `,
  288. },
  289. )
  290. commit1, err := gitRepo.GetCommitByPath("patch-file-1.txt")
  291. require.NoError(t, err)
  292. commit2, err := gitRepo.GetCommitByPath("patch-file-2.txt")
  293. require.NoError(t, err)
  294. resp1, _ := testWebGit(t,
  295. "/user2/repo1/_cherrypick/"+commit1.ID.String()+"/master", map[string]string{"revert": "true"},
  296. "/user2/repo1/_cherrypick/"+commit2.ID.String()+"/master", map[string]string{"revert": "true"},
  297. )
  298. // By the way, test the "cherrypick" page: a successful revert redirects to the main branch
  299. assert.Equal(t, "/user2/repo1/src/branch/master", test.RedirectURL(resp1))
  300. })
  301. }
  302. func testForkToEditFile(t *testing.T, session *TestSession, user, owner, repo, branch, filePath string) {
  303. forkToEdit := func(t *testing.T, session *TestSession, owner, repo, operation, branch, filePath string) {
  304. // visit the base repo, see the "Add File" button
  305. req := NewRequest(t, "GET", path.Join(owner, repo))
  306. resp := session.MakeRequest(t, req, http.StatusOK)
  307. htmlDoc := NewHTMLParser(t, resp.Body)
  308. AssertHTMLElement(t, htmlDoc, ".repo-add-file", 1)
  309. // attempt to edit a file, see the guideline page
  310. req = NewRequest(t, "GET", path.Join(owner, repo, operation, branch, filePath))
  311. resp = session.MakeRequest(t, req, http.StatusOK)
  312. assert.Contains(t, resp.Body.String(), "Fork Repository to Propose Changes")
  313. // fork the repository
  314. req = NewRequestWithValues(t, "POST", path.Join(owner, repo, "_fork", branch), map[string]string{"_csrf": GetUserCSRFToken(t, session)})
  315. resp = session.MakeRequest(t, req, http.StatusOK)
  316. assert.JSONEq(t, `{"redirect":""}`, resp.Body.String())
  317. }
  318. t.Run("ForkButArchived", func(t *testing.T) {
  319. // Fork repository because we can't edit it
  320. forkToEdit(t, session, owner, repo, "_edit", branch, filePath)
  321. // Archive the repository
  322. req := NewRequestWithValues(t, "POST", path.Join(user, repo, "settings"),
  323. map[string]string{
  324. "_csrf": GetUserCSRFToken(t, session),
  325. "repo_name": repo,
  326. "action": "archive",
  327. },
  328. )
  329. session.MakeRequest(t, req, http.StatusSeeOther)
  330. // Check editing archived repository is disabled
  331. req = NewRequest(t, "GET", path.Join(owner, repo, "_edit", branch, filePath)).SetHeader("Accept", "text/html")
  332. resp := session.MakeRequest(t, req, http.StatusNotFound)
  333. assert.Contains(t, resp.Body.String(), "You have forked this repository but your fork is not editable.")
  334. // Unfork the repository
  335. req = NewRequestWithValues(t, "POST", path.Join(user, repo, "settings"),
  336. map[string]string{
  337. "_csrf": GetUserCSRFToken(t, session),
  338. "repo_name": repo,
  339. "action": "convert_fork",
  340. },
  341. )
  342. session.MakeRequest(t, req, http.StatusSeeOther)
  343. })
  344. // Fork repository again, and check the existence of the forked repo with unique name
  345. forkToEdit(t, session, owner, repo, "_edit", branch, filePath)
  346. session.MakeRequest(t, NewRequestf(t, "GET", "/%s/%s-1", user, repo), http.StatusOK)
  347. t.Run("CheckBaseRepoForm", func(t *testing.T) {
  348. // the base repo's edit form should have the correct action and upload links (pointing to the forked repo)
  349. req := NewRequest(t, "GET", path.Join(owner, repo, "_upload", branch, filePath)+"?foo=bar")
  350. resp := session.MakeRequest(t, req, http.StatusOK)
  351. htmlDoc := NewHTMLParser(t, resp.Body)
  352. uploadForm := htmlDoc.doc.Find(".form-fetch-action")
  353. formAction := uploadForm.AttrOr("action", "")
  354. assert.Equal(t, fmt.Sprintf("/%s/%s-1/_upload/%s/%s?from_base_branch=%s&foo=bar", user, repo, branch, filePath, branch), formAction)
  355. uploadLink := uploadForm.Find(".dropzone").AttrOr("data-link-url", "")
  356. assert.Equal(t, fmt.Sprintf("/%s/%s-1/upload-file", user, repo), uploadLink)
  357. newBranchName := uploadForm.Find("input[name=new_branch_name]").AttrOr("value", "")
  358. assert.Equal(t, user+"-patch-1", newBranchName)
  359. commitChoice := uploadForm.Find("input[name=commit_choice][checked]").AttrOr("value", "")
  360. assert.Equal(t, "commit-to-new-branch", commitChoice)
  361. lastCommit := uploadForm.Find("input[name=last_commit]").AttrOr("value", "")
  362. assert.NotEmpty(t, lastCommit)
  363. })
  364. t.Run("ViewBaseEditFormAndCommitToFork", func(t *testing.T) {
  365. req := NewRequest(t, "GET", path.Join(owner, repo, "_edit", branch, filePath))
  366. resp := session.MakeRequest(t, req, http.StatusOK)
  367. htmlDoc := NewHTMLParser(t, resp.Body)
  368. editRequestForm := map[string]string{
  369. "_csrf": GetUserCSRFToken(t, session),
  370. "last_commit": htmlDoc.GetInputValueByName("last_commit"),
  371. "tree_path": filePath,
  372. "content": "new content in fork",
  373. "commit_choice": "commit-to-new-branch",
  374. }
  375. // change a file in the forked repo with existing branch name (should fail)
  376. editRequestForm["new_branch_name"] = "master"
  377. req = NewRequestWithValues(t, "POST", fmt.Sprintf("/%s/%s-1/_edit/%s/%s?from_base_branch=%s", user, repo, branch, filePath, branch), editRequestForm)
  378. resp = session.MakeRequest(t, req, http.StatusBadRequest)
  379. respJSON := test.ParseJSONError(resp.Body.Bytes())
  380. assert.Equal(t, `Branch "master" already exists in your fork. Please choose a new branch name.`, respJSON.ErrorMessage)
  381. // change a file in the forked repo (should succeed)
  382. newBranchName := htmlDoc.GetInputValueByName("new_branch_name")
  383. editRequestForm["new_branch_name"] = newBranchName
  384. req = NewRequestWithValues(t, "POST", fmt.Sprintf("/%s/%s-1/_edit/%s/%s?from_base_branch=%s", user, repo, branch, filePath, branch), editRequestForm)
  385. resp = session.MakeRequest(t, req, http.StatusOK)
  386. assert.Equal(t, fmt.Sprintf("/%s/%s/compare/%s...%s/%s-1:%s", owner, repo, branch, user, repo, newBranchName), test.RedirectURL(resp))
  387. // check the file in the fork's branch is changed
  388. req = NewRequest(t, "GET", fmt.Sprintf("/%s/%s-1/src/branch/%s/%s", user, repo, newBranchName, filePath))
  389. resp = session.MakeRequest(t, req, http.StatusOK)
  390. assert.Contains(t, resp.Body.String(), "new content in fork")
  391. })
  392. }
  393. func testEditFileNotAllowed(t *testing.T) {
  394. sessionUser1 := loginUser(t, "user1") // admin, all access
  395. sessionUser4 := loginUser(t, "user4")
  396. // "_cherrypick" has a different route pattern, so skip its test
  397. operations := []string{"_new", "_edit", "_delete", "_upload", "_diffpatch"}
  398. for _, operation := range operations {
  399. t.Run(operation, func(t *testing.T) {
  400. // Branch does not exist
  401. targetLink := path.Join("user2", "repo1", operation, "missing", "README.md")
  402. sessionUser1.MakeRequest(t, NewRequest(t, "GET", targetLink), http.StatusNotFound)
  403. // Private repository
  404. targetLink = path.Join("user2", "repo2", operation, "master", "Home.md")
  405. sessionUser1.MakeRequest(t, NewRequest(t, "GET", targetLink), http.StatusOK)
  406. sessionUser4.MakeRequest(t, NewRequest(t, "GET", targetLink), http.StatusNotFound)
  407. // Empty repository
  408. targetLink = path.Join("org41", "repo61", operation, "master", "README.md")
  409. sessionUser1.MakeRequest(t, NewRequest(t, "GET", targetLink), http.StatusNotFound)
  410. })
  411. }
  412. }