Mm 43609 (#20657)
* return first inaccessible post time instead of has inaccessible posts
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
478ff50ffd
Коммит
77881fc357
@@ -401,7 +401,7 @@ func getPost(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
// Post is inaccessible due to cloud plan's limit.
|
// Post is inaccessible due to cloud plan's limit.
|
||||||
if err.Id == "app.post.cloud.get.app_error" {
|
if err.Id == "app.post.cloud.get.app_error" {
|
||||||
w.Header().Set(model.HeaderHasInaccessiblePosts, "true")
|
w.Header().Set(model.HeaderFirstInaccessiblePostTime, "1")
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
@@ -438,7 +438,7 @@ func getPostsByIds(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
postsList, hasInaccessiblePosts, err := c.App.GetPostsByIds(postIDs)
|
postsList, firstInaccessiblePostTime, err := c.App.GetPostsByIds(postIDs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Err = err
|
c.Err = err
|
||||||
return
|
return
|
||||||
@@ -471,7 +471,7 @@ func getPostsByIds(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
posts = append(posts, post)
|
posts = append(posts, post)
|
||||||
}
|
}
|
||||||
|
|
||||||
w.Header().Set(model.HeaderHasInaccessiblePosts, strconv.FormatBool(hasInaccessiblePosts))
|
w.Header().Set(model.HeaderFirstInaccessiblePostTime, strconv.FormatInt(firstInaccessiblePostTime, 10))
|
||||||
|
|
||||||
if err := json.NewEncoder(w).Encode(posts); err != nil {
|
if err := json.NewEncoder(w).Encode(posts); err != nil {
|
||||||
mlog.Warn("Error while writing response", mlog.Err(err))
|
mlog.Warn("Error while writing response", mlog.Err(err))
|
||||||
|
|||||||
@@ -202,7 +202,7 @@ type AppIface interface {
|
|||||||
// lock instead.
|
// lock instead.
|
||||||
GetPluginsEnvironment() *plugin.Environment
|
GetPluginsEnvironment() *plugin.Environment
|
||||||
// GetPostsByIds response bool value indicates, if the post is inaccessible due to cloud plan's limit.
|
// GetPostsByIds response bool value indicates, if the post is inaccessible due to cloud plan's limit.
|
||||||
GetPostsByIds(postIDs []string) ([]*model.Post, bool, *model.AppError)
|
GetPostsByIds(postIDs []string) ([]*model.Post, int64, *model.AppError)
|
||||||
// GetPostsUsage returns the total posts count rounded down to the most
|
// GetPostsUsage returns the total posts count rounded down to the most
|
||||||
// significant digit
|
// significant digit
|
||||||
GetPostsUsage() (int64, *model.AppError)
|
GetPostsUsage() (int64, *model.AppError)
|
||||||
|
|||||||
@@ -7881,7 +7881,7 @@ func (a *OpenTracingAppLayer) GetPostsBeforePost(options model.GetPostsOptions)
|
|||||||
return resultVar0, resultVar1
|
return resultVar0, resultVar1
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *OpenTracingAppLayer) GetPostsByIds(postIDs []string) ([]*model.Post, bool, *model.AppError) {
|
func (a *OpenTracingAppLayer) GetPostsByIds(postIDs []string) ([]*model.Post, int64, *model.AppError) {
|
||||||
origCtx := a.ctx
|
origCtx := a.ctx
|
||||||
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.GetPostsByIds")
|
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.GetPostsByIds")
|
||||||
|
|
||||||
|
|||||||
16
app/post.go
16
app/post.go
@@ -870,11 +870,11 @@ func (a *App) GetSinglePost(postID string, includeDeleted bool) (*model.Post, *m
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
isInaccessible, appErr := a.isInaccessiblePost(post)
|
firstInaccessiblePostTime, appErr := a.isInaccessiblePost(post)
|
||||||
if appErr != nil {
|
if appErr != nil {
|
||||||
return nil, appErr
|
return nil, appErr
|
||||||
}
|
}
|
||||||
if isInaccessible {
|
if firstInaccessiblePostTime != 0 {
|
||||||
return nil, model.NewAppError("GetSinglePost", "app.post.cloud.get.app_error", nil, "", http.StatusForbidden)
|
return nil, model.NewAppError("GetSinglePost", "app.post.cloud.get.app_error", nil, "", http.StatusForbidden)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1881,24 +1881,24 @@ func (a *App) GetPostIfAuthorized(c request.CTX, postID string, session *model.S
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetPostsByIds response bool value indicates, if the post is inaccessible due to cloud plan's limit.
|
// GetPostsByIds response bool value indicates, if the post is inaccessible due to cloud plan's limit.
|
||||||
func (a *App) GetPostsByIds(postIDs []string) ([]*model.Post, bool, *model.AppError) {
|
func (a *App) GetPostsByIds(postIDs []string) ([]*model.Post, int64, *model.AppError) {
|
||||||
posts, err := a.Srv().Store.Post().GetPostsByIds(postIDs)
|
posts, err := a.Srv().Store.Post().GetPostsByIds(postIDs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
var nfErr *store.ErrNotFound
|
var nfErr *store.ErrNotFound
|
||||||
switch {
|
switch {
|
||||||
case errors.As(err, &nfErr):
|
case errors.As(err, &nfErr):
|
||||||
return nil, false, model.NewAppError("GetPostsByIds", "app.post.get.app_error", nil, nfErr.Error(), http.StatusNotFound)
|
return nil, 0, model.NewAppError("GetPostsByIds", "app.post.get.app_error", nil, nfErr.Error(), http.StatusNotFound)
|
||||||
default:
|
default:
|
||||||
return nil, false, model.NewAppError("GetPostsByIds", "app.post.get.app_error", nil, err.Error(), http.StatusInternalServerError)
|
return nil, 0, model.NewAppError("GetPostsByIds", "app.post.get.app_error", nil, err.Error(), http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
posts, hasInaccessiblePosts, appErr := a.getFilteredAccessiblePosts(posts, filterPostOptions{assumeSortedCreatedAt: true})
|
posts, firstInaccessiblePostTime, appErr := a.getFilteredAccessiblePosts(posts, filterPostOptions{assumeSortedCreatedAt: true})
|
||||||
if appErr != nil {
|
if appErr != nil {
|
||||||
return nil, false, appErr
|
return nil, 0, appErr
|
||||||
}
|
}
|
||||||
|
|
||||||
return posts, hasInaccessiblePosts, nil
|
return posts, firstInaccessiblePostTime, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *App) GetTopThreadsForTeamSince(c request.CTX, teamID, userID string, opts *model.InsightsOpts) (*model.TopThreadList, *model.AppError) {
|
func (a *App) GetTopThreadsForTeamSince(c request.CTX, teamID, userID string, opts *model.InsightsOpts) (*model.TopThreadList, *model.AppError) {
|
||||||
|
|||||||
@@ -27,6 +27,19 @@ func (b accessibleBounds) noAccessible() bool {
|
|||||||
return b.start == noAccessibleBounds.start && b.end == noAccessibleBounds.end
|
return b.start == noAccessibleBounds.start && b.end == noAccessibleBounds.end
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// assumes checking was already performed that at least one post is inaccessible
|
||||||
|
func (b accessibleBounds) getInaccessibleRange(listLength int) (int, int) {
|
||||||
|
var start, end int
|
||||||
|
if b.start == 0 {
|
||||||
|
start = b.end + 1
|
||||||
|
end = listLength - 1
|
||||||
|
} else {
|
||||||
|
start = 0
|
||||||
|
end = b.start - 1
|
||||||
|
}
|
||||||
|
return start, end
|
||||||
|
}
|
||||||
|
|
||||||
var noAccessibleBounds = accessibleBounds{start: -1, end: -1}
|
var noAccessibleBounds = accessibleBounds{start: -1, end: -1}
|
||||||
var allAccessibleBounds = func(lenPosts int) accessibleBounds { return accessibleBounds{start: 0, end: lenPosts - 1} }
|
var allAccessibleBounds = func(lenPosts int) accessibleBounds { return accessibleBounds{start: 0, end: lenPosts - 1} }
|
||||||
|
|
||||||
@@ -82,11 +95,13 @@ func linearFilterPostList(postList *model.PostList, earliestAccessibleTime int64
|
|||||||
|
|
||||||
n := 0
|
n := 0
|
||||||
for i, postId := range order {
|
for i, postId := range order {
|
||||||
if posts[postId].CreateAt >= earliestAccessibleTime {
|
if createAt := posts[postId].CreateAt; createAt >= earliestAccessibleTime {
|
||||||
order[n] = order[i]
|
order[n] = order[i]
|
||||||
n++
|
n++
|
||||||
} else {
|
} else {
|
||||||
postList.HasInaccessiblePosts = true
|
if createAt > postList.FirstInaccessiblePostTime {
|
||||||
|
postList.FirstInaccessiblePostTime = createAt
|
||||||
|
}
|
||||||
delete(posts, postId)
|
delete(posts, postId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -96,8 +111,10 @@ func linearFilterPostList(postList *model.PostList, earliestAccessibleTime int64
|
|||||||
// for example GetPosts in the CollapsedThreads = false path, parents are not added
|
// for example GetPosts in the CollapsedThreads = false path, parents are not added
|
||||||
// to Order
|
// to Order
|
||||||
for postId := range posts {
|
for postId := range posts {
|
||||||
if posts[postId].CreateAt < earliestAccessibleTime {
|
if createAt := posts[postId].CreateAt; createAt < earliestAccessibleTime {
|
||||||
postList.HasInaccessiblePosts = true
|
if createAt > postList.FirstInaccessiblePostTime {
|
||||||
|
postList.FirstInaccessiblePostTime = createAt
|
||||||
|
}
|
||||||
delete(posts, postId)
|
delete(posts, postId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -106,18 +123,20 @@ func linearFilterPostList(postList *model.PostList, earliestAccessibleTime int64
|
|||||||
// linearFilterPostsSlice make no assumptions about ordering, go through posts one by one
|
// linearFilterPostsSlice make no assumptions about ordering, go through posts one by one
|
||||||
// this is the slower fallback that is still safe if we can not
|
// this is the slower fallback that is still safe if we can not
|
||||||
// assume posts are ordered by CreatedAt
|
// assume posts are ordered by CreatedAt
|
||||||
func linearFilterPostsSlice(posts []*model.Post, earliestAccessibleTime int64) ([]*model.Post, bool) {
|
func linearFilterPostsSlice(posts []*model.Post, earliestAccessibleTime int64) ([]*model.Post, int64) {
|
||||||
hasInaccessiblePosts := false
|
var firstInaccessiblePostTime int64 = 0
|
||||||
n := 0
|
n := 0
|
||||||
for i := range posts {
|
for i := range posts {
|
||||||
if posts[i].CreateAt >= earliestAccessibleTime {
|
if createAt := posts[i].CreateAt; createAt >= earliestAccessibleTime {
|
||||||
posts[n] = posts[i]
|
posts[n] = posts[i]
|
||||||
n++
|
n++
|
||||||
} else {
|
} else {
|
||||||
hasInaccessiblePosts = true
|
if createAt > firstInaccessiblePostTime {
|
||||||
|
firstInaccessiblePostTime = createAt
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return posts[:n], hasInaccessiblePosts
|
}
|
||||||
|
return posts[:n], firstInaccessiblePostTime
|
||||||
}
|
}
|
||||||
|
|
||||||
// filterInaccessiblePosts filters out the posts, past the cloud limit
|
// filterInaccessiblePosts filters out the posts, past the cloud limit
|
||||||
@@ -146,13 +165,18 @@ func (a *App) filterInaccessiblePosts(postList *model.PostList, options filterPo
|
|||||||
}
|
}
|
||||||
if bounds.noAccessible() {
|
if bounds.noAccessible() {
|
||||||
if lenPosts > 0 {
|
if lenPosts > 0 {
|
||||||
postList.HasInaccessiblePosts = true
|
firstPostCreatedAt := postList.Posts[postList.Order[0]].CreateAt
|
||||||
|
lastPostCreatedAt := postList.Posts[postList.Order[len(postList.Order)-1]].CreateAt
|
||||||
|
postList.FirstInaccessiblePostTime = max(firstPostCreatedAt, lastPostCreatedAt)
|
||||||
}
|
}
|
||||||
postList.Posts = map[string]*model.Post{}
|
postList.Posts = map[string]*model.Post{}
|
||||||
postList.Order = []string{}
|
postList.Order = []string{}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
postList.HasInaccessiblePosts = true
|
startInaccessibleIndex, endInaccessibleIndex := bounds.getInaccessibleRange(len(postList.Order))
|
||||||
|
startInaccessibleCreatedAt := postList.Posts[postList.Order[startInaccessibleIndex]].CreateAt
|
||||||
|
endInaccessibleCreatedAt := postList.Posts[postList.Order[endInaccessibleIndex]].CreateAt
|
||||||
|
postList.FirstInaccessiblePostTime = max(startInaccessibleCreatedAt, endInaccessibleCreatedAt)
|
||||||
|
|
||||||
posts := postList.Posts
|
posts := postList.Posts
|
||||||
order := postList.Order
|
order := postList.Order
|
||||||
@@ -183,9 +207,9 @@ func (a *App) filterInaccessiblePosts(postList *model.PostList, options filterPo
|
|||||||
}
|
}
|
||||||
|
|
||||||
// isInaccessiblePost indicates if the post is past the cloud plan's limit.
|
// isInaccessiblePost indicates if the post is past the cloud plan's limit.
|
||||||
func (a *App) isInaccessiblePost(post *model.Post) (bool, *model.AppError) {
|
func (a *App) isInaccessiblePost(post *model.Post) (int64, *model.AppError) {
|
||||||
if post == nil {
|
if post == nil {
|
||||||
return false, nil
|
return 0, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
pl := &model.PostList{
|
pl := &model.PostList{
|
||||||
@@ -193,22 +217,22 @@ func (a *App) isInaccessiblePost(post *model.Post) (bool, *model.AppError) {
|
|||||||
Posts: map[string]*model.Post{post.Id: post},
|
Posts: map[string]*model.Post{post.Id: post},
|
||||||
}
|
}
|
||||||
|
|
||||||
return pl.HasInaccessiblePosts, a.filterInaccessiblePosts(pl, filterPostOptions{assumeSortedCreatedAt: true})
|
return pl.FirstInaccessiblePostTime, a.filterInaccessiblePosts(pl, filterPostOptions{assumeSortedCreatedAt: true})
|
||||||
}
|
}
|
||||||
|
|
||||||
// getFilteredAccessiblePosts returns accessible posts filtered as per the cloud plan's limit and also indicates if there were any inaccessible posts
|
// getFilteredAccessiblePosts returns accessible posts filtered as per the cloud plan's limit and also indicates if there were any inaccessible posts
|
||||||
func (a *App) getFilteredAccessiblePosts(posts []*model.Post, options filterPostOptions) ([]*model.Post, bool, *model.AppError) {
|
func (a *App) getFilteredAccessiblePosts(posts []*model.Post, options filterPostOptions) ([]*model.Post, int64, *model.AppError) {
|
||||||
if len(posts) == 0 {
|
if len(posts) == 0 {
|
||||||
return posts, false, nil
|
return posts, 0, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
filteredPosts := []*model.Post{}
|
filteredPosts := []*model.Post{}
|
||||||
lastAccessiblePostTime, appErr := a.GetLastAccessiblePostTime()
|
lastAccessiblePostTime, appErr := a.GetLastAccessiblePostTime()
|
||||||
if appErr != nil {
|
if appErr != nil {
|
||||||
return filteredPosts, false, model.NewAppError("getFilteredAccessiblePosts", "app.last_accessible_post.app_error", nil, appErr.Error(), http.StatusInternalServerError)
|
return filteredPosts, 0, model.NewAppError("getFilteredAccessiblePosts", "app.last_accessible_post.app_error", nil, appErr.Error(), http.StatusInternalServerError)
|
||||||
} else if lastAccessiblePostTime == 0 {
|
} else if lastAccessiblePostTime == 0 {
|
||||||
// No need to filter, all posts are accessible
|
// No need to filter, all posts are accessible
|
||||||
return posts, false, nil
|
return posts, 0, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if options.assumeSortedCreatedAt {
|
if options.assumeSortedCreatedAt {
|
||||||
@@ -216,16 +240,26 @@ func (a *App) getFilteredAccessiblePosts(posts []*model.Post, options filterPost
|
|||||||
getCreateAt := func(i int) int64 { return posts[i].CreateAt }
|
getCreateAt := func(i int) int64 { return posts[i].CreateAt }
|
||||||
bounds := getTimeSortedPostAccessibleBounds(lastAccessiblePostTime, lenPosts, getCreateAt)
|
bounds := getTimeSortedPostAccessibleBounds(lastAccessiblePostTime, lenPosts, getCreateAt)
|
||||||
if bounds.allAccessible(lenPosts) {
|
if bounds.allAccessible(lenPosts) {
|
||||||
return posts, false, nil
|
return posts, 0, nil
|
||||||
}
|
}
|
||||||
if bounds.noAccessible() {
|
if bounds.noAccessible() {
|
||||||
return filteredPosts, lenPosts > 0, nil
|
var firstInaccessiblePostTime int64 = 0
|
||||||
|
if lenPosts > 0 {
|
||||||
|
firstPostCreatedAt := posts[0].CreateAt
|
||||||
|
lastPostCreatedAt := posts[len(posts)-1].CreateAt
|
||||||
|
firstInaccessiblePostTime = max(firstPostCreatedAt, lastPostCreatedAt)
|
||||||
|
}
|
||||||
|
return filteredPosts, firstInaccessiblePostTime, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
startInaccessibleIndex, endInaccessibleIndex := bounds.getInaccessibleRange(len(posts))
|
||||||
|
firstPostCreatedAt := posts[startInaccessibleIndex].CreateAt
|
||||||
|
lastPostCreatedAt := posts[endInaccessibleIndex].CreateAt
|
||||||
|
firstInaccessiblePostTime := max(firstPostCreatedAt, lastPostCreatedAt)
|
||||||
filteredPosts = posts[bounds.start : bounds.end+1]
|
filteredPosts = posts[bounds.start : bounds.end+1]
|
||||||
return filteredPosts, true, nil
|
return filteredPosts, firstInaccessiblePostTime, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
filteredPosts, hasInaccessiblePosts := linearFilterPostsSlice(posts, lastAccessiblePostTime)
|
filteredPosts, firstInaccessiblePostTime := linearFilterPostsSlice(posts, lastAccessiblePostTime)
|
||||||
return filteredPosts, hasInaccessiblePosts, nil
|
return filteredPosts, firstInaccessiblePostTime, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -231,6 +231,7 @@ func TestFilterInaccessiblePosts(t *testing.T) {
|
|||||||
"post_d",
|
"post_d",
|
||||||
"post_e",
|
"post_e",
|
||||||
}, postList.Order)
|
}, postList.Order)
|
||||||
|
assert.Equal(t, int64(1), postList.FirstInaccessiblePostTime)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("descending order returns correct posts", func(t *testing.T) {
|
t.Run("descending order returns correct posts", func(t *testing.T) {
|
||||||
@@ -259,6 +260,8 @@ func TestFilterInaccessiblePosts(t *testing.T) {
|
|||||||
"post_d",
|
"post_d",
|
||||||
"post_c",
|
"post_c",
|
||||||
}, postList.Order)
|
}, postList.Order)
|
||||||
|
|
||||||
|
assert.Equal(t, int64(1), postList.FirstInaccessiblePostTime)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("handles mixed create at ordering correctly if correct options given", func(t *testing.T) {
|
t.Run("handles mixed create at ordering correctly if correct options given", func(t *testing.T) {
|
||||||
@@ -332,18 +335,20 @@ func TestGetFilteredAccessiblePosts(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("ascending order returns correct posts", func(t *testing.T) {
|
t.Run("ascending order returns correct posts", func(t *testing.T) {
|
||||||
posts := []*model.Post{postFromCreateAt(0), postFromCreateAt(1), postFromCreateAt(2), postFromCreateAt(3), postFromCreateAt(4)}
|
posts := []*model.Post{postFromCreateAt(0), postFromCreateAt(1), postFromCreateAt(2), postFromCreateAt(3), postFromCreateAt(4)}
|
||||||
filteredPosts, _, appErr := th.App.getFilteredAccessiblePosts(posts, filterPostOptions{assumeSortedCreatedAt: true})
|
filteredPosts, firstInaccessiblePostTime, appErr := th.App.getFilteredAccessiblePosts(posts, filterPostOptions{assumeSortedCreatedAt: true})
|
||||||
|
|
||||||
assert.Nil(t, appErr)
|
assert.Nil(t, appErr)
|
||||||
assert.Equal(t, []*model.Post{postFromCreateAt(2), postFromCreateAt(3), postFromCreateAt(4)}, filteredPosts)
|
assert.Equal(t, []*model.Post{postFromCreateAt(2), postFromCreateAt(3), postFromCreateAt(4)}, filteredPosts)
|
||||||
|
assert.Equal(t, int64(1), firstInaccessiblePostTime)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("descending order returns correct posts", func(t *testing.T) {
|
t.Run("descending order returns correct posts", func(t *testing.T) {
|
||||||
posts := []*model.Post{postFromCreateAt(4), postFromCreateAt(3), postFromCreateAt(2), postFromCreateAt(1), postFromCreateAt(0)}
|
posts := []*model.Post{postFromCreateAt(4), postFromCreateAt(3), postFromCreateAt(2), postFromCreateAt(1), postFromCreateAt(0)}
|
||||||
filteredPosts, _, appErr := th.App.getFilteredAccessiblePosts(posts, filterPostOptions{assumeSortedCreatedAt: true})
|
filteredPosts, firstInaccessiblePostTime, appErr := th.App.getFilteredAccessiblePosts(posts, filterPostOptions{assumeSortedCreatedAt: true})
|
||||||
|
|
||||||
assert.Nil(t, appErr)
|
assert.Nil(t, appErr)
|
||||||
assert.Equal(t, []*model.Post{postFromCreateAt(4), postFromCreateAt(3), postFromCreateAt(2)}, filteredPosts)
|
assert.Equal(t, []*model.Post{postFromCreateAt(4), postFromCreateAt(3), postFromCreateAt(2)}, filteredPosts)
|
||||||
|
assert.Equal(t, int64(1), firstInaccessiblePostTime)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("handles mixed create at ordering correctly if correct options given", func(t *testing.T) {
|
t.Run("handles mixed create at ordering correctly if correct options given", func(t *testing.T) {
|
||||||
@@ -366,12 +371,40 @@ func TestIsInaccessiblePost(t *testing.T) {
|
|||||||
defer th.TearDown()
|
defer th.TearDown()
|
||||||
|
|
||||||
post := &model.Post{CreateAt: 3}
|
post := &model.Post{CreateAt: 3}
|
||||||
r, appErr := th.App.isInaccessiblePost(post)
|
firstInaccessiblePostTime, appErr := th.App.isInaccessiblePost(post)
|
||||||
assert.Nil(t, appErr)
|
assert.Nil(t, appErr)
|
||||||
assert.Equal(t, false, r)
|
assert.Equal(t, int64(0), firstInaccessiblePostTime)
|
||||||
|
|
||||||
post = &model.Post{CreateAt: 1}
|
post = &model.Post{CreateAt: 1}
|
||||||
r, appErr = th.App.isInaccessiblePost(post)
|
firstInaccessiblePostTime, appErr = th.App.isInaccessiblePost(post)
|
||||||
assert.Nil(t, appErr)
|
assert.Nil(t, appErr)
|
||||||
assert.Equal(t, true, r)
|
assert.Equal(t, int64(1), firstInaccessiblePostTime)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_getInaccessibleRange(t *testing.T) {
|
||||||
|
type test struct {
|
||||||
|
label string
|
||||||
|
bounds accessibleBounds
|
||||||
|
listLength int
|
||||||
|
expectedStart int
|
||||||
|
expectedEnd int
|
||||||
|
}
|
||||||
|
tests := []test{
|
||||||
|
{
|
||||||
|
label: "inaccessible at end",
|
||||||
|
bounds: accessibleBounds{start: 0, end: 3},
|
||||||
|
listLength: 6,
|
||||||
|
expectedStart: 4,
|
||||||
|
expectedEnd: 5,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
t.Run(test.label, func(t *testing.T) {
|
||||||
|
start, end := test.bounds.getInaccessibleRange(test.listLength)
|
||||||
|
|
||||||
|
assert.Equal(t, test.expectedStart, start)
|
||||||
|
assert.Equal(t, test.expectedEnd, end)
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ func (a *App) PreparePostListForClient(c request.CTX, originalList *model.PostLi
|
|||||||
NextPostId: originalList.NextPostId,
|
NextPostId: originalList.NextPostId,
|
||||||
PrevPostId: originalList.PrevPostId,
|
PrevPostId: originalList.PrevPostId,
|
||||||
HasNext: originalList.HasNext,
|
HasNext: originalList.HasNext,
|
||||||
HasInaccessiblePosts: originalList.HasInaccessiblePosts,
|
FirstInaccessiblePostTime: originalList.FirstInaccessiblePostTime,
|
||||||
}
|
}
|
||||||
|
|
||||||
for id, originalPost := range originalList.Posts {
|
for id, originalPost := range originalList.Posts {
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ const (
|
|||||||
HeaderRemoteclusterId = "X-RemoteCluster-Id"
|
HeaderRemoteclusterId = "X-RemoteCluster-Id"
|
||||||
HeaderRequestedWith = "X-Requested-With"
|
HeaderRequestedWith = "X-Requested-With"
|
||||||
HeaderRequestedWithXML = "XMLHttpRequest"
|
HeaderRequestedWithXML = "XMLHttpRequest"
|
||||||
HeaderHasInaccessiblePosts = "Has-Inaccessible-Posts"
|
HeaderFirstInaccessiblePostTime = "First-Inaccessible-Post-Time"
|
||||||
HeaderRange = "Range"
|
HeaderRange = "Range"
|
||||||
STATUS = "status"
|
STATUS = "status"
|
||||||
StatusOk = "OK"
|
StatusOk = "OK"
|
||||||
|
|||||||
@@ -16,8 +16,8 @@ type PostList struct {
|
|||||||
PrevPostId string `json:"prev_post_id"`
|
PrevPostId string `json:"prev_post_id"`
|
||||||
// HasNext indicates whether there are more items to be fetched or not.
|
// HasNext indicates whether there are more items to be fetched or not.
|
||||||
HasNext bool `json:"has_next"`
|
HasNext bool `json:"has_next"`
|
||||||
// HasInaccessiblePosts tells if there are inaccessible posts, past the cloud limit.
|
// If there are inaccessible posts, FirstInaccessiblePostTime is the time of the latest inaccessible post
|
||||||
HasInaccessiblePosts bool `json:"has_inaccessible_posts"`
|
FirstInaccessiblePostTime int64 `json:"first_inaccessible_post_time"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPostList() *PostList {
|
func NewPostList() *PostList {
|
||||||
@@ -42,7 +42,7 @@ func (o *PostList) Clone() *PostList {
|
|||||||
NextPostId: o.NextPostId,
|
NextPostId: o.NextPostId,
|
||||||
PrevPostId: o.PrevPostId,
|
PrevPostId: o.PrevPostId,
|
||||||
HasNext: o.HasNext,
|
HasNext: o.HasNext,
|
||||||
HasInaccessiblePosts: o.HasInaccessiblePosts,
|
FirstInaccessiblePostTime: o.FirstInaccessiblePostTime,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user