Changes
18 changed files (+279/-273)
-
-
@@ -10,6 +10,7 @@ import ("code.gitea.io/gitea/models/db" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/container" ) // ActionList defines a list of actions
-
@@ -22,7 +23,7 @@ func (actions ActionList) getUserIDs() []int64 {userIDs[action.ActUserID] = struct{}{} } } return keysInt64(userIDs) return container.KeysInt64(userIDs) } func (actions ActionList) loadUsers(e db.Engine) (map[int64]*user_model.User, error) {
-
@@ -52,7 +53,7 @@ func (actions ActionList) getRepoIDs() []int64 {repoIDs[action.RepoID] = struct{}{} } } return keysInt64(repoIDs) return container.KeysInt64(repoIDs) } func (actions ActionList) loadRepositories(e db.Engine) error {
-
-
-
@@ -765,36 +765,6 @@ func (err ErrPullWasClosed) Error() string {return fmt.Sprintf("Pull request [%d] %d was already closed", err.ID, err.Index) } // 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) } // 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) } // __________ .__ .__ __________ __ // \______ \__ __| | | |\______ \ ____ ________ __ ____ _______/ |_ // | ___/ | \ | | | | _// __ \/ ____/ | \_/ __ \ / ___/\ __\
-
-
-
@@ -6,17 +6,8 @@ package modelsimport ( repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" ) func keysInt64(m map[int64]struct{}) []int64 { keys := make([]int64, 0, len(m)) for k := range m { keys = append(keys, k) } return keys } func valuesRepository(m map[int64]*repo_model.Repository) []*repo_model.Repository { values := make([]*repo_model.Repository, 0, len(m)) for _, v := range m {
-
@@ -24,11 +15,3 @@ func valuesRepository(m map[int64]*repo_model.Repository) []*repo_model.Reposito} return values } func valuesUser(m map[int64]*user_model.User) []*user_model.User { values := make([]*user_model.User, 0, len(m)) for _, v := range m { values = append(values, v) } return values }
-
-
-
@@ -72,7 +72,7 @@ type Issue struct {Attachments []*repo_model.Attachment `xorm:"-"` Comments []*Comment `xorm:"-"` Reactions ReactionList `xorm:"-"` Reactions issues.ReactionList `xorm:"-"` TotalTrackedTime int64 `xorm:"-"` Assignees []*user_model.User `xorm:"-"` ForeignReference *foreignreference.ForeignReference `xorm:"-"`
-
@@ -244,8 +244,7 @@ func (issue *Issue) loadReactions(ctx context.Context) (err error) {if issue.Reactions != nil { return nil } e := db.GetEngine(ctx) reactions, _, err := findReactions(e, FindReactionsOptions{ reactions, _, err := issues.FindReactions(ctx, issues.FindReactionsOptions{ IssueID: issue.ID, }) if err != nil {
-
@@ -255,7 +254,7 @@ func (issue *Issue) loadReactions(ctx context.Context) (err error) {return err } // Load reaction user data if _, err := ReactionList(reactions).loadUsers(e, issue.Repo); err != nil { if _, err := issues.ReactionList(reactions).LoadUsers(ctx, issue.Repo); err != nil { return err }
-
@@ -2111,7 +2110,7 @@ func deleteIssue(ctx context.Context, issue *Issue) error {&IssueAssignees{}, &IssueUser{}, &Notification{}, &Reaction{}, &issues.Reaction{}, &IssueWatch{}, &Stopwatch{}, &TrackedTime{},
-
@@ -2429,7 +2428,7 @@ func deleteIssuesByRepoID(sess db.Engine, repoID int64) (attachmentPaths []strin} if _, err = sess.In("issue_id", deleteCond). Delete(&Reaction{}); err != nil { Delete(&issues.Reaction{}); err != nil { return }
-
-
-
@@ -244,7 +244,7 @@ type Comment struct {CommitSHA string `xorm:"VARCHAR(40)"` Attachments []*repo_model.Attachment `xorm:"-"` Reactions ReactionList `xorm:"-"` Reactions issues.ReactionList `xorm:"-"` // For view issue page. ShowRole RoleDescriptor `xorm:"-"`
-
@@ -631,11 +631,11 @@ func (c *Comment) LoadTime() error {return err } func (c *Comment) loadReactions(e db.Engine, repo *repo_model.Repository) (err error) { func (c *Comment) loadReactions(ctx context.Context, repo *repo_model.Repository) (err error) { if c.Reactions != nil { return nil } c.Reactions, _, err = findReactions(e, FindReactionsOptions{ c.Reactions, _, err = issues.FindReactions(ctx, issues.FindReactionsOptions{ IssueID: c.IssueID, CommentID: c.ID, })
-
@@ -643,7 +643,7 @@ func (c *Comment) loadReactions(e db.Engine, repo *repo_model.Repository) (err ereturn err } // Load reaction user data if _, err := c.Reactions.loadUsers(e, repo); err != nil { if _, err := c.Reactions.LoadUsers(ctx, repo); err != nil { return err } return nil
-
@@ -651,7 +651,7 @@ func (c *Comment) loadReactions(e db.Engine, repo *repo_model.Repository) (err e// LoadReactions loads comment reactions func (c *Comment) LoadReactions(repo *repo_model.Repository) error { return c.loadReactions(db.GetEngine(db.DefaultContext), repo) return c.loadReactions(db.DefaultContext, repo) } func (c *Comment) loadReview(e db.Engine) (err error) {
-
@@ -1146,14 +1146,15 @@ func DeleteComment(comment *Comment) error {} defer committer.Close() if err := deleteComment(db.GetEngine(ctx), comment); err != nil { if err := deleteComment(ctx, comment); err != nil { return err } return committer.Commit() } func deleteComment(e db.Engine, comment *Comment) error { func deleteComment(ctx context.Context, comment *Comment) error { e := db.GetEngine(ctx) if _, err := e.ID(comment.ID).NoAutoCondition().Delete(comment); err != nil { return err }
-
@@ -1177,7 +1178,7 @@ func deleteComment(e db.Engine, comment *Comment) error {return err } return deleteReaction(e, &ReactionOptions{Comment: comment}) return issues.DeleteReaction(ctx, &issues.ReactionOptions{CommentID: comment.ID}) } // CodeComments represents comments on code by using this structure: FILENAME -> LINE (+ == proposed; - == previous) -> COMMENTS
-
-
-
@@ -10,6 +10,7 @@ import ("code.gitea.io/gitea/models/db" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/container" ) // CommentList defines a list of comments
-
@@ -22,7 +23,7 @@ func (comments CommentList) getPosterIDs() []int64 {posterIDs[comment.PosterID] = struct{}{} } } return keysInt64(posterIDs) return container.KeysInt64(posterIDs) } func (comments CommentList) loadPosters(e db.Engine) error {
-
@@ -75,7 +76,7 @@ func (comments CommentList) getLabelIDs() []int64 {ids[comment.LabelID] = struct{}{} } } return keysInt64(ids) return container.KeysInt64(ids) } func (comments CommentList) loadLabels(e db.Engine) error {
-
@@ -125,7 +126,7 @@ func (comments CommentList) getMilestoneIDs() []int64 {ids[comment.MilestoneID] = struct{}{} } } return keysInt64(ids) return container.KeysInt64(ids) } func (comments CommentList) loadMilestones(e db.Engine) error {
-
@@ -168,7 +169,7 @@ func (comments CommentList) getOldMilestoneIDs() []int64 {ids[comment.OldMilestoneID] = struct{}{} } } return keysInt64(ids) return container.KeysInt64(ids) } func (comments CommentList) loadOldMilestones(e db.Engine) error {
-
@@ -211,7 +212,7 @@ func (comments CommentList) getAssigneeIDs() []int64 {ids[comment.AssigneeID] = struct{}{} } } return keysInt64(ids) return container.KeysInt64(ids) } func (comments CommentList) loadAssignees(e db.Engine) error {
-
@@ -267,7 +268,7 @@ func (comments CommentList) getIssueIDs() []int64 {ids[comment.IssueID] = struct{}{} } } return keysInt64(ids) return container.KeysInt64(ids) } // Issues returns all the issues of comments
-
@@ -342,7 +343,7 @@ func (comments CommentList) getDependentIssueIDs() []int64 {ids[comment.DependentIssueID] = struct{}{} } } return keysInt64(ids) return container.KeysInt64(ids) } func (comments CommentList) loadDependentIssues(ctx context.Context) error {
-
@@ -444,7 +445,7 @@ func (comments CommentList) getReviewIDs() []int64 {ids[comment.ReviewID] = struct{}{} } } return keysInt64(ids) return container.KeysInt64(ids) } func (comments CommentList) loadReviews(e db.Engine) error {
-
-
-
@@ -10,6 +10,7 @@ import ("code.gitea.io/gitea/models/db" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/container" "xorm.io/builder" )
-
@@ -32,7 +33,7 @@ func (issues IssueList) getRepoIDs() []int64 {repoIDs[issue.RepoID] = struct{}{} } } return keysInt64(repoIDs) return container.KeysInt64(repoIDs) } func (issues IssueList) loadRepositories(e db.Engine) ([]*repo_model.Repository, error) {
-
@@ -83,7 +84,7 @@ func (issues IssueList) getPosterIDs() []int64 {posterIDs[issue.PosterID] = struct{}{} } } return keysInt64(posterIDs) return container.KeysInt64(posterIDs) } func (issues IssueList) loadPosters(e db.Engine) error {
-
@@ -189,7 +190,7 @@ func (issues IssueList) getMilestoneIDs() []int64 {ids[issue.MilestoneID] = struct{}{} } } return keysInt64(ids) return container.KeysInt64(ids) } func (issues IssueList) loadMilestones(e db.Engine) error {
-
-
-
@@ -9,8 +9,18 @@ import ("testing" "code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/modules/setting" ) func init() { setting.SetCustomPathAndConf("", "", "") setting.LoadForTest() } func TestMain(m *testing.M) { unittest.MainTest(m, filepath.Join("..", ".."), "") unittest.MainTest(m, filepath.Join("..", ".."), "reaction.yml", "user.yml", "repository.yml", ) }
-
-
-
@@ -2,21 +2,53 @@// Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. package models package issues import ( "bytes" "context" "fmt" "code.gitea.io/gitea/models/db" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/container" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/timeutil" "xorm.io/builder" ) // 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) } // 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) } // Reaction represents a reactions on issues and comments. type Reaction struct { ID int64 `xorm:"pk autoincr"`
-
@@ -30,6 +62,36 @@ type Reaction struct {CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"` } // LoadUser load user of reaction func (r *Reaction) LoadUser() (*user_model.User, error) { if r.User != nil { return r.User, nil } user, err := user_model.GetUserByIDCtx(db.DefaultContext, r.UserID) if err != nil { return nil, err } r.User = user return user, nil } // RemapExternalUser ExternalUserRemappable interface func (r *Reaction) RemapExternalUser(externalName string, externalID, userID int64) error { r.OriginalAuthor = externalName r.OriginalAuthorID = externalID r.UserID = userID return nil } // GetUserID ExternalUserRemappable interface func (r *Reaction) GetUserID() int64 { return r.UserID } // GetExternalName ExternalUserRemappable interface func (r *Reaction) GetExternalName() string { return r.OriginalAuthor } // GetExternalID ExternalUserRemappable interface func (r *Reaction) GetExternalID() int64 { return r.OriginalAuthorID } func init() { db.RegisterModel(new(Reaction)) }
-
@@ -71,24 +133,25 @@ func (opts *FindReactionsOptions) toConds() builder.Cond {} // FindCommentReactions returns a ReactionList of all reactions from an comment func FindCommentReactions(comment *Comment) (ReactionList, int64, error) { return findReactions(db.GetEngine(db.DefaultContext), FindReactionsOptions{ IssueID: comment.IssueID, CommentID: comment.ID, func FindCommentReactions(issueID, commentID int64) (ReactionList, int64, error) { return FindReactions(db.DefaultContext, FindReactionsOptions{ IssueID: issueID, CommentID: commentID, }) } // FindIssueReactions returns a ReactionList of all reactions from an issue func FindIssueReactions(issue *Issue, listOptions db.ListOptions) (ReactionList, int64, error) { return findReactions(db.GetEngine(db.DefaultContext), FindReactionsOptions{ func FindIssueReactions(issueID int64, listOptions db.ListOptions) (ReactionList, int64, error) { return FindReactions(db.DefaultContext, FindReactionsOptions{ ListOptions: listOptions, IssueID: issue.ID, IssueID: issueID, CommentID: -1, }) } func findReactions(e db.Engine, opts FindReactionsOptions) ([]*Reaction, int64, error) { sess := e. // FindReactions returns a ReactionList of all reactions from an issue or a comment func FindReactions(ctx context.Context, opts FindReactionsOptions) (ReactionList, int64, error) { sess := db.GetEngine(ctx). Where(opts.toConds()). In("reaction.`type`", setting.UI.Reactions). Asc("reaction.issue_id", "reaction.comment_id", "reaction.created_unix", "reaction.id")
-
@@ -105,24 +168,21 @@ func findReactions(e db.Engine, opts FindReactionsOptions) ([]*Reaction, int64,return reactions, count, err } func createReaction(e db.Engine, opts *ReactionOptions) (*Reaction, error) { func createReaction(ctx context.Context, opts *ReactionOptions) (*Reaction, error) { reaction := &Reaction{ Type: opts.Type, UserID: opts.Doer.ID, IssueID: opts.Issue.ID, Type: opts.Type, UserID: opts.DoerID, IssueID: opts.IssueID, CommentID: opts.CommentID, } findOpts := FindReactionsOptions{ IssueID: opts.Issue.ID, CommentID: -1, // reaction to issue only IssueID: opts.IssueID, CommentID: opts.CommentID, Reaction: opts.Type, UserID: opts.Doer.ID, } if opts.Comment != nil { reaction.CommentID = opts.Comment.ID findOpts.CommentID = opts.Comment.ID UserID: opts.DoerID, } existingR, _, err := findReactions(e, findOpts) existingR, _, err := FindReactions(ctx, findOpts) if err != nil { return nil, err }
-
@@ -130,7 +190,7 @@ func createReaction(e db.Engine, opts *ReactionOptions) (*Reaction, error) {return existingR[0], ErrReactionAlreadyExist{Reaction: opts.Type} } if _, err := e.Insert(reaction); err != nil { if err := db.Insert(ctx, reaction); err != nil { return nil, err }
-
@@ -139,10 +199,10 @@ func createReaction(e db.Engine, opts *ReactionOptions) (*Reaction, error) {// ReactionOptions defines options for creating or deleting reactions type ReactionOptions struct { Type string Doer *user_model.User Issue *Issue Comment *Comment Type string DoerID int64 IssueID int64 CommentID int64 } // CreateReaction creates reaction for issue or comment.
-
@@ -157,7 +217,7 @@ func CreateReaction(opts *ReactionOptions) (*Reaction, error) {} defer committer.Close() reaction, err := createReaction(db.GetEngine(ctx), opts) reaction, err := createReaction(ctx, opts) if err != nil { return reaction, err }
-
@@ -169,88 +229,56 @@ func CreateReaction(opts *ReactionOptions) (*Reaction, error) {} // CreateIssueReaction creates a reaction on issue. func CreateIssueReaction(doer *user_model.User, issue *Issue, content string) (*Reaction, error) { func CreateIssueReaction(doerID, issueID int64, content string) (*Reaction, error) { return CreateReaction(&ReactionOptions{ Type: content, Doer: doer, Issue: issue, Type: content, DoerID: doerID, IssueID: issueID, }) } // CreateCommentReaction creates a reaction on comment. func CreateCommentReaction(doer *user_model.User, issue *Issue, comment *Comment, content string) (*Reaction, error) { func CreateCommentReaction(doerID, issueID, commentID int64, content string) (*Reaction, error) { return CreateReaction(&ReactionOptions{ Type: content, Doer: doer, Issue: issue, Comment: comment, Type: content, DoerID: doerID, IssueID: issueID, CommentID: commentID, }) } func deleteReaction(e db.Engine, opts *ReactionOptions) error { reaction := &Reaction{ Type: opts.Type, } if opts.Doer != nil { reaction.UserID = opts.Doer.ID } if opts.Issue != nil { reaction.IssueID = opts.Issue.ID } if opts.Comment != nil { reaction.CommentID = opts.Comment.ID } _, err := e.Where("original_author_id = 0").Delete(reaction) return err } // DeleteReaction deletes reaction for issue or comment. func DeleteReaction(opts *ReactionOptions) error { ctx, committer, err := db.TxContext() if err != nil { return err } defer committer.Close() if err := deleteReaction(db.GetEngine(ctx), opts); err != nil { return err func DeleteReaction(ctx context.Context, opts *ReactionOptions) error { reaction := &Reaction{ Type: opts.Type, UserID: opts.DoerID, IssueID: opts.IssueID, CommentID: opts.CommentID, } return committer.Commit() _, err := db.GetEngine(ctx).Where("original_author_id = 0").Delete(reaction) return err } // DeleteIssueReaction deletes a reaction on issue. func DeleteIssueReaction(doer *user_model.User, issue *Issue, content string) error { return DeleteReaction(&ReactionOptions{ Type: content, Doer: doer, Issue: issue, func DeleteIssueReaction(doerID, issueID int64, content string) error { return DeleteReaction(db.DefaultContext, &ReactionOptions{ Type: content, DoerID: doerID, IssueID: issueID, }) } // DeleteCommentReaction deletes a reaction on comment. func DeleteCommentReaction(doer *user_model.User, issue *Issue, comment *Comment, content string) error { return DeleteReaction(&ReactionOptions{ Type: content, Doer: doer, Issue: issue, Comment: comment, func DeleteCommentReaction(doerID, issueID, commentID int64, content string) error { return DeleteReaction(db.DefaultContext, &ReactionOptions{ Type: content, DoerID: doerID, IssueID: issueID, CommentID: commentID, }) } // LoadUser load user of reaction func (r *Reaction) LoadUser() (*user_model.User, error) { if r.User != nil { return r.User, nil } user, err := user_model.GetUserByIDCtx(db.DefaultContext, r.UserID) if err != nil { return nil, err } r.User = user return user, nil } // ReactionList represents list of reactions type ReactionList []*Reaction
-
@@ -286,17 +314,26 @@ func (list ReactionList) getUserIDs() []int64 {userIDs[reaction.UserID] = struct{}{} } } return keysInt64(userIDs) return container.KeysInt64(userIDs) } func valuesUser(m map[int64]*user_model.User) []*user_model.User { values := make([]*user_model.User, 0, len(m)) for _, v := range m { values = append(values, v) } return values } func (list ReactionList) loadUsers(e db.Engine, repo *repo_model.Repository) ([]*user_model.User, error) { // LoadUsers loads reactions' all users func (list ReactionList) LoadUsers(ctx context.Context, repo *repo_model.Repository) ([]*user_model.User, error) { if len(list) == 0 { return nil, nil } userIDs := list.getUserIDs() userMaps := make(map[int64]*user_model.User, len(userIDs)) err := e. err := db.GetEngine(ctx). In("id", userIDs). Find(&userMaps) if err != nil {
-
@@ -315,11 +352,6 @@ func (list ReactionList) loadUsers(e db.Engine, repo *repo_model.Repository) ([]return valuesUser(userMaps), nil } // LoadUsers loads reactions' all users func (list ReactionList) LoadUsers(repo *repo_model.Repository) ([]*user_model.User, error) { return list.loadUsers(db.GetEngine(db.DefaultContext), repo) } // GetFirstUsers returns first reacted user display names separated by comma func (list ReactionList) GetFirstUsers() string { var buffer bytes.Buffer
-
@@ -343,20 +375,3 @@ func (list ReactionList) GetMoreUserCount() int {} return len(list) - setting.UI.ReactionMaxUserNum } // RemapExternalUser ExternalUserRemappable interface func (r *Reaction) RemapExternalUser(externalName string, externalID, userID int64) error { r.OriginalAuthor = externalName r.OriginalAuthorID = externalID r.UserID = userID return nil } // GetUserID ExternalUserRemappable interface func (r *Reaction) GetUserID() int64 { return r.UserID } // GetExternalName ExternalUserRemappable interface func (r *Reaction) GetExternalName() string { return r.OriginalAuthor } // GetExternalID ExternalUserRemappable interface func (r *Reaction) GetExternalID() int64 { return r.OriginalAuthorID }
-
-
-
@@ -1,7 +1,8 @@// Copyright 2017 The Gitea Authors. All rights reserved. // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. package models package issues import ( "testing"
-
@@ -15,13 +16,13 @@ import ("github.com/stretchr/testify/assert" ) func addReaction(t *testing.T, doer *user_model.User, issue *Issue, comment *Comment, content string) { func addReaction(t *testing.T, doerID, issueID, commentID int64, content string) { var reaction *Reaction var err error if comment == nil { reaction, err = CreateIssueReaction(doer, issue, content) if commentID == 0 { reaction, err = CreateIssueReaction(doerID, issueID, content) } else { reaction, err = CreateCommentReaction(doer, issue, comment, content) reaction, err = CreateCommentReaction(doerID, issueID, commentID, content) } assert.NoError(t, err) assert.NotNil(t, reaction)
-
@@ -32,11 +33,11 @@ func TestIssueAddReaction(t *testing.T) {user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User) issue1 := unittest.AssertExistsAndLoadBean(t, &Issue{ID: 1}).(*Issue) var issue1ID int64 = 1 addReaction(t, user1, issue1, nil, "heart") addReaction(t, user1.ID, issue1ID, 0, "heart") unittest.AssertExistsAndLoadBean(t, &Reaction{Type: "heart", UserID: user1.ID, IssueID: issue1.ID}) unittest.AssertExistsAndLoadBean(t, &Reaction{Type: "heart", UserID: user1.ID, IssueID: issue1ID}) } func TestIssueAddDuplicateReaction(t *testing.T) {
-
@@ -44,19 +45,19 @@ func TestIssueAddDuplicateReaction(t *testing.T) {user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User) issue1 := unittest.AssertExistsAndLoadBean(t, &Issue{ID: 1}).(*Issue) var issue1ID int64 = 1 addReaction(t, user1, issue1, nil, "heart") addReaction(t, user1.ID, issue1ID, 0, "heart") reaction, err := CreateReaction(&ReactionOptions{ Doer: user1, Issue: issue1, Type: "heart", DoerID: user1.ID, IssueID: issue1ID, Type: "heart", }) assert.Error(t, err) assert.Equal(t, ErrReactionAlreadyExist{Reaction: "heart"}, err) existingR := unittest.AssertExistsAndLoadBean(t, &Reaction{Type: "heart", UserID: user1.ID, IssueID: issue1.ID}).(*Reaction) existingR := unittest.AssertExistsAndLoadBean(t, &Reaction{Type: "heart", UserID: user1.ID, IssueID: issue1ID}).(*Reaction) assert.Equal(t, existingR.ID, reaction.ID) }
-
@@ -65,14 +66,14 @@ func TestIssueDeleteReaction(t *testing.T) {user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User) issue1 := unittest.AssertExistsAndLoadBean(t, &Issue{ID: 1}).(*Issue) var issue1ID int64 = 1 addReaction(t, user1, issue1, nil, "heart") addReaction(t, user1.ID, issue1ID, 0, "heart") err := DeleteIssueReaction(user1, issue1, "heart") err := DeleteIssueReaction(user1.ID, issue1ID, "heart") assert.NoError(t, err) unittest.AssertNotExistsBean(t, &Reaction{Type: "heart", UserID: user1.ID, IssueID: issue1.ID}) unittest.AssertNotExistsBean(t, &Reaction{Type: "heart", UserID: user1.ID, IssueID: issue1ID}) } func TestIssueReactionCount(t *testing.T) {
-
@@ -86,22 +87,26 @@ func TestIssueReactionCount(t *testing.T) {user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}).(*user_model.User) ghost := user_model.NewGhostUser() issue := unittest.AssertExistsAndLoadBean(t, &Issue{ID: 2}).(*Issue) var issueID int64 = 2 repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) 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") addReaction(t, user1.ID, issueID, 0, "heart") addReaction(t, user2.ID, issueID, 0, "heart") addReaction(t, user3.ID, issueID, 0, "heart") addReaction(t, user3.ID, issueID, 0, "+1") addReaction(t, user4.ID, issueID, 0, "+1") addReaction(t, user4.ID, issueID, 0, "heart") addReaction(t, ghost.ID, issueID, 0, "-1") err := issue.loadReactions(db.DefaultContext) reactionsList, _, err := FindReactions(db.DefaultContext, FindReactionsOptions{ IssueID: issueID, }) assert.NoError(t, err) assert.Len(t, reactionsList, 7) _, err = reactionsList.LoadUsers(db.DefaultContext, repo) assert.NoError(t, err) assert.Len(t, issue.Reactions, 7) reactions := issue.Reactions.GroupByType() reactions := reactionsList.GroupByType() assert.Len(t, reactions["heart"], 4) assert.Equal(t, 2, reactions["heart"].GetMoreUserCount()) assert.Equal(t, user1.DisplayName()+", "+user2.DisplayName(), reactions["heart"].GetFirstUsers())
-
@@ -118,13 +123,12 @@ func TestIssueCommentAddReaction(t *testing.T) {user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User) issue1 := unittest.AssertExistsAndLoadBean(t, &Issue{ID: 1}).(*Issue) var issue1ID int64 = 1 var comment1ID int64 = 1 comment1 := unittest.AssertExistsAndLoadBean(t, &Comment{ID: 1}).(*Comment) addReaction(t, user1.ID, issue1ID, comment1ID, "heart") addReaction(t, user1, issue1, comment1, "heart") unittest.AssertExistsAndLoadBean(t, &Reaction{Type: "heart", UserID: user1.ID, IssueID: issue1.ID, CommentID: comment1.ID}) unittest.AssertExistsAndLoadBean(t, &Reaction{Type: "heart", UserID: user1.ID, IssueID: issue1ID, CommentID: comment1ID}) } func TestIssueCommentDeleteReaction(t *testing.T) {
-
@@ -135,21 +139,22 @@ func TestIssueCommentDeleteReaction(t *testing.T) {user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}).(*user_model.User) user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}).(*user_model.User) issue1 := unittest.AssertExistsAndLoadBean(t, &Issue{ID: 1}).(*Issue) repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue1.RepoID}).(*repo_model.Repository) comment1 := unittest.AssertExistsAndLoadBean(t, &Comment{ID: 1}).(*Comment) var issue1ID int64 = 1 var comment1ID int64 = 1 addReaction(t, user1, issue1, comment1, "heart") addReaction(t, user2, issue1, comment1, "heart") addReaction(t, user3, issue1, comment1, "heart") addReaction(t, user4, issue1, comment1, "+1") addReaction(t, user1.ID, issue1ID, comment1ID, "heart") addReaction(t, user2.ID, issue1ID, comment1ID, "heart") addReaction(t, user3.ID, issue1ID, comment1ID, "heart") addReaction(t, user4.ID, issue1ID, comment1ID, "+1") err := comment1.LoadReactions(repo1) reactionsList, _, err := FindReactions(db.DefaultContext, FindReactionsOptions{ IssueID: issue1ID, CommentID: comment1ID, }) assert.NoError(t, err) assert.Len(t, comment1.Reactions, 4) assert.Len(t, reactionsList, 4) reactions := comment1.Reactions.GroupByType() reactions := reactionsList.GroupByType() assert.Len(t, reactions["heart"], 3) assert.Len(t, reactions["+1"], 1) }
-
@@ -159,12 +164,11 @@ func TestIssueCommentReactionCount(t *testing.T) {user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User) issue1 := unittest.AssertExistsAndLoadBean(t, &Issue{ID: 1}).(*Issue) comment1 := unittest.AssertExistsAndLoadBean(t, &Comment{ID: 1}).(*Comment) var issue1ID int64 = 1 var comment1ID int64 = 1 addReaction(t, user1, issue1, comment1, "heart") assert.NoError(t, DeleteCommentReaction(user1, issue1, comment1, "heart")) addReaction(t, user1.ID, issue1ID, comment1ID, "heart") assert.NoError(t, DeleteCommentReaction(user1.ID, issue1ID, comment1ID, "heart")) unittest.AssertNotExistsBean(t, &Reaction{Type: "heart", UserID: user1.ID, IssueID: issue1.ID, CommentID: comment1.ID}) unittest.AssertNotExistsBean(t, &Reaction{Type: "heart", UserID: user1.ID, IssueID: issue1ID, CommentID: comment1ID}) }
-
-
-
@@ -9,6 +9,7 @@ import ("testing" "code.gitea.io/gitea/models/foreignreference" issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user"
-
@@ -42,7 +43,7 @@ func assertCreateIssues(t *testing.T, isPull bool) {label := unittest.AssertExistsAndLoadBean(t, &Label{ID: 1}).(*Label) milestone := unittest.AssertExistsAndLoadBean(t, &Milestone{ID: 1}).(*Milestone) assert.EqualValues(t, milestone.ID, 1) reaction := &Reaction{ reaction := &issues_model.Reaction{ Type: "heart", UserID: owner.ID, }
-
@@ -60,7 +61,7 @@ func assertCreateIssues(t *testing.T, isPull bool) {Poster: owner, IsClosed: true, Labels: []*Label{label}, Reactions: []*Reaction{reaction}, Reactions: []*issues_model.Reaction{reaction}, ForeignReference: &foreignreference.ForeignReference{ ForeignIndex: strconv.FormatInt(foreignIndex, 10), RepoID: repo.ID,
-
@@ -75,7 +76,7 @@ func assertCreateIssues(t *testing.T, isPull bool) {err = i.LoadAttributes() assert.NoError(t, err) assert.EqualValues(t, strconv.FormatInt(foreignIndex, 10), i.ForeignReference.ForeignIndex) unittest.AssertExistsAndLoadBean(t, &Reaction{Type: "heart", UserID: owner.ID, IssueID: i.ID}) unittest.AssertExistsAndLoadBean(t, &issues_model.Reaction{Type: "heart", UserID: owner.ID, IssueID: i.ID}) } func TestMigrate_CreateIssuesIsPullFalse(t *testing.T) {
-
@@ -91,7 +92,7 @@ func TestMigrate_InsertIssueComments(t *testing.T) {issue := unittest.AssertExistsAndLoadBean(t, &Issue{ID: 1}).(*Issue) _ = issue.LoadRepo() owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: issue.Repo.OwnerID}).(*user_model.User) reaction := &Reaction{ reaction := &issues_model.Reaction{ Type: "heart", UserID: owner.ID, }
-
@@ -101,7 +102,7 @@ func TestMigrate_InsertIssueComments(t *testing.T) {Poster: owner, IssueID: issue.ID, Issue: issue, Reactions: []*Reaction{reaction}, Reactions: []*issues_model.Reaction{reaction}, } err := InsertIssueComments([]*Comment{comment})
-
-
-
@@ -15,6 +15,7 @@ import (repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/container" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/timeutil"
-
@@ -520,7 +521,7 @@ func (nl NotificationList) getPendingRepoIDs() []int64 {ids[notification.RepoID] = struct{}{} } } return keysInt64(ids) return container.KeysInt64(ids) } // LoadRepos loads repositories from database
-
@@ -596,7 +597,7 @@ func (nl NotificationList) getPendingIssueIDs() []int64 {ids[notification.IssueID] = struct{}{} } } return keysInt64(ids) return container.KeysInt64(ids) } // LoadIssues loads issues from database
-
@@ -682,7 +683,7 @@ func (nl NotificationList) getPendingCommentIDs() []int64 {ids[notification.CommentID] = struct{}{} } } return keysInt64(ids) return container.KeysInt64(ids) } // LoadComments loads comments from database
-
-
-
@@ -13,6 +13,7 @@ import (repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/container" "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/util"
-
@@ -62,7 +63,7 @@ func (repos RepositoryList) loadAttributes(e db.Engine) error {users := make(map[int64]*user_model.User, len(set)) if err := e. Where("id > 0"). In("id", keysInt64(set)). In("id", container.KeysInt64(set)). Find(&users); err != nil { return fmt.Errorf("find users: %v", err) }
-
-
-
@@ -14,6 +14,7 @@ import (asymkey_model "code.gitea.io/gitea/models/asymkey" "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/organization" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user"
-
@@ -76,7 +77,7 @@ func DeleteUser(ctx context.Context, u *user_model.User) (err error) {&IssueUser{UID: u.ID}, &user_model.EmailAddress{UID: u.ID}, &user_model.UserOpenID{UID: u.ID}, &Reaction{UserID: u.ID}, &issues.Reaction{UserID: u.ID}, &organization.TeamUser{UID: u.ID}, &Collaboration{UserID: u.ID}, &Stopwatch{UserID: u.ID},
-
@@ -100,14 +101,14 @@ func DeleteUser(ctx context.Context, u *user_model.User) (err error) {} for _, comment := range comments { if err = deleteComment(e, comment); err != nil { if err = deleteComment(ctx, comment); err != nil { return err } } } // Delete Reactions if err = deleteReaction(e, &ReactionOptions{Doer: u}); err != nil { if err = issues.DeleteReaction(ctx, &issues.ReactionOptions{DoerID: u.ID}); err != nil { return err } }
-
-
modules/container/map.go (new)
-
@@ -0,0 +1,14 @@// Copyright 2022 The Gitea Authors. All rights reserved. // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. package container // KeysInt64 returns keys slice for a map with int64 key func KeysInt64(m map[int64]struct{}) []int64 { keys := make([]int64, 0, len(m)) for k := range m { keys = append(keys, k) } return keys }
-
-
-
@@ -9,6 +9,7 @@ import ("net/http" "code.gitea.io/gitea/models" issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/convert" api "code.gitea.io/gitea/modules/structs"
-
@@ -67,12 +68,12 @@ func GetIssueCommentReactions(ctx *context.APIContext) {return } reactions, _, err := models.FindCommentReactions(comment) reactions, _, err := issues_model.FindCommentReactions(comment.IssueID, comment.ID) if err != nil { ctx.Error(http.StatusInternalServerError, "FindCommentReactions", err) return } _, err = reactions.LoadUsers(ctx.Repo.Repository) _, err = reactions.LoadUsers(ctx, ctx.Repo.Repository) if err != nil { ctx.Error(http.StatusInternalServerError, "ReactionList.LoadUsers()", err) return
-
@@ -197,11 +198,11 @@ func changeIssueCommentReaction(ctx *context.APIContext, form api.EditReactionOpif isCreateType { // PostIssueCommentReaction part reaction, err := models.CreateCommentReaction(ctx.Doer, comment.Issue, comment, form.Reaction) reaction, err := issues_model.CreateCommentReaction(ctx.Doer.ID, comment.Issue.ID, comment.ID, form.Reaction) if err != nil { if models.IsErrForbiddenIssueReaction(err) { if issues_model.IsErrForbiddenIssueReaction(err) { ctx.Error(http.StatusForbidden, err.Error(), err) } else if models.IsErrReactionAlreadyExist(err) { } else if issues_model.IsErrReactionAlreadyExist(err) { ctx.JSON(http.StatusOK, api.Reaction{ User: convert.ToUser(ctx.Doer, ctx.Doer), Reaction: reaction.Type,
-
@@ -220,7 +221,7 @@ func changeIssueCommentReaction(ctx *context.APIContext, form api.EditReactionOp}) } else { // DeleteIssueCommentReaction part err = models.DeleteCommentReaction(ctx.Doer, comment.Issue, comment, form.Reaction) err = issues_model.DeleteCommentReaction(ctx.Doer.ID, comment.Issue.ID, comment.ID, form.Reaction) if err != nil { ctx.Error(http.StatusInternalServerError, "DeleteCommentReaction", err) return
-
@@ -285,12 +286,12 @@ func GetIssueReactions(ctx *context.APIContext) {return } reactions, count, err := models.FindIssueReactions(issue, utils.GetListOptions(ctx)) reactions, count, err := issues_model.FindIssueReactions(issue.ID, utils.GetListOptions(ctx)) if err != nil { ctx.Error(http.StatusInternalServerError, "FindIssueReactions", err) return } _, err = reactions.LoadUsers(ctx.Repo.Repository) _, err = reactions.LoadUsers(ctx, ctx.Repo.Repository) if err != nil { ctx.Error(http.StatusInternalServerError, "ReactionList.LoadUsers()", err) return
-
@@ -407,11 +408,11 @@ func changeIssueReaction(ctx *context.APIContext, form api.EditReactionOption, iif isCreateType { // PostIssueReaction part reaction, err := models.CreateIssueReaction(ctx.Doer, issue, form.Reaction) reaction, err := issues_model.CreateIssueReaction(ctx.Doer.ID, issue.ID, form.Reaction) if err != nil { if models.IsErrForbiddenIssueReaction(err) { if issues_model.IsErrForbiddenIssueReaction(err) { ctx.Error(http.StatusForbidden, err.Error(), err) } else if models.IsErrReactionAlreadyExist(err) { } else if issues_model.IsErrReactionAlreadyExist(err) { ctx.JSON(http.StatusOK, api.Reaction{ User: convert.ToUser(ctx.Doer, ctx.Doer), Reaction: reaction.Type,
-
@@ -430,7 +431,7 @@ func changeIssueReaction(ctx *context.APIContext, form api.EditReactionOption, i}) } else { // DeleteIssueReaction part err = models.DeleteIssueReaction(ctx.Doer, issue, form.Reaction) err = issues_model.DeleteIssueReaction(ctx.Doer.ID, issue.ID, form.Reaction) if err != nil { ctx.Error(http.StatusInternalServerError, "DeleteIssueReaction", err) return
-
-
-
@@ -19,6 +19,7 @@ import ("code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/organization" project_model "code.gitea.io/gitea/models/project" repo_model "code.gitea.io/gitea/models/repo"
-
@@ -2349,9 +2350,9 @@ func ChangeIssueReaction(ctx *context.Context) {switch ctx.Params(":action") { case "react": reaction, err := models.CreateIssueReaction(ctx.Doer, issue, form.Content) reaction, err := issues_model.CreateIssueReaction(ctx.Doer.ID, issue.ID, form.Content) if err != nil { if models.IsErrForbiddenIssueReaction(err) { if issues_model.IsErrForbiddenIssueReaction(err) { ctx.ServerError("ChangeIssueReaction", err) return }
-
@@ -2367,7 +2368,7 @@ func ChangeIssueReaction(ctx *context.Context) {log.Trace("Reaction for issue created: %d/%d/%d", ctx.Repo.Repository.ID, issue.ID, reaction.ID) case "unreact": if err := models.DeleteIssueReaction(ctx.Doer, issue, form.Content); err != nil { if err := issues_model.DeleteIssueReaction(ctx.Doer.ID, issue.ID, form.Content); err != nil { ctx.ServerError("DeleteIssueReaction", err) return }
-
@@ -2451,9 +2452,9 @@ func ChangeCommentReaction(ctx *context.Context) {switch ctx.Params(":action") { case "react": reaction, err := models.CreateCommentReaction(ctx.Doer, comment.Issue, comment, form.Content) reaction, err := issues_model.CreateCommentReaction(ctx.Doer.ID, comment.Issue.ID, comment.ID, form.Content) if err != nil { if models.IsErrForbiddenIssueReaction(err) { if issues_model.IsErrForbiddenIssueReaction(err) { ctx.ServerError("ChangeIssueReaction", err) return }
-
@@ -2469,7 +2470,7 @@ func ChangeCommentReaction(ctx *context.Context) {log.Trace("Reaction for comment created: %d/%d/%d/%d", ctx.Repo.Repository.ID, comment.Issue.ID, comment.ID, reaction.ID) case "unreact": if err := models.DeleteCommentReaction(ctx.Doer, comment.Issue, comment, form.Content); err != nil { if err := issues_model.DeleteCommentReaction(ctx.Doer.ID, comment.Issue.ID, comment.ID, form.Content); err != nil { ctx.ServerError("DeleteCommentReaction", err) return }
-
-
-
@@ -18,6 +18,7 @@ import ("code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/foreignreference" issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/git"
-
@@ -392,7 +393,7 @@ func (g *GiteaLocalUploader) CreateIssues(issues ...*base.Issue) error {} // add reactions for _, reaction := range issue.Reactions { res := models.Reaction{ res := issues_model.Reaction{ Type: reaction.Content, CreatedUnix: timeutil.TimeStampNow(), }
-
@@ -448,7 +449,7 @@ func (g *GiteaLocalUploader) CreateComments(comments ...*base.Comment) error {// add reactions for _, reaction := range comment.Reactions { res := models.Reaction{ res := issues_model.Reaction{ Type: reaction.Content, CreatedUnix: timeutil.TimeStampNow(), }
-
@@ -646,7 +647,7 @@ func (g *GiteaLocalUploader) newPullRequest(pr *base.PullRequest) (*models.PullR// add reactions for _, reaction := range pr.Reactions { res := models.Reaction{ res := issues_model.Reaction{ Type: reaction.Content, CreatedUnix: timeutil.TimeStampNow(), }
-