github.com/mattermosttest/mattermost-server/v5@v5.0.0-20200917143240-9dfa12e121f9/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  	"net/http"
     9  	"sort"
    10  	"strings"
    11  	"testing"
    12  	"time"
    13  
    14  	"github.com/mattermost/mattermost-server/v5/model"
    15  	"github.com/mattermost/mattermost-server/v5/store"
    16  	"github.com/mattermost/mattermost-server/v5/utils"
    17  	"github.com/stretchr/testify/assert"
    18  	"github.com/stretchr/testify/require"
    19  )
    20  
    21  func TestPostStore(t *testing.T, ss store.Store, s SqlSupplier) {
    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.Nil(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.Nil(t, err, "couldn't save item")
    92  		assert.Equal(t, int64(1), p1.ReplyCount)
    93  
    94  		p2, err := ss.Post().Save(&o2)
    95  		require.Nil(t, err, "couldn't save item")
    96  		assert.Equal(t, int64(2), p2.ReplyCount)
    97  
    98  		p3, err := ss.Post().Save(&o3)
    99  		require.Nil(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.Nil(t, err, "couldn't save item")
   111  
   112  		_, err = ss.Post().Save(&o1)
   113  		require.NotNil(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.Nil(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.Nil(t, err)
   137  
   138  		rrootPost, err := ss.Post().GetSingle(rootPost.Id)
   139  		require.Nil(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.Nil(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.Nil(t, err)
   161  
   162  		rchannel, err := ss.Channel().Get(channel.Id, false)
   163  		require.Nil(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.Nil(t, err)
   177  
   178  		rchannel2, err := ss.Channel().Get(channel.Id, false)
   179  		require.Nil(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.Nil(t, err)
   192  
   193  		rchannel3, err := ss.Channel().Get(channel.Id, false)
   194  		require.Nil(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.Nil(t, err)
   224  		require.Equal(t, -1, errIdx)
   225  		for _, post := range newPosts {
   226  			storedPost, err := ss.Post().GetSingle(post.Id)
   227  			assert.Nil(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.Nil(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.NotNil(t, err)
   271  		require.Equal(t, 1, errIdx)
   272  		require.Nil(t, newPosts)
   273  		storedPost, err := ss.Post().GetSingle(p3.Id)
   274  		assert.Nil(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.NotNil(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.Nil(t, err)
   298  
   299  		rrootPost, err := ss.Post().GetSingle(rootPost.Id)
   300  		require.Nil(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.Nil(t, err)
   317  
   318  		rrootPost2, err := ss.Post().GetSingle(rootPost.Id)
   319  		require.Nil(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.Nil(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.Nil(t, err)
   350  
   351  		rchannel, err := ss.Channel().Get(channel.Id, false)
   352  		require.Nil(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.Nil(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.Nil(t, err)
   370  
   371  	c1, err = ss.Channel().Get(c1.Id, false)
   372  	require.Nil(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.Nil(t, err)
   379  
   380  	o1.Id = ""
   381  	o1.Type = model.POST_REMOVE_FROM_TEAM
   382  	_, err = ss.Post().Save(&o1)
   383  	require.Nil(t, err)
   384  
   385  	c1, err = ss.Channel().Get(c1.Id, false)
   386  	require.Nil(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.Nil(t, err)
   398  
   399  	c1, err = ss.Channel().Get(c1.Id, false)
   400  	require.Nil(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)
   411  	require.Equal(t, 0, strings.Index(etag1, model.CurrentVersion+"."), "Invalid Etag")
   412  
   413  	o1, err := ss.Post().Save(o1)
   414  	require.Nil(t, err)
   415  
   416  	etag2 := ss.Post().GetEtag(o1.ChannelId, 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)
   420  	require.Nil(t, err)
   421  	require.Equal(t, r1.Posts[o1.Id].CreateAt, o1.CreateAt, "invalid returned post")
   422  
   423  	_, err = ss.Post().Get("123", false)
   424  	require.NotNil(t, err, "Missing id should have failed")
   425  
   426  	_, err = ss.Post().Get("", false)
   427  	require.NotNil(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.Nil(t, err)
   438  
   439  	post, err := ss.Post().GetSingle(o1.Id)
   440  	require.Nil(t, err)
   441  	require.Equal(t, post.CreateAt, o1.CreateAt, "invalid returned post")
   442  
   443  	_, err = ss.Post().GetSingle("123")
   444  	require.NotNil(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.Nil(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.Nil(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.Nil(t, err)
   470  
   471  	r1, err := ss.Post().Get(o1.Id, false)
   472  	require.Nil(t, err)
   473  	ro1 := r1.Posts[o1.Id]
   474  
   475  	r2, err := ss.Post().Get(o1.Id, false)
   476  	require.Nil(t, err)
   477  	ro2 := r2.Posts[o2.Id]
   478  
   479  	r3, err := ss.Post().Get(o3.Id, false)
   480  	require.Nil(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.Nil(t, err)
   489  
   490  	r1, err = ss.Post().Get(o1.Id, false)
   491  	require.Nil(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.Nil(t, err)
   500  
   501  	r2, err = ss.Post().Get(o1.Id, false)
   502  	require.Nil(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.Nil(t, err)
   511  
   512  	r3, err = ss.Post().Get(o3.Id, false)
   513  	require.Nil(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.Nil(t, err)
   527  
   528  	r4, err := ss.Post().Get(o4.Id, false)
   529  	require.Nil(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.Nil(t, err)
   537  
   538  	r4, err = ss.Post().Get(o4.Id, false)
   539  	require.Nil(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)
   554  	require.Equal(t, 0, strings.Index(etag1, model.CurrentVersion+"."), "Invalid Etag")
   555  
   556  	o1, err := ss.Post().Save(o1)
   557  	require.Nil(t, err)
   558  
   559  	r1, err := ss.Post().Get(o1.Id, false)
   560  	require.Nil(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.Nil(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)
   573  	require.NotNil(t, err, "Missing id should have failed - PostList %v", r3)
   574  
   575  	etag2 := ss.Post().GetEtag(o1.ChannelId, 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.Nil(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.Nil(t, err)
   595  
   596  	err = ss.Post().Delete(o1.Id, model.GetMillis(), "")
   597  	require.Nil(t, err)
   598  
   599  	_, err = ss.Post().Get(o1.Id, false)
   600  	require.NotNil(t, err, "Deleted id should have failed")
   601  
   602  	_, err = ss.Post().Get(o2.Id, false)
   603  	require.NotNil(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.Nil(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.Nil(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.Nil(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.Nil(t, err)
   638  
   639  	err = ss.Post().Delete(o1.Id, model.GetMillis(), "")
   640  	require.Nil(t, err)
   641  
   642  	_, err = ss.Post().Get(o1.Id, false)
   643  	require.NotNil(t, err, "Deleted id should have failed")
   644  
   645  	_, err = ss.Post().Get(o2.Id, false)
   646  	require.NotNil(t, err, "Deleted id should have failed")
   647  
   648  	_, err = ss.Post().Get(o3.Id, false)
   649  	require.NotNil(t, err, "Deleted id should have failed")
   650  
   651  	_, err = ss.Post().Get(o4.Id, false)
   652  	require.Nil(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.Nil(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.Nil(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.Nil(t, err)
   678  
   679  	err2 := ss.Post().PermanentDeleteByUser(o2.UserId)
   680  	require.Nil(t, err2)
   681  
   682  	_, err = ss.Post().Get(o1.Id, false)
   683  	require.Nil(t, err, "Deleted id shouldn't have failed")
   684  
   685  	_, err = ss.Post().Get(o2.Id, false)
   686  	require.NotNil(t, err, "Deleted id should have failed")
   687  
   688  	err = ss.Post().PermanentDeleteByChannel(o3.ChannelId)
   689  	require.Nil(t, err)
   690  
   691  	_, err = ss.Post().Get(o3.Id, false)
   692  	require.NotNil(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.Nil(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.Nil(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.Nil(t, err)
   718  
   719  	err2 := ss.Post().PermanentDeleteByUser(o1.UserId)
   720  	require.Nil(t, err2)
   721  
   722  	_, err = ss.Post().Get(o1.Id, false)
   723  	require.NotNil(t, err, "Deleted id should have failed")
   724  
   725  	_, err = ss.Post().Get(o2.Id, false)
   726  	require.NotNil(t, err, "Deleted id should have failed")
   727  
   728  	_, err = ss.Post().Get(o3.Id, false)
   729  	require.Nil(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.Nil(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.Nil(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.Nil(t, err)
   757  
   758  	pl, err := ss.Post().Get(o1.Id, false)
   759  	require.Nil(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.Nil(t, dErr)
   765  
   766  	pl, err = ss.Post().Get(o1.Id, false)
   767  	require.Nil(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.Nil(t, dErr)
   773  
   774  	pl, err = ss.Post().Get(o1.Id, false)
   775  	require.Nil(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.Nil(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.Nil(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.Nil(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.Nil(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.Nil(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.Nil(t, err)
   835  
   836  	r1, err := ss.Post().GetPosts(model.GetPostsOptions{ChannelId: o1.ChannelId, Page: 0, PerPage: 4}, false)
   837  	require.Nil(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.Nil(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.Nil(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.Nil(t, err)
   872  
   873  	r3, err := ss.Post().GetPosts(model.GetPostsOptions{ChannelId: o1.ChannelId, Page: 0, PerPage: 30}, false)
   874  	require.Nil(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.Nil(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.Equal(t, http.StatusBadRequest, err.StatusCode)
   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.Equal(t, http.StatusBadRequest, err.StatusCode)
   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.Nil(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.Nil(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.Nil(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.Nil(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.Nil(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.Nil(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.Nil(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.Nil(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.Nil(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.Nil(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.Nil(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.Nil(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.Nil(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.Nil(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.Nil(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.Nil(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.Nil(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.Nil(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.Nil(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.Nil(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.Nil(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.Nil(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.Nil(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  }
  1185  
  1186  func testPostStoreGetPostsSince(t *testing.T, ss store.Store) {
  1187  	t.Run("should return posts created after the given time", func(t *testing.T) {
  1188  		channelId := model.NewId()
  1189  		userId := model.NewId()
  1190  
  1191  		post1, err := ss.Post().Save(&model.Post{
  1192  			ChannelId: channelId,
  1193  			UserId:    userId,
  1194  			Message:   "message",
  1195  		})
  1196  		require.Nil(t, err)
  1197  		time.Sleep(time.Millisecond)
  1198  
  1199  		_, err = ss.Post().Save(&model.Post{
  1200  			ChannelId: channelId,
  1201  			UserId:    userId,
  1202  			Message:   "message",
  1203  		})
  1204  		require.Nil(t, err)
  1205  		time.Sleep(time.Millisecond)
  1206  
  1207  		post3, err := ss.Post().Save(&model.Post{
  1208  			ChannelId: channelId,
  1209  			UserId:    userId,
  1210  			Message:   "message",
  1211  		})
  1212  		require.Nil(t, err)
  1213  		time.Sleep(time.Millisecond)
  1214  
  1215  		post4, err := ss.Post().Save(&model.Post{
  1216  			ChannelId: channelId,
  1217  			UserId:    userId,
  1218  			Message:   "message",
  1219  		})
  1220  		require.Nil(t, err)
  1221  		time.Sleep(time.Millisecond)
  1222  
  1223  		post5, err := ss.Post().Save(&model.Post{
  1224  			ChannelId: channelId,
  1225  			UserId:    userId,
  1226  			Message:   "message",
  1227  			RootId:    post3.Id,
  1228  		})
  1229  		require.Nil(t, err)
  1230  		time.Sleep(time.Millisecond)
  1231  
  1232  		post6, err := ss.Post().Save(&model.Post{
  1233  			ChannelId: channelId,
  1234  			UserId:    userId,
  1235  			Message:   "message",
  1236  			RootId:    post1.Id,
  1237  		})
  1238  		require.Nil(t, err)
  1239  		time.Sleep(time.Millisecond)
  1240  
  1241  		postList, err := ss.Post().GetPostsSince(model.GetPostsSinceOptions{ChannelId: channelId, Time: post3.CreateAt}, false)
  1242  		assert.Nil(t, err)
  1243  
  1244  		assert.Equal(t, []string{
  1245  			post6.Id,
  1246  			post5.Id,
  1247  			post4.Id,
  1248  			post3.Id,
  1249  			post1.Id,
  1250  		}, postList.Order)
  1251  
  1252  		assert.Len(t, postList.Posts, 5)
  1253  		assert.NotNil(t, postList.Posts[post1.Id], "should return the parent post")
  1254  		assert.NotNil(t, postList.Posts[post3.Id])
  1255  		assert.NotNil(t, postList.Posts[post4.Id])
  1256  		assert.NotNil(t, postList.Posts[post5.Id])
  1257  		assert.NotNil(t, postList.Posts[post6.Id])
  1258  	})
  1259  
  1260  	t.Run("should return empty list when nothing has changed", func(t *testing.T) {
  1261  		channelId := model.NewId()
  1262  		userId := model.NewId()
  1263  
  1264  		post1, err := ss.Post().Save(&model.Post{
  1265  			ChannelId: channelId,
  1266  			UserId:    userId,
  1267  			Message:   "message",
  1268  		})
  1269  		require.Nil(t, err)
  1270  		time.Sleep(time.Millisecond)
  1271  
  1272  		postList, err := ss.Post().GetPostsSince(model.GetPostsSinceOptions{ChannelId: channelId, Time: post1.CreateAt}, false)
  1273  		assert.Nil(t, err)
  1274  
  1275  		assert.Equal(t, []string{}, postList.Order)
  1276  		assert.Empty(t, postList.Posts)
  1277  	})
  1278  
  1279  	t.Run("should not cache a timestamp of 0 when nothing has changed", func(t *testing.T) {
  1280  		ss.Post().ClearCaches()
  1281  
  1282  		channelId := model.NewId()
  1283  		userId := model.NewId()
  1284  
  1285  		post1, err := ss.Post().Save(&model.Post{
  1286  			ChannelId: channelId,
  1287  			UserId:    userId,
  1288  			Message:   "message",
  1289  		})
  1290  		require.Nil(t, err)
  1291  		time.Sleep(time.Millisecond)
  1292  
  1293  		// Make a request that returns no results
  1294  		postList, err := ss.Post().GetPostsSince(model.GetPostsSinceOptions{ChannelId: channelId, Time: post1.CreateAt}, true)
  1295  		require.Nil(t, err)
  1296  		require.Equal(t, model.NewPostList(), postList)
  1297  
  1298  		// And then ensure that it doesn't cause future requests to also return no results
  1299  		postList, err = ss.Post().GetPostsSince(model.GetPostsSinceOptions{ChannelId: channelId, Time: post1.CreateAt - 1}, true)
  1300  		assert.Nil(t, err)
  1301  
  1302  		assert.Equal(t, []string{post1.Id}, postList.Order)
  1303  
  1304  		assert.Len(t, postList.Posts, 1)
  1305  		assert.NotNil(t, postList.Posts[post1.Id])
  1306  	})
  1307  }
  1308  
  1309  func testPostStoreGetPosts(t *testing.T, ss store.Store) {
  1310  	channelId := model.NewId()
  1311  	userId := model.NewId()
  1312  
  1313  	post1, err := ss.Post().Save(&model.Post{
  1314  		ChannelId: channelId,
  1315  		UserId:    userId,
  1316  		Message:   "message",
  1317  	})
  1318  	require.Nil(t, err)
  1319  	time.Sleep(time.Millisecond)
  1320  
  1321  	post2, err := ss.Post().Save(&model.Post{
  1322  		ChannelId: channelId,
  1323  		UserId:    userId,
  1324  		Message:   "message",
  1325  	})
  1326  	require.Nil(t, err)
  1327  	time.Sleep(time.Millisecond)
  1328  
  1329  	post3, err := ss.Post().Save(&model.Post{
  1330  		ChannelId: channelId,
  1331  		UserId:    userId,
  1332  		Message:   "message",
  1333  	})
  1334  	require.Nil(t, err)
  1335  	time.Sleep(time.Millisecond)
  1336  
  1337  	post4, err := ss.Post().Save(&model.Post{
  1338  		ChannelId: channelId,
  1339  		UserId:    userId,
  1340  		Message:   "message",
  1341  	})
  1342  	require.Nil(t, err)
  1343  	time.Sleep(time.Millisecond)
  1344  
  1345  	post5, err := ss.Post().Save(&model.Post{
  1346  		ChannelId: channelId,
  1347  		UserId:    userId,
  1348  		Message:   "message",
  1349  		RootId:    post3.Id,
  1350  	})
  1351  	require.Nil(t, err)
  1352  	time.Sleep(time.Millisecond)
  1353  
  1354  	post6, err := ss.Post().Save(&model.Post{
  1355  		ChannelId: channelId,
  1356  		UserId:    userId,
  1357  		Message:   "message",
  1358  		RootId:    post1.Id,
  1359  	})
  1360  	require.Nil(t, err)
  1361  
  1362  	t.Run("should return the last posts created in a channel", func(t *testing.T) {
  1363  		postList, err := ss.Post().GetPosts(model.GetPostsOptions{ChannelId: channelId, Page: 0, PerPage: 30, SkipFetchThreads: false}, false)
  1364  		assert.Nil(t, err)
  1365  
  1366  		assert.Equal(t, []string{
  1367  			post6.Id,
  1368  			post5.Id,
  1369  			post4.Id,
  1370  			post3.Id,
  1371  			post2.Id,
  1372  			post1.Id,
  1373  		}, postList.Order)
  1374  
  1375  		assert.Len(t, postList.Posts, 6)
  1376  		assert.NotNil(t, postList.Posts[post1.Id])
  1377  		assert.NotNil(t, postList.Posts[post2.Id])
  1378  		assert.NotNil(t, postList.Posts[post3.Id])
  1379  		assert.NotNil(t, postList.Posts[post4.Id])
  1380  		assert.NotNil(t, postList.Posts[post5.Id])
  1381  		assert.NotNil(t, postList.Posts[post6.Id])
  1382  	})
  1383  
  1384  	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) {
  1385  		postList, err := ss.Post().GetPosts(model.GetPostsOptions{ChannelId: channelId, Page: 0, PerPage: 2, SkipFetchThreads: false}, false)
  1386  		assert.Nil(t, err)
  1387  
  1388  		assert.Equal(t, []string{
  1389  			post6.Id,
  1390  			post5.Id,
  1391  		}, postList.Order)
  1392  
  1393  		assert.Len(t, postList.Posts, 4)
  1394  		require.NotNil(t, postList.Posts[post1.Id])
  1395  		require.NotNil(t, postList.Posts[post3.Id])
  1396  		require.NotNil(t, postList.Posts[post5.Id])
  1397  		require.NotNil(t, postList.Posts[post6.Id])
  1398  		assert.Equal(t, int64(0), postList.Posts[post1.Id].ReplyCount)
  1399  		assert.Equal(t, int64(0), postList.Posts[post3.Id].ReplyCount)
  1400  		assert.Equal(t, int64(0), postList.Posts[post5.Id].ReplyCount)
  1401  		assert.Equal(t, int64(0), postList.Posts[post6.Id].ReplyCount)
  1402  	})
  1403  
  1404  	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) {
  1405  		postList, err := ss.Post().GetPosts(model.GetPostsOptions{ChannelId: channelId, Page: 0, PerPage: 2, SkipFetchThreads: true}, false)
  1406  		assert.Nil(t, err)
  1407  
  1408  		assert.Equal(t, []string{
  1409  			post6.Id,
  1410  			post5.Id,
  1411  		}, postList.Order)
  1412  
  1413  		assert.Len(t, postList.Posts, 4)
  1414  		assert.NotNil(t, postList.Posts[post5.Id])
  1415  		assert.NotNil(t, postList.Posts[post6.Id])
  1416  		assert.Equal(t, int64(1), postList.Posts[post5.Id].ReplyCount)
  1417  		assert.Equal(t, int64(1), postList.Posts[post6.Id].ReplyCount)
  1418  	})
  1419  }
  1420  
  1421  func testPostStoreGetPostBeforeAfter(t *testing.T, ss store.Store) {
  1422  	channelId := model.NewId()
  1423  
  1424  	o0 := &model.Post{}
  1425  	o0.ChannelId = channelId
  1426  	o0.UserId = model.NewId()
  1427  	o0.Message = "zz" + model.NewId() + "b"
  1428  	_, err := ss.Post().Save(o0)
  1429  	require.Nil(t, err)
  1430  	time.Sleep(2 * time.Millisecond)
  1431  
  1432  	o1 := &model.Post{}
  1433  	o1.ChannelId = channelId
  1434  	o1.Type = model.POST_JOIN_CHANNEL
  1435  	o1.UserId = model.NewId()
  1436  	o1.Message = "system_join_channel message"
  1437  	_, err = ss.Post().Save(o1)
  1438  	require.Nil(t, err)
  1439  	time.Sleep(2 * time.Millisecond)
  1440  
  1441  	o0a := &model.Post{}
  1442  	o0a.ChannelId = channelId
  1443  	o0a.UserId = model.NewId()
  1444  	o0a.Message = "zz" + model.NewId() + "b"
  1445  	o0a.ParentId = o1.Id
  1446  	o0a.RootId = o1.Id
  1447  	_, err = ss.Post().Save(o0a)
  1448  	require.Nil(t, err)
  1449  	time.Sleep(2 * time.Millisecond)
  1450  
  1451  	o0b := &model.Post{}
  1452  	o0b.ChannelId = channelId
  1453  	o0b.UserId = model.NewId()
  1454  	o0b.Message = "deleted message"
  1455  	o0b.ParentId = o1.Id
  1456  	o0b.RootId = o1.Id
  1457  	o0b.DeleteAt = 1
  1458  	_, err = ss.Post().Save(o0b)
  1459  	require.Nil(t, err)
  1460  	time.Sleep(2 * time.Millisecond)
  1461  
  1462  	otherChannelPost := &model.Post{}
  1463  	otherChannelPost.ChannelId = model.NewId()
  1464  	otherChannelPost.UserId = model.NewId()
  1465  	otherChannelPost.Message = "zz" + model.NewId() + "b"
  1466  	_, err = ss.Post().Save(otherChannelPost)
  1467  	require.Nil(t, err)
  1468  	time.Sleep(2 * time.Millisecond)
  1469  
  1470  	o2 := &model.Post{}
  1471  	o2.ChannelId = channelId
  1472  	o2.UserId = model.NewId()
  1473  	o2.Message = "zz" + model.NewId() + "b"
  1474  	_, err = ss.Post().Save(o2)
  1475  	require.Nil(t, err)
  1476  	time.Sleep(2 * time.Millisecond)
  1477  
  1478  	o2a := &model.Post{}
  1479  	o2a.ChannelId = channelId
  1480  	o2a.UserId = model.NewId()
  1481  	o2a.Message = "zz" + model.NewId() + "b"
  1482  	o2a.ParentId = o2.Id
  1483  	o2a.RootId = o2.Id
  1484  	_, err = ss.Post().Save(o2a)
  1485  	require.Nil(t, err)
  1486  
  1487  	rPostId1, err := ss.Post().GetPostIdBeforeTime(channelId, o0a.CreateAt)
  1488  	require.Equal(t, rPostId1, o1.Id, "should return before post o1")
  1489  	require.Nil(t, err)
  1490  
  1491  	rPostId1, err = ss.Post().GetPostIdAfterTime(channelId, o0b.CreateAt)
  1492  	require.Equal(t, rPostId1, o2.Id, "should return before post o2")
  1493  	require.Nil(t, err)
  1494  
  1495  	rPost1, err := ss.Post().GetPostAfterTime(channelId, o0b.CreateAt)
  1496  	require.Equal(t, rPost1.Id, o2.Id, "should return before post o2")
  1497  	require.Nil(t, err)
  1498  
  1499  	rPostId2, err := ss.Post().GetPostIdBeforeTime(channelId, o0.CreateAt)
  1500  	require.Empty(t, rPostId2, "should return no post")
  1501  	require.Nil(t, err)
  1502  
  1503  	rPostId2, err = ss.Post().GetPostIdAfterTime(channelId, o0.CreateAt)
  1504  	require.Equal(t, rPostId2, o1.Id, "should return before post o1")
  1505  	require.Nil(t, err)
  1506  
  1507  	rPost2, err := ss.Post().GetPostAfterTime(channelId, o0.CreateAt)
  1508  	require.Equal(t, rPost2.Id, o1.Id, "should return before post o1")
  1509  	require.Nil(t, err)
  1510  
  1511  	rPostId3, err := ss.Post().GetPostIdBeforeTime(channelId, o2a.CreateAt)
  1512  	require.Equal(t, rPostId3, o2.Id, "should return before post o2")
  1513  	require.Nil(t, err)
  1514  
  1515  	rPostId3, err = ss.Post().GetPostIdAfterTime(channelId, o2a.CreateAt)
  1516  	require.Empty(t, rPostId3, "should return no post")
  1517  	require.Nil(t, err)
  1518  
  1519  	rPost3, err := ss.Post().GetPostAfterTime(channelId, o2a.CreateAt)
  1520  	require.Empty(t, rPost3, "should return no post")
  1521  	require.Nil(t, err)
  1522  }
  1523  
  1524  func testUserCountsWithPostsByDay(t *testing.T, ss store.Store) {
  1525  	t1 := &model.Team{}
  1526  	t1.DisplayName = "DisplayName"
  1527  	t1.Name = "zz" + model.NewId() + "b"
  1528  	t1.Email = MakeEmail()
  1529  	t1.Type = model.TEAM_OPEN
  1530  	t1, err := ss.Team().Save(t1)
  1531  	require.Nil(t, err)
  1532  
  1533  	c1 := &model.Channel{}
  1534  	c1.TeamId = t1.Id
  1535  	c1.DisplayName = "Channel2"
  1536  	c1.Name = "zz" + model.NewId() + "b"
  1537  	c1.Type = model.CHANNEL_OPEN
  1538  	c1, nErr := ss.Channel().Save(c1, -1)
  1539  	require.Nil(t, nErr)
  1540  
  1541  	o1 := &model.Post{}
  1542  	o1.ChannelId = c1.Id
  1543  	o1.UserId = model.NewId()
  1544  	o1.CreateAt = utils.MillisFromTime(utils.Yesterday())
  1545  	o1.Message = "zz" + model.NewId() + "b"
  1546  	o1, err = ss.Post().Save(o1)
  1547  	require.Nil(t, err)
  1548  
  1549  	o1a := &model.Post{}
  1550  	o1a.ChannelId = c1.Id
  1551  	o1a.UserId = model.NewId()
  1552  	o1a.CreateAt = o1.CreateAt
  1553  	o1a.Message = "zz" + model.NewId() + "b"
  1554  	_, err = ss.Post().Save(o1a)
  1555  	require.Nil(t, err)
  1556  
  1557  	o2 := &model.Post{}
  1558  	o2.ChannelId = c1.Id
  1559  	o2.UserId = model.NewId()
  1560  	o2.CreateAt = o1.CreateAt - (1000 * 60 * 60 * 24)
  1561  	o2.Message = "zz" + model.NewId() + "b"
  1562  	o2, err = ss.Post().Save(o2)
  1563  	require.Nil(t, err)
  1564  
  1565  	o2a := &model.Post{}
  1566  	o2a.ChannelId = c1.Id
  1567  	o2a.UserId = o2.UserId
  1568  	o2a.CreateAt = o1.CreateAt - (1000 * 60 * 60 * 24)
  1569  	o2a.Message = "zz" + model.NewId() + "b"
  1570  	_, err = ss.Post().Save(o2a)
  1571  	require.Nil(t, err)
  1572  
  1573  	r1, err := ss.Post().AnalyticsUserCountsWithPostsByDay(t1.Id)
  1574  	require.Nil(t, err)
  1575  
  1576  	row1 := r1[0]
  1577  	require.Equal(t, float64(2), row1.Value, "wrong value")
  1578  
  1579  	row2 := r1[1]
  1580  	require.Equal(t, float64(1), row2.Value, "wrong value")
  1581  }
  1582  
  1583  func testPostCountsByDay(t *testing.T, ss store.Store) {
  1584  	t1 := &model.Team{}
  1585  	t1.DisplayName = "DisplayName"
  1586  	t1.Name = "zz" + model.NewId() + "b"
  1587  	t1.Email = MakeEmail()
  1588  	t1.Type = model.TEAM_OPEN
  1589  	t1, err := ss.Team().Save(t1)
  1590  	require.Nil(t, err)
  1591  
  1592  	c1 := &model.Channel{}
  1593  	c1.TeamId = t1.Id
  1594  	c1.DisplayName = "Channel2"
  1595  	c1.Name = "zz" + model.NewId() + "b"
  1596  	c1.Type = model.CHANNEL_OPEN
  1597  	c1, nErr := ss.Channel().Save(c1, -1)
  1598  	require.Nil(t, nErr)
  1599  
  1600  	o1 := &model.Post{}
  1601  	o1.ChannelId = c1.Id
  1602  	o1.UserId = model.NewId()
  1603  	o1.CreateAt = utils.MillisFromTime(utils.Yesterday())
  1604  	o1.Message = "zz" + model.NewId() + "b"
  1605  	o1, err = ss.Post().Save(o1)
  1606  	require.Nil(t, err)
  1607  
  1608  	o1a := &model.Post{}
  1609  	o1a.ChannelId = c1.Id
  1610  	o1a.UserId = model.NewId()
  1611  	o1a.CreateAt = o1.CreateAt
  1612  	o1a.Message = "zz" + model.NewId() + "b"
  1613  	_, err = ss.Post().Save(o1a)
  1614  	require.Nil(t, err)
  1615  
  1616  	o2 := &model.Post{}
  1617  	o2.ChannelId = c1.Id
  1618  	o2.UserId = model.NewId()
  1619  	o2.CreateAt = o1.CreateAt - (1000 * 60 * 60 * 24 * 2)
  1620  	o2.Message = "zz" + model.NewId() + "b"
  1621  	o2, err = ss.Post().Save(o2)
  1622  	require.Nil(t, err)
  1623  
  1624  	o2a := &model.Post{}
  1625  	o2a.ChannelId = c1.Id
  1626  	o2a.UserId = o2.UserId
  1627  	o2a.CreateAt = o1.CreateAt - (1000 * 60 * 60 * 24 * 2)
  1628  	o2a.Message = "zz" + model.NewId() + "b"
  1629  	_, err = ss.Post().Save(o2a)
  1630  	require.Nil(t, err)
  1631  
  1632  	bot1 := &model.Bot{
  1633  		Username:    "username",
  1634  		Description: "a bot",
  1635  		OwnerId:     model.NewId(),
  1636  		UserId:      model.NewId(),
  1637  	}
  1638  	_, nErr = ss.Bot().Save(bot1)
  1639  	require.Nil(t, nErr)
  1640  
  1641  	b1 := &model.Post{}
  1642  	b1.Message = "bot message one"
  1643  	b1.ChannelId = c1.Id
  1644  	b1.UserId = bot1.UserId
  1645  	b1.CreateAt = utils.MillisFromTime(utils.Yesterday())
  1646  	_, err = ss.Post().Save(b1)
  1647  	require.Nil(t, err)
  1648  
  1649  	b1a := &model.Post{}
  1650  	b1a.Message = "bot message two"
  1651  	b1a.ChannelId = c1.Id
  1652  	b1a.UserId = bot1.UserId
  1653  	b1a.CreateAt = utils.MillisFromTime(utils.Yesterday()) - (1000 * 60 * 60 * 24 * 2)
  1654  	_, err = ss.Post().Save(b1a)
  1655  	require.Nil(t, err)
  1656  
  1657  	time.Sleep(1 * time.Second)
  1658  
  1659  	// summary of posts
  1660  	// yesterday - 2 non-bot user posts, 1 bot user post
  1661  	// 3 days ago - 2 non-bot user posts, 1 bot user post
  1662  
  1663  	// last 31 days, all users (including bots)
  1664  	postCountsOptions := &model.AnalyticsPostCountsOptions{TeamId: t1.Id, BotsOnly: false, YesterdayOnly: false}
  1665  	r1, err := ss.Post().AnalyticsPostCountsByDay(postCountsOptions)
  1666  	require.Nil(t, err)
  1667  	assert.Equal(t, float64(3), r1[0].Value)
  1668  	assert.Equal(t, float64(3), r1[1].Value)
  1669  
  1670  	// last 31 days, bots only
  1671  	postCountsOptions = &model.AnalyticsPostCountsOptions{TeamId: t1.Id, BotsOnly: true, YesterdayOnly: false}
  1672  	r1, err = ss.Post().AnalyticsPostCountsByDay(postCountsOptions)
  1673  	require.Nil(t, err)
  1674  	assert.Equal(t, float64(1), r1[0].Value)
  1675  	assert.Equal(t, float64(1), r1[1].Value)
  1676  
  1677  	// yesterday only, all users (including bots)
  1678  	postCountsOptions = &model.AnalyticsPostCountsOptions{TeamId: t1.Id, BotsOnly: false, YesterdayOnly: true}
  1679  	r1, err = ss.Post().AnalyticsPostCountsByDay(postCountsOptions)
  1680  	require.Nil(t, err)
  1681  	assert.Equal(t, float64(3), r1[0].Value)
  1682  
  1683  	// yesterday only, bots only
  1684  	postCountsOptions = &model.AnalyticsPostCountsOptions{TeamId: t1.Id, BotsOnly: true, YesterdayOnly: true}
  1685  	r1, err = ss.Post().AnalyticsPostCountsByDay(postCountsOptions)
  1686  	require.Nil(t, err)
  1687  	assert.Equal(t, float64(1), r1[0].Value)
  1688  
  1689  	// total
  1690  	r2, err := ss.Post().AnalyticsPostCount(t1.Id, false, false)
  1691  	require.Nil(t, err)
  1692  	assert.Equal(t, int64(6), r2)
  1693  }
  1694  
  1695  func testPostStoreGetFlaggedPostsForTeam(t *testing.T, ss store.Store, s SqlSupplier) {
  1696  	c1 := &model.Channel{}
  1697  	c1.TeamId = model.NewId()
  1698  	c1.DisplayName = "Channel1"
  1699  	c1.Name = "zz" + model.NewId() + "b"
  1700  	c1.Type = model.CHANNEL_OPEN
  1701  	c1, err := ss.Channel().Save(c1, -1)
  1702  	require.Nil(t, err)
  1703  
  1704  	o1 := &model.Post{}
  1705  	o1.ChannelId = c1.Id
  1706  	o1.UserId = model.NewId()
  1707  	o1.Message = "zz" + model.NewId() + "b"
  1708  	o1, err = ss.Post().Save(o1)
  1709  	require.Nil(t, err)
  1710  	time.Sleep(2 * time.Millisecond)
  1711  
  1712  	o2 := &model.Post{}
  1713  	o2.ChannelId = o1.ChannelId
  1714  	o2.UserId = model.NewId()
  1715  	o2.Message = "zz" + model.NewId() + "b"
  1716  	o2, err = ss.Post().Save(o2)
  1717  	require.Nil(t, err)
  1718  	time.Sleep(2 * time.Millisecond)
  1719  
  1720  	o3 := &model.Post{}
  1721  	o3.ChannelId = o1.ChannelId
  1722  	o3.UserId = model.NewId()
  1723  	o3.Message = "zz" + model.NewId() + "b"
  1724  	o3.DeleteAt = 1
  1725  	o3, err = ss.Post().Save(o3)
  1726  	require.Nil(t, err)
  1727  	time.Sleep(2 * time.Millisecond)
  1728  
  1729  	o4 := &model.Post{}
  1730  	o4.ChannelId = model.NewId()
  1731  	o4.UserId = model.NewId()
  1732  	o4.Message = "zz" + model.NewId() + "b"
  1733  	o4, err = ss.Post().Save(o4)
  1734  	require.Nil(t, err)
  1735  	time.Sleep(2 * time.Millisecond)
  1736  
  1737  	c2 := &model.Channel{}
  1738  	c2.DisplayName = "DMChannel1"
  1739  	c2.Name = "zz" + model.NewId() + "b"
  1740  	c2.Type = model.CHANNEL_DIRECT
  1741  
  1742  	m1 := &model.ChannelMember{}
  1743  	m1.ChannelId = c2.Id
  1744  	m1.UserId = o1.UserId
  1745  	m1.NotifyProps = model.GetDefaultChannelNotifyProps()
  1746  
  1747  	m2 := &model.ChannelMember{}
  1748  	m2.ChannelId = c2.Id
  1749  	m2.UserId = model.NewId()
  1750  	m2.NotifyProps = model.GetDefaultChannelNotifyProps()
  1751  
  1752  	c2, err = ss.Channel().SaveDirectChannel(c2, m1, m2)
  1753  	require.Nil(t, err)
  1754  
  1755  	o5 := &model.Post{}
  1756  	o5.ChannelId = c2.Id
  1757  	o5.UserId = m2.UserId
  1758  	o5.Message = "zz" + model.NewId() + "b"
  1759  	o5, err = ss.Post().Save(o5)
  1760  	require.Nil(t, err)
  1761  	time.Sleep(2 * time.Millisecond)
  1762  
  1763  	r1, err := ss.Post().GetFlaggedPosts(o1.ChannelId, 0, 2)
  1764  	require.Nil(t, err)
  1765  
  1766  	require.Empty(t, r1.Order, "should be empty")
  1767  
  1768  	preferences := model.Preferences{
  1769  		{
  1770  			UserId:   o1.UserId,
  1771  			Category: model.PREFERENCE_CATEGORY_FLAGGED_POST,
  1772  			Name:     o1.Id,
  1773  			Value:    "true",
  1774  		},
  1775  	}
  1776  
  1777  	err = ss.Preference().Save(&preferences)
  1778  	require.Nil(t, err)
  1779  
  1780  	r2, err := ss.Post().GetFlaggedPostsForTeam(o1.UserId, c1.TeamId, 0, 2)
  1781  	require.Nil(t, err)
  1782  	require.Len(t, r2.Order, 1, "should have 1 post")
  1783  
  1784  	preferences = model.Preferences{
  1785  		{
  1786  			UserId:   o1.UserId,
  1787  			Category: model.PREFERENCE_CATEGORY_FLAGGED_POST,
  1788  			Name:     o2.Id,
  1789  			Value:    "true",
  1790  		},
  1791  	}
  1792  
  1793  	err = ss.Preference().Save(&preferences)
  1794  	require.Nil(t, err)
  1795  
  1796  	r3, err := ss.Post().GetFlaggedPostsForTeam(o1.UserId, c1.TeamId, 0, 1)
  1797  	require.Nil(t, err)
  1798  	require.Len(t, r3.Order, 1, "should have 1 post")
  1799  
  1800  	r3, err = ss.Post().GetFlaggedPostsForTeam(o1.UserId, c1.TeamId, 1, 1)
  1801  	require.Nil(t, err)
  1802  	require.Len(t, r3.Order, 1, "should have 1 post")
  1803  
  1804  	r3, err = ss.Post().GetFlaggedPostsForTeam(o1.UserId, c1.TeamId, 1000, 10)
  1805  	require.Nil(t, err)
  1806  	require.Empty(t, r3.Order, "should be empty")
  1807  
  1808  	r4, err := ss.Post().GetFlaggedPostsForTeam(o1.UserId, c1.TeamId, 0, 2)
  1809  	require.Nil(t, err)
  1810  	require.Len(t, r4.Order, 2, "should have 2 posts")
  1811  
  1812  	preferences = model.Preferences{
  1813  		{
  1814  			UserId:   o1.UserId,
  1815  			Category: model.PREFERENCE_CATEGORY_FLAGGED_POST,
  1816  			Name:     o3.Id,
  1817  			Value:    "true",
  1818  		},
  1819  	}
  1820  
  1821  	err = ss.Preference().Save(&preferences)
  1822  	require.Nil(t, err)
  1823  
  1824  	r4, err = ss.Post().GetFlaggedPostsForTeam(o1.UserId, c1.TeamId, 0, 2)
  1825  	require.Nil(t, err)
  1826  	require.Len(t, r4.Order, 2, "should have 2 posts")
  1827  
  1828  	preferences = model.Preferences{
  1829  		{
  1830  			UserId:   o1.UserId,
  1831  			Category: model.PREFERENCE_CATEGORY_FLAGGED_POST,
  1832  			Name:     o4.Id,
  1833  			Value:    "true",
  1834  		},
  1835  	}
  1836  	err = ss.Preference().Save(&preferences)
  1837  	require.Nil(t, err)
  1838  
  1839  	r4, err = ss.Post().GetFlaggedPostsForTeam(o1.UserId, c1.TeamId, 0, 2)
  1840  	require.Nil(t, err)
  1841  	require.Len(t, r4.Order, 2, "should have 2 posts")
  1842  
  1843  	r4, err = ss.Post().GetFlaggedPostsForTeam(o1.UserId, model.NewId(), 0, 2)
  1844  	require.Nil(t, err)
  1845  	require.Empty(t, r4.Order, "should have 0 posts")
  1846  
  1847  	preferences = model.Preferences{
  1848  		{
  1849  			UserId:   o1.UserId,
  1850  			Category: model.PREFERENCE_CATEGORY_FLAGGED_POST,
  1851  			Name:     o5.Id,
  1852  			Value:    "true",
  1853  		},
  1854  	}
  1855  	err = ss.Preference().Save(&preferences)
  1856  	require.Nil(t, err)
  1857  
  1858  	r4, err = ss.Post().GetFlaggedPostsForTeam(o1.UserId, c1.TeamId, 0, 10)
  1859  	require.Nil(t, err)
  1860  	require.Len(t, r4.Order, 3, "should have 3 posts")
  1861  
  1862  	// Manually truncate Channels table until testlib can handle cleanups
  1863  	s.GetMaster().Exec("TRUNCATE Channels")
  1864  }
  1865  
  1866  func testPostStoreGetFlaggedPosts(t *testing.T, ss store.Store) {
  1867  	o1 := &model.Post{}
  1868  	o1.ChannelId = model.NewId()
  1869  	o1.UserId = model.NewId()
  1870  	o1.Message = "zz" + model.NewId() + "b"
  1871  	o1, err := ss.Post().Save(o1)
  1872  	require.Nil(t, err)
  1873  	time.Sleep(2 * time.Millisecond)
  1874  
  1875  	o2 := &model.Post{}
  1876  	o2.ChannelId = o1.ChannelId
  1877  	o2.UserId = model.NewId()
  1878  	o2.Message = "zz" + model.NewId() + "b"
  1879  	o2, err = ss.Post().Save(o2)
  1880  	require.Nil(t, err)
  1881  	time.Sleep(2 * time.Millisecond)
  1882  
  1883  	o3 := &model.Post{}
  1884  	o3.ChannelId = o1.ChannelId
  1885  	o3.UserId = model.NewId()
  1886  	o3.Message = "zz" + model.NewId() + "b"
  1887  	o3.DeleteAt = 1
  1888  	o3, err = ss.Post().Save(o3)
  1889  	require.Nil(t, err)
  1890  	time.Sleep(2 * time.Millisecond)
  1891  
  1892  	r1, err := ss.Post().GetFlaggedPosts(o1.UserId, 0, 2)
  1893  	require.Nil(t, err)
  1894  	require.Empty(t, r1.Order, "should be empty")
  1895  
  1896  	preferences := model.Preferences{
  1897  		{
  1898  			UserId:   o1.UserId,
  1899  			Category: model.PREFERENCE_CATEGORY_FLAGGED_POST,
  1900  			Name:     o1.Id,
  1901  			Value:    "true",
  1902  		},
  1903  	}
  1904  
  1905  	nErr := ss.Preference().Save(&preferences)
  1906  	require.Nil(t, nErr)
  1907  
  1908  	r2, err := ss.Post().GetFlaggedPosts(o1.UserId, 0, 2)
  1909  	require.Nil(t, err)
  1910  	require.Len(t, r2.Order, 1, "should have 1 post")
  1911  
  1912  	preferences = model.Preferences{
  1913  		{
  1914  			UserId:   o1.UserId,
  1915  			Category: model.PREFERENCE_CATEGORY_FLAGGED_POST,
  1916  			Name:     o2.Id,
  1917  			Value:    "true",
  1918  		},
  1919  	}
  1920  
  1921  	nErr = ss.Preference().Save(&preferences)
  1922  	require.Nil(t, nErr)
  1923  
  1924  	r3, err := ss.Post().GetFlaggedPosts(o1.UserId, 0, 1)
  1925  	require.Nil(t, err)
  1926  	require.Len(t, r3.Order, 1, "should have 1 post")
  1927  
  1928  	r3, err = ss.Post().GetFlaggedPosts(o1.UserId, 1, 1)
  1929  	require.Nil(t, err)
  1930  	require.Len(t, r3.Order, 1, "should have 1 post")
  1931  
  1932  	r3, err = ss.Post().GetFlaggedPosts(o1.UserId, 1000, 10)
  1933  	require.Nil(t, err)
  1934  	require.Empty(t, r3.Order, "should be empty")
  1935  
  1936  	r4, err := ss.Post().GetFlaggedPosts(o1.UserId, 0, 2)
  1937  	require.Nil(t, err)
  1938  	require.Len(t, r4.Order, 2, "should have 2 posts")
  1939  
  1940  	preferences = model.Preferences{
  1941  		{
  1942  			UserId:   o1.UserId,
  1943  			Category: model.PREFERENCE_CATEGORY_FLAGGED_POST,
  1944  			Name:     o3.Id,
  1945  			Value:    "true",
  1946  		},
  1947  	}
  1948  
  1949  	nErr = ss.Preference().Save(&preferences)
  1950  	require.Nil(t, nErr)
  1951  
  1952  	r4, err = ss.Post().GetFlaggedPosts(o1.UserId, 0, 2)
  1953  	require.Nil(t, err)
  1954  	require.Len(t, r4.Order, 2, "should have 2 posts")
  1955  }
  1956  
  1957  func testPostStoreGetFlaggedPostsForChannel(t *testing.T, ss store.Store) {
  1958  	o1 := &model.Post{}
  1959  	o1.ChannelId = model.NewId()
  1960  	o1.UserId = model.NewId()
  1961  	o1.Message = "zz" + model.NewId() + "b"
  1962  	o1, err := ss.Post().Save(o1)
  1963  	require.Nil(t, err)
  1964  	time.Sleep(2 * time.Millisecond)
  1965  
  1966  	o2 := &model.Post{}
  1967  	o2.ChannelId = o1.ChannelId
  1968  	o2.UserId = model.NewId()
  1969  	o2.Message = "zz" + model.NewId() + "b"
  1970  	o2, err = ss.Post().Save(o2)
  1971  	require.Nil(t, err)
  1972  	time.Sleep(2 * time.Millisecond)
  1973  
  1974  	// deleted post
  1975  	o3 := &model.Post{}
  1976  	o3.ChannelId = model.NewId()
  1977  	o3.UserId = o1.ChannelId
  1978  	o3.Message = "zz" + model.NewId() + "b"
  1979  	o3.DeleteAt = 1
  1980  	o3, err = ss.Post().Save(o3)
  1981  	require.Nil(t, err)
  1982  	time.Sleep(2 * time.Millisecond)
  1983  
  1984  	o4 := &model.Post{}
  1985  	o4.ChannelId = model.NewId()
  1986  	o4.UserId = model.NewId()
  1987  	o4.Message = "zz" + model.NewId() + "b"
  1988  	o4, err = ss.Post().Save(o4)
  1989  	require.Nil(t, err)
  1990  	time.Sleep(2 * time.Millisecond)
  1991  
  1992  	r, err := ss.Post().GetFlaggedPostsForChannel(o1.UserId, o1.ChannelId, 0, 10)
  1993  	require.Nil(t, err)
  1994  	require.Empty(t, r.Order, "should be empty")
  1995  
  1996  	preference := model.Preference{
  1997  		UserId:   o1.UserId,
  1998  		Category: model.PREFERENCE_CATEGORY_FLAGGED_POST,
  1999  		Name:     o1.Id,
  2000  		Value:    "true",
  2001  	}
  2002  
  2003  	nErr := ss.Preference().Save(&model.Preferences{preference})
  2004  	require.Nil(t, nErr)
  2005  
  2006  	r, err = ss.Post().GetFlaggedPostsForChannel(o1.UserId, o1.ChannelId, 0, 10)
  2007  	require.Nil(t, err)
  2008  	require.Len(t, r.Order, 1, "should have 1 post")
  2009  
  2010  	preference.Name = o2.Id
  2011  	nErr = ss.Preference().Save(&model.Preferences{preference})
  2012  	require.Nil(t, nErr)
  2013  
  2014  	preference.Name = o3.Id
  2015  	nErr = ss.Preference().Save(&model.Preferences{preference})
  2016  	require.Nil(t, nErr)
  2017  
  2018  	r, err = ss.Post().GetFlaggedPostsForChannel(o1.UserId, o1.ChannelId, 0, 1)
  2019  	require.Nil(t, err)
  2020  	require.Len(t, r.Order, 1, "should have 1 post")
  2021  
  2022  	r, err = ss.Post().GetFlaggedPostsForChannel(o1.UserId, o1.ChannelId, 1, 1)
  2023  	require.Nil(t, err)
  2024  	require.Len(t, r.Order, 1, "should have 1 post")
  2025  
  2026  	r, err = ss.Post().GetFlaggedPostsForChannel(o1.UserId, o1.ChannelId, 1000, 10)
  2027  	require.Nil(t, err)
  2028  	require.Empty(t, r.Order, "should be empty")
  2029  
  2030  	r, err = ss.Post().GetFlaggedPostsForChannel(o1.UserId, o1.ChannelId, 0, 10)
  2031  	require.Nil(t, err)
  2032  	require.Len(t, r.Order, 2, "should have 2 posts")
  2033  
  2034  	preference.Name = o4.Id
  2035  	nErr = ss.Preference().Save(&model.Preferences{preference})
  2036  	require.Nil(t, nErr)
  2037  
  2038  	r, err = ss.Post().GetFlaggedPostsForChannel(o1.UserId, o4.ChannelId, 0, 10)
  2039  	require.Nil(t, err)
  2040  	require.Len(t, r.Order, 1, "should have 1 posts")
  2041  }
  2042  
  2043  func testPostStoreGetPostsCreatedAt(t *testing.T, ss store.Store) {
  2044  	createTime := model.GetMillis() + 1
  2045  
  2046  	o0 := &model.Post{}
  2047  	o0.ChannelId = model.NewId()
  2048  	o0.UserId = model.NewId()
  2049  	o0.Message = "zz" + model.NewId() + "b"
  2050  	o0.CreateAt = createTime
  2051  	o0, err := ss.Post().Save(o0)
  2052  	require.Nil(t, err)
  2053  
  2054  	o1 := &model.Post{}
  2055  	o1.ChannelId = o0.ChannelId
  2056  	o1.UserId = model.NewId()
  2057  	o1.Message = "zz" + model.NewId() + "b"
  2058  	o1.CreateAt = createTime
  2059  	o1, err = ss.Post().Save(o1)
  2060  	require.Nil(t, err)
  2061  
  2062  	o2 := &model.Post{}
  2063  	o2.ChannelId = o1.ChannelId
  2064  	o2.UserId = model.NewId()
  2065  	o2.Message = "zz" + model.NewId() + "b"
  2066  	o2.ParentId = o1.Id
  2067  	o2.RootId = o1.Id
  2068  	o2.CreateAt = createTime + 1
  2069  	_, err = ss.Post().Save(o2)
  2070  	require.Nil(t, err)
  2071  
  2072  	o3 := &model.Post{}
  2073  	o3.ChannelId = model.NewId()
  2074  	o3.UserId = model.NewId()
  2075  	o3.Message = "zz" + model.NewId() + "b"
  2076  	o3.CreateAt = createTime
  2077  	_, err = ss.Post().Save(o3)
  2078  	require.Nil(t, err)
  2079  
  2080  	r1, _ := ss.Post().GetPostsCreatedAt(o1.ChannelId, createTime)
  2081  	assert.Equal(t, 2, len(r1))
  2082  }
  2083  
  2084  func testPostStoreOverwriteMultiple(t *testing.T, ss store.Store) {
  2085  	o1 := &model.Post{}
  2086  	o1.ChannelId = model.NewId()
  2087  	o1.UserId = model.NewId()
  2088  	o1.Message = "zz" + model.NewId() + "AAAAAAAAAAA"
  2089  	o1, err := ss.Post().Save(o1)
  2090  	require.Nil(t, err)
  2091  
  2092  	o2 := &model.Post{}
  2093  	o2.ChannelId = o1.ChannelId
  2094  	o2.UserId = model.NewId()
  2095  	o2.Message = "zz" + model.NewId() + "CCCCCCCCC"
  2096  	o2.ParentId = o1.Id
  2097  	o2.RootId = o1.Id
  2098  	o2, err = ss.Post().Save(o2)
  2099  	require.Nil(t, err)
  2100  
  2101  	o3 := &model.Post{}
  2102  	o3.ChannelId = o1.ChannelId
  2103  	o3.UserId = model.NewId()
  2104  	o3.Message = "zz" + model.NewId() + "QQQQQQQQQQ"
  2105  	o3, err = ss.Post().Save(o3)
  2106  	require.Nil(t, err)
  2107  
  2108  	o4, err := ss.Post().Save(&model.Post{
  2109  		ChannelId: model.NewId(),
  2110  		UserId:    model.NewId(),
  2111  		Message:   model.NewId(),
  2112  		Filenames: []string{"test"},
  2113  	})
  2114  	require.Nil(t, err)
  2115  
  2116  	o5, err := ss.Post().Save(&model.Post{
  2117  		ChannelId: model.NewId(),
  2118  		UserId:    model.NewId(),
  2119  		Message:   model.NewId(),
  2120  		Filenames: []string{"test2", "test3"},
  2121  	})
  2122  	require.Nil(t, err)
  2123  
  2124  	r1, err := ss.Post().Get(o1.Id, false)
  2125  	require.Nil(t, err)
  2126  	ro1 := r1.Posts[o1.Id]
  2127  
  2128  	r2, err := ss.Post().Get(o2.Id, false)
  2129  	require.Nil(t, err)
  2130  	ro2 := r2.Posts[o2.Id]
  2131  
  2132  	r3, err := ss.Post().Get(o3.Id, false)
  2133  	require.Nil(t, err)
  2134  	ro3 := r3.Posts[o3.Id]
  2135  
  2136  	r4, err := ss.Post().Get(o4.Id, false)
  2137  	require.Nil(t, err)
  2138  	ro4 := r4.Posts[o4.Id]
  2139  
  2140  	r5, err := ss.Post().Get(o5.Id, false)
  2141  	require.Nil(t, err)
  2142  	ro5 := r5.Posts[o5.Id]
  2143  
  2144  	require.Equal(t, ro1.Message, o1.Message, "Failed to save/get")
  2145  	require.Equal(t, ro2.Message, o2.Message, "Failed to save/get")
  2146  	require.Equal(t, ro3.Message, o3.Message, "Failed to save/get")
  2147  	require.Equal(t, ro4.Message, o4.Message, "Failed to save/get")
  2148  	require.Equal(t, ro4.Filenames, o4.Filenames, "Failed to save/get")
  2149  	require.Equal(t, ro5.Message, o5.Message, "Failed to save/get")
  2150  	require.Equal(t, ro5.Filenames, o5.Filenames, "Failed to save/get")
  2151  
  2152  	t.Run("overwrite changing message", func(t *testing.T) {
  2153  		o1a := ro1.Clone()
  2154  		o1a.Message = ro1.Message + "BBBBBBBBBB"
  2155  
  2156  		o2a := ro2.Clone()
  2157  		o2a.Message = ro2.Message + "DDDDDDD"
  2158  
  2159  		o3a := ro3.Clone()
  2160  		o3a.Message = ro3.Message + "WWWWWWW"
  2161  
  2162  		_, errIdx, err := ss.Post().OverwriteMultiple([]*model.Post{o1a, o2a, o3a})
  2163  		require.Nil(t, err)
  2164  		require.Equal(t, -1, errIdx)
  2165  
  2166  		r1, err = ss.Post().Get(o1.Id, false)
  2167  		require.Nil(t, err)
  2168  		ro1a := r1.Posts[o1.Id]
  2169  
  2170  		r2, err = ss.Post().Get(o1.Id, false)
  2171  		require.Nil(t, err)
  2172  		ro2a := r2.Posts[o2.Id]
  2173  
  2174  		r3, err = ss.Post().Get(o3.Id, false)
  2175  		require.Nil(t, err)
  2176  		ro3a := r3.Posts[o3.Id]
  2177  
  2178  		assert.Equal(t, ro1a.Message, o1a.Message, "Failed to overwrite/get")
  2179  		assert.Equal(t, ro2a.Message, o2a.Message, "Failed to overwrite/get")
  2180  		assert.Equal(t, ro3a.Message, o3a.Message, "Failed to overwrite/get")
  2181  	})
  2182  
  2183  	t.Run("overwrite clearing filenames", func(t *testing.T) {
  2184  		o4a := ro4.Clone()
  2185  		o4a.Filenames = []string{}
  2186  		o4a.FileIds = []string{model.NewId()}
  2187  
  2188  		o5a := ro5.Clone()
  2189  		o5a.Filenames = []string{}
  2190  		o5a.FileIds = []string{}
  2191  
  2192  		_, errIdx, err := ss.Post().OverwriteMultiple([]*model.Post{o4a, o5a})
  2193  		require.Nil(t, err)
  2194  		require.Equal(t, -1, errIdx)
  2195  
  2196  		r4, err = ss.Post().Get(o4.Id, false)
  2197  		require.Nil(t, err)
  2198  		ro4a := r4.Posts[o4.Id]
  2199  
  2200  		r5, err = ss.Post().Get(o5.Id, false)
  2201  		require.Nil(t, err)
  2202  		ro5a := r5.Posts[o5.Id]
  2203  
  2204  		require.Empty(t, ro4a.Filenames, "Failed to clear Filenames")
  2205  		require.Len(t, ro4a.FileIds, 1, "Failed to set FileIds")
  2206  		require.Empty(t, ro5a.Filenames, "Failed to clear Filenames")
  2207  		require.Empty(t, ro5a.FileIds, "Failed to set FileIds")
  2208  	})
  2209  }
  2210  
  2211  func testPostStoreOverwrite(t *testing.T, ss store.Store) {
  2212  	o1 := &model.Post{}
  2213  	o1.ChannelId = model.NewId()
  2214  	o1.UserId = model.NewId()
  2215  	o1.Message = "zz" + model.NewId() + "AAAAAAAAAAA"
  2216  	o1, err := ss.Post().Save(o1)
  2217  	require.Nil(t, err)
  2218  
  2219  	o2 := &model.Post{}
  2220  	o2.ChannelId = o1.ChannelId
  2221  	o2.UserId = model.NewId()
  2222  	o2.Message = "zz" + model.NewId() + "CCCCCCCCC"
  2223  	o2.ParentId = o1.Id
  2224  	o2.RootId = o1.Id
  2225  	o2, err = ss.Post().Save(o2)
  2226  	require.Nil(t, err)
  2227  
  2228  	o3 := &model.Post{}
  2229  	o3.ChannelId = o1.ChannelId
  2230  	o3.UserId = model.NewId()
  2231  	o3.Message = "zz" + model.NewId() + "QQQQQQQQQQ"
  2232  	o3, err = ss.Post().Save(o3)
  2233  	require.Nil(t, err)
  2234  
  2235  	o4, err := ss.Post().Save(&model.Post{
  2236  		ChannelId: model.NewId(),
  2237  		UserId:    model.NewId(),
  2238  		Message:   model.NewId(),
  2239  		Filenames: []string{"test"},
  2240  	})
  2241  	require.Nil(t, err)
  2242  
  2243  	r1, err := ss.Post().Get(o1.Id, false)
  2244  	require.Nil(t, err)
  2245  	ro1 := r1.Posts[o1.Id]
  2246  
  2247  	r2, err := ss.Post().Get(o2.Id, false)
  2248  	require.Nil(t, err)
  2249  	ro2 := r2.Posts[o2.Id]
  2250  
  2251  	r3, err := ss.Post().Get(o3.Id, false)
  2252  	require.Nil(t, err)
  2253  	ro3 := r3.Posts[o3.Id]
  2254  
  2255  	r4, err := ss.Post().Get(o4.Id, false)
  2256  	require.Nil(t, err)
  2257  	ro4 := r4.Posts[o4.Id]
  2258  
  2259  	require.Equal(t, ro1.Message, o1.Message, "Failed to save/get")
  2260  	require.Equal(t, ro2.Message, o2.Message, "Failed to save/get")
  2261  	require.Equal(t, ro3.Message, o3.Message, "Failed to save/get")
  2262  	require.Equal(t, ro4.Message, o4.Message, "Failed to save/get")
  2263  
  2264  	t.Run("overwrite changing message", func(t *testing.T) {
  2265  		o1a := ro1.Clone()
  2266  		o1a.Message = ro1.Message + "BBBBBBBBBB"
  2267  		_, err = ss.Post().Overwrite(o1a)
  2268  		require.Nil(t, err)
  2269  
  2270  		o2a := ro2.Clone()
  2271  		o2a.Message = ro2.Message + "DDDDDDD"
  2272  		_, err = ss.Post().Overwrite(o2a)
  2273  		require.Nil(t, err)
  2274  
  2275  		o3a := ro3.Clone()
  2276  		o3a.Message = ro3.Message + "WWWWWWW"
  2277  		_, err = ss.Post().Overwrite(o3a)
  2278  		require.Nil(t, err)
  2279  
  2280  		r1, err = ss.Post().Get(o1.Id, false)
  2281  		require.Nil(t, err)
  2282  		ro1a := r1.Posts[o1.Id]
  2283  
  2284  		r2, err = ss.Post().Get(o1.Id, false)
  2285  		require.Nil(t, err)
  2286  		ro2a := r2.Posts[o2.Id]
  2287  
  2288  		r3, err = ss.Post().Get(o3.Id, false)
  2289  		require.Nil(t, err)
  2290  		ro3a := r3.Posts[o3.Id]
  2291  
  2292  		assert.Equal(t, ro1a.Message, o1a.Message, "Failed to overwrite/get")
  2293  		assert.Equal(t, ro2a.Message, o2a.Message, "Failed to overwrite/get")
  2294  		assert.Equal(t, ro3a.Message, o3a.Message, "Failed to overwrite/get")
  2295  	})
  2296  
  2297  	t.Run("overwrite clearing filenames", func(t *testing.T) {
  2298  		o4a := ro4.Clone()
  2299  		o4a.Filenames = []string{}
  2300  		o4a.FileIds = []string{model.NewId()}
  2301  		_, err = ss.Post().Overwrite(o4a)
  2302  		require.Nil(t, err)
  2303  
  2304  		r4, err = ss.Post().Get(o4.Id, false)
  2305  		require.Nil(t, err)
  2306  
  2307  		ro4a := r4.Posts[o4.Id]
  2308  		require.Empty(t, ro4a.Filenames, "Failed to clear Filenames")
  2309  		require.Len(t, ro4a.FileIds, 1, "Failed to set FileIds")
  2310  	})
  2311  }
  2312  
  2313  func testPostStoreGetPostsByIds(t *testing.T, ss store.Store) {
  2314  	o1 := &model.Post{}
  2315  	o1.ChannelId = model.NewId()
  2316  	o1.UserId = model.NewId()
  2317  	o1.Message = "zz" + model.NewId() + "AAAAAAAAAAA"
  2318  	o1, err := ss.Post().Save(o1)
  2319  	require.Nil(t, err)
  2320  
  2321  	o2 := &model.Post{}
  2322  	o2.ChannelId = o1.ChannelId
  2323  	o2.UserId = model.NewId()
  2324  	o2.Message = "zz" + model.NewId() + "CCCCCCCCC"
  2325  	o2, err = ss.Post().Save(o2)
  2326  	require.Nil(t, err)
  2327  
  2328  	o3 := &model.Post{}
  2329  	o3.ChannelId = o1.ChannelId
  2330  	o3.UserId = model.NewId()
  2331  	o3.Message = "zz" + model.NewId() + "QQQQQQQQQQ"
  2332  	o3, err = ss.Post().Save(o3)
  2333  	require.Nil(t, err)
  2334  
  2335  	r1, err := ss.Post().Get(o1.Id, false)
  2336  	require.Nil(t, err)
  2337  	ro1 := r1.Posts[o1.Id]
  2338  
  2339  	r2, err := ss.Post().Get(o2.Id, false)
  2340  	require.Nil(t, err)
  2341  	ro2 := r2.Posts[o2.Id]
  2342  
  2343  	r3, err := ss.Post().Get(o3.Id, false)
  2344  	require.Nil(t, err)
  2345  	ro3 := r3.Posts[o3.Id]
  2346  
  2347  	postIds := []string{
  2348  		ro1.Id,
  2349  		ro2.Id,
  2350  		ro3.Id,
  2351  	}
  2352  
  2353  	posts, err := ss.Post().GetPostsByIds(postIds)
  2354  	require.Nil(t, err)
  2355  	require.Len(t, posts, 3, "Expected 3 posts in results. Got %v", len(posts))
  2356  
  2357  	err = ss.Post().Delete(ro1.Id, model.GetMillis(), "")
  2358  	require.Nil(t, err)
  2359  
  2360  	posts, err = ss.Post().GetPostsByIds(postIds)
  2361  	require.Nil(t, err)
  2362  	require.Len(t, posts, 3, "Expected 3 posts in results. Got %v", len(posts))
  2363  }
  2364  
  2365  func testPostStoreGetPostsBatchForIndexing(t *testing.T, ss store.Store) {
  2366  	c1 := &model.Channel{}
  2367  	c1.TeamId = model.NewId()
  2368  	c1.DisplayName = "Channel1"
  2369  	c1.Name = "zz" + model.NewId() + "b"
  2370  	c1.Type = model.CHANNEL_OPEN
  2371  	c1, _ = ss.Channel().Save(c1, -1)
  2372  
  2373  	c2 := &model.Channel{}
  2374  	c2.TeamId = model.NewId()
  2375  	c2.DisplayName = "Channel2"
  2376  	c2.Name = "zz" + model.NewId() + "b"
  2377  	c2.Type = model.CHANNEL_OPEN
  2378  	c2, _ = ss.Channel().Save(c2, -1)
  2379  
  2380  	o1 := &model.Post{}
  2381  	o1.ChannelId = c1.Id
  2382  	o1.UserId = model.NewId()
  2383  	o1.Message = "zz" + model.NewId() + "AAAAAAAAAAA"
  2384  	o1, err := ss.Post().Save(o1)
  2385  	require.Nil(t, err)
  2386  
  2387  	o2 := &model.Post{}
  2388  	o2.ChannelId = c2.Id
  2389  	o2.UserId = model.NewId()
  2390  	o2.Message = "zz" + model.NewId() + "CCCCCCCCC"
  2391  	o2, err = ss.Post().Save(o2)
  2392  	require.Nil(t, err)
  2393  
  2394  	o3 := &model.Post{}
  2395  	o3.ChannelId = c1.Id
  2396  	o3.UserId = model.NewId()
  2397  	o3.ParentId = o1.Id
  2398  	o3.RootId = o1.Id
  2399  	o3.Message = "zz" + model.NewId() + "QQQQQQQQQQ"
  2400  	o3, err = ss.Post().Save(o3)
  2401  	require.Nil(t, err)
  2402  
  2403  	r, err := ss.Post().GetPostsBatchForIndexing(o1.CreateAt, model.GetMillis()+100000, 100)
  2404  	require.Nil(t, err)
  2405  	require.Len(t, r, 3, "Expected 3 posts in results. Got %v", len(r))
  2406  	for _, p := range r {
  2407  		if p.Id == o1.Id {
  2408  			require.Equal(t, p.TeamId, c1.TeamId, "Unexpected team ID")
  2409  			require.Nil(t, p.ParentCreateAt, "Unexpected parent create at")
  2410  		} else if p.Id == o2.Id {
  2411  			require.Equal(t, p.TeamId, c2.TeamId, "Unexpected team ID")
  2412  			require.Nil(t, p.ParentCreateAt, "Unexpected parent create at")
  2413  		} else if p.Id == o3.Id {
  2414  			require.Equal(t, p.TeamId, c1.TeamId, "Unexpected team ID")
  2415  			require.Equal(t, *p.ParentCreateAt, o1.CreateAt, "Unexpected parent create at")
  2416  		} else {
  2417  			require.Fail(t, "unexpected post returned")
  2418  		}
  2419  	}
  2420  }
  2421  
  2422  func testPostStorePermanentDeleteBatch(t *testing.T, ss store.Store) {
  2423  	o1 := &model.Post{}
  2424  	o1.ChannelId = model.NewId()
  2425  	o1.UserId = model.NewId()
  2426  	o1.Message = "zz" + model.NewId() + "AAAAAAAAAAA"
  2427  	o1.CreateAt = 1000
  2428  	o1, err := ss.Post().Save(o1)
  2429  	require.Nil(t, err)
  2430  
  2431  	o2 := &model.Post{}
  2432  	o2.ChannelId = model.NewId()
  2433  	o2.UserId = model.NewId()
  2434  	o2.Message = "zz" + model.NewId() + "AAAAAAAAAAA"
  2435  	o2.CreateAt = 1000
  2436  	o2, err = ss.Post().Save(o2)
  2437  	require.Nil(t, err)
  2438  
  2439  	o3 := &model.Post{}
  2440  	o3.ChannelId = model.NewId()
  2441  	o3.UserId = model.NewId()
  2442  	o3.Message = "zz" + model.NewId() + "AAAAAAAAAAA"
  2443  	o3.CreateAt = 100000
  2444  	o3, err = ss.Post().Save(o3)
  2445  	require.Nil(t, err)
  2446  
  2447  	_, err = ss.Post().PermanentDeleteBatch(2000, 1000)
  2448  	require.Nil(t, err)
  2449  
  2450  	_, err = ss.Post().Get(o1.Id, false)
  2451  	require.NotNil(t, err, "Should have not found post 1 after purge")
  2452  
  2453  	_, err = ss.Post().Get(o2.Id, false)
  2454  	require.NotNil(t, err, "Should have not found post 2 after purge")
  2455  
  2456  	_, err = ss.Post().Get(o3.Id, false)
  2457  	require.Nil(t, err, "Should have not found post 3 after purge")
  2458  }
  2459  
  2460  func testPostStoreGetOldest(t *testing.T, ss store.Store) {
  2461  	o0 := &model.Post{}
  2462  	o0.ChannelId = model.NewId()
  2463  	o0.UserId = model.NewId()
  2464  	o0.Message = "zz" + model.NewId() + "b"
  2465  	o0.CreateAt = 3
  2466  	o0, err := ss.Post().Save(o0)
  2467  	require.Nil(t, err)
  2468  
  2469  	o1 := &model.Post{}
  2470  	o1.ChannelId = o0.Id
  2471  	o1.UserId = model.NewId()
  2472  	o1.Message = "zz" + model.NewId() + "b"
  2473  	o1.CreateAt = 2
  2474  	o1, err = ss.Post().Save(o1)
  2475  	require.Nil(t, err)
  2476  
  2477  	o2 := &model.Post{}
  2478  	o2.ChannelId = o1.ChannelId
  2479  	o2.UserId = model.NewId()
  2480  	o2.Message = "zz" + model.NewId() + "b"
  2481  	o2.CreateAt = 1
  2482  	o2, err = ss.Post().Save(o2)
  2483  	require.Nil(t, err)
  2484  
  2485  	r1, err := ss.Post().GetOldest()
  2486  
  2487  	require.Nil(t, err)
  2488  	assert.EqualValues(t, o2.Id, r1.Id)
  2489  }
  2490  
  2491  func testGetMaxPostSize(t *testing.T, ss store.Store) {
  2492  	assert.Equal(t, model.POST_MESSAGE_MAX_RUNES_V2, ss.Post().GetMaxPostSize())
  2493  	assert.Equal(t, model.POST_MESSAGE_MAX_RUNES_V2, ss.Post().GetMaxPostSize())
  2494  }
  2495  
  2496  func testPostStoreGetParentsForExportAfter(t *testing.T, ss store.Store) {
  2497  	t1 := model.Team{}
  2498  	t1.DisplayName = "Name"
  2499  	t1.Name = "zz" + model.NewId()
  2500  	t1.Email = MakeEmail()
  2501  	t1.Type = model.TEAM_OPEN
  2502  	_, err := ss.Team().Save(&t1)
  2503  	require.Nil(t, err)
  2504  
  2505  	c1 := model.Channel{}
  2506  	c1.TeamId = t1.Id
  2507  	c1.DisplayName = "Channel1"
  2508  	c1.Name = "zz" + model.NewId() + "b"
  2509  	c1.Type = model.CHANNEL_OPEN
  2510  	_, nErr := ss.Channel().Save(&c1, -1)
  2511  	require.Nil(t, nErr)
  2512  
  2513  	u1 := model.User{}
  2514  	u1.Username = model.NewId()
  2515  	u1.Email = MakeEmail()
  2516  	u1.Nickname = model.NewId()
  2517  	_, err = ss.User().Save(&u1)
  2518  	require.Nil(t, err)
  2519  
  2520  	p1 := &model.Post{}
  2521  	p1.ChannelId = c1.Id
  2522  	p1.UserId = u1.Id
  2523  	p1.Message = "zz" + model.NewId() + "AAAAAAAAAAA"
  2524  	p1.CreateAt = 1000
  2525  	p1, err = ss.Post().Save(p1)
  2526  	require.Nil(t, err)
  2527  
  2528  	posts, err := ss.Post().GetParentsForExportAfter(10000, strings.Repeat("0", 26))
  2529  	assert.Nil(t, err)
  2530  
  2531  	found := false
  2532  	for _, p := range posts {
  2533  		if p.Id == p1.Id {
  2534  			found = true
  2535  			assert.Equal(t, p.Id, p1.Id)
  2536  			assert.Equal(t, p.Message, p1.Message)
  2537  			assert.Equal(t, p.Username, u1.Username)
  2538  			assert.Equal(t, p.TeamName, t1.Name)
  2539  			assert.Equal(t, p.ChannelName, c1.Name)
  2540  		}
  2541  	}
  2542  	assert.True(t, found)
  2543  }
  2544  
  2545  func testPostStoreGetRepliesForExport(t *testing.T, ss store.Store) {
  2546  	t1 := model.Team{}
  2547  	t1.DisplayName = "Name"
  2548  	t1.Name = "zz" + model.NewId()
  2549  	t1.Email = MakeEmail()
  2550  	t1.Type = model.TEAM_OPEN
  2551  	_, err := ss.Team().Save(&t1)
  2552  	require.Nil(t, err)
  2553  
  2554  	c1 := model.Channel{}
  2555  	c1.TeamId = t1.Id
  2556  	c1.DisplayName = "Channel1"
  2557  	c1.Name = "zz" + model.NewId() + "b"
  2558  	c1.Type = model.CHANNEL_OPEN
  2559  	_, nErr := ss.Channel().Save(&c1, -1)
  2560  	require.Nil(t, nErr)
  2561  
  2562  	u1 := model.User{}
  2563  	u1.Email = MakeEmail()
  2564  	u1.Nickname = model.NewId()
  2565  	_, err = ss.User().Save(&u1)
  2566  	require.Nil(t, err)
  2567  
  2568  	p1 := &model.Post{}
  2569  	p1.ChannelId = c1.Id
  2570  	p1.UserId = u1.Id
  2571  	p1.Message = "zz" + model.NewId() + "AAAAAAAAAAA"
  2572  	p1.CreateAt = 1000
  2573  	p1, err = ss.Post().Save(p1)
  2574  	require.Nil(t, err)
  2575  
  2576  	p2 := &model.Post{}
  2577  	p2.ChannelId = c1.Id
  2578  	p2.UserId = u1.Id
  2579  	p2.Message = "zz" + model.NewId() + "AAAAAAAAAAA"
  2580  	p2.CreateAt = 1001
  2581  	p2.ParentId = p1.Id
  2582  	p2.RootId = p1.Id
  2583  	p2, err = ss.Post().Save(p2)
  2584  	require.Nil(t, err)
  2585  
  2586  	r1, err := ss.Post().GetRepliesForExport(p1.Id)
  2587  	assert.Nil(t, err)
  2588  
  2589  	assert.Len(t, r1, 1)
  2590  
  2591  	reply1 := r1[0]
  2592  	assert.Equal(t, reply1.Id, p2.Id)
  2593  	assert.Equal(t, reply1.Message, p2.Message)
  2594  	assert.Equal(t, reply1.Username, u1.Username)
  2595  
  2596  	// Checking whether replies by deleted user are exported
  2597  	u1.DeleteAt = 1002
  2598  	_, err = ss.User().Update(&u1, false)
  2599  	require.Nil(t, err)
  2600  
  2601  	r1, err = ss.Post().GetRepliesForExport(p1.Id)
  2602  	assert.Nil(t, err)
  2603  
  2604  	assert.Len(t, r1, 1)
  2605  
  2606  	reply1 = r1[0]
  2607  	assert.Equal(t, reply1.Id, p2.Id)
  2608  	assert.Equal(t, reply1.Message, p2.Message)
  2609  	assert.Equal(t, reply1.Username, u1.Username)
  2610  
  2611  }
  2612  
  2613  func testPostStoreGetDirectPostParentsForExportAfter(t *testing.T, ss store.Store, s SqlSupplier) {
  2614  	teamId := model.NewId()
  2615  
  2616  	o1 := model.Channel{}
  2617  	o1.TeamId = teamId
  2618  	o1.DisplayName = "Name"
  2619  	o1.Name = "zz" + model.NewId() + "b"
  2620  	o1.Type = model.CHANNEL_DIRECT
  2621  
  2622  	u1 := &model.User{}
  2623  	u1.Email = MakeEmail()
  2624  	u1.Nickname = model.NewId()
  2625  	_, err := ss.User().Save(u1)
  2626  	require.Nil(t, err)
  2627  	_, err = ss.Team().SaveMember(&model.TeamMember{TeamId: model.NewId(), UserId: u1.Id}, -1)
  2628  	require.Nil(t, err)
  2629  
  2630  	u2 := &model.User{}
  2631  	u2.Email = MakeEmail()
  2632  	u2.Nickname = model.NewId()
  2633  	_, err = ss.User().Save(u2)
  2634  	require.Nil(t, err)
  2635  	_, err = ss.Team().SaveMember(&model.TeamMember{TeamId: model.NewId(), UserId: u2.Id}, -1)
  2636  	require.Nil(t, err)
  2637  
  2638  	m1 := model.ChannelMember{}
  2639  	m1.ChannelId = o1.Id
  2640  	m1.UserId = u1.Id
  2641  	m1.NotifyProps = model.GetDefaultChannelNotifyProps()
  2642  
  2643  	m2 := model.ChannelMember{}
  2644  	m2.ChannelId = o1.Id
  2645  	m2.UserId = u2.Id
  2646  	m2.NotifyProps = model.GetDefaultChannelNotifyProps()
  2647  
  2648  	ss.Channel().SaveDirectChannel(&o1, &m1, &m2)
  2649  
  2650  	p1 := &model.Post{}
  2651  	p1.ChannelId = o1.Id
  2652  	p1.UserId = u1.Id
  2653  	p1.Message = "zz" + model.NewId() + "AAAAAAAAAAA"
  2654  	p1.CreateAt = 1000
  2655  	p1, err = ss.Post().Save(p1)
  2656  	require.Nil(t, err)
  2657  
  2658  	r1, err := ss.Post().GetDirectPostParentsForExportAfter(10000, strings.Repeat("0", 26))
  2659  	assert.Nil(t, err)
  2660  
  2661  	assert.Equal(t, p1.Message, r1[0].Message)
  2662  
  2663  	// Manually truncate Channels table until testlib can handle cleanups
  2664  	s.GetMaster().Exec("TRUNCATE Channels")
  2665  }
  2666  
  2667  func testPostStoreGetDirectPostParentsForExportAfterDeleted(t *testing.T, ss store.Store, s SqlSupplier) {
  2668  	teamId := model.NewId()
  2669  
  2670  	o1 := model.Channel{}
  2671  	o1.TeamId = teamId
  2672  	o1.DisplayName = "Name"
  2673  	o1.Name = "zz" + model.NewId() + "b"
  2674  	o1.Type = model.CHANNEL_DIRECT
  2675  
  2676  	u1 := &model.User{}
  2677  	u1.DeleteAt = 1
  2678  	u1.Email = MakeEmail()
  2679  	u1.Nickname = model.NewId()
  2680  	_, err := ss.User().Save(u1)
  2681  	require.Nil(t, err)
  2682  	_, err = ss.Team().SaveMember(&model.TeamMember{TeamId: model.NewId(), UserId: u1.Id}, -1)
  2683  	require.Nil(t, err)
  2684  
  2685  	u2 := &model.User{}
  2686  	u2.DeleteAt = 1
  2687  	u2.Email = MakeEmail()
  2688  	u2.Nickname = model.NewId()
  2689  	_, err = ss.User().Save(u2)
  2690  	require.Nil(t, err)
  2691  	_, err = ss.Team().SaveMember(&model.TeamMember{TeamId: model.NewId(), UserId: u2.Id}, -1)
  2692  	require.Nil(t, err)
  2693  
  2694  	m1 := model.ChannelMember{}
  2695  	m1.ChannelId = o1.Id
  2696  	m1.UserId = u1.Id
  2697  	m1.NotifyProps = model.GetDefaultChannelNotifyProps()
  2698  
  2699  	m2 := model.ChannelMember{}
  2700  	m2.ChannelId = o1.Id
  2701  	m2.UserId = u2.Id
  2702  	m2.NotifyProps = model.GetDefaultChannelNotifyProps()
  2703  
  2704  	ss.Channel().SaveDirectChannel(&o1, &m1, &m2)
  2705  
  2706  	o1.DeleteAt = 1
  2707  	nErr := ss.Channel().SetDeleteAt(o1.Id, 1, 1)
  2708  	assert.Nil(t, nErr)
  2709  
  2710  	p1 := &model.Post{}
  2711  	p1.ChannelId = o1.Id
  2712  	p1.UserId = u1.Id
  2713  	p1.Message = "zz" + model.NewId() + "BBBBBBBBBBBB"
  2714  	p1.CreateAt = 1000
  2715  	p1, err = ss.Post().Save(p1)
  2716  	require.Nil(t, err)
  2717  
  2718  	o1a := p1.Clone()
  2719  	o1a.DeleteAt = 1
  2720  	o1a.Message = p1.Message + "BBBBBBBBBB"
  2721  	_, err = ss.Post().Update(o1a, p1)
  2722  	require.Nil(t, err)
  2723  
  2724  	r1, err := ss.Post().GetDirectPostParentsForExportAfter(10000, strings.Repeat("0", 26))
  2725  	assert.Nil(t, err)
  2726  
  2727  	assert.Equal(t, 0, len(r1))
  2728  
  2729  	// Manually truncate Channels table until testlib can handle cleanups
  2730  	s.GetMaster().Exec("TRUNCATE Channels")
  2731  }
  2732  
  2733  func testPostStoreGetDirectPostParentsForExportAfterBatched(t *testing.T, ss store.Store, s SqlSupplier) {
  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  	var postIds []string
  2743  	for i := 0; i < 150; i++ {
  2744  		u1 := &model.User{}
  2745  		u1.Email = MakeEmail()
  2746  		u1.Nickname = model.NewId()
  2747  		_, err := ss.User().Save(u1)
  2748  		require.Nil(t, err)
  2749  		_, err = ss.Team().SaveMember(&model.TeamMember{TeamId: model.NewId(), UserId: u1.Id}, -1)
  2750  		require.Nil(t, err)
  2751  
  2752  		u2 := &model.User{}
  2753  		u2.Email = MakeEmail()
  2754  		u2.Nickname = model.NewId()
  2755  		_, err = ss.User().Save(u2)
  2756  		require.Nil(t, err)
  2757  		_, err = ss.Team().SaveMember(&model.TeamMember{TeamId: model.NewId(), UserId: u2.Id}, -1)
  2758  		require.Nil(t, err)
  2759  
  2760  		m1 := model.ChannelMember{}
  2761  		m1.ChannelId = o1.Id
  2762  		m1.UserId = u1.Id
  2763  		m1.NotifyProps = model.GetDefaultChannelNotifyProps()
  2764  
  2765  		m2 := model.ChannelMember{}
  2766  		m2.ChannelId = o1.Id
  2767  		m2.UserId = u2.Id
  2768  		m2.NotifyProps = model.GetDefaultChannelNotifyProps()
  2769  
  2770  		ss.Channel().SaveDirectChannel(&o1, &m1, &m2)
  2771  
  2772  		p1 := &model.Post{}
  2773  		p1.ChannelId = o1.Id
  2774  		p1.UserId = u1.Id
  2775  		p1.Message = "zz" + model.NewId() + "AAAAAAAAAAA"
  2776  		p1.CreateAt = 1000
  2777  		p1, err = ss.Post().Save(p1)
  2778  		require.Nil(t, err)
  2779  		postIds = append(postIds, p1.Id)
  2780  	}
  2781  	sort.Slice(postIds, func(i, j int) bool { return postIds[i] < postIds[j] })
  2782  
  2783  	// Get all posts
  2784  	r1, err := ss.Post().GetDirectPostParentsForExportAfter(10000, strings.Repeat("0", 26))
  2785  	assert.Nil(t, err)
  2786  	assert.Equal(t, len(postIds), len(r1))
  2787  	var exportedPostIds []string
  2788  	for i := range r1 {
  2789  		exportedPostIds = append(exportedPostIds, r1[i].Id)
  2790  	}
  2791  	sort.Slice(exportedPostIds, func(i, j int) bool { return exportedPostIds[i] < exportedPostIds[j] })
  2792  	assert.ElementsMatch(t, postIds, exportedPostIds)
  2793  
  2794  	// Get 100
  2795  	r1, err = ss.Post().GetDirectPostParentsForExportAfter(100, strings.Repeat("0", 26))
  2796  	assert.Nil(t, err)
  2797  	assert.Equal(t, 100, len(r1))
  2798  	exportedPostIds = []string{}
  2799  	for i := range r1 {
  2800  		exportedPostIds = append(exportedPostIds, r1[i].Id)
  2801  	}
  2802  	sort.Slice(exportedPostIds, func(i, j int) bool { return exportedPostIds[i] < exportedPostIds[j] })
  2803  	assert.ElementsMatch(t, postIds[:100], exportedPostIds)
  2804  
  2805  	// Manually truncate Channels table until testlib can handle cleanups
  2806  	s.GetMaster().Exec("TRUNCATE Channels")
  2807  }