Skip to content

Commit 6cb1cf3

Browse files
committed
add TestApproveAllRunsOnPullRequestPage
1 parent 4322634 commit 6cb1cf3

File tree

1 file changed

+146
-0
lines changed

1 file changed

+146
-0
lines changed
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
// Copyright 2025 The Gitea Authors. All rights reserved.
2+
// SPDX-License-Identifier: MIT
3+
4+
package integration
5+
6+
import (
7+
"encoding/base64"
8+
"fmt"
9+
"net/http"
10+
"net/url"
11+
"testing"
12+
"time"
13+
14+
actions_model "code.gitea.io/gitea/models/actions"
15+
auth_model "code.gitea.io/gitea/models/auth"
16+
repo_model "code.gitea.io/gitea/models/repo"
17+
"code.gitea.io/gitea/models/unittest"
18+
user_model "code.gitea.io/gitea/models/user"
19+
api "code.gitea.io/gitea/modules/structs"
20+
"code.gitea.io/gitea/modules/util"
21+
22+
"github.com/stretchr/testify/assert"
23+
)
24+
25+
func TestApproveAllRunsOnPullRequestPage(t *testing.T) {
26+
onGiteaRun(t, func(t *testing.T, u *url.URL) {
27+
// user2 is the owner of the base repo
28+
user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
29+
user2Session := loginUser(t, user2.Name)
30+
user2Token := getTokenForLoggedInUser(t, user2Session, auth_model.AccessTokenScopeWriteRepository, auth_model.AccessTokenScopeWriteUser)
31+
// user4 is the owner of the fork repo
32+
user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4})
33+
user4Session := loginUser(t, user4.Name)
34+
user4Token := getTokenForLoggedInUser(t, loginUser(t, user4.Name), auth_model.AccessTokenScopeWriteRepository, auth_model.AccessTokenScopeWriteUser)
35+
36+
apiBaseRepo := createActionsTestRepo(t, user2Token, "approve-all-runs", false)
37+
baseRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: apiBaseRepo.ID})
38+
user2APICtx := NewAPITestContext(t, baseRepo.OwnerName, baseRepo.Name, auth_model.AccessTokenScopeWriteRepository)
39+
defer doAPIDeleteRepository(user2APICtx)(t)
40+
41+
runner := newMockRunner()
42+
runner.registerAsRepoRunner(t, baseRepo.OwnerName, baseRepo.Name, "mock-runner", []string{"ubuntu-latest"}, false)
43+
44+
// init workflows
45+
wf1TreePath := ".gitea/workflows/pull_1.yml"
46+
wf1FileContent := `name: Pull 1
47+
on: pull_request
48+
jobs:
49+
unit-test:
50+
runs-on: ubuntu-latest
51+
steps:
52+
- run: echo unit-test
53+
`
54+
opts1 := getWorkflowCreateFileOptions(user2, baseRepo.DefaultBranch, "create %s"+wf1TreePath, wf1FileContent)
55+
createWorkflowFile(t, user2Token, baseRepo.OwnerName, baseRepo.Name, wf1TreePath, opts1)
56+
wf2TreePath := ".gitea/workflows/pull_2.yml"
57+
wf2FileContent := `name: Pull 2
58+
on: pull_request
59+
jobs:
60+
integration-test:
61+
runs-on: ubuntu-latest
62+
steps:
63+
- run: echo integration-test
64+
`
65+
opts2 := getWorkflowCreateFileOptions(user2, baseRepo.DefaultBranch, "create %s"+wf2TreePath, wf2FileContent)
66+
createWorkflowFile(t, user2Token, baseRepo.OwnerName, baseRepo.Name, wf2TreePath, opts2)
67+
68+
// user4 forks the repo
69+
req := NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/forks", baseRepo.OwnerName, baseRepo.Name),
70+
&api.CreateForkOption{
71+
Name: util.ToPointer("approve-all-runs-fork"),
72+
}).AddTokenAuth(user4Token)
73+
resp := MakeRequest(t, req, http.StatusAccepted)
74+
var apiForkRepo api.Repository
75+
DecodeJSON(t, resp, &apiForkRepo)
76+
forkRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: apiForkRepo.ID})
77+
user4APICtx := NewAPITestContext(t, user4.Name, forkRepo.Name, auth_model.AccessTokenScopeWriteRepository)
78+
defer doAPIDeleteRepository(user4APICtx)(t)
79+
80+
// user4 creates a pull request from branch "bugfix/user4"
81+
doAPICreateFile(user4APICtx, "user4-fix.txt", &api.CreateFileOptions{
82+
FileOptions: api.FileOptions{
83+
NewBranchName: "bugfix/user4",
84+
Message: "create user4-fix.txt",
85+
Author: api.Identity{
86+
Name: user4.Name,
87+
Email: user4.Email,
88+
},
89+
Committer: api.Identity{
90+
Name: user4.Name,
91+
Email: user4.Email,
92+
},
93+
Dates: api.CommitDateOptions{
94+
Author: time.Now(),
95+
Committer: time.Now(),
96+
},
97+
},
98+
ContentBase64: base64.StdEncoding.EncodeToString([]byte("user4-fix")),
99+
})(t)
100+
apiPull, err := doAPICreatePullRequest(user4APICtx, baseRepo.OwnerName, baseRepo.Name, baseRepo.DefaultBranch, user4.Name+":bugfix/user4")(t)
101+
assert.NoError(t, err)
102+
103+
// check runs
104+
run1 := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRun{RepoID: baseRepo.ID, TriggerUserID: user4.ID, WorkflowID: "pull_1.yml"})
105+
assert.True(t, run1.NeedApproval)
106+
assert.Equal(t, actions_model.StatusBlocked, run1.Status)
107+
run2 := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRun{RepoID: baseRepo.ID, TriggerUserID: user4.ID, WorkflowID: "pull_2.yml"})
108+
assert.True(t, run2.NeedApproval)
109+
assert.Equal(t, actions_model.StatusBlocked, run2.Status)
110+
111+
// user4 cannot see the approve button
112+
req = NewRequest(t, "GET", fmt.Sprintf("/%s/%s/pulls/%d", baseRepo.OwnerName, baseRepo.Name, apiPull.Index))
113+
resp = user4Session.MakeRequest(t, req, http.StatusOK)
114+
htmlDoc := NewHTMLParser(t, resp.Body)
115+
assert.Zero(t, htmlDoc.doc.Find(".commit-status-header form").Length())
116+
117+
// user2 can see the approve button
118+
req = NewRequest(t, "GET", fmt.Sprintf("/%s/%s/pulls/%d", baseRepo.OwnerName, baseRepo.Name, apiPull.Index))
119+
resp = user2Session.MakeRequest(t, req, http.StatusOK)
120+
htmlDoc = NewHTMLParser(t, resp.Body)
121+
formAction, exist := htmlDoc.doc.Find(".commit-status-header form").Attr("action")
122+
assert.True(t, exist)
123+
assert.Equal(t,
124+
fmt.Sprintf("%s/actions/approve-all-checks?sha=%s&redirect=/%s/%s/pulls/%d",
125+
baseRepo.Link(), apiPull.Head.Sha, baseRepo.OwnerName, baseRepo.Name, apiPull.Index),
126+
formAction,
127+
)
128+
129+
// user2 approves all runs
130+
req = NewRequestWithValues(t, "POST", formAction,
131+
map[string]string{
132+
"_csrf": GetUserCSRFToken(t, user2Session),
133+
})
134+
user2Session.MakeRequest(t, req, http.StatusSeeOther)
135+
136+
// check runs
137+
run1 = unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRun{ID: run1.ID})
138+
assert.False(t, run1.NeedApproval)
139+
assert.Equal(t, user2.ID, run1.ApprovedBy)
140+
assert.Equal(t, actions_model.StatusWaiting, run1.Status)
141+
run2 = unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRun{ID: run2.ID})
142+
assert.False(t, run2.NeedApproval)
143+
assert.Equal(t, user2.ID, run2.ApprovedBy)
144+
assert.Equal(t, actions_model.StatusWaiting, run2.Status)
145+
})
146+
}

0 commit comments

Comments
 (0)