[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>
This commit is contained in:
		
							parent
							
								
									655aea13a5
								
							
						
					
					
						commit
						9600c27085
					
				
					 9 changed files with 119 additions and 79 deletions
				
			
		|  | @ -47,7 +47,7 @@ func TestAPIIssuesReactions(t *testing.T) { | ||||||
| 		Reaction: "rocket", | 		Reaction: "rocket", | ||||||
| 	}) | 	}) | ||||||
| 	resp = session.MakeRequest(t, req, http.StatusCreated) | 	resp = session.MakeRequest(t, req, http.StatusCreated) | ||||||
| 	var apiNewReaction api.ReactionResponse | 	var apiNewReaction api.Reaction | ||||||
| 	DecodeJSON(t, resp, &apiNewReaction) | 	DecodeJSON(t, resp, &apiNewReaction) | ||||||
| 
 | 
 | ||||||
| 	//Add existing reaction
 | 	//Add existing reaction
 | ||||||
|  | @ -56,10 +56,10 @@ func TestAPIIssuesReactions(t *testing.T) { | ||||||
| 	//Get end result of reaction list of issue #1
 | 	//Get end result of reaction list of issue #1
 | ||||||
| 	req = NewRequestf(t, "GET", urlStr) | 	req = NewRequestf(t, "GET", urlStr) | ||||||
| 	resp = session.MakeRequest(t, req, http.StatusOK) | 	resp = session.MakeRequest(t, req, http.StatusOK) | ||||||
| 	var apiReactions []*api.ReactionResponse | 	var apiReactions []*api.Reaction | ||||||
| 	DecodeJSON(t, resp, &apiReactions) | 	DecodeJSON(t, resp, &apiReactions) | ||||||
| 	expectResponse := make(map[int]api.ReactionResponse) | 	expectResponse := make(map[int]api.Reaction) | ||||||
| 	expectResponse[0] = api.ReactionResponse{ | 	expectResponse[0] = api.Reaction{ | ||||||
| 		User:     user2.APIFormat(), | 		User:     user2.APIFormat(), | ||||||
| 		Reaction: "eyes", | 		Reaction: "eyes", | ||||||
| 		Created:  time.Unix(1573248003, 0), | 		Created:  time.Unix(1573248003, 0), | ||||||
|  | @ -107,7 +107,7 @@ func TestAPICommentReactions(t *testing.T) { | ||||||
| 		Reaction: "+1", | 		Reaction: "+1", | ||||||
| 	}) | 	}) | ||||||
| 	resp = session.MakeRequest(t, req, http.StatusCreated) | 	resp = session.MakeRequest(t, req, http.StatusCreated) | ||||||
| 	var apiNewReaction api.ReactionResponse | 	var apiNewReaction api.Reaction | ||||||
| 	DecodeJSON(t, resp, &apiNewReaction) | 	DecodeJSON(t, resp, &apiNewReaction) | ||||||
| 
 | 
 | ||||||
| 	//Add existing reaction
 | 	//Add existing reaction
 | ||||||
