aboutsummaryrefslogtreecommitdiffstats
path: root/models
diff options
context:
space:
mode:
author6543 <6543@obermui.de>2019-12-31 09:21:21 +0100
committertechknowlogick <techknowlogick@gitea.io>2019-12-31 03:21:21 -0500
commit9600c27085df3f895b2128f1b77aa0ce0b57e7f2 (patch)
tree9dfbbf44126e7c39b77558ec943c8a2b9a717b10 /models
parent655aea13a5ad5dd51bcaafd1b96ecce2673f0312 (diff)
downloadgitea-9600c27085df3f895b2128f1b77aa0ce0b57e7f2.tar.gz
gitea-9600c27085df3f895b2128f1b77aa0ce0b57e7f2.zip
[API] Fix 9544 | return 200 when reaction already exist (#9550)
* add ErrReactionAlreadyExist * extend CreateReaction * reaction already exist = 200 * extend FindReactionsOptions * refactor swagger options/definitions * fix swagger-validate * Update models/error.go Co-Authored-By: zeripath <art27@cantab.net> * fix test PART1 * extend FindReactionsOptions with UserID option * catch error on test * fix test PART2 * format ... Co-authored-by: zeripath <art27@cantab.net> Co-authored-by: techknowlogick <matti@mdranta.net>
Diffstat (limited to 'models')
-rw-r--r--models/error.go15
-rw-r--r--models/issue_reaction.go34
-rw-r--r--models/issue_reaction_test.go13
3 files changed, 50 insertions, 12 deletions
diff --git a/models/error.go b/models/error.go
index 396d7594c8..f0d5699aad 100644
--- a/models/error.go
+++ b/models/error.go
@@ -1201,6 +1201,21 @@ func (err ErrForbiddenIssueReaction) Error() string {
return fmt.Sprintf("'%s' is not an allowed reaction", err.Reaction)
}
+// ErrReactionAlreadyExist is used when a existing reaction was try to created
+type ErrReactionAlreadyExist struct {
+ Reaction string
+}
+
+// IsErrReactionAlreadyExist checks if an error is a ErrReactionAlreadyExist.
+func IsErrReactionAlreadyExist(err error) bool {
+ _, ok := err.(ErrReactionAlreadyExist)
+ return ok
+}
+
+func (err ErrReactionAlreadyExist) Error() string {
+ return fmt.Sprintf("reaction '%s' already exists", err.Reaction)
+}
+
// __________ .__ .__ __________ __
// \______ \__ __| | | |\______ \ ____ ________ __ ____ _______/ |_
// | ___/ | \ | | | | _// __ \/ ____/ | \_/ __ \ / ___/\ __\
diff --git a/models/issue_reaction.go b/models/issue_reaction.go
index 6896eeeafc..d421ab44e9 100644
--- a/models/issue_reaction.go
+++ b/models/issue_reaction.go
@@ -30,6 +30,8 @@ type Reaction struct {
type FindReactionsOptions struct {
IssueID int64
CommentID int64
+ UserID int64
+ Reaction string
}
func (opts *FindReactionsOptions) toConds() builder.Cond {
@@ -46,6 +48,12 @@ func (opts *FindReactionsOptions) toConds() builder.Cond {
} else if opts.CommentID == -1 {
cond = cond.And(builder.Eq{"reaction.comment_id": 0})
}
+ if opts.UserID > 0 {
+ cond = cond.And(builder.Eq{"reaction.user_id": opts.UserID})
+ }
+ if opts.Reaction != "" {
+ cond = cond.And(builder.Eq{"reaction.type": opts.Reaction})
+ }
return cond
}
@@ -80,9 +88,25 @@ func createReaction(e *xorm.Session, opts *ReactionOptions) (*Reaction, error) {
UserID: opts.Doer.ID,
IssueID: opts.Issue.ID,
}
+ findOpts := FindReactionsOptions{
+ IssueID: opts.Issue.ID,
+ CommentID: -1, // reaction to issue only
+ Reaction: opts.Type,
+ UserID: opts.Doer.ID,
+ }
if opts.Comment != nil {
reaction.CommentID = opts.Comment.ID
+ findOpts.CommentID = opts.Comment.ID
}
+
+ existingR, err := findReactions(e, findOpts)
+ if err != nil {
+ return nil, err
+ }
+ if len(existingR) > 0 {
+ return existingR[0], ErrReactionAlreadyExist{Reaction: opts.Type}
+ }
+
if _, err := e.Insert(reaction); err != nil {
return nil, err
}
@@ -99,23 +123,23 @@ type ReactionOptions struct {
}
// CreateReaction creates reaction for issue or comment.
-func CreateReaction(opts *ReactionOptions) (reaction *Reaction, err error) {
+func CreateReaction(opts *ReactionOptions) (*Reaction, error) {
if !setting.UI.ReactionsMap[opts.Type] {
return nil, ErrForbiddenIssueReaction{opts.Type}
}
sess := x.NewSession()
defer sess.Close()
- if err = sess.Begin(); err != nil {
+ if err := sess.Begin(); err != nil {
return nil, err
}
- reaction, err = createReaction(sess, opts)
+ reaction, err := createReaction(sess, opts)
if err != nil {
- return nil, err
+ return reaction, err
}
- if err = sess.Commit(); err != nil {
+ if err := sess.Commit(); err != nil {
return nil, err
}
return reaction, nil
diff --git a/models/issue_reaction_test.go b/models/issue_reaction_test.go
index 1189b389e9..723a6be536 100644
--- a/models/issue_reaction_test.go
+++ b/models/issue_reaction_test.go
@@ -50,9 +50,10 @@ func TestIssueAddDuplicateReaction(t *testing.T) {
Type: "heart",
})
assert.Error(t, err)
- assert.Nil(t, reaction)
+ assert.Equal(t, ErrReactionAlreadyExist{Reaction: "heart"}, err)
- AssertExistsAndLoadBean(t, &Reaction{Type: "heart", UserID: user1.ID, IssueID: issue1.ID})
+ existingR := AssertExistsAndLoadBean(t, &Reaction{Type: "heart", UserID: user1.ID, IssueID: issue1.ID}).(*Reaction)
+ assert.Equal(t, existingR.ID, reaction.ID)
}
func TestIssueDeleteReaction(t *testing.T) {
@@ -129,7 +130,6 @@ func TestIssueCommentDeleteReaction(t *testing.T) {
user2 := AssertExistsAndLoadBean(t, &User{ID: 2}).(*User)
user3 := AssertExistsAndLoadBean(t, &User{ID: 3}).(*User)
user4 := AssertExistsAndLoadBean(t, &User{ID: 4}).(*User)
- ghost := NewGhostUser()
issue1 := AssertExistsAndLoadBean(t, &Issue{ID: 1}).(*Issue)
@@ -139,14 +139,13 @@ func TestIssueCommentDeleteReaction(t *testing.T) {
addReaction(t, user2, issue1, comment1, "heart")
addReaction(t, user3, issue1, comment1, "heart")
addReaction(t, user4, issue1, comment1, "+1")
- addReaction(t, ghost, issue1, comment1, "heart")
err := comment1.LoadReactions()
assert.NoError(t, err)
- assert.Len(t, comment1.Reactions, 5)
+ assert.Len(t, comment1.Reactions, 4)
reactions := comment1.Reactions.GroupByType()
- assert.Len(t, reactions["heart"], 4)
+ assert.Len(t, reactions["heart"], 3)
assert.Len(t, reactions["+1"], 1)
}
@@ -160,7 +159,7 @@ func TestIssueCommentReactionCount(t *testing.T) {
comment1 := AssertExistsAndLoadBean(t, &Comment{ID: 1}).(*Comment)
addReaction(t, user1, issue1, comment1, "heart")
- DeleteCommentReaction(user1, issue1, comment1, "heart")
+ assert.NoError(t, DeleteCommentReaction(user1, issue1, comment1, "heart"))
AssertNotExistsBean(t, &Reaction{Type: "heart", UserID: user1.ID, IssueID: issue1.ID, CommentID: comment1.ID})
}