gitea源码

empty_repo_test.go 7.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. // Copyright 2017 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package integration
  4. import (
  5. "bytes"
  6. "encoding/base64"
  7. "fmt"
  8. "io"
  9. "mime/multipart"
  10. "net/http"
  11. "strings"
  12. "testing"
  13. auth_model "code.gitea.io/gitea/models/auth"
  14. "code.gitea.io/gitea/models/db"
  15. repo_model "code.gitea.io/gitea/models/repo"
  16. "code.gitea.io/gitea/models/unittest"
  17. user_model "code.gitea.io/gitea/models/user"
  18. "code.gitea.io/gitea/modules/json"
  19. "code.gitea.io/gitea/modules/setting"
  20. api "code.gitea.io/gitea/modules/structs"
  21. "code.gitea.io/gitea/modules/test"
  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 testAPINewFile(t *testing.T, session *TestSession, user, repo, branch, treePath, content string) {
  28. url := fmt.Sprintf("/%s/%s/_new/%s", user, repo, branch)
  29. req := NewRequestWithValues(t, "POST", url, map[string]string{
  30. "_csrf": GetUserCSRFToken(t, session),
  31. "commit_choice": "direct",
  32. "tree_path": treePath,
  33. "content": content,
  34. })
  35. resp := session.MakeRequest(t, req, http.StatusOK)
  36. assert.NotEmpty(t, test.RedirectURL(resp))
  37. }
  38. func TestEmptyRepo(t *testing.T) {
  39. defer tests.PrepareTestEnv(t)()
  40. subPaths := []string{
  41. "commits/master",
  42. "raw/foo",
  43. "commit/1ae57b34ccf7e18373",
  44. "graph",
  45. }
  46. emptyRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 6})
  47. assert.True(t, emptyRepo.IsEmpty)
  48. owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: emptyRepo.OwnerID})
  49. for _, subPath := range subPaths {
  50. req := NewRequestf(t, "GET", "/%s/%s/%s", owner.Name, emptyRepo.Name, subPath)
  51. MakeRequest(t, req, http.StatusNotFound)
  52. }
  53. }
  54. func TestEmptyRepoAddFile(t *testing.T) {
  55. defer tests.PrepareTestEnv(t)()
  56. session := loginUser(t, "user30")
  57. token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadRepository)
  58. // test web page
  59. req := NewRequest(t, "GET", "/user30/empty")
  60. resp := session.MakeRequest(t, req, http.StatusOK)
  61. bodyString := resp.Body.String()
  62. assert.Contains(t, bodyString, "empty-repo-guide")
  63. assert.True(t, test.IsNormalPageCompleted(bodyString))
  64. // test api
  65. req = NewRequest(t, "GET", "/api/v1/repos/user30/empty/raw/main/README.md").AddTokenAuth(token)
  66. session.MakeRequest(t, req, http.StatusNotFound)
  67. // test feed
  68. req = NewRequest(t, "GET", "/user30/empty/rss/branch/main/README.md").AddTokenAuth(token).SetHeader("Accept", "application/rss+xml")
  69. resp = session.MakeRequest(t, req, http.StatusOK)
  70. assert.Contains(t, resp.Body.String(), "</rss>")
  71. // create a new file
  72. req = NewRequest(t, "GET", "/user30/empty/_new/"+setting.Repository.DefaultBranch)
  73. resp = session.MakeRequest(t, req, http.StatusOK)
  74. doc := NewHTMLParser(t, resp.Body).Find(`input[name="commit_choice"]`)
  75. assert.Empty(t, doc.AttrOr("checked", "_no_"))
  76. req = NewRequestWithValues(t, "POST", "/user30/empty/_new/"+setting.Repository.DefaultBranch, map[string]string{
  77. "_csrf": GetUserCSRFToken(t, session),
  78. "commit_choice": "direct",
  79. "tree_path": "test-file.md",
  80. "content": "newly-added-test-file",
  81. })
  82. resp = session.MakeRequest(t, req, http.StatusOK)
  83. redirect := test.RedirectURL(resp)
  84. assert.Equal(t, "/user30/empty/src/branch/"+setting.Repository.DefaultBranch+"/test-file.md", redirect)
  85. req = NewRequest(t, "GET", redirect)
  86. resp = session.MakeRequest(t, req, http.StatusOK)
  87. assert.Contains(t, resp.Body.String(), "newly-added-test-file")
  88. // the repo is not empty anymore
  89. req = NewRequest(t, "GET", "/user30/empty")
  90. resp = session.MakeRequest(t, req, http.StatusOK)
  91. assert.Contains(t, resp.Body.String(), "test-file.md")
  92. // if the repo is in incorrect state, it should be able to self-heal (recover to correct state)
  93. testEmptyOrBrokenRecover := func(t *testing.T, isEmpty, isBroken bool) {
  94. user30EmptyRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{OwnerID: 30, Name: "empty"})
  95. user30EmptyRepo.IsEmpty = isEmpty
  96. user30EmptyRepo.Status = util.Iif(isBroken, repo_model.RepositoryBroken, repo_model.RepositoryReady)
  97. user30EmptyRepo.DefaultBranch = "no-such"
  98. _, err := db.GetEngine(t.Context()).ID(user30EmptyRepo.ID).Cols("is_empty", "status", "default_branch").Update(user30EmptyRepo)
  99. require.NoError(t, err)
  100. user30EmptyRepo = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{OwnerID: 30, Name: "empty"})
  101. assert.Equal(t, isEmpty, user30EmptyRepo.IsEmpty)
  102. assert.Equal(t, isBroken, user30EmptyRepo.Status == repo_model.RepositoryBroken)
  103. req = NewRequest(t, "GET", "/user30/empty")
  104. resp = session.MakeRequest(t, req, http.StatusSeeOther)
  105. redirect = test.RedirectURL(resp)
  106. assert.Equal(t, "/user30/empty", redirect)
  107. req = NewRequest(t, "GET", "/user30/empty")
  108. resp = session.MakeRequest(t, req, http.StatusOK)
  109. assert.Contains(t, resp.Body.String(), "test-file.md")
  110. }
  111. testEmptyOrBrokenRecover(t, true, false)
  112. testEmptyOrBrokenRecover(t, false, true)
  113. testEmptyOrBrokenRecover(t, true, true)
  114. }
  115. func TestEmptyRepoUploadFile(t *testing.T) {
  116. defer tests.PrepareTestEnv(t)()
  117. session := loginUser(t, "user30")
  118. req := NewRequest(t, "GET", "/user30/empty/_new/"+setting.Repository.DefaultBranch)
  119. resp := session.MakeRequest(t, req, http.StatusOK)
  120. doc := NewHTMLParser(t, resp.Body).Find(`input[name="commit_choice"]`)
  121. assert.Empty(t, doc.AttrOr("checked", "_no_"))
  122. body := &bytes.Buffer{}
  123. mpForm := multipart.NewWriter(body)
  124. _ = mpForm.WriteField("_csrf", GetUserCSRFToken(t, session))
  125. file, _ := mpForm.CreateFormFile("file", "uploaded-file.txt")
  126. _, _ = io.Copy(file, strings.NewReader("newly-uploaded-test-file"))
  127. _ = mpForm.Close()
  128. req = NewRequestWithBody(t, "POST", "/user30/empty/upload-file", body)
  129. req.Header.Add("Content-Type", mpForm.FormDataContentType())
  130. resp = session.MakeRequest(t, req, http.StatusOK)
  131. respMap := map[string]string{}
  132. assert.NoError(t, json.Unmarshal(resp.Body.Bytes(), &respMap))
  133. req = NewRequestWithValues(t, "POST", "/user30/empty/_upload/"+setting.Repository.DefaultBranch, map[string]string{
  134. "_csrf": GetUserCSRFToken(t, session),
  135. "commit_choice": "direct",
  136. "files": respMap["uuid"],
  137. "tree_path": "",
  138. })
  139. resp = session.MakeRequest(t, req, http.StatusOK)
  140. redirect := test.RedirectURL(resp)
  141. assert.Equal(t, "/user30/empty/src/branch/"+setting.Repository.DefaultBranch, redirect)
  142. req = NewRequest(t, "GET", redirect)
  143. resp = session.MakeRequest(t, req, http.StatusOK)
  144. assert.Contains(t, resp.Body.String(), "uploaded-file.txt")
  145. }
  146. func TestEmptyRepoAddFileByAPI(t *testing.T) {
  147. defer tests.PrepareTestEnv(t)()
  148. session := loginUser(t, "user30")
  149. token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository)
  150. req := NewRequestWithJSON(t, "POST", "/api/v1/repos/user30/empty/contents/new-file.txt", &api.CreateFileOptions{
  151. FileOptions: api.FileOptions{
  152. NewBranchName: "new_branch",
  153. Message: "init",
  154. },
  155. ContentBase64: base64.StdEncoding.EncodeToString([]byte("newly-added-api-file")),
  156. }).AddTokenAuth(token)
  157. resp := MakeRequest(t, req, http.StatusCreated)
  158. var fileResponse api.FileResponse
  159. DecodeJSON(t, resp, &fileResponse)
  160. expectedHTMLURL := setting.AppURL + "user30/empty/src/branch/new_branch/new-file.txt"
  161. assert.Equal(t, expectedHTMLURL, *fileResponse.Content.HTMLURL)
  162. req = NewRequest(t, "GET", "/user30/empty/src/branch/new_branch/new-file.txt")
  163. resp = session.MakeRequest(t, req, http.StatusOK)
  164. assert.Contains(t, resp.Body.String(), "newly-added-api-file")
  165. req = NewRequest(t, "GET", "/api/v1/repos/user30/empty").
  166. AddTokenAuth(token)
  167. resp = session.MakeRequest(t, req, http.StatusOK)
  168. var apiRepo api.Repository
  169. DecodeJSON(t, resp, &apiRepo)
  170. assert.Equal(t, "new_branch", apiRepo.DefaultBranch)
  171. }