summaryrefslogtreecommitdiffstats
path: root/models
diff options
context:
space:
mode:
author6543 <6543@obermui.de>2019-12-07 23:04:19 +0100
committertechknowlogick <techknowlogick@gitea.io>2019-12-07 17:04:19 -0500
commit37e10d4543c1e516e1a721d72c0054fefceb9499 (patch)
treef824b014a135d3bcf243d5bb3e87cab3de225c90 /models
parentee7df7ba8c5e6a4b32b0c4048d2b535d8df3cbe9 (diff)
downloadgitea-37e10d4543c1e516e1a721d72c0054fefceb9499.tar.gz
gitea-37e10d4543c1e516e1a721d72c0054fefceb9499.zip
[API] Add Reactions (#9220)
* reject reactions wich ar not allowed * dont duble check CreateReaction now throw ErrForbiddenIssueReaction * add /repos/{owner}/{repo}/issues/comments/{id}/reactions endpoint * add Find Functions * fix some swagger stuff + add issue reaction endpoints + GET ReactionList now use FindReactions... * explicite Issue Only Reaction for FindReactionsOptions with "-1" commentID * load issue; load user ... * return error again * swagger def canged after LINT * check if user has ben loaded * add Tests * better way of comparing results * add suggestion * use different issue for test (dont interfear with integration test) * test dont compare Location on timeCompare * TEST: add forbidden dubble add * add comments in code to explain * add settings.UI.ReactionsMap so if !setting.UI.ReactionsMap[opts.Type] works
Diffstat (limited to 'models')
-rw-r--r--models/error.go15
-rw-r--r--models/fixtures/reaction.yml40
-rw-r--r--models/issue_reaction.go39
-rw-r--r--models/issue_reaction_test.go24
4 files changed, 105 insertions, 13 deletions
diff --git a/models/error.go b/models/error.go
index 313c36354d..16be512139 100644
--- a/models/error.go
+++ b/models/error.go
@@ -1121,6 +1121,21 @@ func (err ErrNewIssueInsert) Error() string {
return err.OriginalError.Error()
}
+// ErrForbiddenIssueReaction is used when a forbidden reaction was try to created
+type ErrForbiddenIssueReaction struct {
+ Reaction string
+}
+
+// IsErrForbiddenIssueReaction checks if an error is a ErrForbiddenIssueReaction.
+func IsErrForbiddenIssueReaction(err error) bool {
+ _, ok := err.(ErrForbiddenIssueReaction)
+ return ok
+}
+
+func (err ErrForbiddenIssueReaction) Error() string {
+ return fmt.Sprintf("'%s' is not an allowed reaction", err.Reaction)
+}
+
// __________ .__ .__ __________ __
// \______ \__ __| | | |\______ \ ____ ________ __ ____ _______/ |_
// | ___/ | \ | | | | _// __ \/ ____/ | \_/ __ \ / ___/\ __\
diff --git a/models/fixtures/reaction.yml b/models/fixtures/reaction.yml
index ca780a73aa..4925935fe6 100644
--- a/models/fixtures/reaction.yml
+++ b/models/fixtures/reaction.yml
@@ -1 +1,39 @@
-[] # empty
+-
+ id: 1 #issue reaction
+ type: zzz # not allowed reaction (added before allowed reaction list has changed)
+ issue_id: 1
+ comment_id: 0
+ user_id: 2
+ created_unix: 1573248001
+
+-
+ id: 2 #issue reaction
+ type: zzz # not allowed reaction (added before allowed reaction list has changed)
+ issue_id: 1
+ comment_id: 0
+ user_id: 1
+ created_unix: 1573248002
+
+-
+ id: 3 #issue reaction
+ type: eyes # allowed reaction
+ issue_id: 1
+ comment_id: 0
+ user_id: 2
+ created_unix: 1573248003
+
+-
+ id: 4 #comment reaction
+ type: laugh # allowed reaction
+ issue_id: 1
+ comment_id: 2
+ user_id: 2
+ created_unix: 1573248004
+
+-
+ id: 5 #comment reaction
+ type: laugh # allowed reaction
+ issue_id: 1
+ comment_id: 2
+ user_id: 1
+ created_unix: 1573248005
diff --git a/models/issue_reaction.go b/models/issue_reaction.go
index 4596d32d06..b4f332a089 100644
--- a/models/issue_reaction.go
+++ b/models/issue_reaction.go
@@ -33,16 +33,38 @@ type FindReactionsOptions struct {
}
func (opts *FindReactionsOptions) toConds() builder.Cond {
+ //If Issue ID is set add to Query
var cond = builder.NewCond()
if opts.IssueID > 0 {
cond = cond.And(builder.Eq{"reaction.issue_id": opts.IssueID})
}
+ //If CommentID is > 0 add to Query
+ //If it is 0 Query ignore CommentID to select
+ //If it is -1 it explicit search of Issue Reactions where CommentID = 0
if opts.CommentID > 0 {
cond = cond.And(builder.Eq{"reaction.comment_id": opts.CommentID})
+ } else if opts.CommentID == -1 {
+ cond = cond.And(builder.Eq{"reaction.comment_id": 0})
}
+
return cond
}
+// FindCommentReactions returns a ReactionList of all reactions from an comment
+func FindCommentReactions(comment *Comment) (ReactionList, error) {
+ return findReactions(x, FindReactionsOptions{
+ IssueID: comment.IssueID,
+ CommentID: comment.ID})
+}
+
+// FindIssueReactions returns a ReactionList of all reactions from an issue
+func FindIssueReactions(issue *Issue) (ReactionList, error) {
+ return findReactions(x, FindReactionsOptions{
+ IssueID: issue.ID,
+ CommentID: -1,
+ })
+}
+
func findReactions(e Engine, opts FindReactionsOptions) ([]*Reaction, error) {
reactions := make([]*Reaction, 0, 10)
sess := e.Where(opts.toConds())
@@ -77,6 +99,10 @@ type ReactionOptions struct {
// CreateReaction creates reaction for issue or comment.
func CreateReaction(opts *ReactionOptions) (reaction *Reaction, err error) {
+ if !setting.UI.ReactionsMap[opts.Type] {
+ return nil, ErrForbiddenIssueReaction{opts.Type}
+ }
+
sess := x.NewSession()
defer sess.Close()
if err = sess.Begin(); err != nil {
@@ -160,6 +186,19 @@ func DeleteCommentReaction(doer *User, issue *Issue, comment *Comment, content s
})
}
+// LoadUser load user of reaction
+func (r *Reaction) LoadUser() (*User, error) {
+ if r.User != nil {
+ return r.User, nil
+ }
+ user, err := getUserByID(x, r.UserID)
+ if err != nil {
+ return nil, err
+ }
+ r.User = user
+ return user, nil
+}
+
// ReactionList represents list of reactions
type ReactionList []*Reaction
diff --git a/models/issue_reaction_test.go b/models/issue_reaction_test.go
index bbd8cf29fe..1189b389e9 100644
--- a/models/issue_reaction_test.go
+++ b/models/issue_reaction_test.go
@@ -81,22 +81,22 @@ func TestIssueReactionCount(t *testing.T) {
user4 := AssertExistsAndLoadBean(t, &User{ID: 4}).(*User)
ghost := NewGhostUser()
- issue1 := AssertExistsAndLoadBean(t, &Issue{ID: 1}).(*Issue)
+ issue := AssertExistsAndLoadBean(t, &Issue{ID: 2}).(*Issue)
- addReaction(t, user1, issue1, nil, "heart")
- addReaction(t, user2, issue1, nil, "heart")
- addReaction(t, user3, issue1, nil, "heart")
- addReaction(t, user3, issue1, nil, "+1")
- addReaction(t, user4, issue1, nil, "+1")
- addReaction(t, user4, issue1, nil, "heart")
- addReaction(t, ghost, issue1, nil, "-1")
-
- err := issue1.loadReactions(x)
+ addReaction(t, user1, issue, nil, "heart")
+ addReaction(t, user2, issue, nil, "heart")
+ addReaction(t, user3, issue, nil, "heart")
+ addReaction(t, user3, issue, nil, "+1")
+ addReaction(t, user4, issue, nil, "+1")
+ addReaction(t, user4, issue, nil, "heart")
+ addReaction(t, ghost, issue, nil, "-1")
+
+ err := issue.loadReactions(x)
assert.NoError(t, err)
- assert.Len(t, issue1.Reactions, 7)
+ assert.Len(t, issue.Reactions, 7)
- reactions := issue1.Reactions.GroupByType()
+ reactions := issue.Reactions.GroupByType()
assert.Len(t, reactions["heart"], 4)
assert.Equal(t, 2, reactions["heart"].GetMoreUserCount())
assert.Equal(t, user1.DisplayName()+", "+user2.DisplayName(), reactions["heart"].GetFirstUsers())