github.com/masterhung0112/hk_server/v5@v5.0.0-20220302090640-ec71aef15e1c/store/storetest/post_store_test.go (about)

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