diff --git a/services/automerge/automerge_test.go b/services/automerge/automerge_test.go index 4ad5b70cce..38ed4dcd9f 100644 --- a/services/automerge/automerge_test.go +++ b/services/automerge/automerge_test.go @@ -15,6 +15,7 @@ import ( "forgejo.org/models/unittest" user_model "forgejo.org/models/user" "forgejo.org/modules/util" + "github.com/stretchr/testify/require" ) diff --git a/tests/integration/pull_auto_merge_test.go b/tests/integration/pull_auto_merge_test.go new file mode 100644 index 0000000000..e9a428d4e7 --- /dev/null +++ b/tests/integration/pull_auto_merge_test.go @@ -0,0 +1,106 @@ +// Copyright 2026 The Forgejo Authors. All rights reserved. +// SPDX-License-Identifier: GPL-3.0-or-later + +package integration + +import ( + "fmt" + "net/http" + "net/url" + "os" + "path" + "strings" + "testing" + "time" + + unit_model "forgejo.org/models/unit" + "forgejo.org/models/unittest" + user_model "forgejo.org/models/user" + "forgejo.org/modules/git" + app_context "forgejo.org/services/context" + files_service "forgejo.org/services/repository/files" + "forgejo.org/tests" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestPullRemoveAutomerge(t *testing.T) { + onApplicationRun(t, func(t *testing.T, u *url.URL) { + user5 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5}) + user5Session := loginUser(t, user5.Name) + user2Session := loginUser(t, "user2") + + repo, _, f := tests.CreateDeclarativeRepo(t, user5, "", + []unit_model.Type{unit_model.TypeCode, unit_model.TypePullRequests}, nil, + []*files_service.ChangeRepoFile{ + { + Operation: "create", + TreePath: "FUNFACT", + ContentReader: strings.NewReader( + "The Netherlands got its first openly gay prime minister today."), + }, + }, + ) + defer f() + + dstPath := t.TempDir() + cloneURL, _ := url.Parse(fmt.Sprintf("%suser5/%s.git", u.String(), repo.Name)) + cloneURL.User = url.UserPassword("user5", userPassword) + require.NoError(t, git.CloneWithArgs(t.Context(), nil, cloneURL.String(), dstPath, git.CloneRepoOptions{})) + doGitSetRemoteURL(dstPath, "origin", cloneURL)(t) + + require.NoError(t, git.NewCommand(t.Context(), "switch", "-c", "new-fun-fact").Run(&git.RunOpts{Dir: dstPath})) + + require.NoError(t, os.WriteFile(path.Join(dstPath, "README.md"), []byte("The house of representative already had that in 1937."), 0o600)) + require.NoError(t, git.AddChanges(dstPath, true)) + require.NoError(t, git.CommitChanges(dstPath, git.CommitChangesOptions{ + Committer: &git.Signature{ + Email: "user2@example.com", + Name: "user2", + When: time.Now(), + }, + Author: &git.Signature{ + Email: "user2@example.com", + Name: "user2", + When: time.Now(), + }, + Message: "Update funfact.", + })) + + require.NoError(t, git.NewCommand(t.Context(), "push", "origin", "HEAD:refs/for/main", "-o", "topic=new-fun-fact").Run(&git.RunOpts{Dir: dstPath})) + + // Create a protected branch rule for automerge. + user5Session.MakeRequest(t, NewRequestWithValues(t, "POST", fmt.Sprintf("/%s/settings/branches/edit", repo.FullName()), map[string]string{ + "rule_name": "main", + "required_approvals": "1", + }), http.StatusSeeOther) + + // Start a automerge for new pull request. + user5Session.MakeRequest(t, NewRequestWithValues(t, "POST", fmt.Sprintf("/%s/pulls/1/merge", repo.FullName()), map[string]string{ + "merge_message_field": "I love automation when it works", + "do": "merge", + "merge_when_checks_succeed": "true", + }), http.StatusOK) + + t.Run("No permission", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + user2Session.MakeRequest(t, NewRequestWithValues(t, "POST", fmt.Sprintf("/%s/pulls/1/cancel_auto_merge", repo.FullName()), nil), http.StatusSeeOther) + + flashCookie := user2Session.GetCookie(app_context.CookieNameFlash) + assert.NotNil(t, flashCookie) + assert.Equal(t, "error%3DYou%2Bdo%2Bnot%2Bhave%2Bpermission%2Bto%2Bcancel%2Bthis%2Bpull%2Brequest%2527s%2Bauto%2Bmerge.", flashCookie.Value) + }) + + t.Run("Normal", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + + user5Session.MakeRequest(t, NewRequestWithValues(t, "POST", fmt.Sprintf("/%s/pulls/1/cancel_auto_merge", repo.FullName()), nil), http.StatusSeeOther) + + flashCookie := user5Session.GetCookie(app_context.CookieNameFlash) + assert.NotNil(t, flashCookie) + assert.Equal(t, "success%3DThe%2Bauto%2Bmerge%2Bwas%2Bcanceled%2Bfor%2Bthis%2Bpull%2Brequest.", flashCookie.Value) + }) + }) +}