Add pinned posts (#4217)
Этот коммит содержится в:
коммит произвёл
George Goldberg
родитель
482a0fb5fc
Коммит
fe38d6d5bb
@@ -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()
|
||||
}
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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"]
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
}
|
||||
|
||||
55
api/post.go
55
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)
|
||||
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ссылка в новой задаче
Block a user