github.com/haalcala/mattermost-server-change-repo/v5@v5.33.2/store/storetest/post_store.go (about)

     1  // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
     2  // See LICENSE.txt for license information.
     3  
     4  package storetest
     5  
     6  import (
     7  	"fmt"
     8  	"sort"
     9  	"strings"
    10  	"testing"
    11  	"time"
    12  
    13  	"github.com/stretchr/testify/assert"
    14  	"github.com/stretchr/testify/require"
    15  
    16  	"github.com/mattermost/mattermost-server/v5/model"
    17  	"github.com/mattermost/mattermost-server/v5/store"
    18  	"github.com/mattermost/mattermost-server/v5/utils"
    19  )
    20  
    21  func TestPostStore(t *testing.T, ss store.Store, s SqlStore) {
    22  	t.Run("SaveMultiple", func(t *testing.T) { testPostStoreSaveMultiple(t, ss) })
    23  	t.Run("Save", func(t *testing.T) { testPostStoreSave(t, ss) })
    24  	t.Run("SaveAndUpdateChannelMsgCounts", func(t *testing.T) { testPostStoreSaveChannelMsgCounts(t, ss) })
    25  	t.Run("Get", func(t *testing.T) { testPostStoreGet(t, ss) })
    26  	t.Run("GetSingle", func(t *testing.T) { testPostStoreGetSingle(t, ss) })
    27  	t.Run("Update", func(t *testing.T) { testPostStoreUpdate(t, ss) })
    28  	t.Run("Delete", func(t *testing.T) { testPostStoreDelete(t, ss) })
    29  	t.Run("Delete1Level", func(t *testing.T) { testPostStoreDelete1Level(t, ss) })
    30  	t.Run("Delete2Level", func(t *testing.T) { testPostStoreDelete2Level(t, ss) })
    31  	t.Run("PermDelete1Level", func(t *testing.T) { testPostStorePermDelete1Level(t, ss) })
    32  	t.Run("PermDelete1Level2", func(t *testing.T) { testPostStorePermDelete1Level2(t, ss) })
    33  	t.Run("GetWithChildren", func(t *testing.T) { testPostStoreGetWithChildren(t, ss) })
    34  	t.Run("GetPostsWithDetails", func(t *testing.T) { testPostStoreGetPostsWithDetails(t, ss) })
    35  	t.Run("GetPostsBeforeAfter", func(t *testing.T) { testPostStoreGetPostsBeforeAfter(t, ss) })
    36  	t.Run("GetPostsSince", func(t *testing.T) { testPostStoreGetPostsSince(t, ss) })
    37  	t.Run("GetPosts", func(t *testing.T) { testPostStoreGetPosts(t, ss) })
    38  	t.Run("GetPostBeforeAfter", func(t *testing.T) { testPostStoreGetPostBeforeAfter(t, ss) })
    39  	t.Run("UserCountsWithPostsByDay", func(t *testing.T) { testUserCountsWithPostsByDay(t, ss) })
    40  	t.Run("PostCountsByDay", func(t *testing.T) { testPostCountsByDay(t, ss) })
    41  	t.Run("GetFlaggedPostsForTeam", func(t *testing.T) { testPostStoreGetFlaggedPostsForTeam(t, ss, s) })
    42  	t.Run("GetFlaggedPosts", func(t *testing.T) { testPostStoreGetFlaggedPosts(t, ss) })
    43  	t.Run("GetFlaggedPostsForChannel", func(t *testing.T) { testPostStoreGetFlaggedPostsForChannel(t, ss) })
    44  	t.Run("GetPostsCreatedAt", func(t *testing.T) { testPostStoreGetPostsCreatedAt(t, ss) })
    45  	t.Run("Overwrite", func(t *testing.T) { testPostStoreOverwrite(t, ss) })
    46  	t.Run("OverwriteMultiple", func(t *testing.T) { testPostStoreOverwriteMultiple(t, ss) })
    47  	t.Run("GetPostsByIds", func(t *testing.T) { testPostStoreGetPostsByIds(t, ss) })
    48  	t.Run("GetPostsBatchForIndexing", func(t *testing.T) { testPostStoreGetPostsBatchForIndexing(t, ss) })
    49  	t.Run("PermanentDeleteBatch", func(t *testing.T) { testPostStorePermanentDeleteBatch(t, ss) })
    50  	t.Run("GetOldest", func(t *testing.T) { testPostStoreGetOldest(t, ss) })
    51  	t.Run("TestGetMaxPostSize", func(t *testing.T) { testGetMaxPostSize(t, ss) })
    52  	t.Run("GetParentsForExportAfter", func(t *testing.T) { testPostStoreGetParentsForExportAfter(t, ss) })
    53  	t.Run("GetRepliesForExport", func(t *testing.T) { testPostStoreGetRepliesForExport(t, ss) })
    54  	t.Run("GetDirectPostParentsForExportAfter", func(t *testing.T) { testPostStoreGetDirectPostParentsForExportAfter(t, ss, s) })
    55  	t.Run("GetDirectPostParentsForExportAfterDeleted", func(t *testing.T) { testPostStoreGetDirectPostParentsForExportAfterDeleted(t, ss, s) })
    56  	t.Run("GetDirectPostParentsForExportAfterBatched", func(t *testing.T) { testPostStoreGetDirectPostParentsForExportAfterBatched(t, ss, s) })
    57  }
    58  
    59  func testPostStoreSave(t *testing.T, ss store.Store) {
    60  	t.Run("Save post", func(t *testing.T) {
    61  		o1 := model.Post{}
    62  		o1.ChannelId = model.NewId()
    63  		o1.UserId = model.NewId()
    64  		o1.Message = "zz" + model.NewId() + "b"
    65  
    66  		p, err := ss.Post().Save(&o1)
    67  		require.NoError(t, err, "couldn't save item")
    68  		assert.Equal(t, int64(0), p.ReplyCount)
    69  	})
    70  
    71  	t.Run("Save replies", func(t *testing.T) {
    72  		o1 := model.Post{}
    73  		o1.ChannelId = model.NewId()
    74  		o1.UserId = model.NewId()
    75  		o1.RootId = model.NewId()
    76  		o1.Message = "zz" + model.NewId() + "b"
    77  
    78  		o2 := model.Post{}
    79  		o2.ChannelId = model.NewId()
    80  		o2.UserId = model.NewId()
    81  		o2.RootId = o1.RootId
    82  		o2.Message = "zz" + model.NewId() + "b"
    83  
    84  		o3 := model.Post{}
    85  		o3.ChannelId = model.NewId()
    86  		o3.UserId = model.NewId()
    87  		o3.RootId = model.NewId()
    88  		o3.Message = "zz" + model.NewId() + "b"
    89  
    90  		p1, err := ss.Post().Save(&o1)
    91  		require.NoError(t, err, "couldn't save item")
    92  		assert.Equal(t, int64(1), p1.ReplyCount)
    93  
    94  		p2, err := ss.Post().Save(&o2)
    95  		require.NoError(t, err, "couldn't save item")
    96  		assert.Equal(t, int64(2), p2.ReplyCount)
    97  
    98  		p3, err := ss.Post().Save(&o3)
    99  		require.NoError(t, err, "couldn't save item")
   100  		assert.Equal(t, int64(1), p3.ReplyCount)
   101  	})
   102  
   103  	t.Run("Try to save existing post", func(t *testing.T) {
   104  		o1 := model.Post{}
   105  		o1.ChannelId = model.NewId()
   106  		o1.UserId = model.NewId()
   107  		o1.Message = "zz" + model.NewId() + "b"
   108  
   109  		_, err := ss.Post().Save(&o1)
   110  		require.NoError(t, err, "couldn't save item")
   111  
   112  		_, err = ss.Post().Save(&o1)
   113  		require.Error(t, err, "shouldn't be able to update from save")
   114  	})
   115  
   116  	t.Run("Update reply should update the UpdateAt of the root post", func(t *testing.T) {
   117  		rootPost := model.Post{}
   118  		rootPost.ChannelId = model.NewId()
   119  		rootPost.UserId = model.NewId()
   120  		rootPost.Message = "zz" + model.NewId() + "b"
   121  
   122  		_, err := ss.Post().Save(&rootPost)
   123  		require.NoError(t, err)
   124  
   125  		time.Sleep(2 * time.Millisecond)
   126  
   127  		replyPost := model.Post{}
   128  		replyPost.ChannelId = rootPost.ChannelId
   129  		replyPost.UserId = model.NewId()
   130  		replyPost.Message = "zz" + model.NewId() + "b"
   131  		replyPost.RootId = rootPost.Id
   132  
   133  		// We need to sleep here to be sure the post is not created during the same millisecond
   134  		time.Sleep(time.Millisecond)
   135  		_, err = ss.Post().Save(&replyPost)
   136  		require.NoError(t, err)
   137  
   138  		rrootPost, err := ss.Post().GetSingle(rootPost.Id)
   139  		require.NoError(t, err)
   140  		assert.Greater(t, rrootPost.UpdateAt, rootPost.UpdateAt)
   141  	})
   142  
   143  	t.Run("Create a post should update the channel LastPostAt and the total messages count by one", func(t *testing.T) {
   144  		channel := model.Channel{}
   145  		channel.Name = "zz" + model.NewId() + "b"
   146  		channel.DisplayName = "zz" + model.NewId() + "b"
   147  		channel.Type = model.CHANNEL_OPEN
   148  
   149  		_, err := ss.Channel().Save(&channel, 100)
   150  		require.NoError(t, err)
   151  
   152  		post := model.Post{}
   153  		post.ChannelId = channel.Id
   154  		post.UserId = model.NewId()
   155  		post.Message = "zz" + model.NewId() + "b"
   156  
   157  		// We need to sleep here to be sure the post is not created during the same millisecond
   158  		time.Sleep(time.Millisecond)
   159  		_, err = ss.Post().Save(&post)
   160  		require.NoError(t, err)
   161  
   162  		rchannel, err := ss.Channel().Get(channel.Id, false)
   163  		require.NoError(t, err)
   164  		assert.Greater(t, rchannel.LastPostAt, channel.LastPostAt)
   165  		assert.Equal(t, int64(1), rchannel.TotalMsgCount)
   166  
   167  		post = model.Post{}
   168  		post.ChannelId = channel.Id
   169  		post.UserId = model.NewId()
   170  		post.Message = "zz" + model.NewId() + "b"
   171  		post.CreateAt = 5
   172  
   173  		// We need to sleep here to be sure the post is not created during the same millisecond
   174  		time.Sleep(time.Millisecond)
   175  		_, err = ss.Post().Save(&post)
   176  		require.NoError(t, err)
   177  
   178  		rchannel2, err := ss.Channel().Get(channel.Id, false)
   179  		require.NoError(t, err)
   180  		assert.Equal(t, rchannel.LastPostAt, rchannel2.LastPostAt)
   181  		assert.Equal(t, int64(2), rchannel2.TotalMsgCount)
   182  
   183  		post = model.Post{}
   184  		post.ChannelId = channel.Id
   185  		post.UserId = model.NewId()
   186  		post.Message = "zz" + model.NewId() + "b"
   187  
   188  		// We need to sleep here to be sure the post is not created during the same millisecond
   189  		time.Sleep(time.Millisecond)
   190  		_, err = ss.Post().Save(&post)
   191  		require.NoError(t, err)
   192  
   193  		rchannel3, err := ss.Channel().Get(channel.Id, false)
   194  		require.NoError(t, err)
   195  		assert.Greater(t, rchannel3.LastPostAt, rchannel2.LastPostAt)
   196  		assert.Equal(t, int64(3), rchannel3.TotalMsgCount)
   197  	})
   198  }
   199  
   200  func testPostStoreSaveMultiple(t *testing.T, ss store.Store) {
   201  	p1 := model.Post{}
   202  	p1.ChannelId = model.NewId()
   203  	p1.UserId = model.NewId()
   204  	p1.Message = "zz" + model.NewId() + "b"
   205  
   206  	p2 := model.Post{}
   207  	p2.ChannelId = model.NewId()
   208  	p2.UserId = model.NewId()
   209  	p2.Message = "zz" + model.NewId() + "b"
   210  
   211  	p3 := model.Post{}
   212  	p3.ChannelId = model.NewId()
   213  	p3.UserId = model.NewId()
   214  	p3.Message = "zz" + model.NewId() + "b"
   215  
   216  	p4 := model.Post{}
   217  	p4.ChannelId = model.NewId()
   218  	p4.UserId = model.NewId()
   219  	p4.Message = "zz" + model.NewId() + "b"
   220  
   221  	t.Run("Save correctly a new set of posts", func(t *testing.T) {
   222  		newPosts, errIdx, err := ss.Post().SaveMultiple([]*model.Post{&p1, &p2, &p3})
   223  		require.NoError(t, err)
   224  		require.Equal(t, -1, errIdx)
   225  		for _, post := range newPosts {
   226  			storedPost, err := ss.Post().GetSingle(post.Id)
   227  			assert.NoError(t, err)
   228  			assert.Equal(t, post.ChannelId, storedPost.ChannelId)
   229  			assert.Equal(t, post.Message, storedPost.Message)
   230  			assert.Equal(t, post.UserId, storedPost.UserId)
   231  		}
   232  	})
   233  
   234  	t.Run("Save replies", func(t *testing.T) {
   235  		o1 := model.Post{}
   236  		o1.ChannelId = model.NewId()
   237  		o1.UserId = model.NewId()
   238  		o1.RootId = model.NewId()
   239  		o1.Message = "zz" + model.NewId() + "b"
   240  
   241  		o2 := model.Post{}
   242  		o2.ChannelId = model.NewId()
   243  		o2.UserId = model.NewId()
   244  		o2.RootId = o1.RootId
   245  		o2.Message = "zz" + model.NewId() + "b"
   246  
   247  		o3 := model.Post{}
   248  		o3.ChannelId = model.NewId()
   249  		o3.UserId = model.NewId()
   250  		o3.RootId = model.NewId()
   251  		o3.Message = "zz" + model.NewId() + "b"
   252  
   253  		o4 := model.Post{}
   254  		o4.ChannelId = model.NewId()
   255  		o4.UserId = model.NewId()
   256  		o4.Message = "zz" + model.NewId() + "b"
   257  
   258  		newPosts, errIdx, err := ss.Post().SaveMultiple([]*model.Post{&o1, &o2, &o3, &o4})
   259  		require.NoError(t, err, "couldn't save item")
   260  		require.Equal(t, -1, errIdx)
   261  		assert.Len(t, newPosts, 4)
   262  		assert.Equal(t, int64(2), newPosts[0].ReplyCount)
   263  		assert.Equal(t, int64(2), newPosts[1].ReplyCount)
   264  		assert.Equal(t, int64(1), newPosts[2].ReplyCount)
   265  		assert.Equal(t, int64(0), newPosts[3].ReplyCount)
   266  	})
   267  
   268  	t.Run("Try to save mixed, already saved and not saved posts", func(t *testing.T) {
   269  		newPosts, errIdx, err := ss.Post().SaveMultiple([]*model.Post{&p4, &p3})
   270  		require.Error(t, err)
   271  		require.Equal(t, 1, errIdx)
   272  		require.Nil(t, newPosts)
   273  		storedPost, err := ss.Post().GetSingle(p3.Id)
   274  		assert.NoError(t, err)
   275  		assert.Equal(t, p3.ChannelId, storedPost.ChannelId)
   276  		assert.Equal(t, p3.Message, storedPost.Message)
   277  		assert.Equal(t, p3.UserId, storedPost.UserId)
   278  
   279  		storedPost, err = ss.Post().GetSingle(p4.Id)
   280  		assert.Error(t, err)
   281  		assert.Nil(t, storedPost)
   282  	})
   283  
   284  	t.Run("Update reply should update the UpdateAt of the root post", func(t *testing.T) {
   285  		rootPost := model.Post{}
   286  		rootPost.ChannelId = model.NewId()
   287  		rootPost.UserId = model.NewId()
   288  		rootPost.Message = "zz" + model.NewId() + "b"
   289  
   290  		replyPost := model.Post{}
   291  		replyPost.ChannelId = rootPost.ChannelId
   292  		replyPost.UserId = model.NewId()
   293  		replyPost.Message = "zz" + model.NewId() + "b"
   294  		replyPost.RootId = rootPost.Id
   295  
   296  		_, _, err := ss.Post().SaveMultiple([]*model.Post{&rootPost, &replyPost})
   297  		require.NoError(t, err)
   298  
   299  		rrootPost, err := ss.Post().GetSingle(rootPost.Id)
   300  		require.NoError(t, err)
   301  		assert.Equal(t, rrootPost.UpdateAt, rootPost.UpdateAt)
   302  
   303  		replyPost2 := model.Post{}
   304  		replyPost2.ChannelId = rootPost.ChannelId
   305  		replyPost2.UserId = model.NewId()
   306  		replyPost2.Message = "zz" + model.NewId() + "b"
   307  		replyPost2.RootId = rootPost.Id
   308  
   309  		replyPost3 := model.Post{}
   310  		replyPost3.ChannelId = rootPost.ChannelId
   311  		replyPost3.UserId = model.NewId()
   312  		replyPost3.Message = "zz" + model.NewId() + "b"
   313  		replyPost3.RootId = rootPost.Id
   314  
   315  		_, _, err = ss.Post().SaveMultiple([]*model.Post{&replyPost2, &replyPost3})
   316  		require.NoError(t, err)
   317  
   318  		rrootPost2, err := ss.Post().GetSingle(rootPost.Id)
   319  		require.NoError(t, err)
   320  		assert.Greater(t, rrootPost2.UpdateAt, rrootPost.UpdateAt)
   321  	})
   322  
   323  	t.Run("Create a post should update the channel LastPostAt and the total messages count by one", func(t *testing.T) {
   324  		channel := model.Channel{}
   325  		channel.Name = "zz" + model.NewId() + "b"
   326  		channel.DisplayName = "zz" + model.NewId() + "b"
   327  		channel.Type = model.CHANNEL_OPEN
   328  
   329  		_, err := ss.Channel().Save(&channel, 100)
   330  		require.NoError(t, err)
   331  
   332  		post1 := model.Post{}
   333  		post1.ChannelId = channel.Id
   334  		post1.UserId = model.NewId()
   335  		post1.Message = "zz" + model.NewId() + "b"
   336  
   337  		post2 := model.Post{}
   338  		post2.ChannelId = channel.Id
   339  		post2.UserId = model.NewId()
   340  		post2.Message = "zz" + model.NewId() + "b"
   341  		post2.CreateAt = 5
   342  
   343  		post3 := model.Post{}
   344  		post3.ChannelId = channel.Id
   345  		post3.UserId = model.NewId()
   346  		post3.Message = "zz" + model.NewId() + "b"
   347  
   348  		_, _, err = ss.Post().SaveMultiple([]*model.Post{&post1, &post2, &post3})
   349  		require.NoError(t, err)
   350  
   351  		rchannel, err := ss.Channel().Get(channel.Id, false)
   352  		require.NoError(t, err)
   353  		assert.Greater(t, rchannel.LastPostAt, channel.LastPostAt)
   354  		assert.Equal(t, int64(3), rchannel.TotalMsgCount)
   355  	})
   356  }
   357  
   358  func testPostStoreSaveChannelMsgCounts(t *testing.T, ss store.Store) {
   359  	c1 := &model.Channel{Name: model.NewId(), DisplayName: "posttestchannel", Type: model.CHANNEL_OPEN}
   360  	_, err := ss.Channel().Save(c1, 1000000)
   361  	require.NoError(t, err)
   362  
   363  	o1 := model.Post{}
   364  	o1.ChannelId = c1.Id
   365  	o1.UserId = model.NewId()
   366  	o1.Message = "zz" + model.NewId() + "b"
   367  
   368  	_, err = ss.Post().Save(&o1)
   369  	require.NoError(t, err)
   370  
   371  	c1, err = ss.Channel().Get(c1.Id, false)
   372  	require.NoError(t, err)
   373  	assert.Equal(t, int64(1), c1.TotalMsgCount, "Message count should update by 1")
   374  
   375  	o1.Id = ""
   376  	o1.Type = model.POST_ADD_TO_TEAM
   377  	_, err = ss.Post().Save(&o1)
   378  	require.NoError(t, err)
   379  
   380  	o1.Id = ""
   381  	o1.Type = model.POST_REMOVE_FROM_TEAM
   382  	_, err = ss.Post().Save(&o1)
   383  	require.NoError(t, err)
   384  
   385  	c1, err = ss.Channel().Get(c1.Id, false)
   386  	require.NoError(t, err)
   387  	assert.Equal(t, int64(1), c1.TotalMsgCount, "Message count should not update for team add/removed message")
   388  
   389  	oldLastPostAt := c1.LastPostAt
   390  
   391  	o2 := model.Post{}
   392  	o2.ChannelId = c1.Id
   393  	o2.UserId = model.NewId()
   394  	o2.Message = "zz" + model.NewId() + "b"
   395  	o2.CreateAt = int64(7)
   396  	_, err = ss.Post().Save(&o2)
   397  	require.NoError(t, err)
   398  
   399  	c1, err = ss.Channel().Get(c1.Id, false)
   400  	require.NoError(t, err)
   401  	assert.Equal(t, oldLastPostAt, c1.LastPostAt, "LastPostAt should not update for old message save")
   402  }
   403  
   404  func testPostStoreGet(t *testing.T, ss store.Store) {
   405  	o1 := &model.Post{}
   406  	o1.ChannelId = model.NewId()
   407  	o1.UserId = model.NewId()
   408  	o1.Message = "zz" + model.NewId() + "b"
   409  
   410  	etag1 := ss.Post().GetEtag(o1.ChannelId, false, false)
   411  	require.Equal(t, 0, strings.Index(etag1, model.CurrentVersion+"."), "Invalid Etag")
   412  
   413  	o1, err := ss.Post().Save(o1)
   414  	require.NoError(t, err)
   415  
   416  	etag2 := ss.Post().GetEtag(o1.ChannelId, false, false)
   417  	require.Equal(t, 0, strings.Index(etag2, fmt.Sprintf("%v.%v", model.CurrentVersion, o1.UpdateAt)), "Invalid Etag")
   418  
   419  	r1, err := ss.Post().Get(o1.Id, false, false, false)
   420  	require.NoError(t, err)
   421  	require.Equal(t, r1.Posts[o1.Id].CreateAt, o1.CreateAt, "invalid returned post")
   422  
   423  	_, err = ss.Post().Get("123", false, false, false)
   424  	require.Error(t, err, "Missing id should have failed")
   425  
   426  	_, err = ss.Post().Get("", false, false, false)
   427  	require.Error(t, err, "should fail for blank post ids")
   428  }
   429  
   430  func testPostStoreGetSingle(t *testing.T, ss store.Store) {
   431  	o1 := &model.Post{}
   432  	o1.ChannelId = model.NewId()
   433  	o1.UserId = model.NewId()
   434  	o1.Message = "zz" + model.NewId() + "b"
   435  
   436  	o1, err := ss.Post().Save(o1)
   437  	require.NoError(t, err)
   438  
   439  	post, err := ss.Post().GetSingle(o1.Id)
   440  	require.NoError(t, err)
   441  	require.Equal(t, post.CreateAt, o1.CreateAt, "invalid returned post")
   442  
   443  	_, err = ss.Post().GetSingle("123")
   444  	require.Error(t, err, "Missing id should have failed")
   445  }
   446  
   447  func testPostStoreUpdate(t *testing.T, ss store.Store) {
   448  	o1 := &model.Post{}
   449  	o1.ChannelId = model.NewId()
   450  	o1.UserId = model.NewId()
   451  	o1.Message = "zz" + model.NewId() + "AAAAAAAAAAA"
   452  	o1, err := ss.Post().Save(o1)
   453  	require.NoError(t, err)
   454  
   455  	o2 := &model.Post{}
   456  	o2.ChannelId = o1.ChannelId
   457  	o2.UserId = model.NewId()
   458  	o2.Message = "zz" + model.NewId() + "CCCCCCCCC"
   459  	o2.ParentId = o1.Id
   460  	o2.RootId = o1.Id
   461  	o2, err = ss.Post().Save(o2)
   462  	require.NoError(t, err)
   463  
   464  	o3 := &model.Post{}
   465  	o3.ChannelId = o1.ChannelId
   466  	o3.UserId = model.NewId()
   467  	o3.Message = "zz" + model.NewId() + "QQQQQQQQQQ"
   468  	o3, err = ss.Post().Save(o3)
   469  	require.NoError(t, err)
   470  
   471  	r1, err := ss.Post().Get(o1.Id, false, false, false)
   472  	require.NoError(t, err)
   473  	ro1 := r1.Posts[o1.Id]
   474  
   475  	r2, err := ss.Post().Get(o1.Id, false, false, false)
   476  	require.NoError(t, err)
   477  	ro2 := r2.Posts[o2.Id]
   478  
   479  	r3, err := ss.Post().Get(o3.Id, false, false, false)
   480  	require.NoError(t, err)
   481  	ro3 := r3.Posts[o3.Id]
   482  
   483  	require.Equal(t, ro1.Message, o1.Message, "Failed to save/get")
   484  
   485  	o1a := ro1.Clone()
   486  	o1a.Message = ro1.Message + "BBBBBBBBBB"
   487  	_, err = ss.Post().Update(o1a, ro1)
   488  	require.NoError(t, err)
   489  
   490  	r1, err = ss.Post().Get(o1.Id, false, false, false)
   491  	require.NoError(t, err)
   492  
   493  	ro1a := r1.Posts[o1.Id]
   494  	require.Equal(t, ro1a.Message, o1a.Message, "Failed to update/get")
   495  
   496  	o2a := ro2.Clone()
   497  	o2a.Message = ro2.Message + "DDDDDDD"
   498  	_, err = ss.Post().Update(o2a, ro2)
   499  	require.NoError(t, err)
   500  
   501  	r2, err = ss.Post().Get(o1.Id, false, false, false)
   502  	require.NoError(t, err)
   503  	ro2a := r2.Posts[o2.Id]
   504  
   505  	require.Equal(t, ro2a.Message, o2a.Message, "Failed to update/get")
   506  
   507  	o3a := ro3.Clone()
   508  	o3a.Message = ro3.Message + "WWWWWWW"
   509  	_, err = ss.Post().Update(o3a, ro3)
   510  	require.NoError(t, err)
   511  
   512  	r3, err = ss.Post().Get(o3.Id, false, false, false)
   513  	require.NoError(t, err)
   514  	ro3a := r3.Posts[o3.Id]
   515  
   516  	if ro3a.Message != o3a.Message {
   517  		require.Equal(t, ro3a.Hashtags, o3a.Hashtags, "Failed to update/get")
   518  	}
   519  
   520  	o4, err := ss.Post().Save(&model.Post{
   521  		ChannelId: model.NewId(),
   522  		UserId:    model.NewId(),
   523  		Message:   model.NewId(),
   524  		Filenames: []string{"test"},
   525  	})
   526  	require.NoError(t, err)
   527  
   528  	r4, err := ss.Post().Get(o4.Id, false, false, false)
   529  	require.NoError(t, err)
   530  	ro4 := r4.Posts[o4.Id]
   531  
   532  	o4a := ro4.Clone()
   533  	o4a.Filenames = []string{}
   534  	o4a.FileIds = []string{model.NewId()}
   535  	_, err = ss.Post().Update(o4a, ro4)
   536  	require.NoError(t, err)
   537  
   538  	r4, err = ss.Post().Get(o4.Id, false, false, false)
   539  	require.NoError(t, err)
   540  
   541  	ro4a := r4.Posts[o4.Id]
   542  	require.Empty(t, ro4a.Filenames, "Failed to clear Filenames")
   543  	require.Len(t, ro4a.FileIds, 1, "Failed to set FileIds")
   544  }
   545  
   546  func testPostStoreDelete(t *testing.T, ss store.Store) {
   547  	o1 := &model.Post{}
   548  	o1.ChannelId = model.NewId()
   549  	o1.UserId = model.NewId()
   550  	o1.Message = "zz" + model.NewId() + "b"
   551  	deleteByID := model.NewId()
   552  
   553  	etag1 := ss.Post().GetEtag(o1.ChannelId, false, false)
   554  	require.Equal(t, 0, strings.Index(etag1, model.CurrentVersion+"."), "Invalid Etag")
   555  
   556  	o1, err := ss.Post().Save(o1)
   557  	require.NoError(t, err)
   558  
   559  	r1, err := ss.Post().Get(o1.Id, false, false, false)
   560  	require.NoError(t, err)
   561  	require.Equal(t, r1.Posts[o1.Id].CreateAt, o1.CreateAt, "invalid returned post")
   562  
   563  	err = ss.Post().Delete(o1.Id, model.GetMillis(), deleteByID)
   564  	require.NoError(t, err)
   565  
   566  	posts, _ := ss.Post().GetPostsCreatedAt(o1.ChannelId, o1.CreateAt)
   567  	post := posts[0]
   568  	actual := post.GetProp(model.POST_PROPS_DELETE_BY)
   569  
   570  	assert.Equal(t, deleteByID, actual, "Expected (*Post).Props[model.POST_PROPS_DELETE_BY] to be %v but got %v.", deleteByID, actual)
   571  
   572  	r3, err := ss.Post().Get(o1.Id, false, false, false)
   573  	require.Error(t, err, "Missing id should have failed - PostList %v", r3)
   574  
   575  	etag2 := ss.Post().GetEtag(o1.ChannelId, false, false)
   576  	require.Equal(t, 0, strings.Index(etag2, model.CurrentVersion+"."), "Invalid Etag")
   577  }
   578  
   579  func testPostStoreDelete1Level(t *testing.T, ss store.Store) {
   580  	o1 := &model.Post{}
   581  	o1.ChannelId = model.NewId()
   582  	o1.UserId = model.NewId()
   583  	o1.Message = "zz" + model.NewId() + "b"
   584  	o1, err := ss.Post().Save(o1)
   585  	require.NoError(t, err)
   586  
   587  	o2 := &model.Post{}
   588  	o2.ChannelId = o1.ChannelId
   589  	o2.UserId = model.NewId()
   590  	o2.Message = "zz" + model.NewId() + "b"
   591  	o2.ParentId = o1.Id
   592  	o2.RootId = o1.Id
   593  	o2, err = ss.Post().Save(o2)
   594  	require.NoError(t, err)
   595  
   596  	err = ss.Post().Delete(o1.Id, model.GetMillis(), "")
   597  	require.NoError(t, err)
   598  
   599  	_, err = ss.Post().Get(o1.Id, false, false, false)
   600  	require.Error(t, err, "Deleted id should have failed")
   601  
   602  	_, err = ss.Post().Get(o2.Id, false, false, false)
   603  	require.Error(t, err, "Deleted id should have failed")
   604  }
   605  
   606  func testPostStoreDelete2Level(t *testing.T, ss store.Store) {
   607  	o1 := &model.Post{}
   608  	o1.ChannelId = model.NewId()
   609  	o1.UserId = model.NewId()
   610  	o1.Message = "zz" + model.NewId() + "b"
   611  	o1, err := ss.Post().Save(o1)
   612  	require.NoError(t, err)
   613  
   614  	o2 := &model.Post{}
   615  	o2.ChannelId = o1.ChannelId
   616  	o2.UserId = model.NewId()
   617  	o2.Message = "zz" + model.NewId() + "b"
   618  	o2.ParentId = o1.Id
   619  	o2.RootId = o1.Id
   620  	o2, err = ss.Post().Save(o2)
   621  	require.NoError(t, err)
   622  
   623  	o3 := &model.Post{}
   624  	o3.ChannelId = o1.ChannelId
   625  	o3.UserId = model.NewId()
   626  	o3.Message = "zz" + model.NewId() + "b"
   627  	o3.ParentId = o2.Id
   628  	o3.RootId = o1.Id
   629  	o3, err = ss.Post().Save(o3)
   630  	require.NoError(t, err)
   631  
   632  	o4 := &model.Post{}
   633  	o4.ChannelId = model.NewId()
   634  	o4.UserId = model.NewId()
   635  	o4.Message = "zz" + model.NewId() + "b"
   636  	o4, err = ss.Post().Save(o4)
   637  	require.NoError(t, err)
   638  
   639  	err = ss.Post().Delete(o1.Id, model.GetMillis(), "")
   640  	require.NoError(t, err)
   641  
   642  	_, err = ss.Post().Get(o1.Id, false, false, false)
   643  	require.Error(t, err, "Deleted id should have failed")
   644  
   645  	_, err = ss.Post().Get(o2.Id, false, false, false)
   646  	require.Error(t, err, "Deleted id should have failed")
   647  
   648  	_, err = ss.Post().Get(o3.Id, false, false, false)
   649  	require.Error(t, err, "Deleted id should have failed")
   650  
   651  	_, err = ss.Post().Get(o4.Id, false, false, false)
   652  	require.NoError(t, err)
   653  }
   654  
   655  func testPostStorePermDelete1Level(t *testing.T, ss store.Store) {
   656  	o1 := &model.Post{}
   657  	o1.ChannelId = model.NewId()
   658  	o1.UserId = model.NewId()
   659  	o1.Message = "zz" + model.NewId() + "b"
   660  	o1, err := ss.Post().Save(o1)
   661  	require.NoError(t, err)
   662  
   663  	o2 := &model.Post{}
   664  	o2.ChannelId = o1.ChannelId
   665  	o2.UserId = model.NewId()
   666  	o2.Message = "zz" + model.NewId() + "b"
   667  	o2.ParentId = o1.Id
   668  	o2.RootId = o1.Id
   669  	o2, err = ss.Post().Save(o2)
   670  	require.NoError(t, err)
   671  
   672  	o3 := &model.Post{}
   673  	o3.ChannelId = model.NewId()
   674  	o3.UserId = model.NewId()
   675  	o3.Message = "zz" + model.NewId() + "b"
   676  	o3, err = ss.Post().Save(o3)
   677  	require.NoError(t, err)
   678  
   679  	err2 := ss.Post().PermanentDeleteByUser(o2.UserId)
   680  	require.NoError(t, err2)
   681  
   682  	_, err = ss.Post().Get(o1.Id, false, false, false)
   683  	require.NoError(t, err, "Deleted id shouldn't have failed")
   684  
   685  	_, err = ss.Post().Get(o2.Id, false, false, false)
   686  	require.Error(t, err, "Deleted id should have failed")
   687  
   688  	err = ss.Post().PermanentDeleteByChannel(o3.ChannelId)
   689  	require.NoError(t, err)
   690  
   691  	_, err = ss.Post().Get(o3.Id, false, false, false)
   692  	require.Error(t, err, "Deleted id should have failed")
   693  }
   694  
   695  func testPostStorePermDelete1Level2(t *testing.T, ss store.Store) {
   696  	o1 := &model.Post{}
   697  	o1.ChannelId = model.NewId()
   698  	o1.UserId = model.NewId()
   699  	o1.Message = "zz" + model.NewId() + "b"
   700  	o1, err := ss.Post().Save(o1)
   701  	require.NoError(t, err)
   702  
   703  	o2 := &model.Post{}
   704  	o2.ChannelId = o1.ChannelId
   705  	o2.UserId = model.NewId()
   706  	o2.Message = "zz" + model.NewId() + "b"
   707  	o2.ParentId = o1.Id
   708  	o2.RootId = o1.Id
   709  	o2, err = ss.Post().Save(o2)
   710  	require.NoError(t, err)
   711  
   712  	o3 := &model.Post{}
   713  	o3.ChannelId = model.NewId()
   714  	o3.UserId = model.NewId()
   715  	o3.Message = "zz" + model.NewId() + "b"
   716  	o3, err = ss.Post().Save(o3)
   717  	require.NoError(t, err)
   718  
   719  	err2 := ss.Post().PermanentDeleteByUser(o1.UserId)
   720  	require.NoError(t, err2)
   721  
   722  	_, err = ss.Post().Get(o1.Id, false, false, false)
   723  	require.Error(t, err, "Deleted id should have failed")
   724  
   725  	_, err = ss.Post().Get(o2.Id, false, false, false)
   726  	require.Error(t, err, "Deleted id should have failed")
   727  
   728  	_, err = ss.Post().Get(o3.Id, false, false, false)
   729  	require.NoError(t, err, "Deleted id should have failed")
   730  }
   731  
   732  func testPostStoreGetWithChildren(t *testing.T, ss store.Store) {
   733  	o1 := &model.Post{}
   734  	o1.ChannelId = model.NewId()
   735  	o1.UserId = model.NewId()
   736  	o1.Message = "zz" + model.NewId() + "b"
   737  	o1, err := ss.Post().Save(o1)
   738  	require.NoError(t, err)
   739  
   740  	o2 := &model.Post{}
   741  	o2.ChannelId = o1.ChannelId
   742  	o2.UserId = model.NewId()
   743  	o2.Message = "zz" + model.NewId() + "b"
   744  	o2.ParentId = o1.Id
   745  	o2.RootId = o1.Id
   746  	o2, err = ss.Post().Save(o2)
   747  	require.NoError(t, err)
   748  
   749  	o3 := &model.Post{}
   750  	o3.ChannelId = o1.ChannelId
   751  	o3.UserId = model.NewId()
   752  	o3.Message = "zz" + model.NewId() + "b"
   753  	o3.ParentId = o2.Id
   754  	o3.RootId = o1.Id
   755  	o3, err = ss.Post().Save(o3)
   756  	require.NoError(t, err)
   757  
   758  	pl, err := ss.Post().Get(o1.Id, false, false, false)
   759  	require.NoError(t, err)
   760  
   761  	require.Len(t, pl.Posts, 3, "invalid returned post")
   762  
   763  	dErr := ss.Post().Delete(o3.Id, model.GetMillis(), "")
   764  	require.NoError(t, dErr)
   765  
   766  	pl, err = ss.Post().Get(o1.Id, false, false, false)
   767  	require.NoError(t, err)
   768  
   769  	require.Len(t, pl.Posts, 2, "invalid returned post")
   770  
   771  	dErr = ss.Post().Delete(o2.Id, model.GetMillis(), "")
   772  	require.NoError(t, dErr)
   773  
   774  	pl, err = ss.Post().Get(o1.Id, false, false, false)
   775  	require.NoError(t, err)
   776  
   777  	require.Len(t, pl.Posts, 1, "invalid returned post")
   778  }
   779  
   780  func testPostStoreGetPostsWithDetails(t *testing.T, ss store.Store) {
   781  	o1 := &model.Post{}
   782  	o1.ChannelId = model.NewId()
   783  	o1.UserId = model.NewId()
   784  	o1.Message = "zz" + model.NewId() + "b"
   785  	o1, err := ss.Post().Save(o1)
   786  	require.NoError(t, err)
   787  	time.Sleep(2 * time.Millisecond)
   788  
   789  	o2 := &model.Post{}
   790  	o2.ChannelId = o1.ChannelId
   791  	o2.UserId = model.NewId()
   792  	o2.Message = "zz" + model.NewId() + "b"
   793  	o2.ParentId = o1.Id
   794  	o2.RootId = o1.Id
   795  	_, err = ss.Post().Save(o2)
   796  	require.NoError(t, err)
   797  	time.Sleep(2 * time.Millisecond)
   798  
   799  	o2a := &model.Post{}
   800  	o2a.ChannelId = o1.ChannelId
   801  	o2a.UserId = model.NewId()
   802  	o2a.Message = "zz" + model.NewId() + "b"
   803  	o2a.ParentId = o1.Id
   804  	o2a.RootId = o1.Id
   805  	o2a, err = ss.Post().Save(o2a)
   806  	require.NoError(t, err)
   807  	time.Sleep(2 * time.Millisecond)
   808  
   809  	o3 := &model.Post{}
   810  	o3.ChannelId = o1.ChannelId
   811  	o3.UserId = model.NewId()
   812  	o3.Message = "zz" + model.NewId() + "b"
   813  	o3.ParentId = o1.Id
   814  	o3.RootId = o1.Id
   815  	o3, err = ss.Post().Save(o3)
   816  	require.NoError(t, err)
   817  	time.Sleep(2 * time.Millisecond)
   818  
   819  	o4 := &model.Post{}
   820  	o4.ChannelId = o1.ChannelId
   821  	o4.UserId = model.NewId()
   822  	o4.Message = "zz" + model.NewId() + "b"
   823  	o4, err = ss.Post().Save(o4)
   824  	require.NoError(t, err)
   825  	time.Sleep(2 * time.Millisecond)
   826  
   827  	o5 := &model.Post{}
   828  	o5.ChannelId = o1.ChannelId
   829  	o5.UserId = model.NewId()
   830  	o5.Message = "zz" + model.NewId() + "b"
   831  	o5.ParentId = o4.Id
   832  	o5.RootId = o4.Id
   833  	o5, err = ss.Post().Save(o5)
   834  	require.NoError(t, err)
   835  
   836  	r1, err := ss.Post().GetPosts(model.GetPostsOptions{ChannelId: o1.ChannelId, Page: 0, PerPage: 4}, false)
   837  	require.NoError(t, err)
   838  
   839  	require.Equal(t, r1.Order[0], o5.Id, "invalid order")
   840  	require.Equal(t, r1.Order[1], o4.Id, "invalid order")
   841  	require.Equal(t, r1.Order[2], o3.Id, "invalid order")
   842  	require.Equal(t, r1.Order[3], o2a.Id, "invalid order")
   843  
   844  	//the last 4, + o1 (o2a and o3's parent) + o2 (in same thread as o2a and o3)
   845  	require.Len(t, r1.Posts, 6, "wrong size")
   846  
   847  	require.Equal(t, r1.Posts[o1.Id].Message, o1.Message, "Missing parent")
   848  
   849  	r2, err := ss.Post().GetPosts(model.GetPostsOptions{ChannelId: o1.ChannelId, Page: 0, PerPage: 4}, false)
   850  	require.NoError(t, err)
   851  
   852  	require.Equal(t, r2.Order[0], o5.Id, "invalid order")
   853  	require.Equal(t, r2.Order[1], o4.Id, "invalid order")
   854  	require.Equal(t, r2.Order[2], o3.Id, "invalid order")
   855  	require.Equal(t, r2.Order[3], o2a.Id, "invalid order")
   856  
   857  	//the last 4, + o1 (o2a and o3's parent) + o2 (in same thread as o2a and o3)
   858  	require.Len(t, r2.Posts, 6, "wrong size")
   859  
   860  	require.Equal(t, r2.Posts[o1.Id].Message, o1.Message, "Missing parent")
   861  
   862  	// Run once to fill cache
   863  	_, err = ss.Post().GetPosts(model.GetPostsOptions{ChannelId: o1.ChannelId, Page: 0, PerPage: 30}, false)
   864  	require.NoError(t, err)
   865  
   866  	o6 := &model.Post{}
   867  	o6.ChannelId = o1.ChannelId
   868  	o6.UserId = model.NewId()
   869  	o6.Message = "zz" + model.NewId() + "b"
   870  	_, err = ss.Post().Save(o6)
   871  	require.NoError(t, err)
   872  
   873  	r3, err := ss.Post().GetPosts(model.GetPostsOptions{ChannelId: o1.ChannelId, Page: 0, PerPage: 30}, false)
   874  	require.NoError(t, err)
   875  	assert.Equal(t, 7, len(r3.Order))
   876  }
   877  
   878  func testPostStoreGetPostsBeforeAfter(t *testing.T, ss store.Store) {
   879  	t.Run("without threads", func(t *testing.T) {
   880  		channelId := model.NewId()
   881  		userId := model.NewId()
   882  
   883  		var posts []*model.Post
   884  		for i := 0; i < 10; i++ {
   885  			post, err := ss.Post().Save(&model.Post{
   886  				ChannelId: channelId,
   887  				UserId:    userId,
   888  				Message:   "message",
   889  			})
   890  			require.NoError(t, err)
   891  
   892  			posts = append(posts, post)
   893  
   894  			time.Sleep(time.Millisecond)
   895  		}
   896  
   897  		t.Run("should return error if negative Page/PerPage options are passed", func(t *testing.T) {
   898  			postList, err := ss.Post().GetPostsAfter(model.GetPostsOptions{ChannelId: channelId, PostId: posts[0].Id, Page: 0, PerPage: -1})
   899  			assert.Nil(t, postList)
   900  			assert.Error(t, err)
   901  			assert.IsType(t, &store.ErrInvalidInput{}, err)
   902  
   903  			postList, err = ss.Post().GetPostsAfter(model.GetPostsOptions{ChannelId: channelId, PostId: posts[0].Id, Page: -1, PerPage: 10})
   904  			assert.Nil(t, postList)
   905  			assert.Error(t, err)
   906  			assert.IsType(t, &store.ErrInvalidInput{}, err)
   907  		})
   908  
   909  		t.Run("should not return anything before the first post", func(t *testing.T) {
   910  			postList, err := ss.Post().GetPostsBefore(model.GetPostsOptions{ChannelId: channelId, PostId: posts[0].Id, Page: 0, PerPage: 10})
   911  			assert.NoError(t, err)
   912  
   913  			assert.Equal(t, []string{}, postList.Order)
   914  			assert.Equal(t, map[string]*model.Post{}, postList.Posts)
   915  		})
   916  
   917  		t.Run("should return posts before a post", func(t *testing.T) {
   918  			postList, err := ss.Post().GetPostsBefore(model.GetPostsOptions{ChannelId: channelId, PostId: posts[5].Id, Page: 0, PerPage: 10})
   919  			assert.NoError(t, err)
   920  
   921  			assert.Equal(t, []string{posts[4].Id, posts[3].Id, posts[2].Id, posts[1].Id, posts[0].Id}, postList.Order)
   922  			assert.Equal(t, map[string]*model.Post{
   923  				posts[0].Id: posts[0],
   924  				posts[1].Id: posts[1],
   925  				posts[2].Id: posts[2],
   926  				posts[3].Id: posts[3],
   927  				posts[4].Id: posts[4],
   928  			}, postList.Posts)
   929  		})
   930  
   931  		t.Run("should limit posts before", func(t *testing.T) {
   932  			postList, err := ss.Post().GetPostsBefore(model.GetPostsOptions{ChannelId: channelId, PostId: posts[5].Id, PerPage: 2})
   933  			assert.NoError(t, err)
   934  
   935  			assert.Equal(t, []string{posts[4].Id, posts[3].Id}, postList.Order)
   936  			assert.Equal(t, map[string]*model.Post{
   937  				posts[3].Id: posts[3],
   938  				posts[4].Id: posts[4],
   939  			}, postList.Posts)
   940  		})
   941  
   942  		t.Run("should not return anything after the last post", func(t *testing.T) {
   943  			postList, err := ss.Post().GetPostsAfter(model.GetPostsOptions{ChannelId: channelId, PostId: posts[len(posts)-1].Id, PerPage: 10})
   944  			assert.NoError(t, err)
   945  
   946  			assert.Equal(t, []string{}, postList.Order)
   947  			assert.Equal(t, map[string]*model.Post{}, postList.Posts)
   948  		})
   949  
   950  		t.Run("should return posts after a post", func(t *testing.T) {
   951  			postList, err := ss.Post().GetPostsAfter(model.GetPostsOptions{ChannelId: channelId, PostId: posts[5].Id, PerPage: 10})
   952  			assert.NoError(t, err)
   953  
   954  			assert.Equal(t, []string{posts[9].Id, posts[8].Id, posts[7].Id, posts[6].Id}, postList.Order)
   955  			assert.Equal(t, map[string]*model.Post{
   956  				posts[6].Id: posts[6],
   957  				posts[7].Id: posts[7],
   958  				posts[8].Id: posts[8],
   959  				posts[9].Id: posts[9],
   960  			}, postList.Posts)
   961  		})
   962  
   963  		t.Run("should limit posts after", func(t *testing.T) {
   964  			postList, err := ss.Post().GetPostsAfter(model.GetPostsOptions{ChannelId: channelId, PostId: posts[5].Id, PerPage: 2})
   965  			assert.NoError(t, err)
   966  
   967  			assert.Equal(t, []string{posts[7].Id, posts[6].Id}, postList.Order)
   968  			assert.Equal(t, map[string]*model.Post{
   969  				posts[6].Id: posts[6],
   970  				posts[7].Id: posts[7],
   971  			}, postList.Posts)
   972  		})
   973  	})
   974  	t.Run("with threads", func(t *testing.T) {
   975  		channelId := model.NewId()
   976  		userId := model.NewId()
   977  
   978  		// This creates a series of posts that looks like:
   979  		// post1
   980  		// post2
   981  		// post3 (in response to post1)
   982  		// post4 (in response to post2)
   983  		// post5
   984  		// post6 (in response to post2)
   985  
   986  		post1, err := ss.Post().Save(&model.Post{
   987  			ChannelId: channelId,
   988  			UserId:    userId,
   989  			Message:   "message",
   990  		})
   991  		post1.ReplyCount = 1
   992  		require.NoError(t, err)
   993  		time.Sleep(time.Millisecond)
   994  
   995  		post2, err := ss.Post().Save(&model.Post{
   996  			ChannelId: channelId,
   997  			UserId:    userId,
   998  			Message:   "message",
   999  		})
  1000  		require.NoError(t, err)
  1001  		post2.ReplyCount = 2
  1002  		time.Sleep(time.Millisecond)
  1003  
  1004  		post3, err := ss.Post().Save(&model.Post{
  1005  			ChannelId: channelId,
  1006  			UserId:    userId,
  1007  			ParentId:  post1.Id,
  1008  			RootId:    post1.Id,
  1009  			Message:   "message",
  1010  		})
  1011  		require.NoError(t, err)
  1012  		post3.ReplyCount = 1
  1013  		time.Sleep(time.Millisecond)
  1014  
  1015  		post4, err := ss.Post().Save(&model.Post{
  1016  			ChannelId: channelId,
  1017  			UserId:    userId,
  1018  			RootId:    post2.Id,
  1019  			ParentId:  post2.Id,
  1020  			Message:   "message",
  1021  		})
  1022  		require.NoError(t, err)
  1023  		post4.ReplyCount = 2
  1024  		time.Sleep(time.Millisecond)
  1025  
  1026  		post5, err := ss.Post().Save(&model.Post{
  1027  			ChannelId: channelId,
  1028  			UserId:    userId,
  1029  			Message:   "message",
  1030  		})
  1031  		require.NoError(t, err)
  1032  		time.Sleep(time.Millisecond)
  1033  
  1034  		post6, err := ss.Post().Save(&model.Post{
  1035  			ChannelId: channelId,
  1036  			UserId:    userId,
  1037  			ParentId:  post2.Id,
  1038  			RootId:    post2.Id,
  1039  			Message:   "message",
  1040  		})
  1041  		post6.ReplyCount = 2
  1042  		require.NoError(t, err)
  1043  
  1044  		// Adding a post to a thread changes the UpdateAt timestamp of the parent post
  1045  		post1.UpdateAt = post3.UpdateAt
  1046  		post2.UpdateAt = post6.UpdateAt
  1047  
  1048  		t.Run("should return each post and thread before a post", func(t *testing.T) {
  1049  			postList, err := ss.Post().GetPostsBefore(model.GetPostsOptions{ChannelId: channelId, PostId: post4.Id, PerPage: 2})
  1050  			assert.NoError(t, err)
  1051  
  1052  			assert.Equal(t, []string{post3.Id, post2.Id}, postList.Order)
  1053  			assert.Equal(t, map[string]*model.Post{
  1054  				post1.Id: post1,
  1055  				post2.Id: post2,
  1056  				post3.Id: post3,
  1057  				post4.Id: post4,
  1058  				post6.Id: post6,
  1059  			}, postList.Posts)
  1060  		})
  1061  
  1062  		t.Run("should return each post and the root of each thread after a post", func(t *testing.T) {
  1063  			postList, err := ss.Post().GetPostsAfter(model.GetPostsOptions{ChannelId: channelId, PostId: post4.Id, PerPage: 2})
  1064  			assert.NoError(t, err)
  1065  
  1066  			assert.Equal(t, []string{post6.Id, post5.Id}, postList.Order)
  1067  			assert.Equal(t, map[string]*model.Post{
  1068  				post2.Id: post2,
  1069  				post4.Id: post4,
  1070  				post5.Id: post5,
  1071  				post6.Id: post6,
  1072  			}, postList.Posts)
  1073  		})
  1074  	})
  1075  	t.Run("with threads (skipFetchThreads)", func(t *testing.T) {
  1076  		channelId := model.NewId()
  1077  		userId := model.NewId()
  1078  
  1079  		// This creates a series of posts that looks like:
  1080  		// post1
  1081  		// post2
  1082  		// post3 (in response to post1)
  1083  		// post4 (in response to post2)
  1084  		// post5
  1085  		// post6 (in response to post2)
  1086  
  1087  		post1, err := ss.Post().Save(&model.Post{
  1088  			ChannelId: channelId,
  1089  			UserId:    userId,
  1090  			Message:   "post1",
  1091  		})
  1092  		require.NoError(t, err)
  1093  		post1.ReplyCount = 1
  1094  		time.Sleep(time.Millisecond)
  1095  
  1096  		post2, err := ss.Post().Save(&model.Post{
  1097  			ChannelId: channelId,
  1098  			UserId:    userId,
  1099  			Message:   "post2",
  1100  		})
  1101  		require.NoError(t, err)
  1102  		post2.ReplyCount = 2
  1103  		time.Sleep(time.Millisecond)
  1104  
  1105  		post3, err := ss.Post().Save(&model.Post{
  1106  			ChannelId: channelId,
  1107  			UserId:    userId,
  1108  			ParentId:  post1.Id,
  1109  			RootId:    post1.Id,
  1110  			Message:   "post3",
  1111  		})
  1112  		require.NoError(t, err)
  1113  		post3.ReplyCount = 1
  1114  		time.Sleep(time.Millisecond)
  1115  
  1116  		post4, err := ss.Post().Save(&model.Post{
  1117  			ChannelId: channelId,
  1118  			UserId:    userId,
  1119  			RootId:    post2.Id,
  1120  			ParentId:  post2.Id,
  1121  			Message:   "post4",
  1122  		})
  1123  		require.NoError(t, err)
  1124  		post4.ReplyCount = 2
  1125  		time.Sleep(time.Millisecond)
  1126  
  1127  		post5, err := ss.Post().Save(&model.Post{
  1128  			ChannelId: channelId,
  1129  			UserId:    userId,
  1130  			Message:   "post5",
  1131  		})
  1132  		require.NoError(t, err)
  1133  		time.Sleep(time.Millisecond)
  1134  
  1135  		post6, err := ss.Post().Save(&model.Post{
  1136  			ChannelId: channelId,
  1137  			UserId:    userId,
  1138  			ParentId:  post2.Id,
  1139  			RootId:    post2.Id,
  1140  			Message:   "post6",
  1141  		})
  1142  		post6.ReplyCount = 2
  1143  		require.NoError(t, err)
  1144  
  1145  		// Adding a post to a thread changes the UpdateAt timestamp of the parent post
  1146  		post1.UpdateAt = post3.UpdateAt
  1147  		post2.UpdateAt = post6.UpdateAt
  1148  
  1149  		t.Run("should return each post and thread before a post", func(t *testing.T) {
  1150  			postList, err := ss.Post().GetPostsBefore(model.GetPostsOptions{ChannelId: channelId, PostId: post4.Id, PerPage: 2, SkipFetchThreads: true})
  1151  			assert.NoError(t, err)
  1152  
  1153  			assert.Equal(t, []string{post3.Id, post2.Id}, postList.Order)
  1154  			assert.Equal(t, map[string]*model.Post{
  1155  				post1.Id: post1,
  1156  				post2.Id: post2,
  1157  				post3.Id: post3,
  1158  			}, postList.Posts)
  1159  		})
  1160  
  1161  		t.Run("should return each post and thread before a post with limit", func(t *testing.T) {
  1162  			postList, err := ss.Post().GetPostsBefore(model.GetPostsOptions{ChannelId: channelId, PostId: post4.Id, PerPage: 1, SkipFetchThreads: true})
  1163  			assert.NoError(t, err)
  1164  
  1165  			assert.Equal(t, []string{post3.Id}, postList.Order)
  1166  			assert.Equal(t, map[string]*model.Post{
  1167  				post1.Id: post1,
  1168  				post3.Id: post3,
  1169  			}, postList.Posts)
  1170  		})
  1171  
  1172  		t.Run("should return each post and the root of each thread after a post", func(t *testing.T) {
  1173  			postList, err := ss.Post().GetPostsAfter(model.GetPostsOptions{ChannelId: channelId, PostId: post4.Id, PerPage: 2, SkipFetchThreads: true})
  1174  			assert.NoError(t, err)
  1175  
  1176  			assert.Equal(t, []string{post6.Id, post5.Id}, postList.Order)
  1177  			assert.Equal(t, map[string]*model.Post{
  1178  				post2.Id: post2,
  1179  				post5.Id: post5,
  1180  				post6.Id: post6,
  1181  			}, postList.Posts)
  1182  		})
  1183  	})
  1184  	t.Run("with threads (collapsedThreads)", func(t *testing.T) {
  1185  		channelId := model.NewId()
  1186  		userId := model.NewId()
  1187  
  1188  		// This creates a series of posts that looks like:
  1189  		// post1
  1190  		// post2
  1191  		// post3 (in response to post1)
  1192  		// post4 (in response to post2)
  1193  		// post5
  1194  		// post6 (in response to post2)
  1195  
  1196  		post1, err := ss.Post().Save(&model.Post{
  1197  			ChannelId: channelId,
  1198  			UserId:    userId,
  1199  			Message:   "post1",
  1200  		})
  1201  		require.NoError(t, err)
  1202  		post1.ReplyCount = 1
  1203  		time.Sleep(time.Millisecond)
  1204  
  1205  		post2, err := ss.Post().Save(&model.Post{
  1206  			ChannelId: channelId,
  1207  			UserId:    userId,
  1208  			Message:   "post2",
  1209  		})
  1210  		require.NoError(t, err)
  1211  		post2.ReplyCount = 2
  1212  		time.Sleep(time.Millisecond)
  1213  
  1214  		post3, err := ss.Post().Save(&model.Post{
  1215  			ChannelId: channelId,
  1216  			UserId:    userId,
  1217  			ParentId:  post1.Id,
  1218  			RootId:    post1.Id,
  1219  			Message:   "post3",
  1220  		})
  1221  		require.NoError(t, err)
  1222  		post3.ReplyCount = 1
  1223  		time.Sleep(time.Millisecond)
  1224  
  1225  		post4, err := ss.Post().Save(&model.Post{
  1226  			ChannelId: channelId,
  1227  			UserId:    userId,
  1228  			RootId:    post2.Id,
  1229  			ParentId:  post2.Id,
  1230  			Message:   "post4",
  1231  		})
  1232  		require.NoError(t, err)
  1233  		post4.ReplyCount = 2
  1234  		time.Sleep(time.Millisecond)
  1235  
  1236  		post5, err := ss.Post().Save(&model.Post{
  1237  			ChannelId: channelId,
  1238  			UserId:    userId,
  1239  			Message:   "post5",
  1240  		})
  1241  		require.NoError(t, err)
  1242  		time.Sleep(time.Millisecond)
  1243  
  1244  		post6, err := ss.Post().Save(&model.Post{
  1245  			ChannelId: channelId,
  1246  			UserId:    userId,
  1247  			ParentId:  post2.Id,
  1248  			RootId:    post2.Id,
  1249  			Message:   "post6",
  1250  		})
  1251  		post6.ReplyCount = 2
  1252  		require.NoError(t, err)
  1253  
  1254  		// Adding a post to a thread changes the UpdateAt timestamp of the parent post
  1255  		post1.UpdateAt = post3.UpdateAt
  1256  		post2.UpdateAt = post6.UpdateAt
  1257  
  1258  		t.Run("should return each root post before a post", func(t *testing.T) {
  1259  			postList, err := ss.Post().GetPostsBefore(model.GetPostsOptions{ChannelId: channelId, PostId: post4.Id, PerPage: 2, CollapsedThreads: true})
  1260  			assert.NoError(t, err)
  1261  
  1262  			assert.Equal(t, []string{post2.Id, post1.Id}, postList.Order)
  1263  		})
  1264  
  1265  		t.Run("should return each root post before a post with limit", func(t *testing.T) {
  1266  			postList, err := ss.Post().GetPostsBefore(model.GetPostsOptions{ChannelId: channelId, PostId: post4.Id, PerPage: 1, CollapsedThreads: true})
  1267  			assert.NoError(t, err)
  1268  
  1269  			assert.Equal(t, []string{post2.Id}, postList.Order)
  1270  		})
  1271  
  1272  		t.Run("should return each root after a post", func(t *testing.T) {
  1273  			postList, err := ss.Post().GetPostsAfter(model.GetPostsOptions{ChannelId: channelId, PostId: post4.Id, PerPage: 2, CollapsedThreads: true})
  1274  			require.NoError(t, err)
  1275  
  1276  			assert.Equal(t, []string{post5.Id}, postList.Order)
  1277  		})
  1278  	})
  1279  }
  1280  
  1281  func testPostStoreGetPostsSince(t *testing.T, ss store.Store) {
  1282  	t.Run("should return posts created after the given time", func(t *testing.T) {
  1283  		channelId := model.NewId()
  1284  		userId := model.NewId()
  1285  
  1286  		post1, err := ss.Post().Save(&model.Post{
  1287  			ChannelId: channelId,
  1288  			UserId:    userId,
  1289  			Message:   "message",
  1290  		})
  1291  		require.NoError(t, err)
  1292  		time.Sleep(time.Millisecond)
  1293  
  1294  		_, err = ss.Post().Save(&model.Post{
  1295  			ChannelId: channelId,
  1296  			UserId:    userId,
  1297  			Message:   "message",
  1298  		})
  1299  		require.NoError(t, err)
  1300  		time.Sleep(time.Millisecond)
  1301  
  1302  		post3, err := ss.Post().Save(&model.Post{
  1303  			ChannelId: channelId,
  1304  			UserId:    userId,
  1305  			Message:   "message",
  1306  		})
  1307  		require.NoError(t, err)
  1308  		time.Sleep(time.Millisecond)
  1309  
  1310  		post4, err := ss.Post().Save(&model.Post{
  1311  			ChannelId: channelId,
  1312  			UserId:    userId,
  1313  			Message:   "message",
  1314  		})
  1315  		require.NoError(t, err)
  1316  		time.Sleep(time.Millisecond)
  1317  
  1318  		post5, err := ss.Post().Save(&model.Post{
  1319  			ChannelId: channelId,
  1320  			UserId:    userId,
  1321  			Message:   "message",
  1322  			RootId:    post3.Id,
  1323  		})
  1324  		require.NoError(t, err)
  1325  		time.Sleep(time.Millisecond)
  1326  
  1327  		post6, err := ss.Post().Save(&model.Post{
  1328  			ChannelId: channelId,
  1329  			UserId:    userId,
  1330  			Message:   "message",
  1331  			RootId:    post1.Id,
  1332  		})
  1333  		require.NoError(t, err)
  1334  		time.Sleep(time.Millisecond)
  1335  
  1336  		postList, err := ss.Post().GetPostsSince(model.GetPostsSinceOptions{ChannelId: channelId, Time: post3.CreateAt}, false)
  1337  		assert.NoError(t, err)
  1338  
  1339  		assert.Equal(t, []string{
  1340  			post6.Id,
  1341  			post5.Id,
  1342  			post4.Id,
  1343  			post3.Id,
  1344  			post1.Id,
  1345  		}, postList.Order)
  1346  
  1347  		assert.Len(t, postList.Posts, 5)
  1348  		assert.NotNil(t, postList.Posts[post1.Id], "should return the parent post")
  1349  		assert.NotNil(t, postList.Posts[post3.Id])
  1350  		assert.NotNil(t, postList.Posts[post4.Id])
  1351  		assert.NotNil(t, postList.Posts[post5.Id])
  1352  		assert.NotNil(t, postList.Posts[post6.Id])
  1353  	})
  1354  
  1355  	t.Run("should return empty list when nothing has changed", func(t *testing.T) {
  1356  		channelId := model.NewId()
  1357  		userId := model.NewId()
  1358  
  1359  		post1, err := ss.Post().Save(&model.Post{
  1360  			ChannelId: channelId,
  1361  			UserId:    userId,
  1362  			Message:   "message",
  1363  		})
  1364  		require.NoError(t, err)
  1365  		time.Sleep(time.Millisecond)
  1366  
  1367  		postList, err := ss.Post().GetPostsSince(model.GetPostsSinceOptions{ChannelId: channelId, Time: post1.CreateAt}, false)
  1368  		assert.NoError(t, err)
  1369  
  1370  		assert.Equal(t, []string{}, postList.Order)
  1371  		assert.Empty(t, postList.Posts)
  1372  	})
  1373  
  1374  	t.Run("should not cache a timestamp of 0 when nothing has changed", func(t *testing.T) {
  1375  		ss.Post().ClearCaches()
  1376  
  1377  		channelId := model.NewId()
  1378  		userId := model.NewId()
  1379  
  1380  		post1, err := ss.Post().Save(&model.Post{
  1381  			ChannelId: channelId,
  1382  			UserId:    userId,
  1383  			Message:   "message",
  1384  		})
  1385  		require.NoError(t, err)
  1386  		time.Sleep(time.Millisecond)
  1387  
  1388  		// Make a request that returns no results
  1389  		postList, err := ss.Post().GetPostsSince(model.GetPostsSinceOptions{ChannelId: channelId, Time: post1.CreateAt}, true)
  1390  		require.NoError(t, err)
  1391  		require.Equal(t, model.NewPostList(), postList)
  1392  
  1393  		// And then ensure that it doesn't cause future requests to also return no results
  1394  		postList, err = ss.Post().GetPostsSince(model.GetPostsSinceOptions{ChannelId: channelId, Time: post1.CreateAt - 1}, true)
  1395  		assert.NoError(t, err)
  1396  
  1397  		assert.Equal(t, []string{post1.Id}, postList.Order)
  1398  
  1399  		assert.Len(t, postList.Posts, 1)
  1400  		assert.NotNil(t, postList.Posts[post1.Id])
  1401  	})
  1402  }
  1403  
  1404  func testPostStoreGetPosts(t *testing.T, ss store.Store) {
  1405  	channelId := model.NewId()
  1406  	userId := model.NewId()
  1407  
  1408  	post1, err := ss.Post().Save(&model.Post{
  1409  		ChannelId: channelId,
  1410  		UserId:    userId,
  1411  		Message:   "message",
  1412  	})
  1413  	require.NoError(t, err)
  1414  	time.Sleep(time.Millisecond)
  1415  
  1416  	post2, err := ss.Post().Save(&model.Post{
  1417  		ChannelId: channelId,
  1418  		UserId:    userId,
  1419  		Message:   "message",
  1420  	})
  1421  	require.NoError(t, err)
  1422  	time.Sleep(time.Millisecond)
  1423  
  1424  	post3, err := ss.Post().Save(&model.Post{
  1425  		ChannelId: channelId,
  1426  		UserId:    userId,
  1427  		Message:   "message",
  1428  	})
  1429  	require.NoError(t, err)
  1430  	time.Sleep(time.Millisecond)
  1431  
  1432  	post4, err := ss.Post().Save(&model.Post{
  1433  		ChannelId: channelId,
  1434  		UserId:    userId,
  1435  		Message:   "message",
  1436  	})
  1437  	require.NoError(t, err)
  1438  	time.Sleep(time.Millisecond)
  1439  
  1440  	post5, err := ss.Post().Save(&model.Post{
  1441  		ChannelId: channelId,
  1442  		UserId:    userId,
  1443  		Message:   "message",
  1444  		RootId:    post3.Id,
  1445  	})
  1446  	require.NoError(t, err)
  1447  	time.Sleep(time.Millisecond)
  1448  
  1449  	post6, err := ss.Post().Save(&model.Post{
  1450  		ChannelId: channelId,
  1451  		UserId:    userId,
  1452  		Message:   "message",
  1453  		RootId:    post1.Id,
  1454  	})
  1455  	require.NoError(t, err)
  1456  
  1457  	t.Run("should return the last posts created in a channel", func(t *testing.T) {
  1458  		postList, err := ss.Post().GetPosts(model.GetPostsOptions{ChannelId: channelId, Page: 0, PerPage: 30, SkipFetchThreads: false}, false)
  1459  		assert.NoError(t, err)
  1460  
  1461  		assert.Equal(t, []string{
  1462  			post6.Id,
  1463  			post5.Id,
  1464  			post4.Id,
  1465  			post3.Id,
  1466  			post2.Id,
  1467  			post1.Id,
  1468  		}, postList.Order)
  1469  
  1470  		assert.Len(t, postList.Posts, 6)
  1471  		assert.NotNil(t, postList.Posts[post1.Id])
  1472  		assert.NotNil(t, postList.Posts[post2.Id])
  1473  		assert.NotNil(t, postList.Posts[post3.Id])
  1474  		assert.NotNil(t, postList.Posts[post4.Id])
  1475  		assert.NotNil(t, postList.Posts[post5.Id])
  1476  		assert.NotNil(t, postList.Posts[post6.Id])
  1477  	})
  1478  
  1479  	t.Run("should return the last posts created in a channel and the threads and the reply count must be 0", func(t *testing.T) {
  1480  		postList, err := ss.Post().GetPosts(model.GetPostsOptions{ChannelId: channelId, Page: 0, PerPage: 2, SkipFetchThreads: false}, false)
  1481  		assert.NoError(t, err)
  1482  
  1483  		assert.Equal(t, []string{
  1484  			post6.Id,
  1485  			post5.Id,
  1486  		}, postList.Order)
  1487  
  1488  		assert.Len(t, postList.Posts, 4)
  1489  		require.NotNil(t, postList.Posts[post1.Id])
  1490  		require.NotNil(t, postList.Posts[post3.Id])
  1491  		require.NotNil(t, postList.Posts[post5.Id])
  1492  		require.NotNil(t, postList.Posts[post6.Id])
  1493  		assert.Equal(t, int64(0), postList.Posts[post1.Id].ReplyCount)
  1494  		assert.Equal(t, int64(0), postList.Posts[post3.Id].ReplyCount)
  1495  		assert.Equal(t, int64(0), postList.Posts[post5.Id].ReplyCount)
  1496  		assert.Equal(t, int64(0), postList.Posts[post6.Id].ReplyCount)
  1497  	})
  1498  
  1499  	t.Run("should return the last posts created in a channel without the threads and the reply count must be correct", func(t *testing.T) {
  1500  		postList, err := ss.Post().GetPosts(model.GetPostsOptions{ChannelId: channelId, Page: 0, PerPage: 2, SkipFetchThreads: true}, false)
  1501  		assert.NoError(t, err)
  1502  
  1503  		assert.Equal(t, []string{
  1504  			post6.Id,
  1505  			post5.Id,
  1506  		}, postList.Order)
  1507  
  1508  		assert.Len(t, postList.Posts, 4)
  1509  		assert.NotNil(t, postList.Posts[post5.Id])
  1510  		assert.NotNil(t, postList.Posts[post6.Id])
  1511  		assert.Equal(t, int64(1), postList.Posts[post5.Id].ReplyCount)
  1512  		assert.Equal(t, int64(1), postList.Posts[post6.Id].ReplyCount)
  1513  	})
  1514  }
  1515  
  1516  func testPostStoreGetPostBeforeAfter(t *testing.T, ss store.Store) {
  1517  	channelId := model.NewId()
  1518  
  1519  	o0 := &model.Post{}
  1520  	o0.ChannelId = channelId
  1521  	o0.UserId = model.NewId()
  1522  	o0.Message = "zz" + model.NewId() + "b"
  1523  	_, err := ss.Post().Save(o0)
  1524  	require.NoError(t, err)
  1525  	time.Sleep(2 * time.Millisecond)
  1526  
  1527  	o1 := &model.Post{}
  1528  	o1.ChannelId = channelId
  1529  	o1.Type = model.POST_JOIN_CHANNEL
  1530  	o1.UserId = model.NewId()
  1531  	o1.Message = "system_join_channel message"
  1532  	_, err = ss.Post().Save(o1)
  1533  	require.NoError(t, err)
  1534  	time.Sleep(2 * time.Millisecond)
  1535  
  1536  	o0a := &model.Post{}
  1537  	o0a.ChannelId = channelId
  1538  	o0a.UserId = model.NewId()
  1539  	o0a.Message = "zz" + model.NewId() + "b"
  1540  	o0a.ParentId = o1.Id
  1541  	o0a.RootId = o1.Id
  1542  	_, err = ss.Post().Save(o0a)
  1543  	require.NoError(t, err)
  1544  	time.Sleep(2 * time.Millisecond)
  1545  
  1546  	o0b := &model.Post{}
  1547  	o0b.ChannelId = channelId
  1548  	o0b.UserId = model.NewId()
  1549  	o0b.Message = "deleted message"
  1550  	o0b.ParentId = o1.Id
  1551  	o0b.RootId = o1.Id
  1552  	o0b.DeleteAt = 1
  1553  	_, err = ss.Post().Save(o0b)
  1554  	require.NoError(t, err)
  1555  	time.Sleep(2 * time.Millisecond)
  1556  
  1557  	otherChannelPost := &model.Post{}
  1558  	otherChannelPost.ChannelId = model.NewId()
  1559  	otherChannelPost.UserId = model.NewId()
  1560  	otherChannelPost.Message = "zz" + model.NewId() + "b"
  1561  	_, err = ss.Post().Save(otherChannelPost)
  1562  	require.NoError(t, err)
  1563  	time.Sleep(2 * time.Millisecond)
  1564  
  1565  	o2 := &model.Post{}
  1566  	o2.ChannelId = channelId
  1567  	o2.UserId = model.NewId()
  1568  	o2.Message = "zz" + model.NewId() + "b"
  1569  	_, err = ss.Post().Save(o2)
  1570  	require.NoError(t, err)
  1571  	time.Sleep(2 * time.Millisecond)
  1572  
  1573  	o2a := &model.Post{}
  1574  	o2a.ChannelId = channelId
  1575  	o2a.UserId = model.NewId()
  1576  	o2a.Message = "zz" + model.NewId() + "b"
  1577  	o2a.ParentId = o2.Id
  1578  	o2a.RootId = o2.Id
  1579  	_, err = ss.Post().Save(o2a)
  1580  	require.NoError(t, err)
  1581  
  1582  	rPostId1, err := ss.Post().GetPostIdBeforeTime(channelId, o0a.CreateAt)
  1583  	require.Equal(t, rPostId1, o1.Id, "should return before post o1")
  1584  	require.NoError(t, err)
  1585  
  1586  	rPostId1, err = ss.Post().GetPostIdAfterTime(channelId, o0b.CreateAt)
  1587  	require.Equal(t, rPostId1, o2.Id, "should return before post o2")
  1588  	require.NoError(t, err)
  1589  
  1590  	rPost1, err := ss.Post().GetPostAfterTime(channelId, o0b.CreateAt)
  1591  	require.Equal(t, rPost1.Id, o2.Id, "should return before post o2")
  1592  	require.NoError(t, err)
  1593  
  1594  	rPostId2, err := ss.Post().GetPostIdBeforeTime(channelId, o0.CreateAt)
  1595  	require.Empty(t, rPostId2, "should return no post")
  1596  	require.NoError(t, err)
  1597  
  1598  	rPostId2, err = ss.Post().GetPostIdAfterTime(channelId, o0.CreateAt)
  1599  	require.Equal(t, rPostId2, o1.Id, "should return before post o1")
  1600  	require.NoError(t, err)
  1601  
  1602  	rPost2, err := ss.Post().GetPostAfterTime(channelId, o0.CreateAt)
  1603  	require.Equal(t, rPost2.Id, o1.Id, "should return before post o1")
  1604  	require.NoError(t, err)
  1605  
  1606  	rPostId3, err := ss.Post().GetPostIdBeforeTime(channelId, o2a.CreateAt)
  1607  	require.Equal(t, rPostId3, o2.Id, "should return before post o2")
  1608  	require.NoError(t, err)
  1609  
  1610  	rPostId3, err = ss.Post().GetPostIdAfterTime(channelId, o2a.CreateAt)
  1611  	require.Empty(t, rPostId3, "should return no post")
  1612  	require.NoError(t, err)
  1613  
  1614  	rPost3, err := ss.Post().GetPostAfterTime(channelId, o2a.CreateAt)
  1615  	require.Empty(t, rPost3, "should return no post")
  1616  	require.NoError(t, err)
  1617  }
  1618  
  1619  func testUserCountsWithPostsByDay(t *testing.T, ss store.Store) {
  1620  	t1 := &model.Team{}
  1621  	t1.DisplayName = "DisplayName"
  1622  	t1.Name = "zz" + model.NewId() + "b"
  1623  	t1.Email = MakeEmail()
  1624  	t1.Type = model.TEAM_OPEN
  1625  	t1, err := ss.Team().Save(t1)
  1626  	require.NoError(t, err)
  1627  
  1628  	c1 := &model.Channel{}
  1629  	c1.TeamId = t1.Id
  1630  	c1.DisplayName = "Channel2"
  1631  	c1.Name = "zz" + model.NewId() + "b"
  1632  	c1.Type = model.CHANNEL_OPEN
  1633  	c1, nErr := ss.Channel().Save(c1, -1)
  1634  	require.NoError(t, nErr)
  1635  
  1636  	o1 := &model.Post{}
  1637  	o1.ChannelId = c1.Id
  1638  	o1.UserId = model.NewId()
  1639  	o1.CreateAt = utils.MillisFromTime(utils.Yesterday())
  1640  	o1.Message = "zz" + model.NewId() + "b"
  1641  	o1, nErr = ss.Post().Save(o1)
  1642  	require.NoError(t, nErr)
  1643  
  1644  	o1a := &model.Post{}
  1645  	o1a.ChannelId = c1.Id
  1646  	o1a.UserId = model.NewId()
  1647  	o1a.CreateAt = o1.CreateAt
  1648  	o1a.Message = "zz" + model.NewId() + "b"
  1649  	_, nErr = ss.Post().Save(o1a)
  1650  	require.NoError(t, nErr)
  1651  
  1652  	o2 := &model.Post{}
  1653  	o2.ChannelId = c1.Id
  1654  	o2.UserId = model.NewId()
  1655  	o2.CreateAt = o1.CreateAt - (1000 * 60 * 60 * 24)
  1656  	o2.Message = "zz" + model.NewId() + "b"
  1657  	o2, nErr = ss.Post().Save(o2)
  1658  	require.NoError(t, nErr)
  1659  
  1660  	o2a := &model.Post{}
  1661  	o2a.ChannelId = c1.Id
  1662  	o2a.UserId = o2.UserId
  1663  	o2a.CreateAt = o1.CreateAt - (1000 * 60 * 60 * 24)
  1664  	o2a.Message = "zz" + model.NewId() + "b"
  1665  	_, nErr = ss.Post().Save(o2a)
  1666  	require.NoError(t, nErr)
  1667  
  1668  	r1, err := ss.Post().AnalyticsUserCountsWithPostsByDay(t1.Id)
  1669  	require.NoError(t, err)
  1670  
  1671  	row1 := r1[0]
  1672  	require.Equal(t, float64(2), row1.Value, "wrong value")
  1673  
  1674  	row2 := r1[1]
  1675  	require.Equal(t, float64(1), row2.Value, "wrong value")
  1676  }
  1677  
  1678  func testPostCountsByDay(t *testing.T, ss store.Store) {
  1679  	t1 := &model.Team{}
  1680  	t1.DisplayName = "DisplayName"
  1681  	t1.Name = "zz" + model.NewId() + "b"
  1682  	t1.Email = MakeEmail()
  1683  	t1.Type = model.TEAM_OPEN
  1684  	t1, err := ss.Team().Save(t1)
  1685  	require.NoError(t, err)
  1686  
  1687  	c1 := &model.Channel{}
  1688  	c1.TeamId = t1.Id
  1689  	c1.DisplayName = "Channel2"
  1690  	c1.Name = "zz" + model.NewId() + "b"
  1691  	c1.Type = model.CHANNEL_OPEN
  1692  	c1, nErr := ss.Channel().Save(c1, -1)
  1693  	require.NoError(t, nErr)
  1694  
  1695  	o1 := &model.Post{}
  1696  	o1.ChannelId = c1.Id
  1697  	o1.UserId = model.NewId()
  1698  	o1.CreateAt = utils.MillisFromTime(utils.Yesterday())
  1699  	o1.Message = "zz" + model.NewId() + "b"
  1700  	o1.Hashtags = "hashtag"
  1701  	o1, nErr = ss.Post().Save(o1)
  1702  	require.NoError(t, nErr)
  1703  
  1704  	o1a := &model.Post{}
  1705  	o1a.ChannelId = c1.Id
  1706  	o1a.UserId = model.NewId()
  1707  	o1a.CreateAt = o1.CreateAt
  1708  	o1a.Message = "zz" + model.NewId() + "b"
  1709  	o1a.FileIds = []string{"fileId1"}
  1710  	_, nErr = ss.Post().Save(o1a)
  1711  	require.NoError(t, nErr)
  1712  
  1713  	o2 := &model.Post{}
  1714  	o2.ChannelId = c1.Id
  1715  	o2.UserId = model.NewId()
  1716  	o2.CreateAt = o1.CreateAt - (1000 * 60 * 60 * 24 * 2)
  1717  	o2.Message = "zz" + model.NewId() + "b"
  1718  	o2.Filenames = []string{"filename1"}
  1719  	o2, nErr = ss.Post().Save(o2)
  1720  	require.NoError(t, nErr)
  1721  
  1722  	o2a := &model.Post{}
  1723  	o2a.ChannelId = c1.Id
  1724  	o2a.UserId = o2.UserId
  1725  	o2a.CreateAt = o1.CreateAt - (1000 * 60 * 60 * 24 * 2)
  1726  	o2a.Message = "zz" + model.NewId() + "b"
  1727  	o2a.Hashtags = "hashtag"
  1728  	o2a.FileIds = []string{"fileId2"}
  1729  	_, nErr = ss.Post().Save(o2a)
  1730  	require.NoError(t, nErr)
  1731  
  1732  	bot1 := &model.Bot{
  1733  		Username:    "username",
  1734  		Description: "a bot",
  1735  		OwnerId:     model.NewId(),
  1736  		UserId:      model.NewId(),
  1737  	}
  1738  	_, nErr = ss.Bot().Save(bot1)
  1739  	require.NoError(t, nErr)
  1740  
  1741  	b1 := &model.Post{}
  1742  	b1.Message = "bot message one"
  1743  	b1.ChannelId = c1.Id
  1744  	b1.UserId = bot1.UserId
  1745  	b1.CreateAt = utils.MillisFromTime(utils.Yesterday())
  1746  	_, nErr = ss.Post().Save(b1)
  1747  	require.NoError(t, nErr)
  1748  
  1749  	b1a := &model.Post{}
  1750  	b1a.Message = "bot message two"
  1751  	b1a.ChannelId = c1.Id
  1752  	b1a.UserId = bot1.UserId
  1753  	b1a.CreateAt = utils.MillisFromTime(utils.Yesterday()) - (1000 * 60 * 60 * 24 * 2)
  1754  	_, nErr = ss.Post().Save(b1a)
  1755  	require.NoError(t, nErr)
  1756  
  1757  	time.Sleep(1 * time.Second)
  1758  
  1759  	// summary of posts
  1760  	// yesterday - 2 non-bot user posts, 1 bot user post
  1761  	// 3 days ago - 2 non-bot user posts, 1 bot user post
  1762  
  1763  	// last 31 days, all users (including bots)
  1764  	postCountsOptions := &model.AnalyticsPostCountsOptions{TeamId: t1.Id, BotsOnly: false, YesterdayOnly: false}
  1765  	r1, err := ss.Post().AnalyticsPostCountsByDay(postCountsOptions)
  1766  	require.NoError(t, err)
  1767  	assert.Equal(t, float64(3), r1[0].Value)
  1768  	assert.Equal(t, float64(3), r1[1].Value)
  1769  
  1770  	// last 31 days, bots only
  1771  	postCountsOptions = &model.AnalyticsPostCountsOptions{TeamId: t1.Id, BotsOnly: true, YesterdayOnly: false}
  1772  	r1, err = ss.Post().AnalyticsPostCountsByDay(postCountsOptions)
  1773  	require.NoError(t, err)
  1774  	assert.Equal(t, float64(1), r1[0].Value)
  1775  	assert.Equal(t, float64(1), r1[1].Value)
  1776  
  1777  	// yesterday only, all users (including bots)
  1778  	postCountsOptions = &model.AnalyticsPostCountsOptions{TeamId: t1.Id, BotsOnly: false, YesterdayOnly: true}
  1779  	r1, err = ss.Post().AnalyticsPostCountsByDay(postCountsOptions)
  1780  	require.NoError(t, err)
  1781  	assert.Equal(t, float64(3), r1[0].Value)
  1782  
  1783  	// yesterday only, bots only
  1784  	postCountsOptions = &model.AnalyticsPostCountsOptions{TeamId: t1.Id, BotsOnly: true, YesterdayOnly: true}
  1785  	r1, err = ss.Post().AnalyticsPostCountsByDay(postCountsOptions)
  1786  	require.NoError(t, err)
  1787  	assert.Equal(t, float64(1), r1[0].Value)
  1788  
  1789  	// total
  1790  	r2, err := ss.Post().AnalyticsPostCount(t1.Id, false, false)
  1791  	require.NoError(t, err)
  1792  	assert.Equal(t, int64(6), r2)
  1793  
  1794  	// total across teams
  1795  	r2, err = ss.Post().AnalyticsPostCount("", false, false)
  1796  	require.NoError(t, err)
  1797  	assert.GreaterOrEqual(t, r2, int64(6))
  1798  
  1799  	// total across teams with files
  1800  	r2, err = ss.Post().AnalyticsPostCount("", true, false)
  1801  	require.NoError(t, err)
  1802  	assert.GreaterOrEqual(t, r2, int64(3))
  1803  
  1804  	// total across teams with hastags
  1805  	r2, err = ss.Post().AnalyticsPostCount("", false, true)
  1806  	require.NoError(t, err)
  1807  	assert.GreaterOrEqual(t, r2, int64(2))
  1808  
  1809  	// total across teams with hastags and files
  1810  	r2, err = ss.Post().AnalyticsPostCount("", true, true)
  1811  	require.NoError(t, err)
  1812  	assert.GreaterOrEqual(t, r2, int64(1))
  1813  }
  1814  
  1815  func testPostStoreGetFlaggedPostsForTeam(t *testing.T, ss store.Store, s SqlStore) {
  1816  	c1 := &model.Channel{}
  1817  	c1.TeamId = model.NewId()
  1818  	c1.DisplayName = "Channel1"
  1819  	c1.Name = "zz" + model.NewId() + "b"
  1820  	c1.Type = model.CHANNEL_OPEN
  1821  	c1, err := ss.Channel().Save(c1, -1)
  1822  	require.NoError(t, err)
  1823  
  1824  	o1 := &model.Post{}
  1825  	o1.ChannelId = c1.Id
  1826  	o1.UserId = model.NewId()
  1827  	o1.Message = "zz" + model.NewId() + "b"
  1828  	o1, err = ss.Post().Save(o1)
  1829  	require.NoError(t, err)
  1830  	time.Sleep(2 * time.Millisecond)
  1831  
  1832  	o2 := &model.Post{}
  1833  	o2.ChannelId = o1.ChannelId
  1834  	o2.UserId = model.NewId()
  1835  	o2.Message = "zz" + model.NewId() + "b"
  1836  	o2, err = ss.Post().Save(o2)
  1837  	require.NoError(t, err)
  1838  	time.Sleep(2 * time.Millisecond)
  1839  
  1840  	o3 := &model.Post{}
  1841  	o3.ChannelId = o1.ChannelId
  1842  	o3.UserId = model.NewId()
  1843  	o3.Message = "zz" + model.NewId() + "b"
  1844  	o3.DeleteAt = 1
  1845  	o3, err = ss.Post().Save(o3)
  1846  	require.NoError(t, err)
  1847  	time.Sleep(2 * time.Millisecond)
  1848  
  1849  	o4 := &model.Post{}
  1850  	o4.ChannelId = model.NewId()
  1851  	o4.UserId = model.NewId()
  1852  	o4.Message = "zz" + model.NewId() + "b"
  1853  	o4, err = ss.Post().Save(o4)
  1854  	require.NoError(t, err)
  1855  	time.Sleep(2 * time.Millisecond)
  1856  
  1857  	c2 := &model.Channel{}
  1858  	c2.DisplayName = "DMChannel1"
  1859  	c2.Name = "zz" + model.NewId() + "b"
  1860  	c2.Type = model.CHANNEL_DIRECT
  1861  
  1862  	m1 := &model.ChannelMember{}
  1863  	m1.ChannelId = c2.Id
  1864  	m1.UserId = o1.UserId
  1865  	m1.NotifyProps = model.GetDefaultChannelNotifyProps()
  1866  
  1867  	m2 := &model.ChannelMember{}
  1868  	m2.ChannelId = c2.Id
  1869  	m2.UserId = model.NewId()
  1870  	m2.NotifyProps = model.GetDefaultChannelNotifyProps()
  1871  
  1872  	c2, err = ss.Channel().SaveDirectChannel(c2, m1, m2)
  1873  	require.NoError(t, err)
  1874  
  1875  	o5 := &model.Post{}
  1876  	o5.ChannelId = c2.Id
  1877  	o5.UserId = m2.UserId
  1878  	o5.Message = "zz" + model.NewId() + "b"
  1879  	o5, err = ss.Post().Save(o5)
  1880  	require.NoError(t, err)
  1881  	time.Sleep(2 * time.Millisecond)
  1882  
  1883  	r1, err := ss.Post().GetFlaggedPosts(o1.ChannelId, 0, 2)
  1884  	require.NoError(t, err)
  1885  
  1886  	require.Empty(t, r1.Order, "should be empty")
  1887  
  1888  	preferences := model.Preferences{
  1889  		{
  1890  			UserId:   o1.UserId,
  1891  			Category: model.PREFERENCE_CATEGORY_FLAGGED_POST,
  1892  			Name:     o1.Id,
  1893  			Value:    "true",
  1894  		},
  1895  	}
  1896  
  1897  	err = ss.Preference().Save(&preferences)
  1898  	require.NoError(t, err)
  1899  
  1900  	r2, err := ss.Post().GetFlaggedPostsForTeam(o1.UserId, c1.TeamId, 0, 2)
  1901  	require.NoError(t, err)
  1902  	require.Len(t, r2.Order, 1, "should have 1 post")
  1903  
  1904  	preferences = model.Preferences{
  1905  		{
  1906  			UserId:   o1.UserId,
  1907  			Category: model.PREFERENCE_CATEGORY_FLAGGED_POST,
  1908  			Name:     o2.Id,
  1909  			Value:    "true",
  1910  		},
  1911  	}
  1912  
  1913  	err = ss.Preference().Save(&preferences)
  1914  	require.NoError(t, err)
  1915  
  1916  	r3, err := ss.Post().GetFlaggedPostsForTeam(o1.UserId, c1.TeamId, 0, 1)
  1917  	require.NoError(t, err)
  1918  	require.Len(t, r3.Order, 1, "should have 1 post")
  1919  
  1920  	r3, err = ss.Post().GetFlaggedPostsForTeam(o1.UserId, c1.TeamId, 1, 1)
  1921  	require.NoError(t, err)
  1922  	require.Len(t, r3.Order, 1, "should have 1 post")
  1923  
  1924  	r3, err = ss.Post().GetFlaggedPostsForTeam(o1.UserId, c1.TeamId, 1000, 10)
  1925  	require.NoError(t, err)
  1926  	require.Empty(t, r3.Order, "should be empty")
  1927  
  1928  	r4, err := ss.Post().GetFlaggedPostsForTeam(o1.UserId, c1.TeamId, 0, 2)
  1929  	require.NoError(t, err)
  1930  	require.Len(t, r4.Order, 2, "should have 2 posts")
  1931  
  1932  	preferences = model.Preferences{
  1933  		{
  1934  			UserId:   o1.UserId,
  1935  			Category: model.PREFERENCE_CATEGORY_FLAGGED_POST,
  1936  			Name:     o3.Id,
  1937  			Value:    "true",
  1938  		},
  1939  	}
  1940  
  1941  	err = ss.Preference().Save(&preferences)
  1942  	require.NoError(t, err)
  1943  
  1944  	r4, err = ss.Post().GetFlaggedPostsForTeam(o1.UserId, c1.TeamId, 0, 2)
  1945  	require.NoError(t, err)
  1946  	require.Len(t, r4.Order, 2, "should have 2 posts")
  1947  
  1948  	preferences = model.Preferences{
  1949  		{
  1950  			UserId:   o1.UserId,
  1951  			Category: model.PREFERENCE_CATEGORY_FLAGGED_POST,
  1952  			Name:     o4.Id,
  1953  			Value:    "true",
  1954  		},
  1955  	}
  1956  	err = ss.Preference().Save(&preferences)
  1957  	require.NoError(t, err)
  1958  
  1959  	r4, err = ss.Post().GetFlaggedPostsForTeam(o1.UserId, c1.TeamId, 0, 2)
  1960  	require.NoError(t, err)
  1961  	require.Len(t, r4.Order, 2, "should have 2 posts")
  1962  
  1963  	r4, err = ss.Post().GetFlaggedPostsForTeam(o1.UserId, model.NewId(), 0, 2)
  1964  	require.NoError(t, err)
  1965  	require.Empty(t, r4.Order, "should have 0 posts")
  1966  
  1967  	preferences = model.Preferences{
  1968  		{
  1969  			UserId:   o1.UserId,
  1970  			Category: model.PREFERENCE_CATEGORY_FLAGGED_POST,
  1971  			Name:     o5.Id,
  1972  			Value:    "true",
  1973  		},
  1974  	}
  1975  	err = ss.Preference().Save(&preferences)
  1976  	require.NoError(t, err)
  1977  
  1978  	r4, err = ss.Post().GetFlaggedPostsForTeam(o1.UserId, c1.TeamId, 0, 10)
  1979  	require.NoError(t, err)
  1980  	require.Len(t, r4.Order, 3, "should have 3 posts")
  1981  
  1982  	// Manually truncate Channels table until testlib can handle cleanups
  1983  	s.GetMaster().Exec("TRUNCATE Channels")
  1984  }
  1985  
  1986  func testPostStoreGetFlaggedPosts(t *testing.T, ss store.Store) {
  1987  	o1 := &model.Post{}
  1988  	o1.ChannelId = model.NewId()
  1989  	o1.UserId = model.NewId()
  1990  	o1.Message = "zz" + model.NewId() + "b"
  1991  	o1, err := ss.Post().Save(o1)
  1992  	require.NoError(t, err)
  1993  	time.Sleep(2 * time.Millisecond)
  1994  
  1995  	o2 := &model.Post{}
  1996  	o2.ChannelId = o1.ChannelId
  1997  	o2.UserId = model.NewId()
  1998  	o2.Message = "zz" + model.NewId() + "b"
  1999  	o2, err = ss.Post().Save(o2)
  2000  	require.NoError(t, err)
  2001  	time.Sleep(2 * time.Millisecond)
  2002  
  2003  	o3 := &model.Post{}
  2004  	o3.ChannelId = o1.ChannelId
  2005  	o3.UserId = model.NewId()
  2006  	o3.Message = "zz" + model.NewId() + "b"
  2007  	o3.DeleteAt = 1
  2008  	o3, err = ss.Post().Save(o3)
  2009  	require.NoError(t, err)
  2010  	time.Sleep(2 * time.Millisecond)
  2011  
  2012  	r1, err := ss.Post().GetFlaggedPosts(o1.UserId, 0, 2)
  2013  	require.NoError(t, err)
  2014  	require.Empty(t, r1.Order, "should be empty")
  2015  
  2016  	preferences := model.Preferences{
  2017  		{
  2018  			UserId:   o1.UserId,
  2019  			Category: model.PREFERENCE_CATEGORY_FLAGGED_POST,
  2020  			Name:     o1.Id,
  2021  			Value:    "true",
  2022  		},
  2023  	}
  2024  
  2025  	nErr := ss.Preference().Save(&preferences)
  2026  	require.NoError(t, nErr)
  2027  
  2028  	r2, err := ss.Post().GetFlaggedPosts(o1.UserId, 0, 2)
  2029  	require.NoError(t, err)
  2030  	require.Len(t, r2.Order, 1, "should have 1 post")
  2031  
  2032  	preferences = model.Preferences{
  2033  		{
  2034  			UserId:   o1.UserId,
  2035  			Category: model.PREFERENCE_CATEGORY_FLAGGED_POST,
  2036  			Name:     o2.Id,
  2037  			Value:    "true",
  2038  		},
  2039  	}
  2040  
  2041  	nErr = ss.Preference().Save(&preferences)
  2042  	require.NoError(t, nErr)
  2043  
  2044  	r3, err := ss.Post().GetFlaggedPosts(o1.UserId, 0, 1)
  2045  	require.NoError(t, err)
  2046  	require.Len(t, r3.Order, 1, "should have 1 post")
  2047  
  2048  	r3, err = ss.Post().GetFlaggedPosts(o1.UserId, 1, 1)
  2049  	require.NoError(t, err)
  2050  	require.Len(t, r3.Order, 1, "should have 1 post")
  2051  
  2052  	r3, err = ss.Post().GetFlaggedPosts(o1.UserId, 1000, 10)
  2053  	require.NoError(t, err)
  2054  	require.Empty(t, r3.Order, "should be empty")
  2055  
  2056  	r4, err := ss.Post().GetFlaggedPosts(o1.UserId, 0, 2)
  2057  	require.NoError(t, err)
  2058  	require.Len(t, r4.Order, 2, "should have 2 posts")
  2059  
  2060  	preferences = model.Preferences{
  2061  		{
  2062  			UserId:   o1.UserId,
  2063  			Category: model.PREFERENCE_CATEGORY_FLAGGED_POST,
  2064  			Name:     o3.Id,
  2065  			Value:    "true",
  2066  		},
  2067  	}
  2068  
  2069  	nErr = ss.Preference().Save(&preferences)
  2070  	require.NoError(t, nErr)
  2071  
  2072  	r4, err = ss.Post().GetFlaggedPosts(o1.UserId, 0, 2)
  2073  	require.NoError(t, err)
  2074  	require.Len(t, r4.Order, 2, "should have 2 posts")
  2075  }
  2076  
  2077  func testPostStoreGetFlaggedPostsForChannel(t *testing.T, ss store.Store) {
  2078  	o1 := &model.Post{}
  2079  	o1.ChannelId = model.NewId()
  2080  	o1.UserId = model.NewId()
  2081  	o1.Message = "zz" + model.NewId() + "b"
  2082  	o1, err := ss.Post().Save(o1)
  2083  	require.NoError(t, err)
  2084  	time.Sleep(2 * time.Millisecond)
  2085  
  2086  	o2 := &model.Post{}
  2087  	o2.ChannelId = o1.ChannelId
  2088  	o2.UserId = model.NewId()
  2089  	o2.Message = "zz" + model.NewId() + "b"
  2090  	o2, err = ss.Post().Save(o2)
  2091  	require.NoError(t, err)
  2092  	time.Sleep(2 * time.Millisecond)
  2093  
  2094  	// deleted post
  2095  	o3 := &model.Post{}
  2096  	o3.ChannelId = model.NewId()
  2097  	o3.UserId = o1.ChannelId
  2098  	o3.Message = "zz" + model.NewId() + "b"
  2099  	o3.DeleteAt = 1
  2100  	o3, err = ss.Post().Save(o3)
  2101  	require.NoError(t, err)
  2102  	time.Sleep(2 * time.Millisecond)
  2103  
  2104  	o4 := &model.Post{}
  2105  	o4.ChannelId = model.NewId()
  2106  	o4.UserId = model.NewId()
  2107  	o4.Message = "zz" + model.NewId() + "b"
  2108  	o4, err = ss.Post().Save(o4)
  2109  	require.NoError(t, err)
  2110  	time.Sleep(2 * time.Millisecond)
  2111  
  2112  	r, err := ss.Post().GetFlaggedPostsForChannel(o1.UserId, o1.ChannelId, 0, 10)
  2113  	require.NoError(t, err)
  2114  	require.Empty(t, r.Order, "should be empty")
  2115  
  2116  	preference := model.Preference{
  2117  		UserId:   o1.UserId,
  2118  		Category: model.PREFERENCE_CATEGORY_FLAGGED_POST,
  2119  		Name:     o1.Id,
  2120  		Value:    "true",
  2121  	}
  2122  
  2123  	nErr := ss.Preference().Save(&model.Preferences{preference})
  2124  	require.NoError(t, nErr)
  2125  
  2126  	r, err = ss.Post().GetFlaggedPostsForChannel(o1.UserId, o1.ChannelId, 0, 10)
  2127  	require.NoError(t, err)
  2128  	require.Len(t, r.Order, 1, "should have 1 post")
  2129  
  2130  	preference.Name = o2.Id
  2131  	nErr = ss.Preference().Save(&model.Preferences{preference})
  2132  	require.NoError(t, nErr)
  2133  
  2134  	preference.Name = o3.Id
  2135  	nErr = ss.Preference().Save(&model.Preferences{preference})
  2136  	require.NoError(t, nErr)
  2137  
  2138  	r, err = ss.Post().GetFlaggedPostsForChannel(o1.UserId, o1.ChannelId, 0, 1)
  2139  	require.NoError(t, err)
  2140  	require.Len(t, r.Order, 1, "should have 1 post")
  2141  
  2142  	r, err = ss.Post().GetFlaggedPostsForChannel(o1.UserId, o1.ChannelId, 1, 1)
  2143  	require.NoError(t, err)
  2144  	require.Len(t, r.Order, 1, "should have 1 post")
  2145  
  2146  	r, err = ss.Post().GetFlaggedPostsForChannel(o1.UserId, o1.ChannelId, 1000, 10)
  2147  	require.NoError(t, err)
  2148  	require.Empty(t, r.Order, "should be empty")
  2149  
  2150  	r, err = ss.Post().GetFlaggedPostsForChannel(o1.UserId, o1.ChannelId, 0, 10)
  2151  	require.NoError(t, err)
  2152  	require.Len(t, r.Order, 2, "should have 2 posts")
  2153  
  2154  	preference.Name = o4.Id
  2155  	nErr = ss.Preference().Save(&model.Preferences{preference})
  2156  	require.NoError(t, nErr)
  2157  
  2158  	r, err = ss.Post().GetFlaggedPostsForChannel(o1.UserId, o4.ChannelId, 0, 10)
  2159  	require.NoError(t, err)
  2160  	require.Len(t, r.Order, 1, "should have 1 posts")
  2161  }
  2162  
  2163  func testPostStoreGetPostsCreatedAt(t *testing.T, ss store.Store) {
  2164  	createTime := model.GetMillis() + 1
  2165  
  2166  	o0 := &model.Post{}
  2167  	o0.ChannelId = model.NewId()
  2168  	o0.UserId = model.NewId()
  2169  	o0.Message = "zz" + model.NewId() + "b"
  2170  	o0.CreateAt = createTime
  2171  	o0, err := ss.Post().Save(o0)
  2172  	require.NoError(t, err)
  2173  
  2174  	o1 := &model.Post{}
  2175  	o1.ChannelId = o0.ChannelId
  2176  	o1.UserId = model.NewId()
  2177  	o1.Message = "zz" + model.NewId() + "b"
  2178  	o1.CreateAt = createTime
  2179  	o1, err = ss.Post().Save(o1)
  2180  	require.NoError(t, err)
  2181  
  2182  	o2 := &model.Post{}
  2183  	o2.ChannelId = o1.ChannelId
  2184  	o2.UserId = model.NewId()
  2185  	o2.Message = "zz" + model.NewId() + "b"
  2186  	o2.ParentId = o1.Id
  2187  	o2.RootId = o1.Id
  2188  	o2.CreateAt = createTime + 1
  2189  	_, err = ss.Post().Save(o2)
  2190  	require.NoError(t, err)
  2191  
  2192  	o3 := &model.Post{}
  2193  	o3.ChannelId = model.NewId()
  2194  	o3.UserId = model.NewId()
  2195  	o3.Message = "zz" + model.NewId() + "b"
  2196  	o3.CreateAt = createTime
  2197  	_, err = ss.Post().Save(o3)
  2198  	require.NoError(t, err)
  2199  
  2200  	r1, _ := ss.Post().GetPostsCreatedAt(o1.ChannelId, createTime)
  2201  	assert.Equal(t, 2, len(r1))
  2202  }
  2203  
  2204  func testPostStoreOverwriteMultiple(t *testing.T, ss store.Store) {
  2205  	o1 := &model.Post{}
  2206  	o1.ChannelId = model.NewId()
  2207  	o1.UserId = model.NewId()
  2208  	o1.Message = "zz" + model.NewId() + "AAAAAAAAAAA"
  2209  	o1, err := ss.Post().Save(o1)
  2210  	require.NoError(t, err)
  2211  
  2212  	o2 := &model.Post{}
  2213  	o2.ChannelId = o1.ChannelId
  2214  	o2.UserId = model.NewId()
  2215  	o2.Message = "zz" + model.NewId() + "CCCCCCCCC"
  2216  	o2.ParentId = o1.Id
  2217  	o2.RootId = o1.Id
  2218  	o2, err = ss.Post().Save(o2)
  2219  	require.NoError(t, err)
  2220  
  2221  	o3 := &model.Post{}
  2222  	o3.ChannelId = o1.ChannelId
  2223  	o3.UserId = model.NewId()
  2224  	o3.Message = "zz" + model.NewId() + "QQQQQQQQQQ"
  2225  	o3, err = ss.Post().Save(o3)
  2226  	require.NoError(t, err)
  2227  
  2228  	o4, err := ss.Post().Save(&model.Post{
  2229  		ChannelId: model.NewId(),
  2230  		UserId:    model.NewId(),
  2231  		Message:   model.NewId(),
  2232  		Filenames: []string{"test"},
  2233  	})
  2234  	require.NoError(t, err)
  2235  
  2236  	o5, err := ss.Post().Save(&model.Post{
  2237  		ChannelId: model.NewId(),
  2238  		UserId:    model.NewId(),
  2239  		Message:   model.NewId(),
  2240  		Filenames: []string{"test2", "test3"},
  2241  	})
  2242  	require.NoError(t, err)
  2243  
  2244  	r1, err := ss.Post().Get(o1.Id, false, false, false)
  2245  	require.NoError(t, err)
  2246  	ro1 := r1.Posts[o1.Id]
  2247  
  2248  	r2, err := ss.Post().Get(o2.Id, false, false, false)
  2249  	require.NoError(t, err)
  2250  	ro2 := r2.Posts[o2.Id]
  2251  
  2252  	r3, err := ss.Post().Get(o3.Id, false, false, false)
  2253  	require.NoError(t, err)
  2254  	ro3 := r3.Posts[o3.Id]
  2255  
  2256  	r4, err := ss.Post().Get(o4.Id, false, false, false)
  2257  	require.NoError(t, err)
  2258  	ro4 := r4.Posts[o4.Id]
  2259  
  2260  	r5, err := ss.Post().Get(o5.Id, false, false, false)
  2261  	require.NoError(t, err)
  2262  	ro5 := r5.Posts[o5.Id]
  2263  
  2264  	require.Equal(t, ro1.Message, o1.Message, "Failed to save/get")
  2265  	require.Equal(t, ro2.Message, o2.Message, "Failed to save/get")
  2266  	require.Equal(t, ro3.Message, o3.Message, "Failed to save/get")
  2267  	require.Equal(t, ro4.Message, o4.Message, "Failed to save/get")
  2268  	require.Equal(t, ro4.Filenames, o4.Filenames, "Failed to save/get")
  2269  	require.Equal(t, ro5.Message, o5.Message, "Failed to save/get")
  2270  	require.Equal(t, ro5.Filenames, o5.Filenames, "Failed to save/get")
  2271  
  2272  	t.Run("overwrite changing message", func(t *testing.T) {
  2273  		o1a := ro1.Clone()
  2274  		o1a.Message = ro1.Message + "BBBBBBBBBB"
  2275  
  2276  		o2a := ro2.Clone()
  2277  		o2a.Message = ro2.Message + "DDDDDDD"
  2278  
  2279  		o3a := ro3.Clone()
  2280  		o3a.Message = ro3.Message + "WWWWWWW"
  2281  
  2282  		_, errIdx, err := ss.Post().OverwriteMultiple([]*model.Post{o1a, o2a, o3a})
  2283  		require.NoError(t, err)
  2284  		require.Equal(t, -1, errIdx)
  2285  
  2286  		r1, nErr := ss.Post().Get(o1.Id, false, false, false)
  2287  		require.NoError(t, nErr)
  2288  		ro1a := r1.Posts[o1.Id]
  2289  
  2290  		r2, nErr = ss.Post().Get(o1.Id, false, false, false)
  2291  		require.NoError(t, nErr)
  2292  		ro2a := r2.Posts[o2.Id]
  2293  
  2294  		r3, nErr = ss.Post().Get(o3.Id, false, false, false)
  2295  		require.NoError(t, nErr)
  2296  		ro3a := r3.Posts[o3.Id]
  2297  
  2298  		assert.Equal(t, ro1a.Message, o1a.Message, "Failed to overwrite/get")
  2299  		assert.Equal(t, ro2a.Message, o2a.Message, "Failed to overwrite/get")
  2300  		assert.Equal(t, ro3a.Message, o3a.Message, "Failed to overwrite/get")
  2301  	})
  2302  
  2303  	t.Run("overwrite clearing filenames", func(t *testing.T) {
  2304  		o4a := ro4.Clone()
  2305  		o4a.Filenames = []string{}
  2306  		o4a.FileIds = []string{model.NewId()}
  2307  
  2308  		o5a := ro5.Clone()
  2309  		o5a.Filenames = []string{}
  2310  		o5a.FileIds = []string{}
  2311  
  2312  		_, errIdx, err := ss.Post().OverwriteMultiple([]*model.Post{o4a, o5a})
  2313  		require.NoError(t, err)
  2314  		require.Equal(t, -1, errIdx)
  2315  
  2316  		r4, nErr := ss.Post().Get(o4.Id, false, false, false)
  2317  		require.NoError(t, nErr)
  2318  		ro4a := r4.Posts[o4.Id]
  2319  
  2320  		r5, nErr = ss.Post().Get(o5.Id, false, false, false)
  2321  		require.NoError(t, nErr)
  2322  		ro5a := r5.Posts[o5.Id]
  2323  
  2324  		require.Empty(t, ro4a.Filenames, "Failed to clear Filenames")
  2325  		require.Len(t, ro4a.FileIds, 1, "Failed to set FileIds")
  2326  		require.Empty(t, ro5a.Filenames, "Failed to clear Filenames")
  2327  		require.Empty(t, ro5a.FileIds, "Failed to set FileIds")
  2328  	})
  2329  }
  2330  
  2331  func testPostStoreOverwrite(t *testing.T, ss store.Store) {
  2332  	o1 := &model.Post{}
  2333  	o1.ChannelId = model.NewId()
  2334  	o1.UserId = model.NewId()
  2335  	o1.Message = "zz" + model.NewId() + "AAAAAAAAAAA"
  2336  	o1, err := ss.Post().Save(o1)
  2337  	require.NoError(t, err)
  2338  
  2339  	o2 := &model.Post{}
  2340  	o2.ChannelId = o1.ChannelId
  2341  	o2.UserId = model.NewId()
  2342  	o2.Message = "zz" + model.NewId() + "CCCCCCCCC"
  2343  	o2.ParentId = o1.Id
  2344  	o2.RootId = o1.Id
  2345  	o2, err = ss.Post().Save(o2)
  2346  	require.NoError(t, err)
  2347  
  2348  	o3 := &model.Post{}
  2349  	o3.ChannelId = o1.ChannelId
  2350  	o3.UserId = model.NewId()
  2351  	o3.Message = "zz" + model.NewId() + "QQQQQQQQQQ"
  2352  	o3, err = ss.Post().Save(o3)
  2353  	require.NoError(t, err)
  2354  
  2355  	o4, err := ss.Post().Save(&model.Post{
  2356  		ChannelId: model.NewId(),
  2357  		UserId:    model.NewId(),
  2358  		Message:   model.NewId(),
  2359  		Filenames: []string{"test"},
  2360  	})
  2361  	require.NoError(t, err)
  2362  
  2363  	r1, err := ss.Post().Get(o1.Id, false, false, false)
  2364  	require.NoError(t, err)
  2365  	ro1 := r1.Posts[o1.Id]
  2366  
  2367  	r2, err := ss.Post().Get(o2.Id, false, false, false)
  2368  	require.NoError(t, err)
  2369  	ro2 := r2.Posts[o2.Id]
  2370  
  2371  	r3, err := ss.Post().Get(o3.Id, false, false, false)
  2372  	require.NoError(t, err)
  2373  	ro3 := r3.Posts[o3.Id]
  2374  
  2375  	r4, err := ss.Post().Get(o4.Id, false, false, false)
  2376  	require.NoError(t, err)
  2377  	ro4 := r4.Posts[o4.Id]
  2378  
  2379  	require.Equal(t, ro1.Message, o1.Message, "Failed to save/get")
  2380  	require.Equal(t, ro2.Message, o2.Message, "Failed to save/get")
  2381  	require.Equal(t, ro3.Message, o3.Message, "Failed to save/get")
  2382  	require.Equal(t, ro4.Message, o4.Message, "Failed to save/get")
  2383  
  2384  	t.Run("overwrite changing message", func(t *testing.T) {
  2385  		o1a := ro1.Clone()
  2386  		o1a.Message = ro1.Message + "BBBBBBBBBB"
  2387  		_, err = ss.Post().Overwrite(o1a)
  2388  		require.NoError(t, err)
  2389  
  2390  		o2a := ro2.Clone()
  2391  		o2a.Message = ro2.Message + "DDDDDDD"
  2392  		_, err = ss.Post().Overwrite(o2a)
  2393  		require.NoError(t, err)
  2394  
  2395  		o3a := ro3.Clone()
  2396  		o3a.Message = ro3.Message + "WWWWWWW"
  2397  		_, err = ss.Post().Overwrite(o3a)
  2398  		require.NoError(t, err)
  2399  
  2400  		r1, err = ss.Post().Get(o1.Id, false, false, false)
  2401  		require.NoError(t, err)
  2402  		ro1a := r1.Posts[o1.Id]
  2403  
  2404  		r2, err = ss.Post().Get(o1.Id, false, false, false)
  2405  		require.NoError(t, err)
  2406  		ro2a := r2.Posts[o2.Id]
  2407  
  2408  		r3, err = ss.Post().Get(o3.Id, false, false, false)
  2409  		require.NoError(t, err)
  2410  		ro3a := r3.Posts[o3.Id]
  2411  
  2412  		assert.Equal(t, ro1a.Message, o1a.Message, "Failed to overwrite/get")
  2413  		assert.Equal(t, ro2a.Message, o2a.Message, "Failed to overwrite/get")
  2414  		assert.Equal(t, ro3a.Message, o3a.Message, "Failed to overwrite/get")
  2415  	})
  2416  
  2417  	t.Run("overwrite clearing filenames", func(t *testing.T) {
  2418  		o4a := ro4.Clone()
  2419  		o4a.Filenames = []string{}
  2420  		o4a.FileIds = []string{model.NewId()}
  2421  		_, err = ss.Post().Overwrite(o4a)
  2422  		require.NoError(t, err)
  2423  
  2424  		r4, err = ss.Post().Get(o4.Id, false, false, false)
  2425  		require.NoError(t, err)
  2426  
  2427  		ro4a := r4.Posts[o4.Id]
  2428  		require.Empty(t, ro4a.Filenames, "Failed to clear Filenames")
  2429  		require.Len(t, ro4a.FileIds, 1, "Failed to set FileIds")
  2430  	})
  2431  }
  2432  
  2433  func testPostStoreGetPostsByIds(t *testing.T, ss store.Store) {
  2434  	o1 := &model.Post{}
  2435  	o1.ChannelId = model.NewId()
  2436  	o1.UserId = model.NewId()
  2437  	o1.Message = "zz" + model.NewId() + "AAAAAAAAAAA"
  2438  	o1, err := ss.Post().Save(o1)
  2439  	require.NoError(t, err)
  2440  
  2441  	o2 := &model.Post{}
  2442  	o2.ChannelId = o1.ChannelId
  2443  	o2.UserId = model.NewId()
  2444  	o2.Message = "zz" + model.NewId() + "CCCCCCCCC"
  2445  	o2, err = ss.Post().Save(o2)
  2446  	require.NoError(t, err)
  2447  
  2448  	o3 := &model.Post{}
  2449  	o3.ChannelId = o1.ChannelId
  2450  	o3.UserId = model.NewId()
  2451  	o3.Message = "zz" + model.NewId() + "QQQQQQQQQQ"
  2452  	o3, err = ss.Post().Save(o3)
  2453  	require.NoError(t, err)
  2454  
  2455  	r1, err := ss.Post().Get(o1.Id, false, false, false)
  2456  	require.NoError(t, err)
  2457  	ro1 := r1.Posts[o1.Id]
  2458  
  2459  	r2, err := ss.Post().Get(o2.Id, false, false, false)
  2460  	require.NoError(t, err)
  2461  	ro2 := r2.Posts[o2.Id]
  2462  
  2463  	r3, err := ss.Post().Get(o3.Id, false, false, false)
  2464  	require.NoError(t, err)
  2465  	ro3 := r3.Posts[o3.Id]
  2466  
  2467  	postIds := []string{
  2468  		ro1.Id,
  2469  		ro2.Id,
  2470  		ro3.Id,
  2471  	}
  2472  
  2473  	posts, err := ss.Post().GetPostsByIds(postIds)
  2474  	require.NoError(t, err)
  2475  	require.Len(t, posts, 3, "Expected 3 posts in results. Got %v", len(posts))
  2476  
  2477  	err = ss.Post().Delete(ro1.Id, model.GetMillis(), "")
  2478  	require.NoError(t, err)
  2479  
  2480  	posts, err = ss.Post().GetPostsByIds(postIds)
  2481  	require.NoError(t, err)
  2482  	require.Len(t, posts, 3, "Expected 3 posts in results. Got %v", len(posts))
  2483  }
  2484  
  2485  func testPostStoreGetPostsBatchForIndexing(t *testing.T, ss store.Store) {
  2486  	c1 := &model.Channel{}
  2487  	c1.TeamId = model.NewId()
  2488  	c1.DisplayName = "Channel1"
  2489  	c1.Name = "zz" + model.NewId() + "b"
  2490  	c1.Type = model.CHANNEL_OPEN
  2491  	c1, _ = ss.Channel().Save(c1, -1)
  2492  
  2493  	c2 := &model.Channel{}
  2494  	c2.TeamId = model.NewId()
  2495  	c2.DisplayName = "Channel2"
  2496  	c2.Name = "zz" + model.NewId() + "b"
  2497  	c2.Type = model.CHANNEL_OPEN
  2498  	c2, _ = ss.Channel().Save(c2, -1)
  2499  
  2500  	o1 := &model.Post{}
  2501  	o1.ChannelId = c1.Id
  2502  	o1.UserId = model.NewId()
  2503  	o1.Message = "zz" + model.NewId() + "AAAAAAAAAAA"
  2504  	o1, err := ss.Post().Save(o1)
  2505  	require.NoError(t, err)
  2506  
  2507  	o2 := &model.Post{}
  2508  	o2.ChannelId = c2.Id
  2509  	o2.UserId = model.NewId()
  2510  	o2.Message = "zz" + model.NewId() + "CCCCCCCCC"
  2511  	o2, err = ss.Post().Save(o2)
  2512  	require.NoError(t, err)
  2513  
  2514  	o3 := &model.Post{}
  2515  	o3.ChannelId = c1.Id
  2516  	o3.UserId = model.NewId()
  2517  	o3.ParentId = o1.Id
  2518  	o3.RootId = o1.Id
  2519  	o3.Message = "zz" + model.NewId() + "QQQQQQQQQQ"
  2520  	o3, err = ss.Post().Save(o3)
  2521  	require.NoError(t, err)
  2522  
  2523  	r, err := ss.Post().GetPostsBatchForIndexing(o1.CreateAt, model.GetMillis()+100000, 100)
  2524  	require.NoError(t, err)
  2525  	require.Len(t, r, 3, "Expected 3 posts in results. Got %v", len(r))
  2526  	for _, p := range r {
  2527  		if p.Id == o1.Id {
  2528  			require.Equal(t, p.TeamId, c1.TeamId, "Unexpected team ID")
  2529  			require.Nil(t, p.ParentCreateAt, "Unexpected parent create at")
  2530  		} else if p.Id == o2.Id {
  2531  			require.Equal(t, p.TeamId, c2.TeamId, "Unexpected team ID")
  2532  			require.Nil(t, p.ParentCreateAt, "Unexpected parent create at")
  2533  		} else if p.Id == o3.Id {
  2534  			require.Equal(t, p.TeamId, c1.TeamId, "Unexpected team ID")
  2535  			require.Equal(t, *p.ParentCreateAt, o1.CreateAt, "Unexpected parent create at")
  2536  		} else {
  2537  			require.Fail(t, "unexpected post returned")
  2538  		}
  2539  	}
  2540  }
  2541  
  2542  func testPostStorePermanentDeleteBatch(t *testing.T, ss store.Store) {
  2543  	o1 := &model.Post{}
  2544  	o1.ChannelId = model.NewId()
  2545  	o1.UserId = model.NewId()
  2546  	o1.Message = "zz" + model.NewId() + "AAAAAAAAAAA"
  2547  	o1.CreateAt = 1000
  2548  	o1, err := ss.Post().Save(o1)
  2549  	require.NoError(t, err)
  2550  
  2551  	o2 := &model.Post{}
  2552  	o2.ChannelId = model.NewId()
  2553  	o2.UserId = model.NewId()
  2554  	o2.Message = "zz" + model.NewId() + "AAAAAAAAAAA"
  2555  	o2.CreateAt = 1000
  2556  	o2, err = ss.Post().Save(o2)
  2557  	require.NoError(t, err)
  2558  
  2559  	o3 := &model.Post{}
  2560  	o3.ChannelId = model.NewId()
  2561  	o3.UserId = model.NewId()
  2562  	o3.Message = "zz" + model.NewId() + "AAAAAAAAAAA"
  2563  	o3.CreateAt = 100000
  2564  	o3, err = ss.Post().Save(o3)
  2565  	require.NoError(t, err)
  2566  
  2567  	_, err = ss.Post().PermanentDeleteBatch(2000, 1000)
  2568  	require.NoError(t, err)
  2569  
  2570  	_, err = ss.Post().Get(o1.Id, false, false, false)
  2571  	require.Error(t, err, "Should have not found post 1 after purge")
  2572  
  2573  	_, err = ss.Post().Get(o2.Id, false, false, false)
  2574  	require.Error(t, err, "Should have not found post 2 after purge")
  2575  
  2576  	_, err = ss.Post().Get(o3.Id, false, false, false)
  2577  	require.NoError(t, err, "Should have not found post 3 after purge")
  2578  }
  2579  
  2580  func testPostStoreGetOldest(t *testing.T, ss store.Store) {
  2581  	o0 := &model.Post{}
  2582  	o0.ChannelId = model.NewId()
  2583  	o0.UserId = model.NewId()
  2584  	o0.Message = "zz" + model.NewId() + "b"
  2585  	o0.CreateAt = 3
  2586  	o0, err := ss.Post().Save(o0)
  2587  	require.NoError(t, err)
  2588  
  2589  	o1 := &model.Post{}
  2590  	o1.ChannelId = o0.Id
  2591  	o1.UserId = model.NewId()
  2592  	o1.Message = "zz" + model.NewId() + "b"
  2593  	o1.CreateAt = 2
  2594  	o1, err = ss.Post().Save(o1)
  2595  	require.NoError(t, err)
  2596  
  2597  	o2 := &model.Post{}
  2598  	o2.ChannelId = o1.ChannelId
  2599  	o2.UserId = model.NewId()
  2600  	o2.Message = "zz" + model.NewId() + "b"
  2601  	o2.CreateAt = 1
  2602  	o2, err = ss.Post().Save(o2)
  2603  	require.NoError(t, err)
  2604  
  2605  	r1, err := ss.Post().GetOldest()
  2606  
  2607  	require.NoError(t, err)
  2608  	assert.EqualValues(t, o2.Id, r1.Id)
  2609  }
  2610  
  2611  func testGetMaxPostSize(t *testing.T, ss store.Store) {
  2612  	assert.Equal(t, model.POST_MESSAGE_MAX_RUNES_V2, ss.Post().GetMaxPostSize())
  2613  	assert.Equal(t, model.POST_MESSAGE_MAX_RUNES_V2, ss.Post().GetMaxPostSize())
  2614  }
  2615  
  2616  func testPostStoreGetParentsForExportAfter(t *testing.T, ss store.Store) {
  2617  	t1 := model.Team{}
  2618  	t1.DisplayName = "Name"
  2619  	t1.Name = "zz" + model.NewId()
  2620  	t1.Email = MakeEmail()
  2621  	t1.Type = model.TEAM_OPEN
  2622  	_, err := ss.Team().Save(&t1)
  2623  	require.NoError(t, err)
  2624  
  2625  	c1 := model.Channel{}
  2626  	c1.TeamId = t1.Id
  2627  	c1.DisplayName = "Channel1"
  2628  	c1.Name = "zz" + model.NewId() + "b"
  2629  	c1.Type = model.CHANNEL_OPEN
  2630  	_, nErr := ss.Channel().Save(&c1, -1)
  2631  	require.NoError(t, nErr)
  2632  
  2633  	u1 := model.User{}
  2634  	u1.Username = model.NewId()
  2635  	u1.Email = MakeEmail()
  2636  	u1.Nickname = model.NewId()
  2637  	_, err = ss.User().Save(&u1)
  2638  	require.NoError(t, err)
  2639  
  2640  	p1 := &model.Post{}
  2641  	p1.ChannelId = c1.Id
  2642  	p1.UserId = u1.Id
  2643  	p1.Message = "zz" + model.NewId() + "AAAAAAAAAAA"
  2644  	p1.CreateAt = 1000
  2645  	p1, nErr = ss.Post().Save(p1)
  2646  	require.NoError(t, nErr)
  2647  
  2648  	posts, err := ss.Post().GetParentsForExportAfter(10000, strings.Repeat("0", 26))
  2649  	assert.NoError(t, err)
  2650  
  2651  	found := false
  2652  	for _, p := range posts {
  2653  		if p.Id == p1.Id {
  2654  			found = true
  2655  			assert.Equal(t, p.Id, p1.Id)
  2656  			assert.Equal(t, p.Message, p1.Message)
  2657  			assert.Equal(t, p.Username, u1.Username)
  2658  			assert.Equal(t, p.TeamName, t1.Name)
  2659  			assert.Equal(t, p.ChannelName, c1.Name)
  2660  		}
  2661  	}
  2662  	assert.True(t, found)
  2663  }
  2664  
  2665  func testPostStoreGetRepliesForExport(t *testing.T, ss store.Store) {
  2666  	t1 := model.Team{}
  2667  	t1.DisplayName = "Name"
  2668  	t1.Name = "zz" + model.NewId()
  2669  	t1.Email = MakeEmail()
  2670  	t1.Type = model.TEAM_OPEN
  2671  	_, err := ss.Team().Save(&t1)
  2672  	require.NoError(t, err)
  2673  
  2674  	c1 := model.Channel{}
  2675  	c1.TeamId = t1.Id
  2676  	c1.DisplayName = "Channel1"
  2677  	c1.Name = "zz" + model.NewId() + "b"
  2678  	c1.Type = model.CHANNEL_OPEN
  2679  	_, nErr := ss.Channel().Save(&c1, -1)
  2680  	require.NoError(t, nErr)
  2681  
  2682  	u1 := model.User{}
  2683  	u1.Email = MakeEmail()
  2684  	u1.Nickname = model.NewId()
  2685  	_, err = ss.User().Save(&u1)
  2686  	require.NoError(t, err)
  2687  
  2688  	p1 := &model.Post{}
  2689  	p1.ChannelId = c1.Id
  2690  	p1.UserId = u1.Id
  2691  	p1.Message = "zz" + model.NewId() + "AAAAAAAAAAA"
  2692  	p1.CreateAt = 1000
  2693  	p1, nErr = ss.Post().Save(p1)
  2694  	require.NoError(t, nErr)
  2695  
  2696  	p2 := &model.Post{}
  2697  	p2.ChannelId = c1.Id
  2698  	p2.UserId = u1.Id
  2699  	p2.Message = "zz" + model.NewId() + "AAAAAAAAAAA"
  2700  	p2.CreateAt = 1001
  2701  	p2.ParentId = p1.Id
  2702  	p2.RootId = p1.Id
  2703  	p2, nErr = ss.Post().Save(p2)
  2704  	require.NoError(t, nErr)
  2705  
  2706  	r1, err := ss.Post().GetRepliesForExport(p1.Id)
  2707  	assert.NoError(t, err)
  2708  
  2709  	assert.Len(t, r1, 1)
  2710  
  2711  	reply1 := r1[0]
  2712  	assert.Equal(t, reply1.Id, p2.Id)
  2713  	assert.Equal(t, reply1.Message, p2.Message)
  2714  	assert.Equal(t, reply1.Username, u1.Username)
  2715  
  2716  	// Checking whether replies by deleted user are exported
  2717  	u1.DeleteAt = 1002
  2718  	_, err = ss.User().Update(&u1, false)
  2719  	require.NoError(t, err)
  2720  
  2721  	r1, err = ss.Post().GetRepliesForExport(p1.Id)
  2722  	assert.NoError(t, err)
  2723  
  2724  	assert.Len(t, r1, 1)
  2725  
  2726  	reply1 = r1[0]
  2727  	assert.Equal(t, reply1.Id, p2.Id)
  2728  	assert.Equal(t, reply1.Message, p2.Message)
  2729  	assert.Equal(t, reply1.Username, u1.Username)
  2730  
  2731  }
  2732  
  2733  func testPostStoreGetDirectPostParentsForExportAfter(t *testing.T, ss store.Store, s SqlStore) {
  2734  	teamId := model.NewId()
  2735  
  2736  	o1 := model.Channel{}
  2737  	o1.TeamId = teamId
  2738  	o1.DisplayName = "Name"
  2739  	o1.Name = "zz" + model.NewId() + "b"
  2740  	o1.Type = model.CHANNEL_DIRECT
  2741  
  2742  	u1 := &model.User{}
  2743  	u1.Email = MakeEmail()
  2744  	u1.Nickname = model.NewId()
  2745  	_, err := ss.User().Save(u1)
  2746  	require.NoError(t, err)
  2747  	_, nErr := ss.Team().SaveMember(&model.TeamMember{TeamId: model.NewId(), UserId: u1.Id}, -1)
  2748  	require.NoError(t, nErr)
  2749  
  2750  	u2 := &model.User{}
  2751  	u2.Email = MakeEmail()
  2752  	u2.Nickname = model.NewId()
  2753  	_, err = ss.User().Save(u2)
  2754  	require.NoError(t, err)
  2755  	_, nErr = ss.Team().SaveMember(&model.TeamMember{TeamId: model.NewId(), UserId: u2.Id}, -1)
  2756  	require.NoError(t, nErr)
  2757  
  2758  	m1 := model.ChannelMember{}
  2759  	m1.ChannelId = o1.Id
  2760  	m1.UserId = u1.Id
  2761  	m1.NotifyProps = model.GetDefaultChannelNotifyProps()
  2762  
  2763  	m2 := model.ChannelMember{}
  2764  	m2.ChannelId = o1.Id
  2765  	m2.UserId = u2.Id
  2766  	m2.NotifyProps = model.GetDefaultChannelNotifyProps()
  2767  
  2768  	ss.Channel().SaveDirectChannel(&o1, &m1, &m2)
  2769  
  2770  	p1 := &model.Post{}
  2771  	p1.ChannelId = o1.Id
  2772  	p1.UserId = u1.Id
  2773  	p1.Message = "zz" + model.NewId() + "AAAAAAAAAAA"
  2774  	p1.CreateAt = 1000
  2775  	p1, nErr = ss.Post().Save(p1)
  2776  	require.NoError(t, nErr)
  2777  
  2778  	r1, nErr := ss.Post().GetDirectPostParentsForExportAfter(10000, strings.Repeat("0", 26))
  2779  	assert.NoError(t, nErr)
  2780  
  2781  	assert.Equal(t, p1.Message, r1[0].Message)
  2782  
  2783  	// Manually truncate Channels table until testlib can handle cleanups
  2784  	s.GetMaster().Exec("TRUNCATE Channels")
  2785  }
  2786  
  2787  func testPostStoreGetDirectPostParentsForExportAfterDeleted(t *testing.T, ss store.Store, s SqlStore) {
  2788  	teamId := model.NewId()
  2789  
  2790  	o1 := model.Channel{}
  2791  	o1.TeamId = teamId
  2792  	o1.DisplayName = "Name"
  2793  	o1.Name = "zz" + model.NewId() + "b"
  2794  	o1.Type = model.CHANNEL_DIRECT
  2795  
  2796  	u1 := &model.User{}
  2797  	u1.DeleteAt = 1
  2798  	u1.Email = MakeEmail()
  2799  	u1.Nickname = model.NewId()
  2800  	_, err := ss.User().Save(u1)
  2801  	require.NoError(t, err)
  2802  	_, nErr := ss.Team().SaveMember(&model.TeamMember{TeamId: model.NewId(), UserId: u1.Id}, -1)
  2803  	require.NoError(t, nErr)
  2804  
  2805  	u2 := &model.User{}
  2806  	u2.DeleteAt = 1
  2807  	u2.Email = MakeEmail()
  2808  	u2.Nickname = model.NewId()
  2809  	_, err = ss.User().Save(u2)
  2810  	require.NoError(t, err)
  2811  	_, nErr = ss.Team().SaveMember(&model.TeamMember{TeamId: model.NewId(), UserId: u2.Id}, -1)
  2812  	require.NoError(t, nErr)
  2813  
  2814  	m1 := model.ChannelMember{}
  2815  	m1.ChannelId = o1.Id
  2816  	m1.UserId = u1.Id
  2817  	m1.NotifyProps = model.GetDefaultChannelNotifyProps()
  2818  
  2819  	m2 := model.ChannelMember{}
  2820  	m2.ChannelId = o1.Id
  2821  	m2.UserId = u2.Id
  2822  	m2.NotifyProps = model.GetDefaultChannelNotifyProps()
  2823  
  2824  	ss.Channel().SaveDirectChannel(&o1, &m1, &m2)
  2825  
  2826  	o1.DeleteAt = 1
  2827  	nErr = ss.Channel().SetDeleteAt(o1.Id, 1, 1)
  2828  	assert.NoError(t, nErr)
  2829  
  2830  	p1 := &model.Post{}
  2831  	p1.ChannelId = o1.Id
  2832  	p1.UserId = u1.Id
  2833  	p1.Message = "zz" + model.NewId() + "BBBBBBBBBBBB"
  2834  	p1.CreateAt = 1000
  2835  	p1, nErr = ss.Post().Save(p1)
  2836  	require.NoError(t, nErr)
  2837  
  2838  	o1a := p1.Clone()
  2839  	o1a.DeleteAt = 1
  2840  	o1a.Message = p1.Message + "BBBBBBBBBB"
  2841  	_, nErr = ss.Post().Update(o1a, p1)
  2842  	require.NoError(t, nErr)
  2843  
  2844  	r1, nErr := ss.Post().GetDirectPostParentsForExportAfter(10000, strings.Repeat("0", 26))
  2845  	assert.NoError(t, nErr)
  2846  
  2847  	assert.Equal(t, 0, len(r1))
  2848  
  2849  	// Manually truncate Channels table until testlib can handle cleanups
  2850  	s.GetMaster().Exec("TRUNCATE Channels")
  2851  }
  2852  
  2853  func testPostStoreGetDirectPostParentsForExportAfterBatched(t *testing.T, ss store.Store, s SqlStore) {
  2854  	teamId := model.NewId()
  2855  
  2856  	o1 := model.Channel{}
  2857  	o1.TeamId = teamId
  2858  	o1.DisplayName = "Name"
  2859  	o1.Name = "zz" + model.NewId() + "b"
  2860  	o1.Type = model.CHANNEL_DIRECT
  2861  
  2862  	var postIds []string
  2863  	for i := 0; i < 150; i++ {
  2864  		u1 := &model.User{}
  2865  		u1.Email = MakeEmail()
  2866  		u1.Nickname = model.NewId()
  2867  		_, err := ss.User().Save(u1)
  2868  		require.NoError(t, err)
  2869  		_, nErr := ss.Team().SaveMember(&model.TeamMember{TeamId: model.NewId(), UserId: u1.Id}, -1)
  2870  		require.NoError(t, nErr)
  2871  
  2872  		u2 := &model.User{}
  2873  		u2.Email = MakeEmail()
  2874  		u2.Nickname = model.NewId()
  2875  		_, err = ss.User().Save(u2)
  2876  		require.NoError(t, err)
  2877  		_, nErr = ss.Team().SaveMember(&model.TeamMember{TeamId: model.NewId(), UserId: u2.Id}, -1)
  2878  		require.NoError(t, nErr)
  2879  
  2880  		m1 := model.ChannelMember{}
  2881  		m1.ChannelId = o1.Id
  2882  		m1.UserId = u1.Id
  2883  		m1.NotifyProps = model.GetDefaultChannelNotifyProps()
  2884  
  2885  		m2 := model.ChannelMember{}
  2886  		m2.ChannelId = o1.Id
  2887  		m2.UserId = u2.Id
  2888  		m2.NotifyProps = model.GetDefaultChannelNotifyProps()
  2889  
  2890  		ss.Channel().SaveDirectChannel(&o1, &m1, &m2)
  2891  
  2892  		p1 := &model.Post{}
  2893  		p1.ChannelId = o1.Id
  2894  		p1.UserId = u1.Id
  2895  		p1.Message = "zz" + model.NewId() + "AAAAAAAAAAA"
  2896  		p1.CreateAt = 1000
  2897  		p1, nErr = ss.Post().Save(p1)
  2898  		require.NoError(t, nErr)
  2899  		postIds = append(postIds, p1.Id)
  2900  	}
  2901  	sort.Slice(postIds, func(i, j int) bool { return postIds[i] < postIds[j] })
  2902  
  2903  	// Get all posts
  2904  	r1, err := ss.Post().GetDirectPostParentsForExportAfter(10000, strings.Repeat("0", 26))
  2905  	assert.NoError(t, err)
  2906  	assert.Equal(t, len(postIds), len(r1))
  2907  	var exportedPostIds []string
  2908  	for i := range r1 {
  2909  		exportedPostIds = append(exportedPostIds, r1[i].Id)
  2910  	}
  2911  	sort.Slice(exportedPostIds, func(i, j int) bool { return exportedPostIds[i] < exportedPostIds[j] })
  2912  	assert.ElementsMatch(t, postIds, exportedPostIds)
  2913  
  2914  	// Get 100
  2915  	r1, err = ss.Post().GetDirectPostParentsForExportAfter(100, strings.Repeat("0", 26))
  2916  	assert.NoError(t, err)
  2917  	assert.Equal(t, 100, len(r1))
  2918  	exportedPostIds = []string{}
  2919  	for i := range r1 {
  2920  		exportedPostIds = append(exportedPostIds, r1[i].Id)
  2921  	}
  2922  	sort.Slice(exportedPostIds, func(i, j int) bool { return exportedPostIds[i] < exportedPostIds[j] })
  2923  	assert.ElementsMatch(t, postIds[:100], exportedPostIds)
  2924  
  2925  	// Manually truncate Channels table until testlib can handle cleanups
  2926  	s.GetMaster().Exec("TRUNCATE Channels")
  2927  }