Skip to content

Commit 3e0a87c

Browse files
committed
add tests for pulls commit status and some fixes
1 parent efe0220 commit 3e0a87c

File tree

7 files changed

+321
-64
lines changed

7 files changed

+321
-64
lines changed

integrations/editor_test.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,24 @@ func testEditFileToNewBranch(t *testing.T, session *TestSession, user, repo, bra
150150
return resp
151151
}
152152

153+
func testEditFileToNewBranchAndSendPull(t *testing.T, session *TestSession, user, repo, branch, targetBranch, filePath string) *TestResponse {
154+
testEditFileToNewBranch(t, session, user, repo, branch, targetBranch, filePath)
155+
156+
url := path.Join(user, repo, "compare", branch+"..."+targetBranch)
157+
158+
req := NewRequest(t, "GET", url)
159+
resp := session.MakeRequest(t, req, http.StatusOK)
160+
htmlDoc := NewHTMLParser(t, resp.Body)
161+
162+
req = NewRequestWithValues(t, "POST", url,
163+
map[string]string{
164+
"_csrf": htmlDoc.GetCSRF(),
165+
"title": "pull request from " + targetBranch,
166+
},
167+
)
168+
return session.MakeRequest(t, req, http.StatusFound)
169+
}
170+
153171
func TestEditFile(t *testing.T) {
154172
prepareTestEnv(t)
155173
session := loginUser(t, "user2")

integrations/repo_pull_status_test.go

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
// Copyright 2017 The Gitea Authors. All rights reserved.
2+
// Use of this source code is governed by a MIT-style
3+
// license that can be found in the LICENSE file.
4+
5+
package integrations
6+
7+
import (
8+
"fmt"
9+
"net/http"
10+
"path"
11+
"strings"
12+
"testing"
13+
14+
"code.gitea.io/gitea/models"
15+
api "code.gitea.io/sdk/gitea"
16+
17+
"github.com/PuerkitoBio/goquery"
18+
"github.com/stretchr/testify/assert"
19+
)
20+
21+
var (
22+
statesIcons = map[models.CommitStatusState]string{
23+
models.CommitStatusPending: "circle icon yellow",
24+
models.CommitStatusSuccess: "check icon green",
25+
models.CommitStatusError: "warning icon red",
26+
models.CommitStatusFailure: "remove icon red",
27+
models.CommitStatusWarning: "warning sign icon yellow",
28+
}
29+
)
30+
31+
func TestRepoPullsWithStatus(t *testing.T) {
32+
prepareTestEnv(t)
33+
34+
session := loginUser(t, "user2")
35+
36+
var size = 5
37+
// create some pulls
38+
for i := 0; i < size; i++ {
39+
testEditFileToNewBranchAndSendPull(t, session, "user2", "repo16", "master", fmt.Sprintf("test%d", i), "readme.md")
40+
}
41+
42+
// look for repo's pulls page
43+
req := NewRequest(t, "GET", "/user2/repo16/pulls")
44+
resp := session.MakeRequest(t, req, http.StatusOK)
45+
doc := NewHTMLParser(t, resp.Body)
46+
47+
var indexes = make([]string, 0, size)
48+
doc.doc.Find("li.item").Each(func(idx int, s *goquery.Selection) {
49+
indexes = append(indexes, strings.TrimLeft(s.Find("div").Eq(1).Text(), "#"))
50+
})
51+
52+
indexes = indexes[:5]
53+
54+
var status = make([]models.CommitStatusState, len(indexes))
55+
for i := 0; i < len(indexes); i++ {
56+
switch i {
57+
case 0:
58+
status[i] = models.CommitStatusPending
59+
case 1:
60+
status[i] = models.CommitStatusSuccess
61+
case 2:
62+
status[i] = models.CommitStatusError
63+
case 3:
64+
status[i] = models.CommitStatusFailure
65+
case 4:
66+
status[i] = models.CommitStatusWarning
67+
default:
68+
status[i] = models.CommitStatusSuccess
69+
}
70+
}
71+
72+
for i, index := range indexes {
73+
// Request repository commits page
74+
req = NewRequestf(t, "GET", "/user2/repo16/pulls/%s/commits", index)
75+
resp = session.MakeRequest(t, req, http.StatusOK)
76+
doc = NewHTMLParser(t, resp.Body)
77+
78+
// Get first commit URL
79+
commitURL, exists := doc.doc.Find("#commits-table tbody tr td.sha a").Last().Attr("href")
80+
assert.True(t, exists)
81+
assert.NotEmpty(t, commitURL)
82+
83+
commitID := path.Base(commitURL)
84+
// Call API to add status for commit
85+
req = NewRequestWithJSON(t, "POST", "/api/v1/repos/user2/repo16/statuses/"+commitID,
86+
api.CreateStatusOption{
87+
State: api.StatusState(status[i]),
88+
TargetURL: "http://test.ci/",
89+
Description: "",
90+
Context: "testci",
91+
},
92+
)
93+
session.MakeRequest(t, req, http.StatusCreated)
94+
95+
req = NewRequestf(t, "GET", "/user2/repo16/pulls/%s/commits", index)
96+
resp = session.MakeRequest(t, req, http.StatusOK)
97+
doc = NewHTMLParser(t, resp.Body)
98+
99+
commitURL, exists = doc.doc.Find("#commits-table tbody tr td.sha a").Last().Attr("href")
100+
assert.True(t, exists)
101+
assert.NotEmpty(t, commitURL)
102+
assert.EqualValues(t, commitID, path.Base(commitURL))
103+
104+
cls, ok := doc.doc.Find("#commits-table tbody tr td.message i.commit-status").Last().Attr("class")
105+
assert.True(t, ok)
106+
assert.EqualValues(t, "commit-status "+statesIcons[status[i]], cls)
107+
}
108+
109+
req = NewRequest(t, "GET", "/user2/repo16/pulls")
110+
resp = session.MakeRequest(t, req, http.StatusOK)
111+
doc = NewHTMLParser(t, resp.Body)
112+
113+
doc.doc.Find("li.item").Each(func(i int, s *goquery.Selection) {
114+
cls, ok := s.Find("i.commit-status").Attr("class")
115+
assert.True(t, ok)
116+
assert.EqualValues(t, "commit-status "+statesIcons[status[i]], cls)
117+
})
118+
119+
req = NewRequest(t, "GET", "/pulls?type=all&repo=16&sort=&state=open")
120+
resp = session.MakeRequest(t, req, http.StatusOK)
121+
doc = NewHTMLParser(t, resp.Body)
122+
123+
fmt.Println(string(resp.Body))
124+
125+
doc.doc.Find("li.item").Each(func(i int, s *goquery.Selection) {
126+
cls, ok := s.Find("i.commit-status").Attr("class")
127+
assert.True(t, ok)
128+
assert.EqualValues(t, "commit-status "+statesIcons[status[i]], cls)
129+
})
130+
}

models/fixtures/repo_unit.yml

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,4 +220,44 @@
220220
repo_id: 28
221221
type: 1
222222
config: "{}"
223-
created_unix: 1524304355
223+
created_unix: 1524304355
224+
225+
-
226+
id: 33
227+
repo_id: 16
228+
type: 1
229+
index: 0
230+
config: "{}"
231+
created_unix: 946684810
232+
233+
-
234+
id: 34
235+
repo_id: 16
236+
type: 2
237+
index: 1
238+
config: "{\"EnableTimetracker\":false,\"AllowOnlyContributorsToTrackTime\":false}"
239+
created_unix: 946684810
240+
241+
-
242+
id: 35
243+
repo_id: 16
244+
type: 3
245+
index: 2
246+
config: "{}"
247+
created_unix: 946684810
248+
249+
-
250+
id: 36
251+
repo_id: 16
252+
type: 4
253+
index: 3
254+
config: "{}"
255+
created_unix: 946684810
256+
257+
-
258+
id: 37
259+
repo_id: 16
260+
type: 5
261+
index: 4
262+
config: "{}"
263+
created_unix: 946684810

models/status.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ func GetLatestCommitStatuses(repoIDs []int64, shas []string) ([][]*CommitStatus,
168168
var results = make([]struct {
169169
ID int64
170170
RepoID int64
171+
SHA string
171172
}, 0, 10*len(repoIDs))
172173

173174
var cond = builder.NewCond()
@@ -180,7 +181,7 @@ func GetLatestCommitStatuses(repoIDs []int64, shas []string) ([][]*CommitStatus,
180181

181182
err := x.Table(&CommitStatus{}).
182183
Where(cond).
183-
Select("max( id ) as id, repo_id").
184+
Select("max( id ) as id, repo_id, sha").
184185
GroupBy("repo_id, sha, context").OrderBy("max( id ) desc").Find(&results)
185186
if err != nil {
186187
return nil, err
@@ -192,10 +193,10 @@ func GetLatestCommitStatuses(repoIDs []int64, shas []string) ([][]*CommitStatus,
192193
}
193194

194195
var ids = make([]int64, 0, len(results))
195-
var repoIDsMap = make(map[int64][]int64, len(repoIDs))
196+
var repoIDsMap = make(map[string][]int64, len(repoIDs))
196197
for _, res := range results {
197198
ids = append(ids, res.ID)
198-
repoIDsMap[res.RepoID] = append(repoIDsMap[res.RepoID], res.ID)
199+
repoIDsMap[fmt.Sprintf("%d-%s", res.RepoID, res.SHA)] = append(repoIDsMap[fmt.Sprintf("%d-%s", res.RepoID, res.SHA)], res.ID)
199200
}
200201

201202
statuses := make(map[int64]*CommitStatus, len(ids))
@@ -205,7 +206,7 @@ func GetLatestCommitStatuses(repoIDs []int64, shas []string) ([][]*CommitStatus,
205206
}
206207

207208
for i := 0; i < len(repoIDs); i++ {
208-
for _, id := range repoIDsMap[repoIDs[i]] {
209+
for _, id := range repoIDsMap[fmt.Sprintf("%d-%s", repoIDs[i], shas[i])] {
209210
returns[i] = append(returns[i], statuses[id])
210211
}
211212
}

routers/repo/issue.go

Lines changed: 61 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -186,44 +186,80 @@ func issues(ctx *context.Context, milestoneID int64, isPullOption util.OptionalB
186186
}
187187
}
188188

189-
var repoIDs = make([]int64, 0, len(issues))
190-
var shas = make([]string, 0, len(issues))
191-
var pullIDs = make([]int64, 0, len(issues))
192-
// Get posters.
193-
for i, issue := range issues {
194-
// Check read status
195-
if !ctx.IsSigned {
196-
issues[i].IsRead = true
197-
} else if err = issues[i].GetIsRead(ctx.User.ID); err != nil {
198-
ctx.ServerError("GetIsRead", err)
199-
return
189+
if !isPullList {
190+
// Get posters.
191+
for i := 0; i < len(issues); i++ {
192+
// Check read status
193+
if !ctx.IsSigned {
194+
issues[i].IsRead = true
195+
} else if err = issues[i].GetIsRead(ctx.User.ID); err != nil {
196+
ctx.ServerError("GetIsRead", err)
197+
return
198+
}
200199
}
200+
} else {
201+
var repoIDs = make([]int64, 0, len(issues))
202+
var shas = make([]string, 0, len(issues))
203+
var pullIDs = make([]int64, 0, len(issues))
204+
var repoCache = make(map[int64]*git.Repository)
205+
206+
// Get posters.
207+
for i, issue := range issues {
208+
// Check read status
209+
if !ctx.IsSigned {
210+
issues[i].IsRead = true
211+
} else if err = issues[i].GetIsRead(ctx.User.ID); err != nil {
212+
ctx.ServerError("GetIsRead", err)
213+
return
214+
}
201215

202-
if issue.IsPull {
203216
if err := issue.LoadAttributes(); err != nil {
204217
ctx.ServerError("LoadAttributes", err)
205218
return
206219
}
207220

208-
repoIDs = append(repoIDs, ctx.Repo.Repository.ID)
209-
shas = append(shas, issue.PullRequest.MergeBase)
210-
pullIDs = append(pullIDs, issue.ID)
221+
var rep *git.Repository
222+
var ok bool
223+
if rep, ok = repoCache[issue.PullRequest.HeadRepoID]; !ok {
224+
if err := issue.PullRequest.GetHeadRepo(); err != nil {
225+
ctx.ServerError("GetHeadRepo", err)
226+
return
227+
}
228+
229+
rep, err = git.OpenRepository(issue.PullRequest.HeadRepo.RepoPath())
230+
if err != nil {
231+
ctx.ServerError("OpenRepository", err)
232+
return
233+
}
234+
repoCache[issue.PullRequest.HeadRepoID] = rep
235+
}
236+
237+
sha, err := rep.GetBranchCommitID(issue.PullRequest.HeadBranch)
238+
if err != nil {
239+
log.Error(4, "GetBranchCommitID: %v", err)
240+
} else {
241+
repoIDs = append(repoIDs, issue.RepoID)
242+
shas = append(shas, sha)
243+
pullIDs = append(pullIDs, issue.ID)
244+
}
211245
}
212-
}
213246

214-
commitStatuses, err := models.GetLatestCommitStatuses(repoIDs, shas)
215-
if err != nil {
216-
ctx.ServerError("GetLatestCommitStatuses", err)
217-
return
218-
}
247+
var issuesStates = make(map[int64]*models.CommitStatus, len(issues))
248+
if len(repoIDs) > 0 {
249+
commitStatuses, err := models.GetLatestCommitStatuses(repoIDs, shas)
250+
if err != nil {
251+
ctx.ServerError("GetLatestCommitStatuses", err)
252+
return
253+
}
219254

220-
var issuesStates = make(map[int64]*models.CommitStatus, len(issues))
221-
for i, statuses := range commitStatuses {
222-
issuesStates[pullIDs[i]] = models.CalcCommitStatus(statuses)
255+
for i, statuses := range commitStatuses {
256+
issuesStates[pullIDs[i]] = models.CalcCommitStatus(statuses)
257+
}
258+
}
259+
ctx.Data["IssuesStates"] = issuesStates
223260
}
224261

225262
ctx.Data["Issues"] = issues
226-
ctx.Data["IssuesStates"] = issuesStates
227263

228264
// Get assignees.
229265
ctx.Data["Assignees"], err = repo.GetAssignees()

0 commit comments

Comments
 (0)