Skip to content

Commit c63a801

Browse files
6543lafriks
authored andcommitted
backport part of go-gitea#9550 (go-gitea#9564)
* add ErrReactionAlreadyExist * extend FindReactionsOptions * createReaction check if exit before create
1 parent b4b8c96 commit c63a801

File tree

3 files changed

+51
-12
lines changed

3 files changed

+51
-12
lines changed

models/error.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1104,6 +1104,21 @@ func (err ErrNewIssueInsert) Error() string {
11041104
return err.OriginalError.Error()
11051105
}
11061106

1107+
// ErrReactionAlreadyExist is used when a existing reaction was try to created
1108+
type ErrReactionAlreadyExist struct {
1109+
Reaction string
1110+
}
1111+
1112+
// IsErrReactionAlreadyExist checks if an error is a ErrReactionAlreadyExist.
1113+
func IsErrReactionAlreadyExist(err error) bool {
1114+
_, ok := err.(ErrReactionAlreadyExist)
1115+
return ok
1116+
}
1117+
1118+
func (err ErrReactionAlreadyExist) Error() string {
1119+
return fmt.Sprintf("reaction '%s' already exists", err.Reaction)
1120+
}
1121+
11071122
// __________ .__ .__ __________ __
11081123
// \______ \__ __| | | |\______ \ ____ ________ __ ____ _______/ |_
11091124
// | ___/ | \ | | | | _// __ \/ ____/ | \_/ __ \ / ___/\ __\

models/issue_reaction.go

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ type Reaction struct {
3030
type FindReactionsOptions struct {
3131
IssueID int64
3232
CommentID int64
33+
UserID int64
34+
Reaction string
3335
}
3436

3537
func (opts *FindReactionsOptions) toConds() builder.Cond {
@@ -40,6 +42,13 @@ func (opts *FindReactionsOptions) toConds() builder.Cond {
4042
if opts.CommentID > 0 {
4143
cond = cond.And(builder.Eq{"reaction.comment_id": opts.CommentID})
4244
}
45+
if opts.UserID > 0 {
46+
cond = cond.And(builder.Eq{"reaction.user_id": opts.UserID})
47+
}
48+
if opts.Reaction != "" {
49+
cond = cond.And(builder.Eq{"reaction.type": opts.Reaction})
50+
}
51+
4352
return cond
4453
}
4554

@@ -57,9 +66,25 @@ func createReaction(e *xorm.Session, opts *ReactionOptions) (*Reaction, error) {
5766
UserID: opts.Doer.ID,
5867
IssueID: opts.Issue.ID,
5968
}
69+
findOpts := FindReactionsOptions{
70+
IssueID: opts.Issue.ID,
71+
CommentID: -1, // reaction to issue only
72+
Reaction: opts.Type,
73+
UserID: opts.Doer.ID,
74+
}
6075
if opts.Comment != nil {
6176
reaction.CommentID = opts.Comment.ID
77+
findOpts.CommentID = opts.Comment.ID
78+
}
79+
80+
existingR, err := findReactions(e, findOpts)
81+
if err != nil {
82+
return nil, err
83+
}
84+
if len(existingR) > 0 {
85+
return existingR[0], ErrReactionAlreadyExist{Reaction: opts.Type}
6286
}
87+
6388
if _, err := e.Insert(reaction); err != nil {
6489
return nil, err
6590
}
@@ -76,19 +101,19 @@ type ReactionOptions struct {
76101
}
77102

78103
// CreateReaction creates reaction for issue or comment.
79-
func CreateReaction(opts *ReactionOptions) (reaction *Reaction, err error) {
104+
func CreateReaction(opts *ReactionOptions) (*Reaction, error) {
80105
sess := x.NewSession()
81106
defer sess.Close()
82-
if err = sess.Begin(); err != nil {
107+
if err := sess.Begin(); err != nil {
83108
return nil, err
84109
}
85110

86-
reaction, err = createReaction(sess, opts)
111+
reaction, err := createReaction(sess, opts)
87112
if err != nil {
88-
return nil, err
113+
return reaction, err
89114
}
90115

91-
if err = sess.Commit(); err != nil {
116+
if err := sess.Commit(); err != nil {
92117
return nil, err
93118
}
94119
return reaction, nil

models/issue_reaction_test.go

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,10 @@ func TestIssueAddDuplicateReaction(t *testing.T) {
5050
Type: "heart",
5151
})
5252
assert.Error(t, err)
53-
assert.Nil(t, reaction)
53+
assert.Equal(t, ErrReactionAlreadyExist{Reaction: "heart"}, err)
5454

55-
AssertExistsAndLoadBean(t, &Reaction{Type: "heart", UserID: user1.ID, IssueID: issue1.ID})
55+
existingR := AssertExistsAndLoadBean(t, &Reaction{Type: "heart", UserID: user1.ID, IssueID: issue1.ID}).(*Reaction)
56+
assert.Equal(t, existingR.ID, reaction.ID)
5657
}
5758

5859
func TestIssueDeleteReaction(t *testing.T) {
@@ -129,7 +130,6 @@ func TestIssueCommentDeleteReaction(t *testing.T) {
129130
user2 := AssertExistsAndLoadBean(t, &User{ID: 2}).(*User)
130131
user3 := AssertExistsAndLoadBean(t, &User{ID: 3}).(*User)
131132
user4 := AssertExistsAndLoadBean(t, &User{ID: 4}).(*User)
132-
ghost := NewGhostUser()
133133

134134
issue1 := AssertExistsAndLoadBean(t, &Issue{ID: 1}).(*Issue)
135135

@@ -139,14 +139,13 @@ func TestIssueCommentDeleteReaction(t *testing.T) {
139139
addReaction(t, user2, issue1, comment1, "heart")
140140
addReaction(t, user3, issue1, comment1, "heart")
141141
addReaction(t, user4, issue1, comment1, "+1")
142-
addReaction(t, ghost, issue1, comment1, "heart")
143142

144143
err := comment1.LoadReactions()
145144
assert.NoError(t, err)
146-
assert.Len(t, comment1.Reactions, 5)
145+
assert.Len(t, comment1.Reactions, 4)
147146

148147
reactions := comment1.Reactions.GroupByType()
149-
assert.Len(t, reactions["heart"], 4)
148+
assert.Len(t, reactions["heart"], 3)
150149
assert.Len(t, reactions["+1"], 1)
151150
}
152151

@@ -160,7 +159,7 @@ func TestIssueCommentReactionCount(t *testing.T) {
160159
comment1 := AssertExistsAndLoadBean(t, &Comment{ID: 1}).(*Comment)
161160

162161
addReaction(t, user1, issue1, comment1, "heart")
163-
DeleteCommentReaction(user1, issue1, comment1, "heart")
162+
assert.NoError(t, DeleteCommentReaction(user1, issue1, comment1, "heart"))
164163

165164
AssertNotExistsBean(t, &Reaction{Type: "heart", UserID: user1.ID, IssueID: issue1.ID, CommentID: comment1.ID})
166165
}

0 commit comments

Comments
 (0)