diff options
author | Gabin Aureche <gabin.aureche@live.fr> | 2017-03-13 13:25:08 +0100 |
---|---|---|
committer | George Goldberg <george@gberg.me> | 2017-03-13 12:25:08 +0000 |
commit | fe38d6d5bb36e18ddefbe490cc21f48f4f4c8d81 (patch) | |
tree | b96d457cde64b7397f91028106e93a7f92a179bd /api | |
parent | 482a0fb5fc248b1ec61db35299dc3e6d963ad5ab (diff) | |
download | chat-fe38d6d5bb36e18ddefbe490cc21f48f4f4c8d81.tar.gz chat-fe38d6d5bb36e18ddefbe490cc21f48f4f4c8d81.tar.bz2 chat-fe38d6d5bb36e18ddefbe490cc21f48f4f4c8d81.zip |
Add pinned posts (#4217)
Diffstat (limited to 'api')
-rw-r--r-- | api/admin_test.go | 4 | ||||
-rw-r--r-- | api/apitestlib.go | 19 | ||||
-rw-r--r-- | api/channel.go | 16 | ||||
-rw-r--r-- | api/channel_test.go | 33 | ||||
-rw-r--r-- | api/post.go | 55 | ||||
-rw-r--r-- | api/post_test.go | 46 |
6 files changed, 165 insertions, 8 deletions
diff --git a/api/admin_test.go b/api/admin_test.go index 801ad8f21..dc569620e 100644 --- a/api/admin_test.go +++ b/api/admin_test.go @@ -225,7 +225,7 @@ func TestGetTeamAnalyticsStandard(t *testing.T) { t.Fatal() } - if rows[0].Value != 3 { + if rows[0].Value != 4 { t.Log(rows.ToJson()) t.Fatal() } @@ -245,7 +245,7 @@ func TestGetTeamAnalyticsStandard(t *testing.T) { t.Fatal() } - if rows[2].Value != 5 { + if rows[2].Value != 6 { t.Log(rows.ToJson()) t.Fatal() } diff --git a/api/apitestlib.go b/api/apitestlib.go index 475469a36..df5ac5d26 100644 --- a/api/apitestlib.go +++ b/api/apitestlib.go @@ -21,6 +21,7 @@ type TestHelper struct { BasicUser2 *model.User BasicChannel *model.Channel BasicPost *model.Post + PinnedPost *model.Post SystemAdminClient *model.Client SystemAdminTeam *model.Team @@ -91,6 +92,9 @@ func (me *TestHelper) InitBasic() *TestHelper { me.BasicChannel = me.CreateChannel(me.BasicClient, me.BasicTeam) me.BasicPost = me.CreatePost(me.BasicClient, me.BasicChannel) + pinnedPostChannel := me.CreateChannel(me.BasicClient, me.BasicTeam) + me.PinnedPost = me.CreatePinnedPost(me.BasicClient, pinnedPostChannel) + return me } @@ -265,6 +269,21 @@ func (me *TestHelper) CreatePost(client *model.Client, channel *model.Channel) * return r } +func (me *TestHelper) CreatePinnedPost(client *model.Client, channel *model.Channel) *model.Post { + id := model.NewId() + + post := &model.Post{ + ChannelId: channel.Id, + Message: "message_" + id, + IsPinned: true, + } + + utils.DisableDebugLogForTest() + r := client.Must(client.CreatePost(post)).Data.(*model.Post) + utils.EnableDebugLogForTest() + return r +} + func (me *TestHelper) LoginBasic() { utils.DisableDebugLogForTest() me.BasicClient.Must(me.BasicClient.Login(me.BasicUser.Email, me.BasicUser.Password)) diff --git a/api/channel.go b/api/channel.go index 9c11f073e..0db3499e0 100644 --- a/api/channel.go +++ b/api/channel.go @@ -39,6 +39,7 @@ func InitChannel() { BaseRoutes.NeedChannel.Handle("/stats", ApiUserRequired(getChannelStats)).Methods("GET") BaseRoutes.NeedChannel.Handle("/members/{user_id:[A-Za-z0-9]+}", ApiUserRequired(getChannelMember)).Methods("GET") BaseRoutes.NeedChannel.Handle("/members/ids", ApiUserRequired(getChannelMembersByIds)).Methods("POST") + BaseRoutes.NeedChannel.Handle("/pinned", ApiUserRequired(getPinnedPosts)).Methods("GET") BaseRoutes.NeedChannel.Handle("/join", ApiUserRequired(join)).Methods("POST") BaseRoutes.NeedChannel.Handle("/leave", ApiUserRequired(leave)).Methods("POST") BaseRoutes.NeedChannel.Handle("/delete", ApiUserRequired(deleteChannel)).Methods("POST") @@ -598,6 +599,21 @@ func getMyChannelMembers(c *Context, w http.ResponseWriter, r *http.Request) { } } +func getPinnedPosts(c *Context, w http.ResponseWriter, r *http.Request) { + params := mux.Vars(r) + channelId := params["channel_id"] + posts := &model.PostList{} + + if result := <-app.Srv.Store.Channel().GetPinnedPosts(channelId); result.Err != nil { + c.Err = result.Err + return + } else { + posts = result.Data.(*model.PostList) + } + + w.Write([]byte(posts.ToJson())) +} + func addMember(c *Context, w http.ResponseWriter, r *http.Request) { params := mux.Vars(r) id := params["channel_id"] diff --git a/api/channel_test.go b/api/channel_test.go index 93c79d416..08136bc35 100644 --- a/api/channel_test.go +++ b/api/channel_test.go @@ -926,8 +926,8 @@ func TestGetMoreChannelsPage(t *testing.T) { } else { channels := r.Data.(*model.ChannelList) - // 1 for BasicChannel, 2 for open channels created above - if len(*channels) != 3 { + // 1 for BasicChannel, 1 for PinnedPostChannel, 2 for open channels created above + if len(*channels) != 4 { t.Fatal("wrong length") } @@ -990,11 +990,11 @@ func TestGetChannelCounts(t *testing.T) { } else { counts := result.Data.(*model.ChannelCounts) - if len(counts.Counts) != 5 { + if len(counts.Counts) != 6 { t.Fatal("wrong number of channel counts") } - if len(counts.UpdateTimes) != 5 { + if len(counts.UpdateTimes) != 6 { t.Fatal("wrong number of channel update times") } @@ -1024,8 +1024,8 @@ func TestGetMyChannelMembers(t *testing.T) { } else { members := result.Data.(*model.ChannelMembers) - // town-square, off-topic, basic test channel, channel1, channel2 - if len(*members) != 5 { + // town-square, off-topic, basic test channel, pinned post channel, channel1, channel2 + if len(*members) != 6 { t.Fatal("wrong number of members", len(*members)) } } @@ -2117,3 +2117,24 @@ func TestUpdateChannelRoles(t *testing.T) { t.Fatal("Channel member should not be able to promote itself to channel admin:", meta) } } + +func TestGetPinnedPosts(t *testing.T) { + th := Setup().InitBasic() + Client := th.BasicClient + + post1 := th.BasicPost + r1 := Client.Must(Client.GetPinnedPosts(post1.ChannelId)).Data.(*model.PostList) + if len(r1.Order) != 0 { + t.Fatal("should not have gotten a pinned post") + } + + post2 := th.PinnedPost + r2 := Client.Must(Client.GetPinnedPosts(post2.ChannelId)).Data.(*model.PostList) + if len(r2.Order) == 0 { + t.Fatal("should have gotten a pinned post") + } + + if _, ok := r2.Posts[post2.Id]; !ok { + t.Fatal("missing pinned post") + } +} diff --git a/api/post.go b/api/post.go index 4e7801e2b..d6de65e40 100644 --- a/api/post.go +++ b/api/post.go @@ -38,6 +38,8 @@ func InitPost() { BaseRoutes.NeedPost.Handle("/before/{offset:[0-9]+}/{num_posts:[0-9]+}", ApiUserRequired(getPostsBefore)).Methods("GET") BaseRoutes.NeedPost.Handle("/after/{offset:[0-9]+}/{num_posts:[0-9]+}", ApiUserRequired(getPostsAfter)).Methods("GET") BaseRoutes.NeedPost.Handle("/get_file_infos", ApiUserRequired(getFileInfosForPost)).Methods("GET") + BaseRoutes.NeedPost.Handle("/pin", ApiUserRequired(pinPost)).Methods("POST") + BaseRoutes.NeedPost.Handle("/unpin", ApiUserRequired(unpinPost)).Methods("POST") } func createPost(c *Context, w http.ResponseWriter, r *http.Request) { @@ -91,6 +93,59 @@ func updatePost(c *Context, w http.ResponseWriter, r *http.Request) { w.Write([]byte(rpost.ToJson())) } +func saveIsPinnedPost(c *Context, w http.ResponseWriter, r *http.Request, isPinned bool) { + params := mux.Vars(r) + + channelId := params["channel_id"] + if len(channelId) != 26 { + c.SetInvalidParam("savedIsPinnedPost", "channelId") + return + } + + postId := params["post_id"] + if len(postId) != 26 { + c.SetInvalidParam("savedIsPinnedPost", "postId") + return + } + + pchan := app.Srv.Store.Post().Get(postId) + + var oldPost *model.Post + if result := <-pchan; result.Err != nil { + c.Err = result.Err + return + } else { + oldPost = result.Data.(*model.PostList).Posts[postId] + newPost := &model.Post{} + *newPost = *oldPost + newPost.IsPinned = isPinned + + if result := <-app.Srv.Store.Post().Update(newPost, oldPost); result.Err != nil { + c.Err = result.Err + return + } else { + rpost := result.Data.(*model.Post) + + message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_POST_EDITED, "", rpost.ChannelId, "", nil) + message.Add("post", rpost.ToJson()) + + go app.Publish(message) + + app.InvalidateCacheForChannelPosts(rpost.ChannelId) + + w.Write([]byte(rpost.ToJson())) + } + } +} + +func pinPost(c *Context, w http.ResponseWriter, r *http.Request) { + saveIsPinnedPost(c, w, r, true) +} + +func unpinPost(c *Context, w http.ResponseWriter, r *http.Request) { + saveIsPinnedPost(c, w, r, false) +} + func getFlaggedPosts(c *Context, w http.ResponseWriter, r *http.Request) { params := mux.Vars(r) diff --git a/api/post_test.go b/api/post_test.go index bab27cc65..5546e7165 100644 --- a/api/post_test.go +++ b/api/post_test.go @@ -1378,3 +1378,49 @@ func TestGetOpenGraphMetadata(t *testing.T) { t.Fatal("should have failed with 501 - disabled link previews") } } + +func TestPinPost(t *testing.T) { + th := Setup().InitBasic() + Client := th.BasicClient + + post := th.BasicPost + if rupost1, err := Client.PinPost(post.ChannelId, post.Id); err != nil { + t.Fatal(err) + } else { + if rupost1.Data.(*model.Post).IsPinned != true { + t.Fatal("failed to pin post") + } + } + + pinnedPost := th.PinnedPost + if rupost2, err := Client.PinPost(pinnedPost.ChannelId, pinnedPost.Id); err != nil { + t.Fatal(err) + } else { + if rupost2.Data.(*model.Post).IsPinned != true { + t.Fatal("pinning a post should be idempotent") + } + } +} + +func TestUnpinPost(t *testing.T) { + th := Setup().InitBasic() + Client := th.BasicClient + + pinnedPost := th.PinnedPost + if rupost1, err := Client.UnpinPost(pinnedPost.ChannelId, pinnedPost.Id); err != nil { + t.Fatal(err) + } else { + if rupost1.Data.(*model.Post).IsPinned != false { + t.Fatal("failed to unpin post") + } + } + + post := th.BasicPost + if rupost2, err := Client.UnpinPost(post.ChannelId, post.Id); err != nil { + t.Fatal(err) + } else { + if rupost2.Data.(*model.Post).IsPinned != false { + t.Fatal("unpinning a post should be idempotent") + } + } +} |