|  | @ -116,15 +116,15 @@ func TestAPICommentReactions(t *testing.T) { | ||||||
| 	//Get end result of reaction list of issue #1
 | 	//Get end result of reaction list of issue #1
 | ||||||
| 	req = NewRequestf(t, "GET", urlStr) | 	req = NewRequestf(t, "GET", urlStr) | ||||||
| 	resp = session.MakeRequest(t, req, http.StatusOK) | 	resp = session.MakeRequest(t, req, http.StatusOK) | ||||||
| 	var apiReactions []*api.ReactionResponse | 	var apiReactions []*api.Reaction | ||||||
| 	DecodeJSON(t, resp, &apiReactions) | 	DecodeJSON(t, resp, &apiReactions) | ||||||
| 	expectResponse := make(map[int]api.ReactionResponse) | 	expectResponse := make(map[int]api.Reaction) | ||||||
| 	expectResponse[0] = api.ReactionResponse{ | 	expectResponse[0] = api.Reaction{ | ||||||
| 		User:     user2.APIFormat(), | 		User:     user2.APIFormat(), | ||||||
| 		Reaction: "laugh", | 		Reaction: "laugh", | ||||||
| 		Created:  time.Unix(1573248004, 0), | 		Created:  time.Unix(1573248004, 0), | ||||||
| 	} | 	} | ||||||
| 	expectResponse[1] = api.ReactionResponse{ | 	expectResponse[1] = api.Reaction{ | ||||||
| 		User:     user1.APIFormat(), | 		User:     user1.APIFormat(), | ||||||
| 		Reaction: "laugh", | 		Reaction: "laugh", | ||||||
| 		Created:  time.Unix(1573248005, 0), | 		Created:  time.Unix(1573248005, 0), | ||||||
|  |  | ||||||
|  | @ -1201,6 +1201,21 @@ func (err ErrForbiddenIssueReaction) Error() string { | ||||||
| 	return fmt.Sprintf("'%s' is not an allowed reaction", err.Reaction) | 	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) | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // __________      .__  .__ __________                                     __
 | // __________      .__  .__ __________                                     __
 | ||||||
| // \______   \__ __|  | |  |\______   \ ____  ________ __   ____   _______/  |_
 | // \______   \__ __|  | |  |\______   \ ____  ________ __   ____   _______/  |_
 | ||||||
| //  |     ___/  |  \  | |  | |       _// __ \/ ____/  |  \_/ __ \ /  ___/\   __\
 | //  |     ___/  |  \  | |  | |       _// __ \/ ____/  |  \_/ __ \ /  ___/\   __\
 | ||||||
|  |  | ||||||
|  | @ -30,6 +30,8 @@ type Reaction struct { | ||||||
| type FindReactionsOptions struct { | type FindReactionsOptions struct { | ||||||
| 	IssueID   int64 | 	IssueID   int64 | ||||||
| 	CommentID int64 | 	CommentID int64 | ||||||
|  | 	UserID    int64 | ||||||
|  | 	Reaction  string | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (opts *FindReactionsOptions) toConds() builder.Cond { | func (opts *FindReactionsOptions) toConds() builder.Cond { | ||||||
|  | @ -46,6 +48,12 @@ func (opts *FindReactionsOptions) toConds() builder.Cond { | ||||||
| 	} else if opts.CommentID == -1 { | 	} else if opts.CommentID == -1 { | ||||||
| 		cond = cond.And(builder.Eq{"reaction.comment_id": 0}) | 		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 | 	return cond | ||||||
| } | } | ||||||
|  | @ -80,9 +88,25 @@ func createReaction(e *xorm.Session, opts *ReactionOptions) (*Reaction, error) { | ||||||
| 		UserID:  opts.Doer.ID, | 		UserID:  opts.Doer.ID, | ||||||
| 		IssueID: opts.Issue.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 { | 	if opts.Comment != nil { | ||||||
| 		reaction.CommentID = opts.Comment.ID | 		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 { | 	if _, err := e.Insert(reaction); err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
|  | @ -99,23 +123,23 @@ type ReactionOptions struct { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // CreateReaction creates reaction for issue or comment.
 | // 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] { | 	if !setting.UI.ReactionsMap[opts.Type] { | ||||||
| 		return nil, ErrForbiddenIssueReaction{opts.Type} | 		return nil, ErrForbiddenIssueReaction{opts.Type} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	sess := x.NewSession() | 	sess := x.NewSession() | ||||||
| 	defer sess.Close() | 	defer sess.Close() | ||||||
| 	if err = sess.Begin(); err != nil { | 	if err := sess.Begin(); err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	reaction, err = createReaction(sess, opts) | 	reaction, err := createReaction(sess, opts) | ||||||
| 	if err != nil { | 	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 nil, err | ||||||
| 	} | 	} | ||||||
| 	return reaction, nil | 	return reaction, nil | ||||||
|  |  | ||||||
|  | @ -50,9 +50,10 @@ func TestIssueAddDuplicateReaction(t *testing.T) { | ||||||
| 		Type:  "heart", | 		Type:  "heart", | ||||||
| 	}) | 	}) | ||||||
| 	assert.Error(t, err) | 	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) { | func TestIssueDeleteReaction(t *testing.T) { | ||||||
|  | @ -129,7 +130,6 @@ func TestIssueCommentDeleteReaction(t *testing.T) { | ||||||
| 	user2 := AssertExistsAndLoadBean(t, &User{ID: 2}).(*User) | 	user2 := AssertExistsAndLoadBean(t, &User{ID: 2}).(*User) | ||||||
| 	user3 := AssertExistsAndLoadBean(t, &User{ID: 3}).(*User) | 	user3 := AssertExistsAndLoadBean(t, &User{ID: 3}).(*User) | ||||||
| 	user4 := AssertExistsAndLoadBean(t, &User{ID: 4}).(*User) | 	user4 := AssertExistsAndLoadBean(t, &User{ID: 4}).(*User) | ||||||
| 	ghost := NewGhostUser() |  | ||||||
| 
 | 
 | ||||||
| 	issue1 := AssertExistsAndLoadBean(t, &Issue{ID: 1}).(*Issue) | 	issue1 := AssertExistsAndLoadBean(t, &Issue{ID: 1}).(*Issue) | ||||||
| 
 | 
 | ||||||
|  | @ -139,14 +139,13 @@ func TestIssueCommentDeleteReaction(t *testing.T) { | ||||||
| 	addReaction(t, user2, issue1, comment1, "heart") | 	addReaction(t, user2, issue1, comment1, "heart") | ||||||
| 	addReaction(t, user3, issue1, comment1, "heart") | 	addReaction(t, user3, issue1, comment1, "heart") | ||||||
| 	addReaction(t, user4, issue1, comment1, "+1") | 	addReaction(t, user4, issue1, comment1, "+1") | ||||||
| 	addReaction(t, ghost, issue1, comment1, "heart") |  | ||||||
| 
 | 
 | ||||||
| 	err := comment1.LoadReactions() | 	err := comment1.LoadReactions() | ||||||
| 	assert.NoError(t, err) | 	assert.NoError(t, err) | ||||||
| 	assert.Len(t, comment1.Reactions, 5) | 	assert.Len(t, comment1.Reactions, 4) | ||||||
| 
 | 
 | ||||||
| 	reactions := comment1.Reactions.GroupByType() | 	reactions := comment1.Reactions.GroupByType() | ||||||
| 	assert.Len(t, reactions["heart"], 4) | 	assert.Len(t, reactions["heart"], 3) | ||||||
| 	assert.Len(t, reactions["+1"], 1) | 	assert.Len(t, reactions["+1"], 1) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -160,7 +159,7 @@ func TestIssueCommentReactionCount(t *testing.T) { | ||||||
| 	comment1 := AssertExistsAndLoadBean(t, &Comment{ID: 1}).(*Comment) | 	comment1 := AssertExistsAndLoadBean(t, &Comment{ID: 1}).(*Comment) | ||||||
| 
 | 
 | ||||||
| 	addReaction(t, user1, issue1, comment1, "heart") | 	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}) | 	AssertNotExistsBean(t, &Reaction{Type: "heart", UserID: user1.ID, IssueID: issue1.ID, CommentID: comment1.ID}) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -13,8 +13,8 @@ type EditReactionOption struct { | ||||||
| 	Reaction string `json:"content"` | 	Reaction string `json:"content"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // ReactionResponse contain one reaction
 | // Reaction contain one reaction
 | ||||||
| type ReactionResponse struct { | type Reaction struct { | ||||||
| 	User     *User  `json:"user"` | 	User     *User  `json:"user"` | ||||||
| 	Reaction string `json:"content"` | 	Reaction string `json:"content"` | ||||||
| 	// swagger:strfmt date-time
 | 	// swagger:strfmt date-time
 | ||||||
|  |  | ||||||
|  | @ -41,7 +41,7 @@ func GetIssueCommentReactions(ctx *context.APIContext) { | ||||||
| 	//   required: true
 | 	//   required: true
 | ||||||
| 	// responses:
 | 	// responses:
 | ||||||
| 	//   "200":
 | 	//   "200":
 | ||||||
| 	//     "$ref": "#/responses/ReactionResponseList"
 | 	//     "$ref": "#/responses/ReactionList"
 | ||||||
| 	//   "403":
 | 	//   "403":
 | ||||||
| 	//     "$ref": "#/responses/forbidden"
 | 	//     "$ref": "#/responses/forbidden"
 | ||||||
| 
 | 
 | ||||||
|  | @ -71,9 +71,9 @@ func GetIssueCommentReactions(ctx *context.APIContext) { | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	var result []api.ReactionResponse | 	var result []api.Reaction | ||||||
| 	for _, r := range reactions { | 	for _, r := range reactions { | ||||||
| 		result = append(result, api.ReactionResponse{ | 		result = append(result, api.Reaction{ | ||||||
| 			User:     r.User.APIFormat(), | 			User:     r.User.APIFormat(), | ||||||
| 			Reaction: r.Type, | 			Reaction: r.Type, | ||||||
| 			Created:  r.CreatedUnix.AsTime(), | 			Created:  r.CreatedUnix.AsTime(), | ||||||
|  | @ -114,8 +114,10 @@ func PostIssueCommentReaction(ctx *context.APIContext, form api.EditReactionOpti | ||||||
| 	//   schema:
 | 	//   schema:
 | ||||||
| 	//     "$ref": "#/definitions/EditReactionOption"
 | 	//     "$ref": "#/definitions/EditReactionOption"
 | ||||||
| 	// responses:
 | 	// responses:
 | ||||||
|  | 	//   "200":
 | ||||||
|  | 	//     "$ref": "#/responses/Reaction"
 | ||||||
| 	//   "201":
 | 	//   "201":
 | ||||||
| 	//     "$ref": "#/responses/ReactionResponse"
 | 	//     "$ref": "#/responses/Reaction"
 | ||||||
| 	//   "403":
 | 	//   "403":
 | ||||||
| 	//     "$ref": "#/responses/forbidden"
 | 	//     "$ref": "#/responses/forbidden"
 | ||||||
| 
 | 
 | ||||||
|  | @ -188,19 +190,20 @@ func changeIssueCommentReaction(ctx *context.APIContext, form api.EditReactionOp | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			if models.IsErrForbiddenIssueReaction(err) { | 			if models.IsErrForbiddenIssueReaction(err) { | ||||||
| 				ctx.Error(http.StatusForbidden, err.Error(), err) | 				ctx.Error(http.StatusForbidden, err.Error(), err) | ||||||
|  | 			} else if models.IsErrReactionAlreadyExist(err) { | ||||||
|  | 				ctx.JSON(http.StatusOK, api.Reaction{ | ||||||
|  | 					User:     ctx.User.APIFormat(), | ||||||
|  | 					Reaction: reaction.Type, | ||||||
|  | 					Created:  reaction.CreatedUnix.AsTime(), | ||||||
|  | 				}) | ||||||
| 			} else { | 			} else { | ||||||
| 				ctx.Error(http.StatusInternalServerError, "CreateCommentReaction", err) | 				ctx.Error(http.StatusInternalServerError, "CreateCommentReaction", err) | ||||||
| 			} | 			} | ||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
| 		_, err = reaction.LoadUser() |  | ||||||
| 		if err != nil { |  | ||||||
| 			ctx.Error(http.StatusInternalServerError, "Reaction.LoadUser()", err) |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
| 
 | 
 | ||||||
| 		ctx.JSON(http.StatusCreated, api.ReactionResponse{ | 		ctx.JSON(http.StatusCreated, api.Reaction{ | ||||||
| 			User:     reaction.User.APIFormat(), | 			User:     ctx.User.APIFormat(), | ||||||
| 			Reaction: reaction.Type, | 			Reaction: reaction.Type, | ||||||
| 			Created:  reaction.CreatedUnix.AsTime(), | 			Created:  reaction.CreatedUnix.AsTime(), | ||||||
| 		}) | 		}) | ||||||
|  | @ -244,7 +247,7 @@ func GetIssueReactions(ctx *context.APIContext) { | ||||||
| 	//   required: true
 | 	//   required: true
 | ||||||
| 	// responses:
 | 	// responses:
 | ||||||
| 	//   "200":
 | 	//   "200":
 | ||||||
| 	//     "$ref": "#/responses/ReactionResponseList"
 | 	//     "$ref": "#/responses/ReactionList"
 | ||||||
| 	//   "403":
 | 	//   "403":
 | ||||||
| 	//     "$ref": "#/responses/forbidden"
 | 	//     "$ref": "#/responses/forbidden"
 | ||||||
| 
 | 
 | ||||||
|  | @ -274,9 +277,9 @@ func GetIssueReactions(ctx *context.APIContext) { | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	var result []api.ReactionResponse | 	var result []api.Reaction | ||||||
| 	for _, r := range reactions { | 	for _, r := range reactions { | ||||||
| 		result = append(result, api.ReactionResponse{ | 		result = append(result, api.Reaction{ | ||||||
| 			User:     r.User.APIFormat(), | 			User:     r.User.APIFormat(), | ||||||
| 			Reaction: r.Type, | 			Reaction: r.Type, | ||||||
| 			Created:  r.CreatedUnix.AsTime(), | 			Created:  r.CreatedUnix.AsTime(), | ||||||
|  | @ -317,8 +320,10 @@ func PostIssueReaction(ctx *context.APIContext, form api.EditReactionOption) { | ||||||
| 	//   schema:
 | 	//   schema:
 | ||||||
| 	//     "$ref": "#/definitions/EditReactionOption"
 | 	//     "$ref": "#/definitions/EditReactionOption"
 | ||||||
| 	// responses:
 | 	// responses:
 | ||||||
|  | 	//   "200":
 | ||||||
|  | 	//     "$ref": "#/responses/Reaction"
 | ||||||
| 	//   "201":
 | 	//   "201":
 | ||||||
| 	//     "$ref": "#/responses/ReactionResponse"
 | 	//     "$ref": "#/responses/Reaction"
 | ||||||
| 	//   "403":
 | 	//   "403":
 | ||||||
| 	//     "$ref": "#/responses/forbidden"
 | 	//     "$ref": "#/responses/forbidden"
 | ||||||
| 
 | 
 | ||||||
|  | @ -386,19 +391,20 @@ func changeIssueReaction(ctx *context.APIContext, form api.EditReactionOption, i | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			if models.IsErrForbiddenIssueReaction(err) { | 			if models.IsErrForbiddenIssueReaction(err) { | ||||||
| 				ctx.Error(http.StatusForbidden, err.Error(), err) | 				ctx.Error(http.StatusForbidden, err.Error(), err) | ||||||
|  | 			} else if models.IsErrReactionAlreadyExist(err) { | ||||||
|  | 				ctx.JSON(http.StatusOK, api.Reaction{ | ||||||
|  | 					User:     ctx.User.APIFormat(), | ||||||
|  | 					Reaction: reaction.Type, | ||||||
|  | 					Created:  reaction.CreatedUnix.AsTime(), | ||||||
|  | 				}) | ||||||
| 			} else { | 			} else { | ||||||
| 				ctx.Error(http.StatusInternalServerError, "CreateCommentReaction", err) | 				ctx.Error(http.StatusInternalServerError, "CreateCommentReaction", err) | ||||||
| 			} | 			} | ||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
| 		_, err = reaction.LoadUser() |  | ||||||
| 		if err != nil { |  | ||||||
| 			ctx.Error(http.StatusInternalServerError, "Reaction.LoadUser()", err) |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
| 
 | 
 | ||||||
| 		ctx.JSON(http.StatusCreated, api.ReactionResponse{ | 		ctx.JSON(http.StatusCreated, api.Reaction{ | ||||||
| 			User:     reaction.User.APIFormat(), | 			User:     ctx.User.APIFormat(), | ||||||
| 			Reaction: reaction.Type, | 			Reaction: reaction.Type, | ||||||
| 			Created:  reaction.CreatedUnix.AsTime(), | 			Created:  reaction.CreatedUnix.AsTime(), | ||||||
| 		}) | 		}) | ||||||
|  |  | ||||||
|  | @ -99,23 +99,16 @@ type swaggerResponseStopWatchList struct { | ||||||
| 	Body []api.StopWatch `json:"body"` | 	Body []api.StopWatch `json:"body"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // EditReactionOption
 | // Reaction
 | ||||||
| // swagger:response EditReactionOption
 | // swagger:response Reaction
 | ||||||
| type swaggerEditReactionOption struct { | type swaggerReaction struct { | ||||||
| 	// in:body
 | 	// in:body
 | ||||||
| 	Body api.EditReactionOption `json:"body"` | 	Body api.Reaction `json:"body"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // ReactionResponse
 | // ReactionList
 | ||||||
| // swagger:response ReactionResponse
 | // swagger:response ReactionList
 | ||||||
| type swaggerReactionResponse struct { | type swaggerReactionList struct { | ||||||
| 	// in:body
 | 	// in:body
 | ||||||
| 	Body api.ReactionResponse `json:"body"` | 	Body []api.Reaction `json:"body"` | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // ReactionResponseList
 |  | ||||||
| // swagger:response ReactionResponseList
 |  | ||||||
| type swaggerReactionResponseList struct { |  | ||||||
| 	// in:body
 |  | ||||||
| 	Body []api.ReactionResponse `json:"body"` |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -123,4 +123,7 @@ type swaggerParameterBodies struct { | ||||||
| 
 | 
 | ||||||
| 	// in:body
 | 	// in:body
 | ||||||
| 	RepoTopicOptions api.RepoTopicOptions | 	RepoTopicOptions api.RepoTopicOptions | ||||||
|  | 
 | ||||||
|  | 	// in:body
 | ||||||
|  | 	EditReactionOption api.EditReactionOption | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -3130,7 +3130,7 @@ | ||||||
|         ], |         ], | ||||||
|         "responses": { |         "responses": { | ||||||
|           "200": { |           "200": { | ||||||
|             "$ref": "#/responses/ReactionResponseList" |             "$ref": "#/responses/ReactionList" | ||||||
|           }, |           }, | ||||||
|           "403": { |           "403": { | ||||||
|             "$ref": "#/responses/forbidden" |             "$ref": "#/responses/forbidden" | ||||||
|  | @ -3181,8 +3181,11 @@ | ||||||
|           } |           } | ||||||
|         ], |         ], | ||||||
|         "responses": { |         "responses": { | ||||||
|  |           "200": { | ||||||
|  |             "$ref": "#/responses/Reaction" | ||||||
|  |           }, | ||||||
|           "201": { |           "201": { | ||||||
|             "$ref": "#/responses/ReactionResponse" |             "$ref": "#/responses/Reaction" | ||||||
|           }, |           }, | ||||||
|           "403": { |           "403": { | ||||||
|             "$ref": "#/responses/forbidden" |             "$ref": "#/responses/forbidden" | ||||||
|  | @ -3896,7 +3899,7 @@ | ||||||
|         ], |         ], | ||||||
|         "responses": { |         "responses": { | ||||||
|           "200": { |           "200": { | ||||||
|             "$ref": "#/responses/ReactionResponseList" |             "$ref": "#/responses/ReactionList" | ||||||
|           }, |           }, | ||||||
|           "403": { |           "403": { | ||||||
|             "$ref": "#/responses/forbidden" |             "$ref": "#/responses/forbidden" | ||||||
|  | @ -3947,8 +3950,11 @@ | ||||||
|           } |           } | ||||||
|         ], |         ], | ||||||
|         "responses": { |         "responses": { | ||||||
|  |           "200": { | ||||||
|  |             "$ref": "#/responses/Reaction" | ||||||
|  |           }, | ||||||
|           "201": { |           "201": { | ||||||
|             "$ref": "#/responses/ReactionResponse" |             "$ref": "#/responses/Reaction" | ||||||
|           }, |           }, | ||||||
|           "403": { |           "403": { | ||||||
|             "$ref": "#/responses/forbidden" |             "$ref": "#/responses/forbidden" | ||||||
|  | @ -10822,8 +10828,8 @@ | ||||||
|       }, |       }, | ||||||
|       "x-go-package": "code.gitea.io/gitea/modules/structs" |       "x-go-package": "code.gitea.io/gitea/modules/structs" | ||||||
|     }, |     }, | ||||||
|     "ReactionResponse": { |     "Reaction": { | ||||||
|       "description": "ReactionResponse contain one reaction", |       "description": "Reaction contain one reaction", | ||||||
|       "type": "object", |       "type": "object", | ||||||
|       "properties": { |       "properties": { | ||||||
|         "content": { |         "content": { | ||||||
|  | @ -11735,12 +11741,6 @@ | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "EditReactionOption": { |  | ||||||
|       "description": "EditReactionOption", |  | ||||||
|       "schema": { |  | ||||||
|         "$ref": "#/definitions/EditReactionOption" |  | ||||||
|       } |  | ||||||
|     }, |  | ||||||
|     "EmailList": { |     "EmailList": { | ||||||
|       "description": "EmailList", |       "description": "EmailList", | ||||||
|       "schema": { |       "schema": { | ||||||
|  | @ -11927,18 +11927,18 @@ | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "ReactionResponse": { |     "Reaction": { | ||||||
|       "description": "ReactionResponse", |       "description": "Reaction", | ||||||
|       "schema": { |       "schema": { | ||||||
|         "$ref": "#/definitions/ReactionResponse" |         "$ref": "#/definitions/Reaction" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "ReactionResponseList": { |     "ReactionList": { | ||||||
|       "description": "ReactionResponseList", |       "description": "ReactionList", | ||||||
|       "schema": { |       "schema": { | ||||||
|         "type": "array", |         "type": "array", | ||||||
|         "items": { |         "items": { | ||||||
|           "$ref": "#/definitions/ReactionResponse" |           "$ref": "#/definitions/Reaction" | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  | @ -12164,7 +12164,7 @@ | ||||||
|     "parameterBodies": { |     "parameterBodies": { | ||||||
|       "description": "parameterBodies", |       "description": "parameterBodies", | ||||||
|       "schema": { |       "schema": { | ||||||
|         "$ref": "#/definitions/RepoTopicOptions" |         "$ref": "#/definitions/EditReactionOption" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "redirect": { |     "redirect": { | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue