Skip to content

Commit 280f4be

Browse files
lunnylafriks
authored andcommitted
Move issue label operations to issue service package (#8553)
* Move issue label operations to issue service package * fix test * fix fmt
1 parent 240f46a commit 280f4be

File tree

7 files changed

+168
-138
lines changed

7 files changed

+168
-138
lines changed

models/issue.go

-88
Original file line numberDiff line numberDiff line change
@@ -428,52 +428,6 @@ func (issue *Issue) HasLabel(labelID int64) bool {
428428
return issue.hasLabel(x, labelID)
429429
}
430430

431-
func (issue *Issue) sendLabelUpdatedWebhook(doer *User) {
432-
var err error
433-
434-
if err = issue.loadRepo(x); err != nil {
435-
log.Error("loadRepo: %v", err)
436-
return
437-
}
438-
439-
if err = issue.loadPoster(x); err != nil {
440-
log.Error("loadPoster: %v", err)
441-
return
442-
}
443-
444-
mode, _ := AccessLevel(issue.Poster, issue.Repo)
445-
if issue.IsPull {
446-
if err = issue.loadPullRequest(x); err != nil {
447-
log.Error("loadPullRequest: %v", err)
448-
return
449-
}
450-
if err = issue.PullRequest.LoadIssue(); err != nil {
451-
log.Error("LoadIssue: %v", err)
452-
return
453-
}
454-
err = PrepareWebhooks(issue.Repo, HookEventPullRequest, &api.PullRequestPayload{
455-
Action: api.HookIssueLabelUpdated,
456-
Index: issue.Index,
457-
PullRequest: issue.PullRequest.APIFormat(),
458-
Repository: issue.Repo.APIFormat(AccessModeNone),
459-
Sender: doer.APIFormat(),
460-
})
461-
} else {
462-
err = PrepareWebhooks(issue.Repo, HookEventIssues, &api.IssuePayload{
463-
Action: api.HookIssueLabelUpdated,
464-
Index: issue.Index,
465-
Issue: issue.APIFormat(),
466-
Repository: issue.Repo.APIFormat(mode),
467-
Sender: doer.APIFormat(),
468-
})
469-
}
470-
if err != nil {
471-
log.Error("PrepareWebhooks [is_pull: %v]: %v", issue.IsPull, err)
472-
} else {
473-
go HookQueue.Add(issue.RepoID)
474-
}
475-
}
476-
477431
// ReplyReference returns tokenized address to use for email reply headers
478432
func (issue *Issue) ReplyReference() string {
479433
var path string
@@ -490,30 +444,10 @@ func (issue *Issue) addLabel(e *xorm.Session, label *Label, doer *User) error {
490444
return newIssueLabel(e, issue, label, doer)
491445
}
492446

493-
// AddLabel adds a new label to the issue.
494-
func (issue *Issue) AddLabel(doer *User, label *Label) error {
495-
if err := NewIssueLabel(issue, label, doer); err != nil {
496-
return err
497-
}
498-
499-
issue.sendLabelUpdatedWebhook(doer)
500-
return nil
501-
}
502-
503447
func (issue *Issue) addLabels(e *xorm.Session, labels []*Label, doer *User) error {
504448
return newIssueLabels(e, issue, labels, doer)
505449
}
506450

507-
// AddLabels adds a list of new labels to the issue.
508-
func (issue *Issue) AddLabels(doer *User, labels []*Label) error {
509-
if err := NewIssueLabels(issue, labels, doer); err != nil {
510-
return err
511-
}
512-
513-
issue.sendLabelUpdatedWebhook(doer)
514-
return nil
515-
}
516-
517451
func (issue *Issue) getLabels(e Engine) (err error) {
518452
if len(issue.Labels) > 0 {
519453
return nil
@@ -530,28 +464,6 @@ func (issue *Issue) removeLabel(e *xorm.Session, doer *User, label *Label) error
530464
return deleteIssueLabel(e, issue, label, doer)
531465
}
532466

533-
// RemoveLabel removes a label from issue by given ID.
534-
func (issue *Issue) RemoveLabel(doer *User, label *Label) error {
535-
if err := issue.loadRepo(x); err != nil {
536-
return err
537-
}
538-
539-
perm, err := GetUserRepoPermission(issue.Repo, doer)
540-
if err != nil {
541-
return err
542-
}
543-
if !perm.CanWriteIssuesOrPulls(issue.IsPull) {
544-
return ErrLabelNotExist{}
545-
}
546-
547-
if err := DeleteIssueLabel(issue, label, doer); err != nil {
548-
return err
549-
}
550-
551-
issue.sendLabelUpdatedWebhook(doer)
552-
return nil
553-
}
554-
555467
func (issue *Issue) clearLabels(e *xorm.Session, doer *User) (err error) {
556468
if err = issue.getLabels(e); err != nil {
557469
return fmt.Errorf("getLabels: %v", err)

models/issue_test.go

-47
Original file line numberDiff line numberDiff line change
@@ -84,53 +84,6 @@ func TestGetParticipantsByIssueID(t *testing.T) {
8484
checkParticipants(1, []int{5})
8585
}
8686

87-
func TestIssue_AddLabel(t *testing.T) {
88-
var tests = []struct {
89-
issueID int64
90-
labelID int64
91-
doerID int64
92-
}{
93-
{1, 2, 2}, // non-pull-request, not-already-added label
94-
{1, 1, 2}, // non-pull-request, already-added label
95-
{2, 2, 2}, // pull-request, not-already-added label
96-
{2, 1, 2}, // pull-request, already-added label
97-
}
98-
for _, test := range tests {
99-
assert.NoError(t, PrepareTestDatabase())
100-
issue := AssertExistsAndLoadBean(t, &Issue{ID: test.issueID}).(*Issue)
101-
label := AssertExistsAndLoadBean(t, &Label{ID: test.labelID}).(*Label)
102-
doer := AssertExistsAndLoadBean(t, &User{ID: test.doerID}).(*User)
103-
assert.NoError(t, issue.AddLabel(doer, label))
104-
AssertExistsAndLoadBean(t, &IssueLabel{IssueID: test.issueID, LabelID: test.labelID})
105-
}
106-
}
107-
108-
func TestIssue_AddLabels(t *testing.T) {
109-
var tests = []struct {
110-
issueID int64
111-
labelIDs []int64
112-
doerID int64
113-
}{
114-
{1, []int64{1, 2}, 2}, // non-pull-request
115-
{1, []int64{}, 2}, // non-pull-request, empty
116-
{2, []int64{1, 2}, 2}, // pull-request
117-
{2, []int64{}, 1}, // pull-request, empty
118-
}
119-
for _, test := range tests {
120-
assert.NoError(t, PrepareTestDatabase())
121-
issue := AssertExistsAndLoadBean(t, &Issue{ID: test.issueID}).(*Issue)
122-
labels := make([]*Label, len(test.labelIDs))
123-
for i, labelID := range test.labelIDs {
124-
labels[i] = AssertExistsAndLoadBean(t, &Label{ID: labelID}).(*Label)
125-
}
126-
doer := AssertExistsAndLoadBean(t, &User{ID: test.doerID}).(*User)
127-
assert.NoError(t, issue.AddLabels(doer, labels))
128-
for _, labelID := range test.labelIDs {
129-
AssertExistsAndLoadBean(t, &IssueLabel{IssueID: test.issueID, LabelID: labelID})
130-
}
131-
}
132-
}
133-
13487
func TestIssue_ClearLabels(t *testing.T) {
13588
var tests = []struct {
13689
issueID int64

routers/api/v1/repo/issue_label.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ func AddIssueLabels(ctx *context.APIContext, form api.IssueLabelsOption) {
117117
return
118118
}
119119

120-
if err = issue.AddLabels(ctx.User, labels); err != nil {
120+
if err = issue_service.AddLabels(issue, ctx.User, labels); err != nil {
121121
ctx.Error(500, "AddLabels", err)
122122
return
123123
}

routers/repo/issue_label.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -162,14 +162,14 @@ func UpdateIssueLabel(ctx *context.Context) {
162162

163163
if action == "attach" {
164164
for _, issue := range issues {
165-
if err = issue.AddLabel(ctx.User, label); err != nil {
165+
if err = issue_service.AddLabel(issue, ctx.User, label); err != nil {
166166
ctx.ServerError("AddLabel", err)
167167
return
168168
}
169169
}
170170
} else {
171171
for _, issue := range issues {
172-
if err = issue.RemoveLabel(ctx.User, label); err != nil {
172+
if err = issue_service.RemoveLabel(issue, ctx.User, label); err != nil {
173173
ctx.ServerError("RemoveLabel", err)
174174
return
175175
}

services/issue/label.go

+90
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,57 @@ package issue
66

77
import (
88
"code.gitea.io/gitea/models"
9+
"code.gitea.io/gitea/modules/log"
910
"code.gitea.io/gitea/modules/notification"
11+
api "code.gitea.io/gitea/modules/structs"
1012
)
1113

14+
func sendLabelUpdatedWebhook(issue *models.Issue, doer *models.User) {
15+
var err error
16+
17+
if err = issue.LoadRepo(); err != nil {
18+
log.Error("LoadRepo: %v", err)
19+
return
20+
}
21+
22+
if err = issue.LoadPoster(); err != nil {
23+
log.Error("LoadPoster: %v", err)
24+
return
25+
}
26+
27+
mode, _ := models.AccessLevel(issue.Poster, issue.Repo)
28+
if issue.IsPull {
29+
if err = issue.LoadPullRequest(); err != nil {
30+
log.Error("loadPullRequest: %v", err)
31+
return
32+
}
33+
if err = issue.PullRequest.LoadIssue(); err != nil {
34+
log.Error("LoadIssue: %v", err)
35+
return
36+
}
37+
err = models.PrepareWebhooks(issue.Repo, models.HookEventPullRequest, &api.PullRequestPayload{
38+
Action: api.HookIssueLabelUpdated,
39+
Index: issue.Index,
40+
PullRequest: issue.PullRequest.APIFormat(),
41+
Repository: issue.Repo.APIFormat(models.AccessModeNone),
42+
Sender: doer.APIFormat(),
43+
})
44+
} else {
45+
err = models.PrepareWebhooks(issue.Repo, models.HookEventIssues, &api.IssuePayload{
46+
Action: api.HookIssueLabelUpdated,
47+
Index: issue.Index,
48+
Issue: issue.APIFormat(),
49+
Repository: issue.Repo.APIFormat(mode),
50+
Sender: doer.APIFormat(),
51+
})
52+
}
53+
if err != nil {
54+
log.Error("PrepareWebhooks [is_pull: %v]: %v", issue.IsPull, err)
55+
} else {
56+
go models.HookQueue.Add(issue.RepoID)
57+
}
58+
}
59+
1260
// ClearLabels clears all of an issue's labels
1361
func ClearLabels(issue *models.Issue, doer *models.User) (err error) {
1462
if err = issue.ClearLabels(doer); err != nil {
@@ -19,3 +67,45 @@ func ClearLabels(issue *models.Issue, doer *models.User) (err error) {
1967

2068
return nil
2169
}
70+
71+
// AddLabel adds a new label to the issue.
72+
func AddLabel(issue *models.Issue, doer *models.User, label *models.Label) error {
73+
if err := models.NewIssueLabel(issue, label, doer); err != nil {
74+
return err
75+
}
76+
77+
sendLabelUpdatedWebhook(issue, doer)
78+
return nil
79+
}
80+
81+
// AddLabels adds a list of new labels to the issue.
82+
func AddLabels(issue *models.Issue, doer *models.User, labels []*models.Label) error {
83+
if err := models.NewIssueLabels(issue, labels, doer); err != nil {
84+
return err
85+
}
86+
87+
sendLabelUpdatedWebhook(issue, doer)
88+
return nil
89+
}
90+
91+
// RemoveLabel removes a label from issue by given ID.
92+
func RemoveLabel(issue *models.Issue, doer *models.User, label *models.Label) error {
93+
if err := issue.LoadRepo(); err != nil {
94+
return err
95+
}
96+
97+
perm, err := models.GetUserRepoPermission(issue.Repo, doer)
98+
if err != nil {
99+
return err
100+
}
101+
if !perm.CanWriteIssuesOrPulls(issue.IsPull) {
102+
return models.ErrLabelNotExist{}
103+
}
104+
105+
if err := models.DeleteIssueLabel(issue, label, doer); err != nil {
106+
return err
107+
}
108+
109+
sendLabelUpdatedWebhook(issue, doer)
110+
return nil
111+
}

services/issue/label_test.go

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
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 issue
6+
7+
import (
8+
"testing"
9+
10+
"code.gitea.io/gitea/models"
11+
"github.com/stretchr/testify/assert"
12+
)
13+
14+
func TestIssue_AddLabels(t *testing.T) {
15+
var tests = []struct {
16+
issueID int64
17+
labelIDs []int64
18+
doerID int64
19+
}{
20+
{1, []int64{1, 2}, 2}, // non-pull-request
21+
{1, []int64{}, 2}, // non-pull-request, empty
22+
{2, []int64{1, 2}, 2}, // pull-request
23+
{2, []int64{}, 1}, // pull-request, empty
24+
}
25+
for _, test := range tests {
26+
assert.NoError(t, models.PrepareTestDatabase())
27+
issue := models.AssertExistsAndLoadBean(t, &models.Issue{ID: test.issueID}).(*models.Issue)
28+
labels := make([]*models.Label, len(test.labelIDs))
29+
for i, labelID := range test.labelIDs {
30+
labels[i] = models.AssertExistsAndLoadBean(t, &models.Label{ID: labelID}).(*models.Label)
31+
}
32+
doer := models.AssertExistsAndLoadBean(t, &models.User{ID: test.doerID}).(*models.User)
33+
assert.NoError(t, AddLabels(issue, doer, labels))
34+
for _, labelID := range test.labelIDs {
35+
models.AssertExistsAndLoadBean(t, &models.IssueLabel{IssueID: test.issueID, LabelID: labelID})
36+
}
37+
}
38+
}
39+
40+
func TestIssue_AddLabel(t *testing.T) {
41+
var tests = []struct {
42+
issueID int64
43+
labelID int64
44+
doerID int64
45+
}{
46+
{1, 2, 2}, // non-pull-request, not-already-added label
47+
{1, 1, 2}, // non-pull-request, already-added label
48+
{2, 2, 2}, // pull-request, not-already-added label
49+
{2, 1, 2}, // pull-request, already-added label
50+
}
51+
for _, test := range tests {
52+
assert.NoError(t, models.PrepareTestDatabase())
53+
issue := models.AssertExistsAndLoadBean(t, &models.Issue{ID: test.issueID}).(*models.Issue)
54+
label := models.AssertExistsAndLoadBean(t, &models.Label{ID: test.labelID}).(*models.Label)
55+
doer := models.AssertExistsAndLoadBean(t, &models.User{ID: test.doerID}).(*models.User)
56+
assert.NoError(t, AddLabel(issue, doer, label))
57+
models.AssertExistsAndLoadBean(t, &models.IssueLabel{IssueID: test.issueID, LabelID: test.labelID})
58+
}
59+
}

services/issue/main_test.go

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Copyright 2019 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 issue
6+
7+
import (
8+
"path/filepath"
9+
"testing"
10+
11+
"code.gitea.io/gitea/models"
12+
)
13+
14+
func TestMain(m *testing.M) {
15+
models.MainTest(m, filepath.Join("..", ".."))
16+
}

0 commit comments

Comments
 (0)