Merge branch 'forgejo' into feat/add-oidc-ssh-keys

This commit is contained in:
Maks1mS 2024-12-26 14:33:09 +00:00
commit 8a3fb4885e
89 changed files with 4813 additions and 1391 deletions

View file

@ -5,6 +5,7 @@ package integration
import (
"context"
"fmt"
"net/http"
"net/http/httptest"
"net/url"
@ -19,6 +20,7 @@ import (
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/gitrepo"
repo_module "code.gitea.io/gitea/modules/repository"
"code.gitea.io/gitea/modules/test"
issue_service "code.gitea.io/gitea/services/issue"
repo_service "code.gitea.io/gitea/services/repository"
@ -62,6 +64,74 @@ func loadComment(t *testing.T, commentID string) *issues_model.Comment {
return unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: id})
}
func TestPullView_SelfReviewNotification(t *testing.T) {
onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) {
user1Session := loginUser(t, "user1")
user2Session := loginUser(t, "user2")
user1csrf := GetCSRF(t, user1Session, "/")
oldUser1NotificationCount := getUserNotificationCount(t, user1Session, user1csrf)
user2csrf := GetCSRF(t, user2Session, "/")
oldUser2NotificationCount := getUserNotificationCount(t, user2Session, user2csrf)
user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
repo, _, f := tests.CreateDeclarativeRepo(t, user2, "test_reviewer", nil, nil, []*files_service.ChangeRepoFile{
{
Operation: "create",
TreePath: "CODEOWNERS",
ContentReader: strings.NewReader("README.md @user5\n"),
},
})
defer f()
// we need to add user1 as collaborator so it can be added as reviewer
err := repo_module.AddCollaborator(db.DefaultContext, repo, user1)
require.NoError(t, err)
// create a new branch to prepare for pull request
_, err = files_service.ChangeRepoFiles(db.DefaultContext, repo, user2, &files_service.ChangeRepoFilesOptions{
NewBranch: "codeowner-basebranch",
Files: []*files_service.ChangeRepoFile{
{
Operation: "update",
TreePath: "README.md",
ContentReader: strings.NewReader("# This is a new project\n"),
},
},
})
require.NoError(t, err)
// Create a pull request.
resp := testPullCreate(t, user2Session, "user2", "test_reviewer", false, repo.DefaultBranch, "codeowner-basebranch", "Test Pull Request")
prURL := test.RedirectURL(resp)
elem := strings.Split(prURL, "/")
assert.EqualValues(t, "pulls", elem[3])
req := NewRequest(t, http.MethodGet, prURL)
resp = MakeRequest(t, req, http.StatusOK)
doc := NewHTMLParser(t, resp.Body)
attributeFilter := fmt.Sprintf("[data-update-url='/%s/%s/issues/request_review']", user2.Name, repo.Name)
issueID, ok := doc.Find(attributeFilter).Attr("data-issue-id")
assert.True(t, ok, "doc must contain data-issue-id")
user1csrf = GetCSRF(t, user1Session, "/")
testAssignReviewer(t, user1Session, user1csrf, user2.Name, repo.Name, issueID, "1", http.StatusOK)
// both user notification should keep the same notification count since
// user2 added itself as reviewer.
user1csrf = GetCSRF(t, user1Session, "/")
notificationCount := getUserNotificationCount(t, user1Session, user1csrf)
assert.Equal(t, oldUser1NotificationCount, notificationCount)
user2csrf = GetCSRF(t, user2Session, "/")
notificationCount = getUserNotificationCount(t, user2Session, user2csrf)
assert.Equal(t, oldUser2NotificationCount, notificationCount)
})
}
func TestPullView_ResolveInvalidatedReviewComment(t *testing.T) {
defer tests.PrepareTestEnv(t)()
session := loginUser(t, "user1")
@ -474,6 +544,28 @@ func TestPullView_GivenApproveOrRejectReviewOnClosedPR(t *testing.T) {
})
}
func testNofiticationCount(t *testing.T, session *TestSession, csrf string, expectedSubmitStatus int) *httptest.ResponseRecorder {
options := map[string]string{
"_csrf": csrf,
}
req := NewRequestWithValues(t, "GET", "/", options)
return session.MakeRequest(t, req, expectedSubmitStatus)
}
func testAssignReviewer(t *testing.T, session *TestSession, csrf, owner, repo, pullID, reviewer string, expectedSubmitStatus int) *httptest.ResponseRecorder {
options := map[string]string{
"_csrf": csrf,
"action": "attach",
"issue_ids": pullID,
"id": reviewer,
}
submitURL := path.Join(owner, repo, "issues", "request_review")
req := NewRequestWithValues(t, "POST", submitURL, options)
return session.MakeRequest(t, req, expectedSubmitStatus)
}
func testSubmitReview(t *testing.T, session *TestSession, csrf, owner, repo, pullNumber, commitID, reviewType string, expectedSubmitStatus int) *httptest.ResponseRecorder {
options := map[string]string{
"_csrf": csrf,
@ -502,3 +594,9 @@ func testIssueClose(t *testing.T, session *TestSession, owner, repo, issueNumber
req = NewRequestWithValues(t, "POST", closeURL, options)
return session.MakeRequest(t, req, http.StatusOK)
}
func getUserNotificationCount(t *testing.T, session *TestSession, csrf string) string {
resp := testNofiticationCount(t, session, csrf, http.StatusOK)
doc := NewHTMLParser(t, resp.Body)
return doc.Find(`.notification_count`).Text()
}

View file

@ -4,6 +4,7 @@
package integration
import (
"fmt"
"net/http"
"net/url"
"strings"
@ -16,6 +17,9 @@ import (
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/test"
pull_service "code.gitea.io/gitea/services/pull"
repo_service "code.gitea.io/gitea/services/repository"
files_service "code.gitea.io/gitea/services/repository/files"
@ -83,6 +87,102 @@ func TestAPIPullUpdateByRebase(t *testing.T) {
})
}
func TestAPIViewUpdateSettings(t *testing.T) {
onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) {
defer tests.PrepareTestEnv(t)()
// Create PR to test
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
org26 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 26})
pr := createOutdatedPR(t, user, org26)
// Test GetDiverging
diffCount, err := pull_service.GetDiverging(git.DefaultContext, pr)
require.NoError(t, err)
assert.EqualValues(t, 1, diffCount.Behind)
assert.EqualValues(t, 1, diffCount.Ahead)
require.NoError(t, pr.LoadBaseRepo(db.DefaultContext))
require.NoError(t, pr.LoadIssue(db.DefaultContext))
session := loginUser(t, "user2")
token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeAll)
defaultUpdateStyle := "rebase"
editOption := api.EditRepoOption{
DefaultUpdateStyle: &defaultUpdateStyle,
}
req := NewRequestWithJSON(t, "PATCH", fmt.Sprintf("/api/v1/repos/%s/%s", pr.BaseRepo.OwnerName, pr.BaseRepo.Name), editOption).AddTokenAuth(token)
session.MakeRequest(t, req, http.StatusOK)
assertViewPullUpdate(t, pr, session, "rebase", true)
defaultUpdateStyle = "merge"
req = NewRequestWithJSON(t, "PATCH", fmt.Sprintf("/api/v1/repos/%s/%s", pr.BaseRepo.OwnerName, pr.BaseRepo.Name), editOption).AddTokenAuth(token)
session.MakeRequest(t, req, http.StatusOK)
assertViewPullUpdate(t, pr, session, "merge", true)
})
}
func TestViewPullUpdateByMerge(t *testing.T) {
onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) {
testViewPullUpdate(t, "merge")
})
}
func TestViewPullUpdateByRebase(t *testing.T) {
onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) {
testViewPullUpdate(t, "rebase")
})
}
func testViewPullUpdate(t *testing.T, updateStyle string) {
defer test.MockVariableValue(&setting.Repository.PullRequest.DefaultUpdateStyle, updateStyle)()
defer tests.PrepareTestEnv(t)()
// Create PR to test
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
org26 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 26})
pr := createOutdatedPR(t, user, org26)
// Test GetDiverging
diffCount, err := pull_service.GetDiverging(git.DefaultContext, pr)
require.NoError(t, err)
assert.EqualValues(t, 1, diffCount.Behind)
assert.EqualValues(t, 1, diffCount.Ahead)
require.NoError(t, pr.LoadBaseRepo(db.DefaultContext))
require.NoError(t, pr.LoadIssue(db.DefaultContext))
session := loginUser(t, "user2")
assertViewPullUpdate(t, pr, session, updateStyle, true)
}
func assertViewPullUpdate(t *testing.T, pr *issues_model.PullRequest, session *TestSession, expectedStyle string, dropdownExpected bool) {
req := NewRequest(t, "GET", fmt.Sprintf("%s/%s/pulls/%d", pr.BaseRepo.OwnerName, pr.BaseRepo.Name, pr.Issue.Index))
resp := session.MakeRequest(t, req, http.StatusOK)
htmlDoc := NewHTMLParser(t, resp.Body)
// Verify that URL of the update button is shown correctly.
var mainExpectedURL string
mergeExpectedURL := fmt.Sprintf("/%s/%s/pulls/%d/update?style=merge", pr.BaseRepo.OwnerName, pr.BaseRepo.Name, pr.Issue.Index)
rebaseExpectedURL := fmt.Sprintf("/%s/%s/pulls/%d/update?style=rebase", pr.BaseRepo.OwnerName, pr.BaseRepo.Name, pr.Issue.Index)
if expectedStyle == "rebase" {
mainExpectedURL = rebaseExpectedURL
if dropdownExpected {
htmlDoc.AssertElement(t, fmt.Sprintf(".update-button .dropdown .menu .item[data-do=\"%s\"]:not(.active.selected)", mergeExpectedURL), true)
htmlDoc.AssertElement(t, fmt.Sprintf(".update-button .dropdown .menu .active.selected.item[data-do=\"%s\"]", rebaseExpectedURL), true)
}
} else {
mainExpectedURL = mergeExpectedURL
if dropdownExpected {
htmlDoc.AssertElement(t, fmt.Sprintf(".update-button .dropdown .menu .active.selected.item[data-do=\"%s\"]", mergeExpectedURL), true)
htmlDoc.AssertElement(t, fmt.Sprintf(".update-button .dropdown .menu .item[data-do=\"%s\"]:not(.active.selected)", rebaseExpectedURL), true)
}
}
if dropdownExpected {
htmlDoc.AssertElement(t, fmt.Sprintf(".update-button .button[data-do=\"%s\"]", mainExpectedURL), true)
} else {
htmlDoc.AssertElement(t, fmt.Sprintf("form[action=\"%s\"]", mainExpectedURL), true)
}
}
func createOutdatedPR(t *testing.T, actor, forkOrg *user_model.User) *issues_model.PullRequest {
baseRepo, _, _ := tests.CreateDeclarativeRepo(t, actor, "repo-pr-update", nil, nil, nil)

View file

@ -7,6 +7,7 @@ package integration
import (
"fmt"
"net/http"
"net/url"
"strconv"
"strings"
"testing"
@ -14,9 +15,11 @@ import (
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/optional"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/test"
"code.gitea.io/gitea/modules/translation"
files_service "code.gitea.io/gitea/services/repository/files"
"code.gitea.io/gitea/tests"
"github.com/stretchr/testify/assert"
@ -76,10 +79,14 @@ func testRepoGenerate(t *testing.T, session *TestSession, templateID, templateOw
// Step4: check the existence of the generated repo
req = NewRequestf(t, "GET", "/%s/%s", generateOwner.Name, generateRepoName)
session.MakeRequest(t, req, http.StatusOK)
}
// Step5: check substituted values in Readme
req = NewRequestf(t, "GET", "/%s/%s/raw/branch/master/README.md", generateOwner.Name, generateRepoName)
resp = session.MakeRequest(t, req, http.StatusOK)
func testRepoGenerateWithFixture(t *testing.T, session *TestSession, templateID, templateOwnerName, templateRepoName string, user, generateOwner *user_model.User, generateRepoName string) {
testRepoGenerate(t, session, templateID, templateOwnerName, templateRepoName, user, generateOwner, generateRepoName)
// check substituted values in Readme
req := NewRequestf(t, "GET", "/%s/%s/raw/branch/master/README.md", generateOwner.Name, generateRepoName)
resp := session.MakeRequest(t, req, http.StatusOK)
body := fmt.Sprintf(`# %s Readme
Owner: %s
Link: /%s/%s
@ -125,7 +132,7 @@ func TestRepoGenerate(t *testing.T) {
session := loginUser(t, userName)
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: userName})
testRepoGenerate(t, session, "44", "user27", "template1", user, user, "generated1")
testRepoGenerateWithFixture(t, session, "44", "user27", "template1", user, user, "generated1")
}
func TestRepoGenerateToOrg(t *testing.T) {
@ -135,7 +142,7 @@ func TestRepoGenerateToOrg(t *testing.T) {
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: userName})
org := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "org3"})
testRepoGenerate(t, session, "44", "user27", "template1", user, org, "generated2")
testRepoGenerateWithFixture(t, session, "44", "user27", "template1", user, org, "generated2")
}
func TestRepoCreateFormTrimSpace(t *testing.T) {
@ -153,3 +160,66 @@ func TestRepoCreateFormTrimSpace(t *testing.T) {
assert.EqualValues(t, "/user2/spaced-name", test.RedirectURL(resp))
unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{OwnerID: 2, Name: "spaced-name"})
}
func TestRepoGenerateTemplating(t *testing.T) {
onGiteaRun(t, func(t *testing.T, u *url.URL) {
input := `# $REPO_NAME
This is a Repo By $REPO_OWNER
ThisIsThe${REPO_NAME}InAnInlineWay`
expected := `# %s
This is a Repo By %s
ThisIsThe%sInAnInlineWay`
templateName := "my_template"
generatedName := "my_generated"
userName := "user1"
session := loginUser(t, userName)
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: userName})
template, _, f := tests.CreateDeclarativeRepoWithOptions(t, user, tests.DeclarativeRepoOptions{
Name: optional.Some(templateName),
IsTemplate: optional.Some(true),
Files: optional.Some([]*files_service.ChangeRepoFile{
{
Operation: "create",
TreePath: ".forgejo/template",
ContentReader: strings.NewReader("Readme.md"),
},
{
Operation: "create",
TreePath: "Readme.md",
ContentReader: strings.NewReader(input),
},
}),
})
defer f()
// The repo.TemplateID field is not initalized. Luckly the ID field holds the expected value
templateID := strconv.FormatInt(template.ID, 10)
testRepoGenerate(
t,
session,
templateID,
user.Name,
templateName,
user,
user,
generatedName,
)
req := NewRequestf(
t,
"GET", "/%s/%s/raw/branch/%s/Readme.md",
user.Name,
generatedName,
template.DefaultBranch,
)
resp := session.MakeRequest(t, req, http.StatusOK)
body := fmt.Sprintf(expected,
generatedName,
user.Name,
generatedName)
assert.Equal(t, body, resp.Body.String())
})
}

View file

@ -1009,16 +1009,29 @@ func TestRepoCodeSearchForm(t *testing.T) {
resp := MakeRequest(t, req, http.StatusOK)
htmlDoc := NewHTMLParser(t, resp.Body)
action, exists := htmlDoc.doc.Find("form[data-test-tag=codesearch]").Attr("action")
formEl := htmlDoc.doc.Find("form[data-test-tag=codesearch]")
action, exists := formEl.Attr("action")
assert.True(t, exists)
branchSubURL := "/branch/master"
if indexer {
assert.NotContains(t, action, branchSubURL)
} else {
assert.Contains(t, action, branchSubURL)
}
filepath, exists := formEl.Find("input[name=path]").Attr("value")
assert.True(t, exists)
assert.Empty(t, filepath)
req = NewRequest(t, "GET", "/user2/glob/src/branch/master/x/y")
resp = MakeRequest(t, req, http.StatusOK)
filepath, exists = NewHTMLParser(t, resp.Body).doc.
Find("form[data-test-tag=codesearch] input[name=path]").
Attr("value")
assert.True(t, exists)
assert.Equal(t, "x/y", filepath)
}
t.Run("indexer disabled", func(t *testing.T) {