diff options
author | 6543 <6543@obermui.de> | 2019-12-07 23:04:19 +0100 |
---|---|---|
committer | techknowlogick <techknowlogick@gitea.io> | 2019-12-07 17:04:19 -0500 |
commit | 37e10d4543c1e516e1a721d72c0054fefceb9499 (patch) | |
tree | f824b014a135d3bcf243d5bb3e87cab3de225c90 /models | |
parent | ee7df7ba8c5e6a4b32b0c4048d2b535d8df3cbe9 (diff) | |
download | gitea-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.go | 15 | ||||
-rw-r--r-- | models/fixtures/reaction.yml | 40 | ||||
-rw-r--r-- | models/issue_reaction.go | 39 | ||||
-rw-r--r-- | models/issue_reaction_test.go | 24 |
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()) |