Skip to content

Commit d9d2b03

Browse files
committed
Add tests
1 parent 602b905 commit d9d2b03

File tree

3 files changed

+188
-116
lines changed

3 files changed

+188
-116
lines changed

routers/web/repo/issue_comment.go

Lines changed: 122 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
repo_module "code.gitea.io/gitea/modules/repository"
2424
"code.gitea.io/gitea/modules/setting"
2525
api "code.gitea.io/gitea/modules/structs"
26+
"code.gitea.io/gitea/modules/util"
2627
"code.gitea.io/gitea/modules/web"
2728
"code.gitea.io/gitea/services/context"
2829
"code.gitea.io/gitea/services/convert"
@@ -31,102 +32,84 @@ import (
3132
pull_service "code.gitea.io/gitea/services/pull"
3233
)
3334

34-
func newCommentWithReopen(ctx *context.Context, issue *issues_model.Issue, content string, attachments []string) *issues_model.Comment {
35-
if !issue.IsClosed {
36-
ctx.JSONError(ctx.Tr("repo.issues.not_closed"))
37-
return nil
38-
}
35+
func reopenPullWithComment(ctx *context.Context, issue *issues_model.Issue, content string, attachments []string) *issues_model.Comment {
36+
pull := issue.PullRequest
3937

40-
if !ctx.Repo.CanWriteIssuesOrPulls(issue.IsPull) &&
41-
!issue.IsPoster(ctx.Doer.ID) &&
42-
!ctx.Doer.IsAdmin {
43-
ctx.JSONError(ctx.Tr("repo.issues.reopen_not_allowed"))
38+
// get head commit of branch in the head repo
39+
if err := pull.LoadHeadRepo(ctx); err != nil {
40+
ctx.ServerError("Unable to load head repo", err)
4441
return nil
4542
}
4643

47-
if issue.IsPull {
48-
pull := issue.PullRequest
49-
if pull.HasMerged {
50-
ctx.JSONError(ctx.Tr("repo.issues.reopen_not_allowed_merged"))
44+
// check whether the ref of PR <refs/pulls/pr_index/head> in base repo is consistent with the head commit of head branch in the head repo
45+
// get head commit of PR
46+
if pull.Flow == issues_model.PullRequestFlowGithub {
47+
prHeadRef := pull.GetGitHeadRefName()
48+
if err := pull.LoadBaseRepo(ctx); err != nil {
49+
ctx.ServerError("Unable to load base repo", err)
5150
return nil
5251
}
53-
54-
// get head commit of branch in the head repo
55-
if err := pull.LoadHeadRepo(ctx); err != nil {
56-
ctx.ServerError("Unable to load head repo", err)
52+
prHeadCommitID, err := git.GetFullCommitID(ctx, pull.BaseRepo.RepoPath(), prHeadRef)
53+
if err != nil {
54+
ctx.ServerError("Get head commit Id of pr fail", err)
5755
return nil
5856
}
5957

60-
// check whether the ref of PR <refs/pulls/pr_index/head> in base repo is consistent with the head commit of head branch in the head repo
61-
// get head commit of PR
62-
if pull.Flow == issues_model.PullRequestFlowGithub {
63-
prHeadRef := pull.GetGitHeadRefName()
64-
if err := pull.LoadBaseRepo(ctx); err != nil {
65-
ctx.ServerError("Unable to load base repo", err)
66-
return nil
67-
}
68-
prHeadCommitID, err := git.GetFullCommitID(ctx, pull.BaseRepo.RepoPath(), prHeadRef)
69-
if err != nil {
70-
ctx.ServerError("Get head commit Id of pr fail", err)
71-
return nil
72-
}
73-
74-
if ok := gitrepo.IsBranchExist(ctx, pull.HeadRepo, pull.BaseBranch); !ok {
75-
// todo localize
76-
ctx.JSONError("The origin branch is delete, cannot reopen.")
77-
return nil
78-
}
79-
headBranchRef := git.RefNameFromBranch(pull.HeadBranch)
80-
headBranchCommitID, err := git.GetFullCommitID(ctx, pull.HeadRepo.RepoPath(), headBranchRef.String())
81-
if err != nil {
82-
ctx.ServerError("Get head commit Id of head branch fail", err)
83-
return nil
84-
}
85-
86-
err = pull.LoadIssue(ctx)
87-
if err != nil {
88-
ctx.ServerError("load the issue of pull request error", err)
89-
return nil
90-
}
91-
92-
if prHeadCommitID != headBranchCommitID {
93-
// force push to base repo
94-
err := git.Push(ctx, pull.HeadRepo.RepoPath(), git.PushOptions{
95-
Remote: pull.BaseRepo.RepoPath(),
96-
Branch: pull.HeadBranch + ":" + prHeadRef,
97-
Force: true,
98-
Env: repo_module.InternalPushingEnvironment(pull.Issue.Poster, pull.BaseRepo),
99-
})
100-
if err != nil {
101-
ctx.ServerError("force push error", err)
102-
return nil
103-
}
104-
}
58+
if ok := gitrepo.IsBranchExist(ctx, pull.HeadRepo, pull.BaseBranch); !ok {
59+
// todo localize
60+
ctx.JSONError("The origin branch is delete, cannot reopen.")
61+
return nil
10562
}
106-
107-
branchExist, err := git_model.IsBranchExist(ctx, pull.HeadRepo.ID, pull.HeadBranch)
63+
headBranchRef := git.RefNameFromBranch(pull.HeadBranch)
64+
headBranchCommitID, err := git.GetFullCommitID(ctx, pull.HeadRepo.RepoPath(), headBranchRef.String())
10865
if err != nil {
109-
ctx.ServerError("IsBranchExist", err)
66+
ctx.ServerError("Get head commit Id of head branch fail", err)
11067
return nil
11168
}
112-
if !branchExist {
113-
ctx.JSONError(ctx.Tr("repo.pulls.head_branch_not_exist"))
69+
70+
err = pull.LoadIssue(ctx)
71+
if err != nil {
72+
ctx.ServerError("load the issue of pull request error", err)
11473
return nil
11574
}
11675

117-
// check if an opened pull request exists with the same head branch and base branch
118-
pr, err := issues_model.GetUnmergedPullRequest(ctx, pull.HeadRepoID, pull.BaseRepoID, pull.HeadBranch, pull.BaseBranch, pull.Flow)
119-
if err != nil {
120-
if !issues_model.IsErrPullRequestNotExist(err) {
121-
ctx.JSONError(err.Error())
76+
if prHeadCommitID != headBranchCommitID {
77+
// force push to base repo
78+
err := git.Push(ctx, pull.HeadRepo.RepoPath(), git.PushOptions{
79+
Remote: pull.BaseRepo.RepoPath(),
80+
Branch: pull.HeadBranch + ":" + prHeadRef,
81+
Force: true,
82+
Env: repo_module.InternalPushingEnvironment(pull.Issue.Poster, pull.BaseRepo),
83+
})
84+
if err != nil {
85+
ctx.ServerError("force push error", err)
12286
return nil
12387
}
12488
}
125-
if pr != nil {
126-
ctx.Flash.Info(ctx.Tr("repo.pulls.open_unmerged_pull_exists", pr.Index))
89+
}
90+
91+
branchExist, err := git_model.IsBranchExist(ctx, pull.HeadRepo.ID, pull.HeadBranch)
92+
if err != nil {
93+
ctx.ServerError("IsBranchExist", err)
94+
return nil
95+
}
96+
if !branchExist {
97+
ctx.JSONError(ctx.Tr("repo.pulls.head_branch_not_exist"))
98+
return nil
99+
}
100+
101+
// check if an opened pull request exists with the same head branch and base branch
102+
pr, err := issues_model.GetUnmergedPullRequest(ctx, pull.HeadRepoID, pull.BaseRepoID, pull.HeadBranch, pull.BaseBranch, pull.Flow)
103+
if err != nil {
104+
if !issues_model.IsErrPullRequestNotExist(err) {
105+
ctx.JSONError(err.Error())
127106
return nil
128107
}
129108
}
109+
if pr != nil {
110+
ctx.Flash.Info(ctx.Tr("repo.pulls.open_unmerged_pull_exists", pr.Index))
111+
return nil
112+
}
130113

131114
createdComment, err := issue_service.ReopenIssueWithComment(ctx, issue, ctx.Doer, "", content, attachments)
132115
if err != nil {
@@ -138,46 +121,43 @@ func newCommentWithReopen(ctx *context.Context, issue *issues_model.Issue, conte
138121
return nil
139122
}
140123

141-
if issue.IsPull {
142-
pull := issue.PullRequest
143-
// check whether the ref of PR <refs/pulls/pr_index/head> in base repo is consistent with the head commit of head branch in the head repo
144-
// get head commit of PR
145-
if pull.Flow == issues_model.PullRequestFlowGithub {
146-
prHeadRef := pull.GetGitHeadRefName()
147-
if err := pull.LoadBaseRepo(ctx); err != nil {
148-
ctx.ServerError("Unable to load base repo", err)
149-
return nil
150-
}
151-
prHeadCommitID, err := ctx.Repo.GitRepo.GetRefCommitID(prHeadRef)
152-
if err != nil {
153-
ctx.ServerError("Get head commit Id of pr fail", err)
154-
return nil
155-
}
124+
// check whether the ref of PR <refs/pulls/pr_index/head> in base repo is consistent with the head commit of head branch in the head repo
125+
// get head commit of PR
126+
if pull.Flow == issues_model.PullRequestFlowGithub {
127+
prHeadRef := pull.GetGitHeadRefName()
128+
if err := pull.LoadBaseRepo(ctx); err != nil {
129+
ctx.ServerError("Unable to load base repo", err)
130+
return nil
131+
}
132+
prHeadCommitID, err := ctx.Repo.GitRepo.GetRefCommitID(prHeadRef)
133+
if err != nil {
134+
ctx.ServerError("Get head commit Id of pr fail", err)
135+
return nil
136+
}
156137

157-
headBranchCommitID, err := gitrepo.GetBranchCommitID(ctx, pull.HeadRepo, pull.HeadBranch)
158-
if err != nil {
159-
ctx.ServerError("Get head commit Id of head branch fail", err)
160-
return nil
161-
}
138+
headBranchCommitID, err := gitrepo.GetBranchCommitID(ctx, pull.HeadRepo, pull.HeadBranch)
139+
if err != nil {
140+
ctx.ServerError("Get head commit Id of head branch fail", err)
141+
return nil
142+
}
162143

163-
if err = pull.LoadIssue(ctx); err != nil {
164-
ctx.ServerError("load the issue of pull request error", err)
165-
return nil
166-
}
144+
if err = pull.LoadIssue(ctx); err != nil {
145+
ctx.ServerError("load the issue of pull request error", err)
146+
return nil
147+
}
167148

168-
// if the head commit ID of the PR is different from the head branch
169-
if prHeadCommitID != headBranchCommitID {
170-
// force push to base repo
171-
err := git.Push(ctx, pull.HeadRepo.RepoPath(), git.PushOptions{
172-
Remote: pull.BaseRepo.RepoPath(),
173-
Branch: pull.HeadBranch + ":" + prHeadRef,
174-
Force: true,
175-
Env: repo_module.InternalPushingEnvironment(pull.Issue.Poster, pull.BaseRepo),
176-
})
177-
if err != nil {
178-
ctx.ServerError("force push error", err)
179-
return nil
180-
}
149+
// if the head commit ID of the PR is different from the head branch
150+
if prHeadCommitID != headBranchCommitID {
151+
// force push to base repo
152+
err := git.Push(ctx, pull.HeadRepo.RepoPath(), git.PushOptions{
153+
Remote: pull.BaseRepo.RepoPath(),
154+
Branch: pull.HeadBranch + ":" + prHeadRef,
155+
Force: true,
156+
Env: repo_module.InternalPushingEnvironment(pull.Issue.Poster, pull.BaseRepo),
157+
})
158+
if err != nil {
159+
ctx.ServerError("force push error", err)
160+
return nil
181161
}
182162
}
183163

@@ -224,6 +204,11 @@ func NewComment(ctx *context.Context) {
224204
return
225205
}
226206

207+
if form.Content == "" {
208+
ctx.JSONError(ctx.Tr("repo.issues.comment.empty_content"))
209+
return
210+
}
211+
227212
var attachments []string
228213
if setting.Attachment.Enabled {
229214
attachments = form.Files
@@ -239,7 +224,30 @@ func NewComment(ctx *context.Context) {
239224

240225
switch form.Status {
241226
case "reopen":
242-
createdComment = newCommentWithReopen(ctx, issue, form.Content, attachments)
227+
if !issue.IsClosed {
228+
ctx.JSONError(ctx.Tr("repo.issues.not_closed"))
229+
return
230+
}
231+
if !ctx.Repo.CanWriteIssuesOrPulls(issue.IsPull) &&
232+
!issue.IsPoster(ctx.Doer.ID) &&
233+
!ctx.Doer.IsAdmin {
234+
ctx.JSONError(ctx.Tr("repo.issues.reopen_not_allowed"))
235+
return
236+
}
237+
238+
if issue.IsPull {
239+
createdComment = reopenPullWithComment(ctx, issue, form.Content, attachments)
240+
} else {
241+
createdComment, err = issue_service.ReopenIssueWithComment(ctx, issue, ctx.Doer, "", form.Content, attachments)
242+
if err != nil {
243+
if errors.Is(err, user_model.ErrBlockedUser) {
244+
ctx.JSONError(ctx.Tr("repo.issues.comment.blocked_user"))
245+
} else {
246+
ctx.ServerError("ReopenIssue", err)
247+
}
248+
return
249+
}
250+
}
243251
if ctx.Written() {
244252
return
245253
}
@@ -276,10 +284,8 @@ func NewComment(ctx *context.Context) {
276284
}
277285

278286
// Redirect to comment hashtag if there is any actual content.
279-
typeName := "issues"
280-
if issue.IsPull {
281-
typeName = "pulls"
282-
}
287+
typeName := util.Iif(issue.IsPull, "pulls", "issues")
288+
283289
if createdComment != nil {
284290
log.Trace("Comment created: %d/%d/%d", ctx.Repo.Repository.ID, issue.ID, createdComment.ID)
285291
ctx.JSONRedirect(fmt.Sprintf("%s/%s/%d#%s", ctx.Repo.RepoLink, typeName, issue.Index, createdComment.HashTag()))

tests/integration/issue_test.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,26 @@ func TestIssueCommentClose(t *testing.T) {
255255
htmlDoc := NewHTMLParser(t, resp.Body)
256256
val := htmlDoc.doc.Find(".comment-list .comment .render-content p").First().Text()
257257
assert.Equal(t, "Description", val)
258+
val = strings.TrimSpace(htmlDoc.doc.Find(".issue-title-header .issue-state-label").Text())
259+
assert.Equal(t, "Closed", val)
260+
}
261+
262+
func TestIssueCommentReopen(t *testing.T) {
263+
defer tests.PrepareTestEnv(t)()
264+
session := loginUser(t, "user2")
265+
issueURL := testNewIssue(t, session, "user2", "repo1", "Title", "Description")
266+
testIssueAddComment(t, session, issueURL, "Test comment 1", "")
267+
testIssueAddComment(t, session, issueURL, "Test comment 2", "close")
268+
testIssueAddComment(t, session, issueURL, "Test comment 2", "reopen")
269+
270+
// Validate that issue content has not been updated
271+
req := NewRequest(t, "GET", issueURL)
272+
resp := session.MakeRequest(t, req, http.StatusOK)
273+
htmlDoc := NewHTMLParser(t, resp.Body)
274+
val := htmlDoc.doc.Find(".comment-list .comment .render-content p").First().Text()
275+
assert.Equal(t, "Description", val)
276+
val = strings.TrimSpace(htmlDoc.doc.Find(".issue-title-header .issue-state-label").Text())
277+
assert.Equal(t, "Open", val)
258278
}
259279

260280
func TestIssueCommentDelete(t *testing.T) {

tests/integration/pull_create_test.go

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,3 +313,49 @@ func TestCreatePullWhenBlocked(t *testing.T) {
313313
MakeRequest(t, req, http.StatusNoContent)
314314
})
315315
}
316+
317+
func TestPullRequestCommentClose(t *testing.T) {
318+
onGiteaRun(t, func(t *testing.T, u *url.URL) {
319+
session := loginUser(t, "user1")
320+
testRepoFork(t, session, "user2", "repo1", "user1", "repo1", "")
321+
testEditFile(t, session, "user1", "repo1", "master", "README.md", "Hello, World (Edited)\n")
322+
resp := testPullCreate(t, session, "user1", "repo1", false, "master", "master", "This is a pull title")
323+
pullURL := test.RedirectURL(resp)
324+
325+
testIssueAddComment(t, session, pullURL, "Test comment 1", "")
326+
testIssueAddComment(t, session, pullURL, "Test comment 2", "")
327+
testIssueAddComment(t, session, pullURL, "Test comment 3", "close")
328+
329+
// Validate that issue content has not been updated
330+
req := NewRequest(t, "GET", pullURL)
331+
resp = session.MakeRequest(t, req, http.StatusOK)
332+
htmlDoc := NewHTMLParser(t, resp.Body)
333+
val := strings.Split(strings.TrimSpace(htmlDoc.doc.Find("#issue-title-display > h1").First().Text()), "\n")[0]
334+
assert.Equal(t, "This is a pull title", val)
335+
val = strings.TrimSpace(htmlDoc.doc.Find(".issue-title-header .issue-state-label").Text())
336+
assert.Equal(t, "Closed", val)
337+
})
338+
}
339+
340+
func TestPullRequestCommentReopen(t *testing.T) {
341+
onGiteaRun(t, func(t *testing.T, u *url.URL) {
342+
session := loginUser(t, "user1")
343+
testRepoFork(t, session, "user2", "repo1", "user1", "repo1", "")
344+
testEditFile(t, session, "user1", "repo1", "master", "README.md", "Hello, World (Edited)\n")
345+
resp := testPullCreate(t, session, "user1", "repo1", false, "master", "master", "This is a pull title")
346+
pullURL := test.RedirectURL(resp)
347+
348+
testIssueAddComment(t, session, pullURL, "Test comment 1", "")
349+
testIssueAddComment(t, session, pullURL, "Test comment 2", "close")
350+
testIssueAddComment(t, session, pullURL, "Test comment 2", "reopen")
351+
352+
// Validate that issue content has not been updated
353+
req := NewRequest(t, "GET", pullURL)
354+
resp = session.MakeRequest(t, req, http.StatusOK)
355+
htmlDoc := NewHTMLParser(t, resp.Body)
356+
val := strings.Split(strings.TrimSpace(htmlDoc.doc.Find("#issue-title-display > h1").First().Text()), "\n")[0]
357+
assert.Equal(t, "This is a pull title", val)
358+
val = strings.TrimSpace(htmlDoc.doc.Find(".issue-title-header .issue-state-label").Text())
359+
assert.Equal(t, "Open", val)
360+
})
361+
}

0 commit comments

Comments
 (0)