aboutsummaryrefslogtreecommitdiffstats
path: root/tests/integration/repo_fork_test.go
blob: 95325eefebd8975d8280c83eed262b5384db389f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
// Copyright 2017 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT

package integration

import (
	"fmt"
	"net/http"
	"net/http/httptest"
	"strconv"
	"testing"

	"code.gitea.io/gitea/models/db"
	org_model "code.gitea.io/gitea/models/organization"
	"code.gitea.io/gitea/models/unittest"
	user_model "code.gitea.io/gitea/models/user"
	"code.gitea.io/gitea/modules/structs"
	"code.gitea.io/gitea/modules/test"
	org_service "code.gitea.io/gitea/services/org"
	"code.gitea.io/gitea/tests"

	"github.com/stretchr/testify/assert"
)

func testRepoFork(t *testing.T, session *TestSession, ownerName, repoName, forkOwnerName, forkRepoName, forkBranch string) *httptest.ResponseRecorder {
	forkOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: forkOwnerName})

	// Step0: check the existence of the to-fork repo
	req := NewRequestf(t, "GET", "/%s/%s", forkOwnerName, forkRepoName)
	session.MakeRequest(t, req, http.StatusNotFound)

	// Step1: go to the main page of repo
	req = NewRequestf(t, "GET", "/%s/%s", ownerName, repoName)
	resp := session.MakeRequest(t, req, http.StatusOK)

	// Step2: click the fork button
	htmlDoc := NewHTMLParser(t, resp.Body)
	link, exists := htmlDoc.doc.Find(`a.ui.button[href*="/fork"]`).Attr("href")
	assert.True(t, exists, "The template has changed")
	req = NewRequest(t, "GET", link)
	resp = session.MakeRequest(t, req, http.StatusOK)

	// Step3: fill the form of the forking
	htmlDoc = NewHTMLParser(t, resp.Body)
	link, exists = htmlDoc.doc.Find(`form.ui.form[action*="/fork"]`).Attr("action")
	assert.True(t, exists, "The template has changed")
	_, exists = htmlDoc.doc.Find(fmt.Sprintf(".owner.dropdown .item[data-value=\"%d\"]", forkOwner.ID)).Attr("data-value")
	assert.True(t, exists, "Fork owner '%s' is not present in select box", forkOwnerName)
	req = NewRequestWithValues(t, "POST", link, map[string]string{
		"_csrf":              htmlDoc.GetCSRF(),
		"uid":                strconv.FormatInt(forkOwner.ID, 10),
		"repo_name":          forkRepoName,
		"fork_single_branch": forkBranch,
	})
	resp = session.MakeRequest(t, req, http.StatusOK)
	assert.Equal(t, fmt.Sprintf("/%s/%s", forkOwnerName, forkRepoName), test.RedirectURL(resp))

	// Step4: check the existence of the forked repo
	req = NewRequestf(t, "GET", "/%s/%s", forkOwnerName, forkRepoName)
	resp = session.MakeRequest(t, req, http.StatusOK)

	return resp
}

func TestRepoFork(t *testing.T) {
	defer tests.PrepareTestEnv(t)()
	session := loginUser(t, "user1")
	testRepoFork(t, session, "user2", "repo1", "user1", "repo1", "")
}

func TestRepoForkToOrg(t *testing.T) {
	defer tests.PrepareTestEnv(t)()
	session := loginUser(t, "user2")
	testRepoFork(t, session, "user2", "repo1", "org3", "repo1", "")

	// Check that no more forking is allowed as user2 owns repository
	//  and org3 organization that owner user2 is also now has forked this repository
	req := NewRequest(t, "GET", "/user2/repo1")
	resp := session.MakeRequest(t, req, http.StatusOK)
	htmlDoc := NewHTMLParser(t, resp.Body)
	_, exists := htmlDoc.doc.Find(`a.ui.button[href*="/fork"]`).Attr("href")
	assert.False(t, exists, "Forking should not be allowed anymore")
}

func TestForkListLimitedAndPrivateRepos(t *testing.T) {
	defer tests.PrepareTestEnv(t)()
	forkItemSelector := ".fork-list .flex-item"

	user1Sess := loginUser(t, "user1")
	user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "user1"})

	// fork to a limited org
	limitedOrg := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 22})
	assert.Equal(t, structs.VisibleTypeLimited, limitedOrg.Visibility)
	ownerTeam1, err := org_model.OrgFromUser(limitedOrg).GetOwnerTeam(db.DefaultContext)
	assert.NoError(t, err)
	assert.NoError(t, org_service.AddTeamMember(db.DefaultContext, ownerTeam1, user1))
	testRepoFork(t, user1Sess, "user2", "repo1", limitedOrg.Name, "repo1", "")

	// fork to a private org
	user4Sess := loginUser(t, "user4")
	user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "user4"})
	privateOrg := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 23})
	assert.Equal(t, structs.VisibleTypePrivate, privateOrg.Visibility)
	ownerTeam2, err := org_model.OrgFromUser(privateOrg).GetOwnerTeam(db.DefaultContext)
	assert.NoError(t, err)
	assert.NoError(t, org_service.AddTeamMember(db.DefaultContext, ownerTeam2, user4))
	testRepoFork(t, user4Sess, "user2", "repo1", privateOrg.Name, "repo1", "")

	t.Run("Anonymous", func(t *testing.T) {
		defer tests.PrintCurrentTest(t)()
		req := NewRequest(t, "GET", "/user2/repo1/forks")
		resp := MakeRequest(t, req, http.StatusOK)
		htmlDoc := NewHTMLParser(t, resp.Body)
		assert.Equal(t, 0, htmlDoc.Find(forkItemSelector).Length())
	})

	t.Run("Logged in", func(t *testing.T) {
		defer tests.PrintCurrentTest(t)()

		req := NewRequest(t, "GET", "/user2/repo1/forks")
		resp := user1Sess.MakeRequest(t, req, http.StatusOK)
		htmlDoc := NewHTMLParser(t, resp.Body)
		// since user1 is an admin, he can get both of the forked repositories
		assert.Equal(t, 2, htmlDoc.Find(forkItemSelector).Length())

		assert.NoError(t, org_service.AddTeamMember(db.DefaultContext, ownerTeam2, user1))
		resp = user1Sess.MakeRequest(t, req, http.StatusOK)
		htmlDoc = NewHTMLParser(t, resp.Body)
		assert.Equal(t, 2, htmlDoc.Find(forkItemSelector).Length())
	})
}