gitea源码

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. // Copyright 2017 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package integration
  4. import (
  5. "fmt"
  6. "net/http"
  7. "net/http/httptest"
  8. "strconv"
  9. "testing"
  10. org_model "code.gitea.io/gitea/models/organization"
  11. "code.gitea.io/gitea/models/unittest"
  12. user_model "code.gitea.io/gitea/models/user"
  13. "code.gitea.io/gitea/modules/structs"
  14. "code.gitea.io/gitea/modules/test"
  15. org_service "code.gitea.io/gitea/services/org"
  16. "code.gitea.io/gitea/tests"
  17. "github.com/stretchr/testify/assert"
  18. )
  19. func testRepoFork(t *testing.T, session *TestSession, ownerName, repoName, forkOwnerName, forkRepoName, forkBranch string) *httptest.ResponseRecorder {
  20. forkOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: forkOwnerName})
  21. // Step0: check the existence of the to-fork repo
  22. req := NewRequestf(t, "GET", "/%s/%s", forkOwnerName, forkRepoName)
  23. session.MakeRequest(t, req, http.StatusNotFound)
  24. // Step1: go to the main page of repo
  25. req = NewRequestf(t, "GET", "/%s/%s", ownerName, repoName)
  26. resp := session.MakeRequest(t, req, http.StatusOK)
  27. // Step2: click the fork button
  28. htmlDoc := NewHTMLParser(t, resp.Body)
  29. link, exists := htmlDoc.doc.Find(`a.ui.button[href*="/fork"]`).Attr("href")
  30. assert.True(t, exists, "The template has changed")
  31. req = NewRequest(t, "GET", link)
  32. resp = session.MakeRequest(t, req, http.StatusOK)
  33. // Step3: fill the form of the forking
  34. htmlDoc = NewHTMLParser(t, resp.Body)
  35. link, exists = htmlDoc.doc.Find(`form.ui.form[action*="/fork"]`).Attr("action")
  36. assert.True(t, exists, "The template has changed")
  37. _, exists = htmlDoc.doc.Find(fmt.Sprintf(".owner.dropdown .item[data-value=\"%d\"]", forkOwner.ID)).Attr("data-value")
  38. assert.True(t, exists, "Fork owner '%s' is not present in select box", forkOwnerName)
  39. req = NewRequestWithValues(t, "POST", link, map[string]string{
  40. "_csrf": htmlDoc.GetCSRF(),
  41. "uid": strconv.FormatInt(forkOwner.ID, 10),
  42. "repo_name": forkRepoName,
  43. "fork_single_branch": forkBranch,
  44. })
  45. resp = session.MakeRequest(t, req, http.StatusOK)
  46. assert.Equal(t, fmt.Sprintf("/%s/%s", forkOwnerName, forkRepoName), test.RedirectURL(resp))
  47. // Step4: check the existence of the forked repo
  48. req = NewRequestf(t, "GET", "/%s/%s", forkOwnerName, forkRepoName)
  49. resp = session.MakeRequest(t, req, http.StatusOK)
  50. return resp
  51. }
  52. func TestRepoFork(t *testing.T) {
  53. defer tests.PrepareTestEnv(t)()
  54. session := loginUser(t, "user1")
  55. testRepoFork(t, session, "user2", "repo1", "user1", "repo1", "")
  56. }
  57. func TestRepoForkToOrg(t *testing.T) {
  58. defer tests.PrepareTestEnv(t)()
  59. session := loginUser(t, "user2")
  60. testRepoFork(t, session, "user2", "repo1", "org3", "repo1", "")
  61. // Check that no more forking is allowed as user2 owns repository
  62. // and org3 organization that owner user2 is also now has forked this repository
  63. req := NewRequest(t, "GET", "/user2/repo1")
  64. resp := session.MakeRequest(t, req, http.StatusOK)
  65. htmlDoc := NewHTMLParser(t, resp.Body)
  66. _, exists := htmlDoc.doc.Find(`a.ui.button[href*="/fork"]`).Attr("href")
  67. assert.False(t, exists, "Forking should not be allowed anymore")
  68. }
  69. func TestForkListLimitedAndPrivateRepos(t *testing.T) {
  70. defer tests.PrepareTestEnv(t)()
  71. forkItemSelector := ".fork-list .flex-item"
  72. user1Sess := loginUser(t, "user1")
  73. user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "user1"})
  74. // fork to a limited org
  75. limitedOrg := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 22})
  76. assert.Equal(t, structs.VisibleTypeLimited, limitedOrg.Visibility)
  77. ownerTeam1, err := org_model.OrgFromUser(limitedOrg).GetOwnerTeam(t.Context())
  78. assert.NoError(t, err)
  79. assert.NoError(t, org_service.AddTeamMember(t.Context(), ownerTeam1, user1))
  80. testRepoFork(t, user1Sess, "user2", "repo1", limitedOrg.Name, "repo1", "")
  81. // fork to a private org
  82. user4Sess := loginUser(t, "user4")
  83. user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "user4"})
  84. privateOrg := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 23})
  85. assert.Equal(t, structs.VisibleTypePrivate, privateOrg.Visibility)
  86. ownerTeam2, err := org_model.OrgFromUser(privateOrg).GetOwnerTeam(t.Context())
  87. assert.NoError(t, err)
  88. assert.NoError(t, org_service.AddTeamMember(t.Context(), ownerTeam2, user4))
  89. testRepoFork(t, user4Sess, "user2", "repo1", privateOrg.Name, "repo1", "")
  90. t.Run("Anonymous", func(t *testing.T) {
  91. defer tests.PrintCurrentTest(t)()
  92. req := NewRequest(t, "GET", "/user2/repo1/forks")
  93. resp := MakeRequest(t, req, http.StatusOK)
  94. htmlDoc := NewHTMLParser(t, resp.Body)
  95. assert.Equal(t, 0, htmlDoc.Find(forkItemSelector).Length())
  96. })
  97. t.Run("Logged in", func(t *testing.T) {
  98. defer tests.PrintCurrentTest(t)()
  99. req := NewRequest(t, "GET", "/user2/repo1/forks")
  100. resp := user1Sess.MakeRequest(t, req, http.StatusOK)
  101. htmlDoc := NewHTMLParser(t, resp.Body)
  102. // since user1 is an admin, he can get both of the forked repositories
  103. assert.Equal(t, 2, htmlDoc.Find(forkItemSelector).Length())
  104. assert.NoError(t, org_service.AddTeamMember(t.Context(), ownerTeam2, user1))
  105. resp = user1Sess.MakeRequest(t, req, http.StatusOK)
  106. htmlDoc = NewHTMLParser(t, resp.Body)
  107. assert.Equal(t, 2, htmlDoc.Find(forkItemSelector).Length())
  108. })
  109. }