diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/integration/git_general_test.go | 40 | ||||
-rw-r--r-- | tests/integration/issue_test.go | 9 | ||||
-rw-r--r-- | tests/integration/repo_commits_test.go | 36 | ||||
-rw-r--r-- | tests/integration/repo_webhook_test.go | 195 |
4 files changed, 237 insertions, 43 deletions
diff --git a/tests/integration/git_general_test.go b/tests/integration/git_general_test.go index 34fe212d50..ed60bdb58a 100644 --- a/tests/integration/git_general_test.go +++ b/tests/integration/git_general_test.go @@ -11,8 +11,10 @@ import ( "net/http" "net/url" "os" + "os/exec" "path" "path/filepath" + "slices" "strconv" "testing" "time" @@ -30,6 +32,7 @@ import ( api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/tests" + "github.com/kballard/go-shellquote" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -105,7 +108,12 @@ func testGitGeneral(t *testing.T, u *url.URL) { // Setup key the user ssh key withKeyFile(t, keyname, func(keyFile string) { - t.Run("CreateUserKey", doAPICreateUserKey(sshContext, "test-key", keyFile)) + var keyID int64 + t.Run("CreateUserKey", doAPICreateUserKey(sshContext, "test-key", keyFile, func(t *testing.T, key api.PublicKey) { + keyID = key.ID + })) + assert.NotZero(t, keyID) + t.Run("LFSAccessTest", doSSHLFSAccessTest(sshContext, keyID)) // Setup remote link // TODO: get url from api @@ -136,6 +144,36 @@ func testGitGeneral(t *testing.T, u *url.URL) { }) } +func doSSHLFSAccessTest(_ APITestContext, keyID int64) func(*testing.T) { + return func(t *testing.T) { + sshCommand := os.Getenv("GIT_SSH_COMMAND") // it is set in withKeyFile + sshCmdParts, err := shellquote.Split(sshCommand) // and parse the ssh command to construct some mocked arguments + require.NoError(t, err) + + t.Run("User2AccessOwned", func(t *testing.T) { + sshCmdUser2Self := append(slices.Clone(sshCmdParts), + "-p", strconv.Itoa(setting.SSH.ListenPort), "git@"+setting.SSH.ListenHost, + "git-lfs-authenticate", "user2/repo1.git", "upload", // accessible to own repo + ) + cmd := exec.CommandContext(t.Context(), sshCmdUser2Self[0], sshCmdUser2Self[1:]...) + _, err := cmd.Output() + assert.NoError(t, err) // accessible, no error + }) + + t.Run("User2AccessOther", func(t *testing.T) { + sshCmdUser2Other := append(slices.Clone(sshCmdParts), + "-p", strconv.Itoa(setting.SSH.ListenPort), "git@"+setting.SSH.ListenHost, + "git-lfs-authenticate", "user5/repo4.git", "upload", // inaccessible to other's (user5/repo4) + ) + cmd := exec.CommandContext(t.Context(), sshCmdUser2Other[0], sshCmdUser2Other[1:]...) + _, err := cmd.Output() + var errExit *exec.ExitError + require.ErrorAs(t, err, &errExit) // inaccessible, error + assert.Contains(t, string(errExit.Stderr), fmt.Sprintf("User: 2:user2 with Key: %d:test-key is not authorized to write to user5/repo4.", keyID)) + }) + } +} + func ensureAnonymousClone(t *testing.T, u *url.URL) { dstLocalPath := t.TempDir() t.Run("CloneAnonymous", doGitClone(dstLocalPath, u)) diff --git a/tests/integration/issue_test.go b/tests/integration/issue_test.go index f0a5e4f519..b403b3cf17 100644 --- a/tests/integration/issue_test.go +++ b/tests/integration/issue_test.go @@ -184,6 +184,15 @@ func testIssueAddComment(t *testing.T, session *TestSession, issueURL, content, return int64(id) } +func testIssueChangeMilestone(t *testing.T, session *TestSession, repoLink string, issueID, milestoneID int64) { + req := NewRequestWithValues(t, "POST", fmt.Sprintf(repoLink+"/issues/milestone?issue_ids=%d", issueID), map[string]string{ + "_csrf": GetUserCSRFToken(t, session), + "id": strconv.FormatInt(milestoneID, 10), + }) + resp := session.MakeRequest(t, req, http.StatusOK) + assert.Equal(t, `{"ok":true}`, strings.TrimSpace(resp.Body.String())) +} + func TestNewIssue(t *testing.T) { defer tests.PrepareTestEnv(t)() session := loginUser(t, "user2") diff --git a/tests/integration/repo_commits_test.go b/tests/integration/repo_commits_test.go index dee0aa6176..504d2adacc 100644 --- a/tests/integration/repo_commits_test.go +++ b/tests/integration/repo_commits_test.go @@ -12,8 +12,6 @@ import ( "testing" auth_model "code.gitea.io/gitea/models/auth" - "code.gitea.io/gitea/models/unittest" - user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" @@ -40,40 +38,24 @@ func TestRepoCommits(t *testing.T) { func Test_ReposGitCommitListNotMaster(t *testing.T) { defer tests.PrepareTestEnv(t)() - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) - // Login as User2. - session := loginUser(t, user.Name) - - // Test getting commits (Page 1) - req := NewRequestf(t, "GET", "/%s/repo16/commits/branch/master", user.Name) + session := loginUser(t, "user2") + req := NewRequest(t, "GET", "/user2/repo16/commits/branch/master") resp := session.MakeRequest(t, req, http.StatusOK) doc := NewHTMLParser(t, resp.Body) - commits := []string{} + var commits []string doc.doc.Find("#commits-table .commit-id-short").Each(func(i int, s *goquery.Selection) { - commitURL, exists := s.Attr("href") - assert.True(t, exists) - assert.NotEmpty(t, commitURL) + commitURL, _ := s.Attr("href") commits = append(commits, path.Base(commitURL)) }) + assert.Equal(t, []string{"69554a64c1e6030f051e5c3f94bfbd773cd6a324", "27566bd5738fc8b4e3fef3c5e72cce608537bd95", "5099b81332712fe655e34e8dd63574f503f61811"}, commits) - assert.Len(t, commits, 3) - assert.Equal(t, "69554a64c1e6030f051e5c3f94bfbd773cd6a324", commits[0]) - assert.Equal(t, "27566bd5738fc8b4e3fef3c5e72cce608537bd95", commits[1]) - assert.Equal(t, "5099b81332712fe655e34e8dd63574f503f61811", commits[2]) - - userNames := []string{} + var userHrefs []string doc.doc.Find("#commits-table .author-wrapper").Each(func(i int, s *goquery.Selection) { - userPath, exists := s.Attr("href") - assert.True(t, exists) - assert.NotEmpty(t, userPath) - userNames = append(userNames, path.Base(userPath)) + userHref, _ := s.Attr("href") + userHrefs = append(userHrefs, userHref) }) - - assert.Len(t, userNames, 3) - assert.Equal(t, "User2", userNames[0]) - assert.Equal(t, "user21", userNames[1]) - assert.Equal(t, "User2", userNames[2]) + assert.Equal(t, []string{"/user2", "/user21", "/user2"}, userHrefs) } func doTestRepoCommitWithStatus(t *testing.T, state string, classes ...string) { diff --git a/tests/integration/repo_webhook_test.go b/tests/integration/repo_webhook_test.go index 89df15b8de..13e3d198ea 100644 --- a/tests/integration/repo_webhook_test.go +++ b/tests/integration/repo_webhook_test.go @@ -56,16 +56,21 @@ func TestNewWebHookLink(t *testing.T) { } } -func testAPICreateWebhookForRepo(t *testing.T, session *TestSession, userName, repoName, url, event string) { +func testAPICreateWebhookForRepo(t *testing.T, session *TestSession, userName, repoName, url, event string, branchFilter ...string) { token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeAll) + var branchFilterString string + if len(branchFilter) > 0 { + branchFilterString = branchFilter[0] + } req := NewRequestWithJSON(t, "POST", "/api/v1/repos/"+userName+"/"+repoName+"/hooks", api.CreateHookOption{ Type: "gitea", Config: api.CreateHookOptionConfig{ "content_type": "json", "url": url, }, - Events: []string{event}, - Active: true, + Events: []string{event}, + Active: true, + BranchFilter: branchFilterString, }).AddTokenAuth(token) MakeRequest(t, req, http.StatusCreated) } @@ -241,19 +246,68 @@ func Test_WebhookIssueComment(t *testing.T) { testAPICreateWebhookForRepo(t, session, "user2", "repo1", provider.URL(), "issue_comment") - // 2. trigger the webhook - issueURL := testNewIssue(t, session, "user2", "repo1", "Title2", "Description2") - testIssueAddComment(t, session, issueURL, "issue title2 comment1", "") + t.Run("create comment", func(t *testing.T) { + // 2. trigger the webhook + issueURL := testNewIssue(t, session, "user2", "repo1", "Title2", "Description2") + testIssueAddComment(t, session, issueURL, "issue title2 comment1", "") + + // 3. validate the webhook is triggered + assert.Equal(t, "issue_comment", triggeredEvent) + assert.Len(t, payloads, 1) + assert.EqualValues(t, "created", payloads[0].Action) + assert.Equal(t, "repo1", payloads[0].Issue.Repo.Name) + assert.Equal(t, "user2/repo1", payloads[0].Issue.Repo.FullName) + assert.Equal(t, "Title2", payloads[0].Issue.Title) + assert.Equal(t, "Description2", payloads[0].Issue.Body) + assert.Equal(t, "issue title2 comment1", payloads[0].Comment.Body) + }) - // 3. validate the webhook is triggered - assert.Equal(t, "issue_comment", triggeredEvent) - assert.Len(t, payloads, 1) - assert.EqualValues(t, "created", payloads[0].Action) - assert.Equal(t, "repo1", payloads[0].Issue.Repo.Name) - assert.Equal(t, "user2/repo1", payloads[0].Issue.Repo.FullName) - assert.Equal(t, "Title2", payloads[0].Issue.Title) - assert.Equal(t, "Description2", payloads[0].Issue.Body) - assert.Equal(t, "issue title2 comment1", payloads[0].Comment.Body) + t.Run("update comment", func(t *testing.T) { + payloads = make([]api.IssueCommentPayload, 0, 2) + triggeredEvent = "" + + // 2. trigger the webhook + issueURL := testNewIssue(t, session, "user2", "repo1", "Title3", "Description3") + commentID := testIssueAddComment(t, session, issueURL, "issue title3 comment1", "") + modifiedContent := "issue title2 comment1 - modified" + req := NewRequestWithValues(t, "POST", fmt.Sprintf("/%s/%s/comments/%d", "user2", "repo1", commentID), map[string]string{ + "_csrf": GetUserCSRFToken(t, session), + "content": modifiedContent, + }) + session.MakeRequest(t, req, http.StatusOK) + + // 3. validate the webhook is triggered + assert.Equal(t, "issue_comment", triggeredEvent) + assert.Len(t, payloads, 2) + assert.EqualValues(t, "edited", payloads[1].Action) + assert.Equal(t, "repo1", payloads[1].Issue.Repo.Name) + assert.Equal(t, "user2/repo1", payloads[1].Issue.Repo.FullName) + assert.Equal(t, "Title3", payloads[1].Issue.Title) + assert.Equal(t, "Description3", payloads[1].Issue.Body) + assert.Equal(t, modifiedContent, payloads[1].Comment.Body) + }) + + t.Run("Update comment with no content change", func(t *testing.T) { + payloads = make([]api.IssueCommentPayload, 0, 2) + triggeredEvent = "" + commentContent := "issue title3 comment1" + + // 2. trigger the webhook + issueURL := testNewIssue(t, session, "user2", "repo1", "Title3", "Description3") + commentID := testIssueAddComment(t, session, issueURL, commentContent, "") + + payloads = make([]api.IssueCommentPayload, 0, 2) + triggeredEvent = "" + req := NewRequestWithValues(t, "POST", fmt.Sprintf("/%s/%s/comments/%d", "user2", "repo1", commentID), map[string]string{ + "_csrf": GetUserCSRFToken(t, session), + "content": commentContent, + }) + session.MakeRequest(t, req, http.StatusOK) + + // 3. validate the webhook is not triggered because no content change + assert.Empty(t, triggeredEvent) + assert.Empty(t, payloads) + }) }) } @@ -322,6 +376,45 @@ func Test_WebhookPush(t *testing.T) { }) } +func Test_WebhookPushDevBranch(t *testing.T) { + var payloads []api.PushPayload + var triggeredEvent string + provider := newMockWebhookProvider(func(r *http.Request) { + content, _ := io.ReadAll(r.Body) + var payload api.PushPayload + err := json.Unmarshal(content, &payload) + assert.NoError(t, err) + payloads = append(payloads, payload) + triggeredEvent = "push" + }, http.StatusOK) + defer provider.Close() + + onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) { + // 1. create a new webhook with special webhook for repo1 + session := loginUser(t, "user2") + + // only for dev branch + testAPICreateWebhookForRepo(t, session, "user2", "repo1", provider.URL(), "push", "develop") + + // 2. this should not trigger the webhook + testCreateFile(t, session, "user2", "repo1", "master", "test_webhook_push.md", "# a test file for webhook push") + assert.Empty(t, triggeredEvent) + assert.Empty(t, payloads) + + // 3. trigger the webhook + testCreateFile(t, session, "user2", "repo1", "develop", "test_webhook_push.md", "# a test file for webhook push") + + // 4. validate the webhook is triggered + assert.Equal(t, "push", triggeredEvent) + assert.Len(t, payloads, 1) + assert.Equal(t, "repo1", payloads[0].Repo.Name) + assert.Equal(t, "develop", payloads[0].Branch()) + assert.Equal(t, "user2/repo1", payloads[0].Repo.FullName) + assert.Len(t, payloads[0].Commits, 1) + assert.Equal(t, []string{"test_webhook_push.md"}, payloads[0].Commits[0].Added) + }) +} + func Test_WebhookIssue(t *testing.T) { var payloads []api.IssuePayload var triggeredEvent string @@ -355,6 +448,78 @@ func Test_WebhookIssue(t *testing.T) { }) } +func Test_WebhookIssueMilestone(t *testing.T) { + var payloads []api.IssuePayload + var triggeredEvent string + provider := newMockWebhookProvider(func(r *http.Request) { + content, _ := io.ReadAll(r.Body) + var payload api.IssuePayload + err := json.Unmarshal(content, &payload) + assert.NoError(t, err) + payloads = append(payloads, payload) + triggeredEvent = "issues" + }, http.StatusOK) + defer provider.Close() + + onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) { + // create a new webhook with special webhook for repo1 + session := loginUser(t, "user2") + repo1 := unittest.AssertExistsAndLoadBean(t, &repo.Repository{ID: 1}) + testAPICreateWebhookForRepo(t, session, "user2", "repo1", provider.URL(), "issue_milestone") + + t.Run("assign a milestone", func(t *testing.T) { + // trigger the webhook + testIssueChangeMilestone(t, session, repo1.Link(), 1, 1) + + // validate the webhook is triggered + assert.Equal(t, "issues", triggeredEvent) + assert.Len(t, payloads, 1) + assert.Equal(t, "milestoned", string(payloads[0].Action)) + assert.Equal(t, "repo1", payloads[0].Issue.Repo.Name) + assert.Equal(t, "user2/repo1", payloads[0].Issue.Repo.FullName) + assert.Equal(t, "issue1", payloads[0].Issue.Title) + assert.Equal(t, "content for the first issue", payloads[0].Issue.Body) + assert.EqualValues(t, 1, payloads[0].Issue.Milestone.ID) + }) + + t.Run("change a milestong", func(t *testing.T) { + // trigger the webhook again + triggeredEvent = "" + payloads = make([]api.IssuePayload, 0, 1) + // change milestone to 2 + testIssueChangeMilestone(t, session, repo1.Link(), 1, 2) + + // validate the webhook is triggered + assert.Equal(t, "issues", triggeredEvent) + assert.Len(t, payloads, 1) + assert.Equal(t, "milestoned", string(payloads[0].Action)) + assert.Equal(t, "repo1", payloads[0].Issue.Repo.Name) + assert.Equal(t, "user2/repo1", payloads[0].Issue.Repo.FullName) + assert.Equal(t, "issue1", payloads[0].Issue.Title) + assert.Equal(t, "content for the first issue", payloads[0].Issue.Body) + assert.EqualValues(t, 2, payloads[0].Issue.Milestone.ID) + }) + + t.Run("remove a milestone", func(t *testing.T) { + // trigger the webhook again + triggeredEvent = "" + payloads = make([]api.IssuePayload, 0, 1) + // change milestone to 0 + testIssueChangeMilestone(t, session, repo1.Link(), 1, 0) + + // validate the webhook is triggered + assert.Equal(t, "issues", triggeredEvent) + assert.Len(t, payloads, 1) + assert.Equal(t, "demilestoned", string(payloads[0].Action)) + assert.Equal(t, "repo1", payloads[0].Issue.Repo.Name) + assert.Equal(t, "user2/repo1", payloads[0].Issue.Repo.FullName) + assert.Equal(t, "issue1", payloads[0].Issue.Title) + assert.Equal(t, "content for the first issue", payloads[0].Issue.Body) + assert.Nil(t, payloads[0].Issue.Milestone) + }) + }) +} + func Test_WebhookPullRequest(t *testing.T) { var payloads []api.PullRequestPayload var triggeredEvent string |