From d2b86f1b8de4784baf578b611cf80779ccfa722a Mon Sep 17 00:00:00 2001 From: Saturnino Abril Date: Wed, 19 Apr 2017 05:15:15 +0900 Subject: APIv4 POST /reactions (#6092) * APIv4 POST /reactions * update corresponding V3 endpoint --- api4/api.go | 3 ++ api4/reaction.go | 34 ++++++++++++++++ api4/reaction_test.go | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 143 insertions(+) (limited to 'api4') diff --git a/api4/api.go b/api4/api.go index a91fb80b5..18e1e4022 100644 --- a/api4/api.go +++ b/api4/api.go @@ -82,6 +82,8 @@ type Routes struct { Public *mux.Router // 'api/v4/public' + Reactions *mux.Router // 'api/v4/reactions' + Emojis *mux.Router // 'api/v4/emoji' Emoji *mux.Router // 'api/v4/emoji/{emoji_id:[A-Za-z0-9]+}' @@ -154,6 +156,7 @@ func InitApi(full bool) { BaseRoutes.Preferences = BaseRoutes.User.PathPrefix("/preferences").Subrouter() BaseRoutes.License = BaseRoutes.ApiRoot.PathPrefix("/license").Subrouter() BaseRoutes.Public = BaseRoutes.ApiRoot.PathPrefix("/public").Subrouter() + BaseRoutes.Reactions = BaseRoutes.ApiRoot.PathPrefix("/reactions").Subrouter() BaseRoutes.Emojis = BaseRoutes.ApiRoot.PathPrefix("/emoji").Subrouter() BaseRoutes.Emoji = BaseRoutes.Emojis.PathPrefix("/{emoji_id:[A-Za-z0-9]+}").Subrouter() diff --git a/api4/reaction.go b/api4/reaction.go index 4deae4370..7d5952eea 100644 --- a/api4/reaction.go +++ b/api4/reaction.go @@ -15,9 +15,43 @@ import ( func InitReaction() { l4g.Debug(utils.T("api.reaction.init.debug")) + BaseRoutes.Reactions.Handle("", ApiSessionRequired(saveReaction)).Methods("POST") BaseRoutes.Post.Handle("/reactions", ApiSessionRequired(getReactions)).Methods("GET") } +func saveReaction(c *Context, w http.ResponseWriter, r *http.Request) { + reaction := model.ReactionFromJson(r.Body) + if reaction == nil { + c.SetInvalidParam("reaction") + return + } + + if len(reaction.UserId) != 26 || len(reaction.PostId) != 26 || len(reaction.EmojiName) == 0 || len(reaction.EmojiName) > 64 { + c.Err = model.NewLocAppError("saveReaction", "api.reaction.save_reaction.invalid.app_error", nil, "") + c.Err.StatusCode = http.StatusBadRequest + return + } + + if reaction.UserId != c.Session.UserId { + c.Err = model.NewLocAppError("saveReaction", "api.reaction.save_reaction.user_id.app_error", nil, "") + c.Err.StatusCode = http.StatusForbidden + return + } + + if !app.SessionHasPermissionToChannelByPost(c.Session, reaction.PostId, model.PERMISSION_READ_CHANNEL) { + c.SetPermissionError(model.PERMISSION_READ_CHANNEL) + return + } + + if reaction, err := app.SaveReactionForPost(reaction); err != nil { + c.Err = err + return + } else { + w.Write([]byte(reaction.ToJson())) + return + } +} + func getReactions(c *Context, w http.ResponseWriter, r *http.Request) { c.RequirePostId() if c.Err != nil { diff --git a/api4/reaction_test.go b/api4/reaction_test.go index 9e0847c2d..980a96d68 100644 --- a/api4/reaction_test.go +++ b/api4/reaction_test.go @@ -4,6 +4,7 @@ package api4 import ( + "strings" "testing" "reflect" @@ -12,6 +13,111 @@ import ( "github.com/mattermost/platform/model" ) +func TestSaveReaction(t *testing.T) { + th := Setup().InitBasic().InitSystemAdmin() + defer TearDown() + Client := th.Client + userId := th.BasicUser.Id + postId := th.BasicPost.Id + + reaction := &model.Reaction{ + UserId: userId, + PostId: postId, + EmojiName: "smile", + } + + rr, resp := Client.SaveReaction(reaction) + CheckNoError(t, resp) + + if rr.UserId != reaction.UserId { + t.Fatal("UserId did not match") + } + + if rr.PostId != reaction.PostId { + t.Fatal("PostId did not match") + } + + if rr.EmojiName != reaction.EmojiName { + t.Fatal("EmojiName did not match") + } + + if rr.CreateAt == 0 { + t.Fatal("CreateAt should exist") + } + + if reactions, err := app.GetReactionsForPost(postId); err != nil && len(reactions) != 1 { + t.Fatal("didn't save reaction correctly") + } + + // saving a duplicate reaction + rr, resp = Client.SaveReaction(reaction) + CheckNoError(t, resp) + + if reactions, err := app.GetReactionsForPost(postId); err != nil && len(reactions) != 1 { + t.Fatal("should have not save duplicated reaction") + } + + reaction.EmojiName = "sad" + + rr, resp = Client.SaveReaction(reaction) + CheckNoError(t, resp) + + if rr.EmojiName != reaction.EmojiName { + t.Fatal("EmojiName did not match") + } + + if reactions, err := app.GetReactionsForPost(postId); err != nil && len(reactions) != 2 { + t.Fatal("should have save multiple reactions") + } + + reaction.PostId = GenerateTestId() + + _, resp = Client.SaveReaction(reaction) + CheckForbiddenStatus(t, resp) + + reaction.PostId = "junk" + + _, resp = Client.SaveReaction(reaction) + CheckBadRequestStatus(t, resp) + + reaction.PostId = postId + reaction.UserId = GenerateTestId() + + _, resp = Client.SaveReaction(reaction) + CheckForbiddenStatus(t, resp) + + reaction.UserId = "junk" + + _, resp = Client.SaveReaction(reaction) + CheckBadRequestStatus(t, resp) + + reaction.UserId = userId + reaction.EmojiName = "" + + _, resp = Client.SaveReaction(reaction) + CheckBadRequestStatus(t, resp) + + reaction.EmojiName = strings.Repeat("a", 65) + + _, resp = Client.SaveReaction(reaction) + CheckBadRequestStatus(t, resp) + + reaction.EmojiName = "smile" + otherUser := th.CreateUser() + Client.Logout() + Client.Login(otherUser.Email, otherUser.Password) + + _, resp = Client.SaveReaction(reaction) + CheckForbiddenStatus(t, resp) + + Client.Logout() + _, resp = Client.SaveReaction(reaction) + CheckUnauthorizedStatus(t, resp) + + _, resp = th.SystemAdminClient.SaveReaction(reaction) + CheckForbiddenStatus(t, resp) +} + func TestGetReactions(t *testing.T) { th := Setup().InitBasic().InitSystemAdmin() defer TearDown() -- cgit v1.2.3-1-g7c22