44package integration
55
66import (
7+ "encoding/base64"
78 "fmt"
89 "net/http"
910 "net/http/httptest"
@@ -17,7 +18,9 @@ import (
1718 repo_model "code.gitea.io/gitea/models/repo"
1819 "code.gitea.io/gitea/models/unittest"
1920 "code.gitea.io/gitea/modules/git/gitcmd"
21+ api "code.gitea.io/gitea/modules/structs"
2022 "code.gitea.io/gitea/modules/test"
23+ "code.gitea.io/gitea/modules/util"
2124 "code.gitea.io/gitea/tests"
2225
2326 "github.com/stretchr/testify/assert"
@@ -153,8 +156,16 @@ func TestPullCreate(t *testing.T) {
153156 url := test .RedirectURL (resp )
154157 assert .Regexp (t , "^/user2/repo1/pulls/[0-9]*$" , url )
155158
159+ // test create the pull request again and it should fail now
160+ link := "/user2/repo1/compare/master...user1/repo1:master"
161+ req := NewRequestWithValues (t , "POST" , link , map [string ]string {
162+ "_csrf" : GetUserCSRFToken (t , session ),
163+ "title" : "This is a pull title" ,
164+ })
165+ session .MakeRequest (t , req , http .StatusBadRequest )
166+
156167 // check .diff can be accessed and matches performed change
157- req : = NewRequest (t , "GET" , url + ".diff" )
168+ req = NewRequest (t , "GET" , url + ".diff" )
158169 resp = session .MakeRequest (t , req , http .StatusOK )
159170 assert .Regexp (t , `\+Hello, World \(Edited\)` , resp .Body )
160171 assert .Regexp (t , "^diff" , resp .Body )
@@ -295,6 +306,95 @@ func TestPullCreatePrFromBaseToFork(t *testing.T) {
295306 })
296307}
297308
309+ func TestCreatePullRequestFromNestedOrgForks (t * testing.T ) {
310+ onGiteaRun (t , func (t * testing.T , _ * url.URL ) {
311+ session := loginUser (t , "user1" )
312+ token := getTokenForLoggedInUser (t , session , auth_model .AccessTokenScopeWriteRepository , auth_model .AccessTokenScopeWriteOrganization )
313+
314+ const (
315+ baseOrg = "test-fork-org1"
316+ midForkOrg = "test-fork-org2"
317+ leafForkOrg = "test-fork-org3"
318+ repoName = "test-fork-repo"
319+ patchBranch = "teabot-patch-1"
320+ )
321+
322+ createOrg := func (name string ) {
323+ req := NewRequestWithJSON (t , "POST" , "/api/v1/orgs" , & api.CreateOrgOption {
324+ UserName : name ,
325+ Visibility : "public" ,
326+ }).AddTokenAuth (token )
327+ MakeRequest (t , req , http .StatusCreated )
328+ }
329+
330+ createOrg (baseOrg )
331+ createOrg (midForkOrg )
332+ createOrg (leafForkOrg )
333+
334+ req := NewRequestWithJSON (t , "POST" , fmt .Sprintf ("/api/v1/orgs/%s/repos" , baseOrg ), & api.CreateRepoOption {
335+ Name : repoName ,
336+ AutoInit : true ,
337+ DefaultBranch : "main" ,
338+ Private : false ,
339+ Readme : "Default" ,
340+ }).AddTokenAuth (token )
341+ resp := MakeRequest (t , req , http .StatusCreated )
342+ var baseRepo api.Repository
343+ DecodeJSON (t , resp , & baseRepo )
344+ assert .Equal (t , "main" , baseRepo .DefaultBranch )
345+
346+ forkIntoOrg := func (srcOrg , dstOrg string ) api.Repository {
347+ req := NewRequestWithJSON (t , "POST" , fmt .Sprintf ("/api/v1/repos/%s/%s/forks" , srcOrg , repoName ), & api.CreateForkOption {
348+ Organization : util .ToPointer (dstOrg ),
349+ }).AddTokenAuth (token )
350+ resp := MakeRequest (t , req , http .StatusAccepted )
351+ var forkRepo api.Repository
352+ DecodeJSON (t , resp , & forkRepo )
353+ assert .NotNil (t , forkRepo .Owner )
354+ if forkRepo .Owner != nil {
355+ assert .Equal (t , dstOrg , forkRepo .Owner .UserName )
356+ }
357+ return forkRepo
358+ }
359+
360+ forkIntoOrg (baseOrg , midForkOrg )
361+ forkIntoOrg (midForkOrg , leafForkOrg )
362+
363+ req = NewRequestWithJSON (t , "POST" , fmt .Sprintf ("/api/v1/repos/%s/%s/contents/%s" , leafForkOrg , repoName , "patch-from-org3.txt" ), & api.CreateFileOptions {
364+ FileOptions : api.FileOptions {
365+ BranchName : "main" ,
366+ NewBranchName : patchBranch ,
367+ Message : "create patch from org3" ,
368+ },
369+ ContentBase64 : base64 .StdEncoding .EncodeToString ([]byte ("patch content" )),
370+ }).AddTokenAuth (token )
371+ MakeRequest (t , req , http .StatusCreated )
372+
373+ prPayload := map [string ]string {
374+ "head" : fmt .Sprintf ("%s:%s" , leafForkOrg , patchBranch ),
375+ "base" : "main" ,
376+ "title" : "test creating pull from test-fork-org3 to test-fork-org1" ,
377+ }
378+ req = NewRequestWithJSON (t , "POST" , fmt .Sprintf ("/api/v1/repos/%s/%s/pulls" , baseOrg , repoName ), prPayload ).AddTokenAuth (token )
379+ resp = MakeRequest (t , req , http .StatusCreated )
380+ var pr api.PullRequest
381+ DecodeJSON (t , resp , & pr )
382+ assert .Equal (t , prPayload ["title" ], pr .Title )
383+ if assert .NotNil (t , pr .Head ) {
384+ assert .Equal (t , patchBranch , pr .Head .Ref )
385+ if assert .NotNil (t , pr .Head .Repository ) {
386+ assert .Equal (t , fmt .Sprintf ("%s/%s" , leafForkOrg , repoName ), pr .Head .Repository .FullName )
387+ }
388+ }
389+ if assert .NotNil (t , pr .Base ) {
390+ assert .Equal (t , "main" , pr .Base .Ref )
391+ if assert .NotNil (t , pr .Base .Repository ) {
392+ assert .Equal (t , fmt .Sprintf ("%s/%s" , baseOrg , repoName ), pr .Base .Repository .FullName )
393+ }
394+ }
395+ })
396+ }
397+
298398func TestPullCreateParallel (t * testing.T ) {
299399 onGiteaRun (t , func (t * testing.T , u * url.URL ) {
300400 sessionFork := loginUser (t , "user1" )
0 commit comments