github.com/nhannv/mattermost-server@v5.11.1+incompatible/store/storetest/post_store.go (about)

     1  // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
     2  // See License.txt for license information.
     3  
     4  package storetest
     5  
     6  import (
     7  	"fmt"
     8  	"sort"
     9  	"strings"
    10  	"testing"
    11  	"time"
    12  
    13  	"github.com/mattermost/mattermost-server/model"
    14  	"github.com/mattermost/mattermost-server/store"
    15  	"github.com/mattermost/mattermost-server/utils"
    16  	"github.com/stretchr/testify/assert"
    17  	"github.com/stretchr/testify/require"
    18  )
    19  
    20  func TestPostStore(t *testing.T, ss store.Store, s SqlSupplier) {
    21  	t.Run("Save", func(t *testing.T) { testPostStoreSave(t, ss) })
    22  	t.Run("SaveAndUpdateChannelMsgCounts", func(t *testing.T) { testPostStoreSaveChannelMsgCounts(t, ss) })
    23  	t.Run("Get", func(t *testing.T) { testPostStoreGet(t, ss) })
    24  	t.Run("GetSingle", func(t *testing.T) { testPostStoreGetSingle(t, ss) })
    25  	t.Run("GetEtagCache", func(t *testing.T) { testGetEtagCache(t, ss) })
    26  	t.Run("Update", func(t *testing.T) { testPostStoreUpdate(t, ss) })
    27  	t.Run("Delete", func(t *testing.T) { testPostStoreDelete(t, ss) })
    28  	t.Run("Delete1Level", func(t *testing.T) { testPostStoreDelete1Level(t, ss) })
    29  	t.Run("Delete2Level", func(t *testing.T) { testPostStoreDelete2Level(t, ss) })
    30  	t.Run("PermDelete1Level", func(t *testing.T) { testPostStorePermDelete1Level(t, ss) })
    31  	t.Run("PermDelete1Level2", func(t *testing.T) { testPostStorePermDelete1Level2(t, ss) })
    32  	t.Run("GetWithChildren", func(t *testing.T) { testPostStoreGetWithChildren(t, ss) })
    33  	t.Run("GetPostsWithDetails", func(t *testing.T) { testPostStoreGetPostsWithDetails(t, ss) })
    34  	t.Run("GetPostsBeforeAfter", func(t *testing.T) { testPostStoreGetPostsBeforeAfter(t, ss) })
    35  	t.Run("GetPostsSince", func(t *testing.T) { testPostStoreGetPostsSince(t, ss) })
    36  	t.Run("Search", func(t *testing.T) { testPostStoreSearch(t, ss) })
    37  	t.Run("UserCountsWithPostsByDay", func(t *testing.T) { testUserCountsWithPostsByDay(t, ss) })
    38  	t.Run("PostCountsByDay", func(t *testing.T) { testPostCountsByDay(t, ss) })
    39  	t.Run("GetFlaggedPostsForTeam", func(t *testing.T) { testPostStoreGetFlaggedPostsForTeam(t, ss, s) })
    40  	t.Run("GetFlaggedPosts", func(t *testing.T) { testPostStoreGetFlaggedPosts(t, ss) })
    41  	t.Run("GetFlaggedPostsForChannel", func(t *testing.T) { testPostStoreGetFlaggedPostsForChannel(t, ss) })
    42  	t.Run("GetPostsCreatedAt", func(t *testing.T) { testPostStoreGetPostsCreatedAt(t, ss) })
    43  	t.Run("Overwrite", func(t *testing.T) { testPostStoreOverwrite(t, ss) })
    44  	t.Run("GetPostsByIds", func(t *testing.T) { testPostStoreGetPostsByIds(t, ss) })
    45  	t.Run("GetPostsBatchForIndexing", func(t *testing.T) { testPostStoreGetPostsBatchForIndexing(t, ss) })
    46  	t.Run("PermanentDeleteBatch", func(t *testing.T) { testPostStorePermanentDeleteBatch(t, ss) })
    47  	t.Run("GetOldest", func(t *testing.T) { testPostStoreGetOldest(t, ss) })
    48  	t.Run("TestGetMaxPostSize", func(t *testing.T) { testGetMaxPostSize(t, ss) })
    49  	t.Run("GetParentsForExportAfter", func(t *testing.T) { testPostStoreGetParentsForExportAfter(t, ss) })
    50  	t.Run("GetRepliesForExport", func(t *testing.T) { testPostStoreGetRepliesForExport(t, ss) })
    51  	t.Run("GetDirectPostParentsForExportAfter", func(t *testing.T) { testPostStoreGetDirectPostParentsForExportAfter(t, ss, s) })
    52  	t.Run("GetDirectPostParentsForExportAfterDeleted", func(t *testing.T) { testPostStoreGetDirectPostParentsForExportAfterDeleted(t, ss, s) })
    53  	t.Run("GetDirectPostParentsForExportAfterBatched", func(t *testing.T) { testPostStoreGetDirectPostParentsForExportAfterBatched(t, ss, s) })
    54  }
    55  
    56  func testPostStoreSave(t *testing.T, ss store.Store) {
    57  	o1 := model.Post{}
    58  	o1.ChannelId = model.NewId()
    59  	o1.UserId = model.NewId()
    60  	o1.Message = "zz" + model.NewId() + "b"
    61  
    62  	if err := (<-ss.Post().Save(&o1)).Err; err != nil {
    63  		t.Fatal("couldn't save item", err)
    64  	}
    65  
    66  	if err := (<-ss.Post().Save(&o1)).Err; err == nil {
    67  		t.Fatal("shouldn't be able to update from save")
    68  	}
    69  }
    70  
    71  func testPostStoreSaveChannelMsgCounts(t *testing.T, ss store.Store) {
    72  	c1 := &model.Channel{Name: model.NewId(), DisplayName: "posttestchannel", Type: model.CHANNEL_OPEN}
    73  	res := <-ss.Channel().Save(c1, 1000000)
    74  	require.Nil(t, res.Err)
    75  
    76  	o1 := model.Post{}
    77  	o1.ChannelId = c1.Id
    78  	o1.UserId = model.NewId()
    79  	o1.Message = "zz" + model.NewId() + "b"
    80  
    81  	require.Nil(t, (<-ss.Post().Save(&o1)).Err)
    82  
    83  	res = <-ss.Channel().Get(c1.Id, false)
    84  	require.Nil(t, res.Err)
    85  	c1 = res.Data.(*model.Channel)
    86  	assert.Equal(t, int64(1), c1.TotalMsgCount, "Message count should update by 1")
    87  
    88  	o1.Id = ""
    89  	o1.Type = model.POST_ADD_TO_TEAM
    90  	require.Nil(t, (<-ss.Post().Save(&o1)).Err)
    91  
    92  	o1.Id = ""
    93  	o1.Type = model.POST_REMOVE_FROM_TEAM
    94  	require.Nil(t, (<-ss.Post().Save(&o1)).Err)
    95  
    96  	res = <-ss.Channel().Get(c1.Id, false)
    97  	require.Nil(t, res.Err)
    98  	c1 = res.Data.(*model.Channel)
    99  	assert.Equal(t, int64(1), c1.TotalMsgCount, "Message count should not update for team add/removed message")
   100  
   101  	oldLastPostAt := c1.LastPostAt
   102  
   103  	o2 := model.Post{}
   104  	o2.ChannelId = c1.Id
   105  	o2.UserId = model.NewId()
   106  	o2.Message = "zz" + model.NewId() + "b"
   107  	o2.CreateAt = int64(7)
   108  	require.Nil(t, (<-ss.Post().Save(&o2)).Err)
   109  
   110  	res = <-ss.Channel().Get(c1.Id, false)
   111  	require.Nil(t, res.Err)
   112  	c1 = res.Data.(*model.Channel)
   113  	assert.Equal(t, oldLastPostAt, c1.LastPostAt, "LastPostAt should not update for old message save")
   114  }
   115  
   116  func testPostStoreGet(t *testing.T, ss store.Store) {
   117  	o1 := &model.Post{}
   118  	o1.ChannelId = model.NewId()
   119  	o1.UserId = model.NewId()
   120  	o1.Message = "zz" + model.NewId() + "b"
   121  
   122  	etag1 := (<-ss.Post().GetEtag(o1.ChannelId, false)).Data.(string)
   123  	if strings.Index(etag1, model.CurrentVersion+".") != 0 {
   124  		t.Fatal("Invalid Etag")
   125  	}
   126  
   127  	o1 = (<-ss.Post().Save(o1)).Data.(*model.Post)
   128  
   129  	etag2 := (<-ss.Post().GetEtag(o1.ChannelId, false)).Data.(string)
   130  	if strings.Index(etag2, fmt.Sprintf("%v.%v", model.CurrentVersion, o1.UpdateAt)) != 0 {
   131  		t.Fatal("Invalid Etag")
   132  	}
   133  
   134  	if r1 := <-ss.Post().Get(o1.Id); r1.Err != nil {
   135  		t.Fatal(r1.Err)
   136  	} else {
   137  		if r1.Data.(*model.PostList).Posts[o1.Id].CreateAt != o1.CreateAt {
   138  			t.Fatal("invalid returned post")
   139  		}
   140  	}
   141  
   142  	if err := (<-ss.Post().Get("123")).Err; err == nil {
   143  		t.Fatal("Missing id should have failed")
   144  	}
   145  
   146  	if err := (<-ss.Post().Get("")).Err; err == nil {
   147  		t.Fatal("should fail for blank post ids")
   148  	}
   149  }
   150  
   151  func testPostStoreGetSingle(t *testing.T, ss store.Store) {
   152  	o1 := &model.Post{}
   153  	o1.ChannelId = model.NewId()
   154  	o1.UserId = model.NewId()
   155  	o1.Message = "zz" + model.NewId() + "b"
   156  
   157  	o1 = (<-ss.Post().Save(o1)).Data.(*model.Post)
   158  
   159  	if r1 := <-ss.Post().GetSingle(o1.Id); r1.Err != nil {
   160  		t.Fatal(r1.Err)
   161  	} else {
   162  		if r1.Data.(*model.Post).CreateAt != o1.CreateAt {
   163  			t.Fatal("invalid returned post")
   164  		}
   165  	}
   166  
   167  	if err := (<-ss.Post().GetSingle("123")).Err; err == nil {
   168  		t.Fatal("Missing id should have failed")
   169  	}
   170  }
   171  
   172  func testGetEtagCache(t *testing.T, ss store.Store) {
   173  	o1 := &model.Post{}
   174  	o1.ChannelId = model.NewId()
   175  	o1.UserId = model.NewId()
   176  	o1.Message = "zz" + model.NewId() + "b"
   177  
   178  	etag1 := (<-ss.Post().GetEtag(o1.ChannelId, true)).Data.(string)
   179  	if strings.Index(etag1, model.CurrentVersion+".") != 0 {
   180  		t.Fatal("Invalid Etag")
   181  	}
   182  
   183  	// This one should come from the cache
   184  	etag2 := (<-ss.Post().GetEtag(o1.ChannelId, true)).Data.(string)
   185  	if strings.Index(etag2, model.CurrentVersion+".") != 0 {
   186  		t.Fatal("Invalid Etag")
   187  	}
   188  
   189  	o1 = (<-ss.Post().Save(o1)).Data.(*model.Post)
   190  
   191  	// We have not invalidated the cache so this should be the same as above
   192  	etag3 := (<-ss.Post().GetEtag(o1.ChannelId, true)).Data.(string)
   193  	if strings.Index(etag3, etag2) != 0 {
   194  		t.Fatal("Invalid Etag")
   195  	}
   196  
   197  	ss.Post().InvalidateLastPostTimeCache(o1.ChannelId)
   198  
   199  	// Invalidated cache so we should get a good result
   200  	etag4 := (<-ss.Post().GetEtag(o1.ChannelId, true)).Data.(string)
   201  	if strings.Index(etag4, fmt.Sprintf("%v.%v", model.CurrentVersion, o1.UpdateAt)) != 0 {
   202  		t.Fatal("Invalid Etag")
   203  	}
   204  }
   205  
   206  func testPostStoreUpdate(t *testing.T, ss store.Store) {
   207  	o1 := &model.Post{}
   208  	o1.ChannelId = model.NewId()
   209  	o1.UserId = model.NewId()
   210  	o1.Message = "zz" + model.NewId() + "AAAAAAAAAAA"
   211  	o1 = (<-ss.Post().Save(o1)).Data.(*model.Post)
   212  
   213  	o2 := &model.Post{}
   214  	o2.ChannelId = o1.ChannelId
   215  	o2.UserId = model.NewId()
   216  	o2.Message = "zz" + model.NewId() + "CCCCCCCCC"
   217  	o2.ParentId = o1.Id
   218  	o2.RootId = o1.Id
   219  	o2 = (<-ss.Post().Save(o2)).Data.(*model.Post)
   220  
   221  	o3 := &model.Post{}
   222  	o3.ChannelId = o1.ChannelId
   223  	o3.UserId = model.NewId()
   224  	o3.Message = "zz" + model.NewId() + "QQQQQQQQQQ"
   225  	o3 = (<-ss.Post().Save(o3)).Data.(*model.Post)
   226  
   227  	ro1 := (<-ss.Post().Get(o1.Id)).Data.(*model.PostList).Posts[o1.Id]
   228  	ro2 := (<-ss.Post().Get(o1.Id)).Data.(*model.PostList).Posts[o2.Id]
   229  	ro3 := (<-ss.Post().Get(o3.Id)).Data.(*model.PostList).Posts[o3.Id]
   230  
   231  	if ro1.Message != o1.Message {
   232  		t.Fatal("Failed to save/get")
   233  	}
   234  
   235  	o1a := &model.Post{}
   236  	*o1a = *ro1
   237  	o1a.Message = ro1.Message + "BBBBBBBBBB"
   238  	if result := <-ss.Post().Update(o1a, ro1); result.Err != nil {
   239  		t.Fatal(result.Err)
   240  	}
   241  
   242  	ro1a := (<-ss.Post().Get(o1.Id)).Data.(*model.PostList).Posts[o1.Id]
   243  
   244  	if ro1a.Message != o1a.Message {
   245  		t.Fatal("Failed to update/get")
   246  	}
   247  
   248  	o2a := &model.Post{}
   249  	*o2a = *ro2
   250  	o2a.Message = ro2.Message + "DDDDDDD"
   251  	if result := <-ss.Post().Update(o2a, ro2); result.Err != nil {
   252  		t.Fatal(result.Err)
   253  	}
   254  
   255  	ro2a := (<-ss.Post().Get(o1.Id)).Data.(*model.PostList).Posts[o2.Id]
   256  
   257  	if ro2a.Message != o2a.Message {
   258  		t.Fatal("Failed to update/get")
   259  	}
   260  
   261  	o3a := &model.Post{}
   262  	*o3a = *ro3
   263  	o3a.Message = ro3.Message + "WWWWWWW"
   264  	if result := <-ss.Post().Update(o3a, ro3); result.Err != nil {
   265  		t.Fatal(result.Err)
   266  	}
   267  
   268  	ro3a := (<-ss.Post().Get(o3.Id)).Data.(*model.PostList).Posts[o3.Id]
   269  
   270  	if ro3a.Message != o3a.Message && ro3a.Hashtags != o3a.Hashtags {
   271  		t.Fatal("Failed to update/get")
   272  	}
   273  
   274  	o4 := store.Must(ss.Post().Save(&model.Post{
   275  		ChannelId: model.NewId(),
   276  		UserId:    model.NewId(),
   277  		Message:   model.NewId(),
   278  		Filenames: []string{"test"},
   279  	})).(*model.Post)
   280  
   281  	ro4 := (<-ss.Post().Get(o4.Id)).Data.(*model.PostList).Posts[o4.Id]
   282  
   283  	o4a := &model.Post{}
   284  	*o4a = *ro4
   285  	o4a.Filenames = []string{}
   286  	o4a.FileIds = []string{model.NewId()}
   287  	if result := <-ss.Post().Update(o4a, ro4); result.Err != nil {
   288  		t.Fatal(result.Err)
   289  	}
   290  
   291  	if ro4a := store.Must(ss.Post().Get(o4.Id)).(*model.PostList).Posts[o4.Id]; len(ro4a.Filenames) != 0 {
   292  		t.Fatal("Failed to clear Filenames")
   293  	} else if len(ro4a.FileIds) != 1 {
   294  		t.Fatal("Failed to set FileIds")
   295  	}
   296  }
   297  
   298  func testPostStoreDelete(t *testing.T, ss store.Store) {
   299  	o1 := &model.Post{}
   300  	o1.ChannelId = model.NewId()
   301  	o1.UserId = model.NewId()
   302  	o1.Message = "zz" + model.NewId() + "b"
   303  	deleteByID := model.NewId()
   304  
   305  	etag1 := (<-ss.Post().GetEtag(o1.ChannelId, false)).Data.(string)
   306  	if strings.Index(etag1, model.CurrentVersion+".") != 0 {
   307  		t.Fatal("Invalid Etag")
   308  	}
   309  
   310  	o1 = (<-ss.Post().Save(o1)).Data.(*model.Post)
   311  
   312  	if r1 := <-ss.Post().Get(o1.Id); r1.Err != nil {
   313  		t.Fatal(r1.Err)
   314  	} else {
   315  		if r1.Data.(*model.PostList).Posts[o1.Id].CreateAt != o1.CreateAt {
   316  			t.Fatal("invalid returned post")
   317  		}
   318  	}
   319  
   320  	if r2 := <-ss.Post().Delete(o1.Id, model.GetMillis(), deleteByID); r2.Err != nil {
   321  		t.Fatal(r2.Err)
   322  	}
   323  
   324  	r5 := <-ss.Post().GetPostsCreatedAt(o1.ChannelId, o1.CreateAt)
   325  	post := r5.Data.([]*model.Post)[0]
   326  	actual := post.Props[model.POST_PROPS_DELETE_BY]
   327  	if actual != deleteByID {
   328  		t.Errorf("Expected (*Post).Props[model.POST_PROPS_DELETE_BY] to be %v but got %v.", deleteByID, actual)
   329  	}
   330  
   331  	if r3 := (<-ss.Post().Get(o1.Id)); r3.Err == nil {
   332  		t.Log(r3.Data)
   333  		t.Fatal("Missing id should have failed")
   334  	}
   335  
   336  	etag2 := (<-ss.Post().GetEtag(o1.ChannelId, false)).Data.(string)
   337  	if strings.Index(etag2, model.CurrentVersion+".") != 0 {
   338  		t.Fatal("Invalid Etag")
   339  	}
   340  }
   341  
   342  func testPostStoreDelete1Level(t *testing.T, ss store.Store) {
   343  	o1 := &model.Post{}
   344  	o1.ChannelId = model.NewId()
   345  	o1.UserId = model.NewId()
   346  	o1.Message = "zz" + model.NewId() + "b"
   347  	o1 = (<-ss.Post().Save(o1)).Data.(*model.Post)
   348  
   349  	o2 := &model.Post{}
   350  	o2.ChannelId = o1.ChannelId
   351  	o2.UserId = model.NewId()
   352  	o2.Message = "zz" + model.NewId() + "b"
   353  	o2.ParentId = o1.Id
   354  	o2.RootId = o1.Id
   355  	o2 = (<-ss.Post().Save(o2)).Data.(*model.Post)
   356  
   357  	if r2 := <-ss.Post().Delete(o1.Id, model.GetMillis(), ""); r2.Err != nil {
   358  		t.Fatal(r2.Err)
   359  	}
   360  
   361  	if r3 := (<-ss.Post().Get(o1.Id)); r3.Err == nil {
   362  		t.Fatal("Deleted id should have failed")
   363  	}
   364  
   365  	if r4 := (<-ss.Post().Get(o2.Id)); r4.Err == nil {
   366  		t.Fatal("Deleted id should have failed")
   367  	}
   368  }
   369  
   370  func testPostStoreDelete2Level(t *testing.T, ss store.Store) {
   371  	o1 := &model.Post{}
   372  	o1.ChannelId = model.NewId()
   373  	o1.UserId = model.NewId()
   374  	o1.Message = "zz" + model.NewId() + "b"
   375  	o1 = (<-ss.Post().Save(o1)).Data.(*model.Post)
   376  
   377  	o2 := &model.Post{}
   378  	o2.ChannelId = o1.ChannelId
   379  	o2.UserId = model.NewId()
   380  	o2.Message = "zz" + model.NewId() + "b"
   381  	o2.ParentId = o1.Id
   382  	o2.RootId = o1.Id
   383  	o2 = (<-ss.Post().Save(o2)).Data.(*model.Post)
   384  
   385  	o3 := &model.Post{}
   386  	o3.ChannelId = o1.ChannelId
   387  	o3.UserId = model.NewId()
   388  	o3.Message = "zz" + model.NewId() + "b"
   389  	o3.ParentId = o2.Id
   390  	o3.RootId = o1.Id
   391  	o3 = (<-ss.Post().Save(o3)).Data.(*model.Post)
   392  
   393  	o4 := &model.Post{}
   394  	o4.ChannelId = model.NewId()
   395  	o4.UserId = model.NewId()
   396  	o4.Message = "zz" + model.NewId() + "b"
   397  	o4 = (<-ss.Post().Save(o4)).Data.(*model.Post)
   398  
   399  	if r2 := <-ss.Post().Delete(o1.Id, model.GetMillis(), ""); r2.Err != nil {
   400  		t.Fatal(r2.Err)
   401  	}
   402  
   403  	if r3 := (<-ss.Post().Get(o1.Id)); r3.Err == nil {
   404  		t.Fatal("Deleted id should have failed")
   405  	}
   406  
   407  	if r4 := (<-ss.Post().Get(o2.Id)); r4.Err == nil {
   408  		t.Fatal("Deleted id should have failed")
   409  	}
   410  
   411  	if r5 := (<-ss.Post().Get(o3.Id)); r5.Err == nil {
   412  		t.Fatal("Deleted id should have failed")
   413  	}
   414  
   415  	if r6 := <-ss.Post().Get(o4.Id); r6.Err != nil {
   416  		t.Fatal(r6.Err)
   417  	}
   418  }
   419  
   420  func testPostStorePermDelete1Level(t *testing.T, ss store.Store) {
   421  	o1 := &model.Post{}
   422  	o1.ChannelId = model.NewId()
   423  	o1.UserId = model.NewId()
   424  	o1.Message = "zz" + model.NewId() + "b"
   425  	o1 = (<-ss.Post().Save(o1)).Data.(*model.Post)
   426  
   427  	o2 := &model.Post{}
   428  	o2.ChannelId = o1.ChannelId
   429  	o2.UserId = model.NewId()
   430  	o2.Message = "zz" + model.NewId() + "b"
   431  	o2.ParentId = o1.Id
   432  	o2.RootId = o1.Id
   433  	o2 = (<-ss.Post().Save(o2)).Data.(*model.Post)
   434  
   435  	o3 := &model.Post{}
   436  	o3.ChannelId = model.NewId()
   437  	o3.UserId = model.NewId()
   438  	o3.Message = "zz" + model.NewId() + "b"
   439  	o3 = (<-ss.Post().Save(o3)).Data.(*model.Post)
   440  
   441  	if r2 := <-ss.Post().PermanentDeleteByUser(o2.UserId); r2.Err != nil {
   442  		t.Fatal(r2.Err)
   443  	}
   444  
   445  	if r3 := (<-ss.Post().Get(o1.Id)); r3.Err != nil {
   446  		t.Fatal("Deleted id shouldn't have failed")
   447  	}
   448  
   449  	if r4 := (<-ss.Post().Get(o2.Id)); r4.Err == nil {
   450  		t.Fatal("Deleted id should have failed")
   451  	}
   452  
   453  	if r2 := <-ss.Post().PermanentDeleteByChannel(o3.ChannelId); r2.Err != nil {
   454  		t.Fatal(r2.Err)
   455  	}
   456  
   457  	if r3 := (<-ss.Post().Get(o3.Id)); r3.Err == nil {
   458  		t.Fatal("Deleted id should have failed")
   459  	}
   460  }
   461  
   462  func testPostStorePermDelete1Level2(t *testing.T, ss store.Store) {
   463  	o1 := &model.Post{}
   464  	o1.ChannelId = model.NewId()
   465  	o1.UserId = model.NewId()
   466  	o1.Message = "zz" + model.NewId() + "b"
   467  	o1 = (<-ss.Post().Save(o1)).Data.(*model.Post)
   468  
   469  	o2 := &model.Post{}
   470  	o2.ChannelId = o1.ChannelId
   471  	o2.UserId = model.NewId()
   472  	o2.Message = "zz" + model.NewId() + "b"
   473  	o2.ParentId = o1.Id
   474  	o2.RootId = o1.Id
   475  	o2 = (<-ss.Post().Save(o2)).Data.(*model.Post)
   476  
   477  	o3 := &model.Post{}
   478  	o3.ChannelId = model.NewId()
   479  	o3.UserId = model.NewId()
   480  	o3.Message = "zz" + model.NewId() + "b"
   481  	o3 = (<-ss.Post().Save(o3)).Data.(*model.Post)
   482  
   483  	if r2 := <-ss.Post().PermanentDeleteByUser(o1.UserId); r2.Err != nil {
   484  		t.Fatal(r2.Err)
   485  	}
   486  
   487  	if r3 := (<-ss.Post().Get(o1.Id)); r3.Err == nil {
   488  		t.Fatal("Deleted id should have failed")
   489  	}
   490  
   491  	if r4 := (<-ss.Post().Get(o2.Id)); r4.Err == nil {
   492  		t.Fatal("Deleted id should have failed")
   493  	}
   494  
   495  	if r5 := (<-ss.Post().Get(o3.Id)); r5.Err != nil {
   496  		t.Fatal("Deleted id shouldn't have failed")
   497  	}
   498  }
   499  
   500  func testPostStoreGetWithChildren(t *testing.T, ss store.Store) {
   501  	o1 := &model.Post{}
   502  	o1.ChannelId = model.NewId()
   503  	o1.UserId = model.NewId()
   504  	o1.Message = "zz" + model.NewId() + "b"
   505  	o1 = (<-ss.Post().Save(o1)).Data.(*model.Post)
   506  
   507  	o2 := &model.Post{}
   508  	o2.ChannelId = o1.ChannelId
   509  	o2.UserId = model.NewId()
   510  	o2.Message = "zz" + model.NewId() + "b"
   511  	o2.ParentId = o1.Id
   512  	o2.RootId = o1.Id
   513  	o2 = (<-ss.Post().Save(o2)).Data.(*model.Post)
   514  
   515  	o3 := &model.Post{}
   516  	o3.ChannelId = o1.ChannelId
   517  	o3.UserId = model.NewId()
   518  	o3.Message = "zz" + model.NewId() + "b"
   519  	o3.ParentId = o2.Id
   520  	o3.RootId = o1.Id
   521  	o3 = (<-ss.Post().Save(o3)).Data.(*model.Post)
   522  
   523  	if r1 := <-ss.Post().Get(o1.Id); r1.Err != nil {
   524  		t.Fatal(r1.Err)
   525  	} else {
   526  		pl := r1.Data.(*model.PostList)
   527  		if len(pl.Posts) != 3 {
   528  			t.Fatal("invalid returned post")
   529  		}
   530  	}
   531  
   532  	store.Must(ss.Post().Delete(o3.Id, model.GetMillis(), ""))
   533  
   534  	if r2 := <-ss.Post().Get(o1.Id); r2.Err != nil {
   535  		t.Fatal(r2.Err)
   536  	} else {
   537  		pl := r2.Data.(*model.PostList)
   538  		if len(pl.Posts) != 2 {
   539  			t.Fatal("invalid returned post")
   540  		}
   541  	}
   542  
   543  	store.Must(ss.Post().Delete(o2.Id, model.GetMillis(), ""))
   544  
   545  	if r3 := <-ss.Post().Get(o1.Id); r3.Err != nil {
   546  		t.Fatal(r3.Err)
   547  	} else {
   548  		pl := r3.Data.(*model.PostList)
   549  		if len(pl.Posts) != 1 {
   550  			t.Fatal("invalid returned post")
   551  		}
   552  	}
   553  }
   554  
   555  func testPostStoreGetPostsWithDetails(t *testing.T, ss store.Store) {
   556  	o1 := &model.Post{}
   557  	o1.ChannelId = model.NewId()
   558  	o1.UserId = model.NewId()
   559  	o1.Message = "zz" + model.NewId() + "b"
   560  	o1 = (<-ss.Post().Save(o1)).Data.(*model.Post)
   561  	time.Sleep(2 * time.Millisecond)
   562  
   563  	o2 := &model.Post{}
   564  	o2.ChannelId = o1.ChannelId
   565  	o2.UserId = model.NewId()
   566  	o2.Message = "zz" + model.NewId() + "b"
   567  	o2.ParentId = o1.Id
   568  	o2.RootId = o1.Id
   569  	_ = (<-ss.Post().Save(o2)).Data.(*model.Post)
   570  	time.Sleep(2 * time.Millisecond)
   571  
   572  	o2a := &model.Post{}
   573  	o2a.ChannelId = o1.ChannelId
   574  	o2a.UserId = model.NewId()
   575  	o2a.Message = "zz" + model.NewId() + "b"
   576  	o2a.ParentId = o1.Id
   577  	o2a.RootId = o1.Id
   578  	o2a = (<-ss.Post().Save(o2a)).Data.(*model.Post)
   579  	time.Sleep(2 * time.Millisecond)
   580  
   581  	o3 := &model.Post{}
   582  	o3.ChannelId = o1.ChannelId
   583  	o3.UserId = model.NewId()
   584  	o3.Message = "zz" + model.NewId() + "b"
   585  	o3.ParentId = o1.Id
   586  	o3.RootId = o1.Id
   587  	o3 = (<-ss.Post().Save(o3)).Data.(*model.Post)
   588  	time.Sleep(2 * time.Millisecond)
   589  
   590  	o4 := &model.Post{}
   591  	o4.ChannelId = o1.ChannelId
   592  	o4.UserId = model.NewId()
   593  	o4.Message = "zz" + model.NewId() + "b"
   594  	o4 = (<-ss.Post().Save(o4)).Data.(*model.Post)
   595  	time.Sleep(2 * time.Millisecond)
   596  
   597  	o5 := &model.Post{}
   598  	o5.ChannelId = o1.ChannelId
   599  	o5.UserId = model.NewId()
   600  	o5.Message = "zz" + model.NewId() + "b"
   601  	o5.ParentId = o4.Id
   602  	o5.RootId = o4.Id
   603  	o5 = (<-ss.Post().Save(o5)).Data.(*model.Post)
   604  
   605  	r1 := (<-ss.Post().GetPosts(o1.ChannelId, 0, 4, false)).Data.(*model.PostList)
   606  
   607  	if r1.Order[0] != o5.Id {
   608  		t.Fatal("invalid order")
   609  	}
   610  
   611  	if r1.Order[1] != o4.Id {
   612  		t.Fatal("invalid order")
   613  	}
   614  
   615  	if r1.Order[2] != o3.Id {
   616  		t.Fatal("invalid order")
   617  	}
   618  
   619  	if r1.Order[3] != o2a.Id {
   620  		t.Fatal("invalid order")
   621  	}
   622  
   623  	if len(r1.Posts) != 6 { //the last 4, + o1 (o2a and o3's parent) + o2 (in same thread as o2a and o3)
   624  		t.Fatal("wrong size")
   625  	}
   626  
   627  	if r1.Posts[o1.Id].Message != o1.Message {
   628  		t.Fatal("Missing parent")
   629  	}
   630  
   631  	r2 := (<-ss.Post().GetPosts(o1.ChannelId, 0, 4, true)).Data.(*model.PostList)
   632  
   633  	if r2.Order[0] != o5.Id {
   634  		t.Fatal("invalid order")
   635  	}
   636  
   637  	if r2.Order[1] != o4.Id {
   638  		t.Fatal("invalid order")
   639  	}
   640  
   641  	if r2.Order[2] != o3.Id {
   642  		t.Fatal("invalid order")
   643  	}
   644  
   645  	if r2.Order[3] != o2a.Id {
   646  		t.Fatal("invalid order")
   647  	}
   648  
   649  	if len(r2.Posts) != 6 { //the last 4, + o1 (o2a and o3's parent) + o2 (in same thread as o2a and o3)
   650  		t.Fatal("wrong size")
   651  	}
   652  
   653  	if r2.Posts[o1.Id].Message != o1.Message {
   654  		t.Fatal("Missing parent")
   655  	}
   656  
   657  	// Run once to fill cache
   658  	<-ss.Post().GetPosts(o1.ChannelId, 0, 30, true)
   659  
   660  	o6 := &model.Post{}
   661  	o6.ChannelId = o1.ChannelId
   662  	o6.UserId = model.NewId()
   663  	o6.Message = "zz" + model.NewId() + "b"
   664  	_ = (<-ss.Post().Save(o6)).Data.(*model.Post)
   665  
   666  	// Should only be 6 since we hit the cache
   667  	r3 := (<-ss.Post().GetPosts(o1.ChannelId, 0, 30, true)).Data.(*model.PostList)
   668  	assert.Equal(t, 6, len(r3.Order))
   669  
   670  	ss.Post().InvalidateLastPostTimeCache(o1.ChannelId)
   671  
   672  	// Cache was invalidated, we should get all the posts
   673  	r4 := (<-ss.Post().GetPosts(o1.ChannelId, 0, 30, true)).Data.(*model.PostList)
   674  	assert.Equal(t, 7, len(r4.Order))
   675  }
   676  
   677  func testPostStoreGetPostsBeforeAfter(t *testing.T, ss store.Store) {
   678  	o0 := &model.Post{}
   679  	o0.ChannelId = model.NewId()
   680  	o0.UserId = model.NewId()
   681  	o0.Message = "zz" + model.NewId() + "b"
   682  	_ = (<-ss.Post().Save(o0)).Data.(*model.Post)
   683  	time.Sleep(2 * time.Millisecond)
   684  
   685  	o1 := &model.Post{}
   686  	o1.ChannelId = model.NewId()
   687  	o1.UserId = model.NewId()
   688  	o1.Message = "zz" + model.NewId() + "b"
   689  	o1 = (<-ss.Post().Save(o1)).Data.(*model.Post)
   690  	time.Sleep(2 * time.Millisecond)
   691  
   692  	o2 := &model.Post{}
   693  	o2.ChannelId = o1.ChannelId
   694  	o2.UserId = model.NewId()
   695  	o2.Message = "zz" + model.NewId() + "b"
   696  	o2.ParentId = o1.Id
   697  	o2.RootId = o1.Id
   698  	o2 = (<-ss.Post().Save(o2)).Data.(*model.Post)
   699  	time.Sleep(2 * time.Millisecond)
   700  
   701  	o2a := &model.Post{}
   702  	o2a.ChannelId = o1.ChannelId
   703  	o2a.UserId = model.NewId()
   704  	o2a.Message = "zz" + model.NewId() + "b"
   705  	o2a.ParentId = o1.Id
   706  	o2a.RootId = o1.Id
   707  	o2a = (<-ss.Post().Save(o2a)).Data.(*model.Post)
   708  	time.Sleep(2 * time.Millisecond)
   709  
   710  	o3 := &model.Post{}
   711  	o3.ChannelId = o1.ChannelId
   712  	o3.UserId = model.NewId()
   713  	o3.Message = "zz" + model.NewId() + "b"
   714  	o3.ParentId = o1.Id
   715  	o3.RootId = o1.Id
   716  	o3 = (<-ss.Post().Save(o3)).Data.(*model.Post)
   717  	time.Sleep(2 * time.Millisecond)
   718  
   719  	o4 := &model.Post{}
   720  	o4.ChannelId = o1.ChannelId
   721  	o4.UserId = model.NewId()
   722  	o4.Message = "zz" + model.NewId() + "b"
   723  	o4 = (<-ss.Post().Save(o4)).Data.(*model.Post)
   724  	time.Sleep(2 * time.Millisecond)
   725  
   726  	o5 := &model.Post{}
   727  	o5.ChannelId = o1.ChannelId
   728  	o5.UserId = model.NewId()
   729  	o5.Message = "zz" + model.NewId() + "b"
   730  	o5.ParentId = o4.Id
   731  	o5.RootId = o4.Id
   732  	_ = (<-ss.Post().Save(o5)).Data.(*model.Post)
   733  
   734  	r1 := (<-ss.Post().GetPostsBefore(o1.ChannelId, o1.Id, 4, 0)).Data.(*model.PostList)
   735  
   736  	if len(r1.Posts) != 0 {
   737  		t.Fatal("Wrong size")
   738  	}
   739  
   740  	r2 := (<-ss.Post().GetPostsAfter(o1.ChannelId, o1.Id, 4, 0)).Data.(*model.PostList)
   741  
   742  	if r2.Order[0] != o4.Id {
   743  		t.Fatal("invalid order")
   744  	}
   745  
   746  	if r2.Order[1] != o3.Id {
   747  		t.Fatal("invalid order")
   748  	}
   749  
   750  	if r2.Order[2] != o2a.Id {
   751  		t.Fatal("invalid order")
   752  	}
   753  
   754  	if r2.Order[3] != o2.Id {
   755  		t.Fatal("invalid order")
   756  	}
   757  
   758  	if len(r2.Posts) != 5 {
   759  		t.Fatal("wrong size")
   760  	}
   761  
   762  	r3 := (<-ss.Post().GetPostsBefore(o3.ChannelId, o3.Id, 2, 0)).Data.(*model.PostList)
   763  
   764  	if r3.Order[0] != o2a.Id {
   765  		t.Fatal("invalid order")
   766  	}
   767  
   768  	if r3.Order[1] != o2.Id {
   769  		t.Fatal("invalid order")
   770  	}
   771  
   772  	if len(r3.Posts) != 3 {
   773  		t.Fatal("wrong size")
   774  	}
   775  
   776  	if r3.Posts[o1.Id].Message != o1.Message {
   777  		t.Fatal("Missing parent")
   778  	}
   779  }
   780  
   781  func testPostStoreGetPostsSince(t *testing.T, ss store.Store) {
   782  	o0 := &model.Post{}
   783  	o0.ChannelId = model.NewId()
   784  	o0.UserId = model.NewId()
   785  	o0.Message = "zz" + model.NewId() + "b"
   786  	_ = (<-ss.Post().Save(o0)).Data.(*model.Post)
   787  	time.Sleep(2 * time.Millisecond)
   788  
   789  	o1 := &model.Post{}
   790  	o1.ChannelId = model.NewId()
   791  	o1.UserId = model.NewId()
   792  	o1.Message = "zz" + model.NewId() + "b"
   793  	o1 = (<-ss.Post().Save(o1)).Data.(*model.Post)
   794  	time.Sleep(2 * time.Millisecond)
   795  
   796  	o2 := &model.Post{}
   797  	o2.ChannelId = o1.ChannelId
   798  	o2.UserId = model.NewId()
   799  	o2.Message = "zz" + model.NewId() + "b"
   800  	o2.ParentId = o1.Id
   801  	o2.RootId = o1.Id
   802  	_ = (<-ss.Post().Save(o2)).Data.(*model.Post)
   803  	time.Sleep(2 * time.Millisecond)
   804  
   805  	o2a := &model.Post{}
   806  	o2a.ChannelId = o1.ChannelId
   807  	o2a.UserId = model.NewId()
   808  	o2a.Message = "zz" + model.NewId() + "b"
   809  	o2a.ParentId = o1.Id
   810  	o2a.RootId = o1.Id
   811  	o2a = (<-ss.Post().Save(o2a)).Data.(*model.Post)
   812  	time.Sleep(2 * time.Millisecond)
   813  
   814  	o3 := &model.Post{}
   815  	o3.ChannelId = o1.ChannelId
   816  	o3.UserId = model.NewId()
   817  	o3.Message = "zz" + model.NewId() + "b"
   818  	o3.ParentId = o1.Id
   819  	o3.RootId = o1.Id
   820  	o3 = (<-ss.Post().Save(o3)).Data.(*model.Post)
   821  	time.Sleep(2 * time.Millisecond)
   822  
   823  	o4 := &model.Post{}
   824  	o4.ChannelId = o1.ChannelId
   825  	o4.UserId = model.NewId()
   826  	o4.Message = "zz" + model.NewId() + "b"
   827  	o4 = (<-ss.Post().Save(o4)).Data.(*model.Post)
   828  	time.Sleep(2 * time.Millisecond)
   829  
   830  	o5 := &model.Post{}
   831  	o5.ChannelId = o1.ChannelId
   832  	o5.UserId = model.NewId()
   833  	o5.Message = "zz" + model.NewId() + "b"
   834  	o5.ParentId = o4.Id
   835  	o5.RootId = o4.Id
   836  	o5 = (<-ss.Post().Save(o5)).Data.(*model.Post)
   837  
   838  	r1 := (<-ss.Post().GetPostsSince(o1.ChannelId, o1.CreateAt, false)).Data.(*model.PostList)
   839  
   840  	if r1.Order[0] != o5.Id {
   841  		t.Fatal("invalid order")
   842  	}
   843  
   844  	if r1.Order[1] != o4.Id {
   845  		t.Fatal("invalid order")
   846  	}
   847  
   848  	if r1.Order[2] != o3.Id {
   849  		t.Fatal("invalid order")
   850  	}
   851  
   852  	if r1.Order[3] != o2a.Id {
   853  		t.Fatal("invalid order")
   854  	}
   855  
   856  	if len(r1.Posts) != 6 {
   857  		t.Fatal("wrong size")
   858  	}
   859  
   860  	if r1.Posts[o1.Id].Message != o1.Message {
   861  		t.Fatal("Missing parent")
   862  	}
   863  
   864  	r2 := (<-ss.Post().GetPostsSince(o1.ChannelId, o5.UpdateAt, true)).Data.(*model.PostList)
   865  
   866  	if len(r2.Order) != 0 {
   867  		t.Fatal("wrong size ", len(r2.Posts))
   868  	}
   869  }
   870  
   871  func testPostStoreSearch(t *testing.T, ss store.Store) {
   872  	teamId := model.NewId()
   873  	userId := model.NewId()
   874  
   875  	c1 := &model.Channel{}
   876  	c1.TeamId = teamId
   877  	c1.DisplayName = "Channel1"
   878  	c1.Name = "zz" + model.NewId() + "b"
   879  	c1.Type = model.CHANNEL_OPEN
   880  	c1 = (<-ss.Channel().Save(c1, -1)).Data.(*model.Channel)
   881  
   882  	m1 := model.ChannelMember{}
   883  	m1.ChannelId = c1.Id
   884  	m1.UserId = userId
   885  	m1.NotifyProps = model.GetDefaultChannelNotifyProps()
   886  	store.Must(ss.Channel().SaveMember(&m1))
   887  
   888  	c2 := &model.Channel{}
   889  	c2.TeamId = teamId
   890  	c2.DisplayName = "Channel1"
   891  	c2.Name = "zz" + model.NewId() + "b"
   892  	c2.Type = model.CHANNEL_OPEN
   893  	c2 = (<-ss.Channel().Save(c2, -1)).Data.(*model.Channel)
   894  
   895  	c3 := &model.Channel{}
   896  	c3.TeamId = teamId
   897  	c3.DisplayName = "Channel1"
   898  	c3.Name = "zz" + model.NewId() + "b"
   899  	c3.Type = model.CHANNEL_OPEN
   900  	c3 = (<-ss.Channel().Save(c3, -1)).Data.(*model.Channel)
   901  	<-ss.Channel().Delete(c3.Id, model.GetMillis())
   902  
   903  	m3 := model.ChannelMember{}
   904  	m3.ChannelId = c3.Id
   905  	m3.UserId = userId
   906  	m3.NotifyProps = model.GetDefaultChannelNotifyProps()
   907  	store.Must(ss.Channel().SaveMember(&m3))
   908  
   909  	o1 := &model.Post{}
   910  	o1.ChannelId = c1.Id
   911  	o1.UserId = model.NewId()
   912  	o1.Message = "corey mattermost new york"
   913  	o1 = (<-ss.Post().Save(o1)).Data.(*model.Post)
   914  
   915  	o1a := &model.Post{}
   916  	o1a.ChannelId = c1.Id
   917  	o1a.UserId = model.NewId()
   918  	o1a.Message = "corey mattermost new york"
   919  	o1a.Type = model.POST_JOIN_CHANNEL
   920  	_ = (<-ss.Post().Save(o1a)).Data.(*model.Post)
   921  
   922  	o2 := &model.Post{}
   923  	o2.ChannelId = c1.Id
   924  	o2.UserId = model.NewId()
   925  	o2.Message = "New Jersey is where John is from"
   926  	o2 = (<-ss.Post().Save(o2)).Data.(*model.Post)
   927  
   928  	o3 := &model.Post{}
   929  	o3.ChannelId = c2.Id
   930  	o3.UserId = model.NewId()
   931  	o3.Message = "New Jersey is where John is from corey new york"
   932  	_ = (<-ss.Post().Save(o3)).Data.(*model.Post)
   933  
   934  	o4 := &model.Post{}
   935  	o4.ChannelId = c1.Id
   936  	o4.UserId = model.NewId()
   937  	o4.Hashtags = "#hashtag"
   938  	o4.Message = "(message)blargh"
   939  	o4 = (<-ss.Post().Save(o4)).Data.(*model.Post)
   940  
   941  	o5 := &model.Post{}
   942  	o5.ChannelId = c1.Id
   943  	o5.UserId = model.NewId()
   944  	o5.Hashtags = "#secret #howdy"
   945  	o5 = (<-ss.Post().Save(o5)).Data.(*model.Post)
   946  
   947  	o6 := &model.Post{}
   948  	o6.ChannelId = c3.Id
   949  	o6.UserId = model.NewId()
   950  	o6.Hashtags = "#hashtag"
   951  	o6 = (<-ss.Post().Save(o6)).Data.(*model.Post)
   952  
   953  	o7 := &model.Post{}
   954  	o7.ChannelId = c3.Id
   955  	o7.UserId = model.NewId()
   956  	o7.Message = "New Jersey is where John is from corey new york"
   957  	o7 = (<-ss.Post().Save(o7)).Data.(*model.Post)
   958  
   959  	o8 := &model.Post{}
   960  	o8.ChannelId = c3.Id
   961  	o8.UserId = model.NewId()
   962  	o8.Message = "Deleted"
   963  	o8 = (<-ss.Post().Save(o8)).Data.(*model.Post)
   964  
   965  	tt := []struct {
   966  		name                     string
   967  		searchParams             *model.SearchParams
   968  		extectedResultsCount     int
   969  		expectedMessageResultIds []string
   970  	}{
   971  		{
   972  			"normal-search-1",
   973  			&model.SearchParams{Terms: "corey"},
   974  			1,
   975  			[]string{o1.Id},
   976  		},
   977  		{
   978  			"normal-search-2",
   979  			&model.SearchParams{Terms: "new"},
   980  			2,
   981  			[]string{o1.Id, o2.Id},
   982  		},
   983  		{
   984  			"normal-search-3",
   985  			&model.SearchParams{Terms: "john"},
   986  			1,
   987  			[]string{o2.Id},
   988  		},
   989  		{
   990  			"wildcard-search",
   991  			&model.SearchParams{Terms: "matter*"},
   992  			1,
   993  			[]string{o1.Id},
   994  		},
   995  		{
   996  			"hashtag-search",
   997  			&model.SearchParams{Terms: "#hashtag", IsHashtag: true},
   998  			1,
   999  			[]string{o4.Id},
  1000  		},
  1001  		{
  1002  			"hashtag-search-2",
  1003  			&model.SearchParams{Terms: "#secret", IsHashtag: true},
  1004  			1,
  1005  			[]string{o5.Id},
  1006  		},
  1007  		{
  1008  			"no-match-mention",
  1009  			&model.SearchParams{Terms: "@thisshouldmatchnothing", IsHashtag: true},
  1010  			0,
  1011  			[]string{},
  1012  		},
  1013  		{
  1014  			"no-results-search",
  1015  			&model.SearchParams{Terms: "mattermost jersey"},
  1016  			0,
  1017  			[]string{},
  1018  		},
  1019  		{
  1020  			"multiple-words-search",
  1021  			&model.SearchParams{Terms: "corey new york"},
  1022  			1,
  1023  			[]string{o1.Id},
  1024  		},
  1025  		{
  1026  			"multiple-wildcard-search",
  1027  			&model.SearchParams{Terms: "matter* jer*"},
  1028  			0,
  1029  			[]string{},
  1030  		},
  1031  		{
  1032  			"search-with-work-next-to-a-symbol",
  1033  			&model.SearchParams{Terms: "message blargh"},
  1034  			1,
  1035  			[]string{o4.Id},
  1036  		},
  1037  		{
  1038  			"search-with-or",
  1039  			&model.SearchParams{Terms: "Jersey corey", OrTerms: true},
  1040  			2,
  1041  			[]string{o1.Id, o2.Id},
  1042  		},
  1043  		{
  1044  			"search-with-or-and-deleted",
  1045  			&model.SearchParams{Terms: "Jersey corey", OrTerms: true, IncludeDeletedChannels: true},
  1046  			3,
  1047  			[]string{o1.Id, o2.Id, o7.Id},
  1048  		},
  1049  		{
  1050  			"search-hashtag-deleted",
  1051  			&model.SearchParams{Terms: "#hashtag", IsHashtag: true, IncludeDeletedChannels: true},
  1052  			2,
  1053  			[]string{o4.Id, o6.Id},
  1054  		},
  1055  		{
  1056  			"search-deleted-only",
  1057  			&model.SearchParams{Terms: "Deleted", IncludeDeletedChannels: true},
  1058  			1,
  1059  			[]string{o8.Id},
  1060  		},
  1061  	}
  1062  	for _, tc := range tt {
  1063  		t.Run(tc.name, func(t *testing.T) {
  1064  			result := (<-ss.Post().Search(teamId, userId, tc.searchParams)).Data.(*model.PostList)
  1065  			require.Len(t, result.Order, tc.extectedResultsCount)
  1066  			for _, expectedMessageResultId := range tc.expectedMessageResultIds {
  1067  				assert.Contains(t, result.Order, expectedMessageResultId)
  1068  			}
  1069  		})
  1070  	}
  1071  }
  1072  
  1073  func testUserCountsWithPostsByDay(t *testing.T, ss store.Store) {
  1074  	t1 := &model.Team{}
  1075  	t1.DisplayName = "DisplayName"
  1076  	t1.Name = "zz" + model.NewId() + "b"
  1077  	t1.Email = MakeEmail()
  1078  	t1.Type = model.TEAM_OPEN
  1079  	t1 = store.Must(ss.Team().Save(t1)).(*model.Team)
  1080  
  1081  	c1 := &model.Channel{}
  1082  	c1.TeamId = t1.Id
  1083  	c1.DisplayName = "Channel2"
  1084  	c1.Name = "zz" + model.NewId() + "b"
  1085  	c1.Type = model.CHANNEL_OPEN
  1086  	c1 = store.Must(ss.Channel().Save(c1, -1)).(*model.Channel)
  1087  
  1088  	o1 := &model.Post{}
  1089  	o1.ChannelId = c1.Id
  1090  	o1.UserId = model.NewId()
  1091  	o1.CreateAt = utils.MillisFromTime(utils.Yesterday())
  1092  	o1.Message = "zz" + model.NewId() + "b"
  1093  	o1 = store.Must(ss.Post().Save(o1)).(*model.Post)
  1094  
  1095  	o1a := &model.Post{}
  1096  	o1a.ChannelId = c1.Id
  1097  	o1a.UserId = model.NewId()
  1098  	o1a.CreateAt = o1.CreateAt
  1099  	o1a.Message = "zz" + model.NewId() + "b"
  1100  	_ = store.Must(ss.Post().Save(o1a)).(*model.Post)
  1101  
  1102  	o2 := &model.Post{}
  1103  	o2.ChannelId = c1.Id
  1104  	o2.UserId = model.NewId()
  1105  	o2.CreateAt = o1.CreateAt - (1000 * 60 * 60 * 24)
  1106  	o2.Message = "zz" + model.NewId() + "b"
  1107  	o2 = store.Must(ss.Post().Save(o2)).(*model.Post)
  1108  
  1109  	o2a := &model.Post{}
  1110  	o2a.ChannelId = c1.Id
  1111  	o2a.UserId = o2.UserId
  1112  	o2a.CreateAt = o1.CreateAt - (1000 * 60 * 60 * 24)
  1113  	o2a.Message = "zz" + model.NewId() + "b"
  1114  	_ = store.Must(ss.Post().Save(o2a)).(*model.Post)
  1115  
  1116  	if r1 := <-ss.Post().AnalyticsUserCountsWithPostsByDay(t1.Id); r1.Err != nil {
  1117  		t.Fatal(r1.Err)
  1118  	} else {
  1119  		row1 := r1.Data.(model.AnalyticsRows)[0]
  1120  		if row1.Value != 2 {
  1121  			t.Fatal("wrong value")
  1122  		}
  1123  
  1124  		row2 := r1.Data.(model.AnalyticsRows)[1]
  1125  		if row2.Value != 1 {
  1126  			t.Fatal("wrong value")
  1127  		}
  1128  	}
  1129  }
  1130  
  1131  func testPostCountsByDay(t *testing.T, ss store.Store) {
  1132  	t1 := &model.Team{}
  1133  	t1.DisplayName = "DisplayName"
  1134  	t1.Name = "zz" + model.NewId() + "b"
  1135  	t1.Email = MakeEmail()
  1136  	t1.Type = model.TEAM_OPEN
  1137  	t1 = store.Must(ss.Team().Save(t1)).(*model.Team)
  1138  
  1139  	c1 := &model.Channel{}
  1140  	c1.TeamId = t1.Id
  1141  	c1.DisplayName = "Channel2"
  1142  	c1.Name = "zz" + model.NewId() + "b"
  1143  	c1.Type = model.CHANNEL_OPEN
  1144  	c1 = store.Must(ss.Channel().Save(c1, -1)).(*model.Channel)
  1145  
  1146  	o1 := &model.Post{}
  1147  	o1.ChannelId = c1.Id
  1148  	o1.UserId = model.NewId()
  1149  	o1.CreateAt = utils.MillisFromTime(utils.Yesterday())
  1150  	o1.Message = "zz" + model.NewId() + "b"
  1151  	o1 = store.Must(ss.Post().Save(o1)).(*model.Post)
  1152  
  1153  	o1a := &model.Post{}
  1154  	o1a.ChannelId = c1.Id
  1155  	o1a.UserId = model.NewId()
  1156  	o1a.CreateAt = o1.CreateAt
  1157  	o1a.Message = "zz" + model.NewId() + "b"
  1158  	_ = store.Must(ss.Post().Save(o1a)).(*model.Post)
  1159  
  1160  	o2 := &model.Post{}
  1161  	o2.ChannelId = c1.Id
  1162  	o2.UserId = model.NewId()
  1163  	o2.CreateAt = o1.CreateAt - (1000 * 60 * 60 * 24 * 2)
  1164  	o2.Message = "zz" + model.NewId() + "b"
  1165  	o2 = store.Must(ss.Post().Save(o2)).(*model.Post)
  1166  
  1167  	o2a := &model.Post{}
  1168  	o2a.ChannelId = c1.Id
  1169  	o2a.UserId = o2.UserId
  1170  	o2a.CreateAt = o1.CreateAt - (1000 * 60 * 60 * 24 * 2)
  1171  	o2a.Message = "zz" + model.NewId() + "b"
  1172  	_ = store.Must(ss.Post().Save(o2a)).(*model.Post)
  1173  
  1174  	time.Sleep(1 * time.Second)
  1175  
  1176  	if r1 := <-ss.Post().AnalyticsPostCountsByDay(t1.Id); r1.Err != nil {
  1177  		t.Fatal(r1.Err)
  1178  	} else {
  1179  		row1 := r1.Data.(model.AnalyticsRows)[0]
  1180  		if row1.Value != 2 {
  1181  			t.Fatal(row1)
  1182  		}
  1183  
  1184  		row2 := r1.Data.(model.AnalyticsRows)[1]
  1185  		if row2.Value != 2 {
  1186  			t.Fatal("wrong value")
  1187  		}
  1188  	}
  1189  
  1190  	if r1 := <-ss.Post().AnalyticsPostCount(t1.Id, false, false); r1.Err != nil {
  1191  		t.Fatal(r1.Err)
  1192  	} else {
  1193  		if r1.Data.(int64) != 4 {
  1194  			t.Fatal("wrong value")
  1195  		}
  1196  	}
  1197  }
  1198  
  1199  func testPostStoreGetFlaggedPostsForTeam(t *testing.T, ss store.Store, s SqlSupplier) {
  1200  	c1 := &model.Channel{}
  1201  	c1.TeamId = model.NewId()
  1202  	c1.DisplayName = "Channel1"
  1203  	c1.Name = "zz" + model.NewId() + "b"
  1204  	c1.Type = model.CHANNEL_OPEN
  1205  	c1 = store.Must(ss.Channel().Save(c1, -1)).(*model.Channel)
  1206  
  1207  	o1 := &model.Post{}
  1208  	o1.ChannelId = c1.Id
  1209  	o1.UserId = model.NewId()
  1210  	o1.Message = "zz" + model.NewId() + "b"
  1211  	o1 = (<-ss.Post().Save(o1)).Data.(*model.Post)
  1212  	time.Sleep(2 * time.Millisecond)
  1213  
  1214  	o2 := &model.Post{}
  1215  	o2.ChannelId = o1.ChannelId
  1216  	o2.UserId = model.NewId()
  1217  	o2.Message = "zz" + model.NewId() + "b"
  1218  	o2 = (<-ss.Post().Save(o2)).Data.(*model.Post)
  1219  	time.Sleep(2 * time.Millisecond)
  1220  
  1221  	o3 := &model.Post{}
  1222  	o3.ChannelId = o1.ChannelId
  1223  	o3.UserId = model.NewId()
  1224  	o3.Message = "zz" + model.NewId() + "b"
  1225  	o3.DeleteAt = 1
  1226  	o3 = (<-ss.Post().Save(o3)).Data.(*model.Post)
  1227  	time.Sleep(2 * time.Millisecond)
  1228  
  1229  	o4 := &model.Post{}
  1230  	o4.ChannelId = model.NewId()
  1231  	o4.UserId = model.NewId()
  1232  	o4.Message = "zz" + model.NewId() + "b"
  1233  	o4 = (<-ss.Post().Save(o4)).Data.(*model.Post)
  1234  	time.Sleep(2 * time.Millisecond)
  1235  
  1236  	c2 := &model.Channel{}
  1237  	c2.DisplayName = "DMChannel1"
  1238  	c2.Name = "zz" + model.NewId() + "b"
  1239  	c2.Type = model.CHANNEL_DIRECT
  1240  
  1241  	m1 := &model.ChannelMember{}
  1242  	m1.ChannelId = c2.Id
  1243  	m1.UserId = o1.UserId
  1244  	m1.NotifyProps = model.GetDefaultChannelNotifyProps()
  1245  
  1246  	m2 := &model.ChannelMember{}
  1247  	m2.ChannelId = c2.Id
  1248  	m2.UserId = model.NewId()
  1249  	m2.NotifyProps = model.GetDefaultChannelNotifyProps()
  1250  
  1251  	c2 = store.Must(ss.Channel().SaveDirectChannel(c2, m1, m2)).(*model.Channel)
  1252  
  1253  	o5 := &model.Post{}
  1254  	o5.ChannelId = c2.Id
  1255  	o5.UserId = m2.UserId
  1256  	o5.Message = "zz" + model.NewId() + "b"
  1257  	o5 = (<-ss.Post().Save(o5)).Data.(*model.Post)
  1258  	time.Sleep(2 * time.Millisecond)
  1259  
  1260  	r1 := (<-ss.Post().GetFlaggedPosts(o1.ChannelId, 0, 2)).Data.(*model.PostList)
  1261  
  1262  	if len(r1.Order) != 0 {
  1263  		t.Fatal("should be empty")
  1264  	}
  1265  
  1266  	preferences := model.Preferences{
  1267  		{
  1268  			UserId:   o1.UserId,
  1269  			Category: model.PREFERENCE_CATEGORY_FLAGGED_POST,
  1270  			Name:     o1.Id,
  1271  			Value:    "true",
  1272  		},
  1273  	}
  1274  
  1275  	store.Must(ss.Preference().Save(&preferences))
  1276  
  1277  	r2 := (<-ss.Post().GetFlaggedPostsForTeam(o1.UserId, c1.TeamId, 0, 2)).Data.(*model.PostList)
  1278  
  1279  	if len(r2.Order) != 1 {
  1280  		t.Fatal("should have 1 post")
  1281  	}
  1282  
  1283  	preferences = model.Preferences{
  1284  		{
  1285  			UserId:   o1.UserId,
  1286  			Category: model.PREFERENCE_CATEGORY_FLAGGED_POST,
  1287  			Name:     o2.Id,
  1288  			Value:    "true",
  1289  		},
  1290  	}
  1291  
  1292  	store.Must(ss.Preference().Save(&preferences))
  1293  
  1294  	r3 := (<-ss.Post().GetFlaggedPostsForTeam(o1.UserId, c1.TeamId, 0, 1)).Data.(*model.PostList)
  1295  
  1296  	if len(r3.Order) != 1 {
  1297  		t.Fatal("should have 1 post")
  1298  	}
  1299  
  1300  	r3 = (<-ss.Post().GetFlaggedPostsForTeam(o1.UserId, c1.TeamId, 1, 1)).Data.(*model.PostList)
  1301  
  1302  	if len(r3.Order) != 1 {
  1303  		t.Fatal("should have 1 post")
  1304  	}
  1305  
  1306  	r3 = (<-ss.Post().GetFlaggedPostsForTeam(o1.UserId, c1.TeamId, 1000, 10)).Data.(*model.PostList)
  1307  
  1308  	if len(r3.Order) != 0 {
  1309  		t.Fatal("should be empty")
  1310  	}
  1311  
  1312  	r4 := (<-ss.Post().GetFlaggedPostsForTeam(o1.UserId, c1.TeamId, 0, 2)).Data.(*model.PostList)
  1313  
  1314  	if len(r4.Order) != 2 {
  1315  		t.Fatal("should have 2 posts")
  1316  	}
  1317  
  1318  	preferences = model.Preferences{
  1319  		{
  1320  			UserId:   o1.UserId,
  1321  			Category: model.PREFERENCE_CATEGORY_FLAGGED_POST,
  1322  			Name:     o3.Id,
  1323  			Value:    "true",
  1324  		},
  1325  	}
  1326  
  1327  	store.Must(ss.Preference().Save(&preferences))
  1328  
  1329  	r4 = (<-ss.Post().GetFlaggedPostsForTeam(o1.UserId, c1.TeamId, 0, 2)).Data.(*model.PostList)
  1330  
  1331  	if len(r4.Order) != 2 {
  1332  		t.Fatal("should have 2 posts")
  1333  	}
  1334  
  1335  	preferences = model.Preferences{
  1336  		{
  1337  			UserId:   o1.UserId,
  1338  			Category: model.PREFERENCE_CATEGORY_FLAGGED_POST,
  1339  			Name:     o4.Id,
  1340  			Value:    "true",
  1341  		},
  1342  	}
  1343  	store.Must(ss.Preference().Save(&preferences))
  1344  
  1345  	r4 = (<-ss.Post().GetFlaggedPostsForTeam(o1.UserId, c1.TeamId, 0, 2)).Data.(*model.PostList)
  1346  
  1347  	if len(r4.Order) != 2 {
  1348  		t.Fatal("should have 2 posts")
  1349  	}
  1350  
  1351  	r4 = (<-ss.Post().GetFlaggedPostsForTeam(o1.UserId, model.NewId(), 0, 2)).Data.(*model.PostList)
  1352  
  1353  	if len(r4.Order) != 0 {
  1354  		t.Fatal("should have 0 posts")
  1355  	}
  1356  
  1357  	preferences = model.Preferences{
  1358  		{
  1359  			UserId:   o1.UserId,
  1360  			Category: model.PREFERENCE_CATEGORY_FLAGGED_POST,
  1361  			Name:     o5.Id,
  1362  			Value:    "true",
  1363  		},
  1364  	}
  1365  	store.Must(ss.Preference().Save(&preferences))
  1366  
  1367  	r4 = (<-ss.Post().GetFlaggedPostsForTeam(o1.UserId, c1.TeamId, 0, 10)).Data.(*model.PostList)
  1368  
  1369  	if len(r4.Order) != 3 {
  1370  		t.Fatal("should have 3 posts")
  1371  	}
  1372  
  1373  	// Manually truncate Channels table until testlib can handle cleanups
  1374  	s.GetMaster().Exec("TRUNCATE Channels")
  1375  }
  1376  
  1377  func testPostStoreGetFlaggedPosts(t *testing.T, ss store.Store) {
  1378  	o1 := &model.Post{}
  1379  	o1.ChannelId = model.NewId()
  1380  	o1.UserId = model.NewId()
  1381  	o1.Message = "zz" + model.NewId() + "b"
  1382  	o1 = (<-ss.Post().Save(o1)).Data.(*model.Post)
  1383  	time.Sleep(2 * time.Millisecond)
  1384  
  1385  	o2 := &model.Post{}
  1386  	o2.ChannelId = o1.ChannelId
  1387  	o2.UserId = model.NewId()
  1388  	o2.Message = "zz" + model.NewId() + "b"
  1389  	o2 = (<-ss.Post().Save(o2)).Data.(*model.Post)
  1390  	time.Sleep(2 * time.Millisecond)
  1391  
  1392  	o3 := &model.Post{}
  1393  	o3.ChannelId = o1.ChannelId
  1394  	o3.UserId = model.NewId()
  1395  	o3.Message = "zz" + model.NewId() + "b"
  1396  	o3.DeleteAt = 1
  1397  	o3 = (<-ss.Post().Save(o3)).Data.(*model.Post)
  1398  	time.Sleep(2 * time.Millisecond)
  1399  
  1400  	r1 := (<-ss.Post().GetFlaggedPosts(o1.UserId, 0, 2)).Data.(*model.PostList)
  1401  
  1402  	if len(r1.Order) != 0 {
  1403  		t.Fatal("should be empty")
  1404  	}
  1405  
  1406  	preferences := model.Preferences{
  1407  		{
  1408  			UserId:   o1.UserId,
  1409  			Category: model.PREFERENCE_CATEGORY_FLAGGED_POST,
  1410  			Name:     o1.Id,
  1411  			Value:    "true",
  1412  		},
  1413  	}
  1414  
  1415  	store.Must(ss.Preference().Save(&preferences))
  1416  
  1417  	r2 := (<-ss.Post().GetFlaggedPosts(o1.UserId, 0, 2)).Data.(*model.PostList)
  1418  
  1419  	if len(r2.Order) != 1 {
  1420  		t.Fatal("should have 1 post")
  1421  	}
  1422  
  1423  	preferences = model.Preferences{
  1424  		{
  1425  			UserId:   o1.UserId,
  1426  			Category: model.PREFERENCE_CATEGORY_FLAGGED_POST,
  1427  			Name:     o2.Id,
  1428  			Value:    "true",
  1429  		},
  1430  	}
  1431  
  1432  	store.Must(ss.Preference().Save(&preferences))
  1433  
  1434  	r3 := (<-ss.Post().GetFlaggedPosts(o1.UserId, 0, 1)).Data.(*model.PostList)
  1435  
  1436  	if len(r3.Order) != 1 {
  1437  		t.Fatal("should have 1 post")
  1438  	}
  1439  
  1440  	r3 = (<-ss.Post().GetFlaggedPosts(o1.UserId, 1, 1)).Data.(*model.PostList)
  1441  
  1442  	if len(r3.Order) != 1 {
  1443  		t.Fatal("should have 1 post")
  1444  	}
  1445  
  1446  	r3 = (<-ss.Post().GetFlaggedPosts(o1.UserId, 1000, 10)).Data.(*model.PostList)
  1447  
  1448  	if len(r3.Order) != 0 {
  1449  		t.Fatal("should be empty")
  1450  	}
  1451  
  1452  	r4 := (<-ss.Post().GetFlaggedPosts(o1.UserId, 0, 2)).Data.(*model.PostList)
  1453  
  1454  	if len(r4.Order) != 2 {
  1455  		t.Fatal("should have 2 posts")
  1456  	}
  1457  
  1458  	preferences = model.Preferences{
  1459  		{
  1460  			UserId:   o1.UserId,
  1461  			Category: model.PREFERENCE_CATEGORY_FLAGGED_POST,
  1462  			Name:     o3.Id,
  1463  			Value:    "true",
  1464  		},
  1465  	}
  1466  
  1467  	store.Must(ss.Preference().Save(&preferences))
  1468  
  1469  	r4 = (<-ss.Post().GetFlaggedPosts(o1.UserId, 0, 2)).Data.(*model.PostList)
  1470  
  1471  	if len(r4.Order) != 2 {
  1472  		t.Fatal("should have 2 posts")
  1473  	}
  1474  }
  1475  
  1476  func testPostStoreGetFlaggedPostsForChannel(t *testing.T, ss store.Store) {
  1477  	o1 := &model.Post{}
  1478  	o1.ChannelId = model.NewId()
  1479  	o1.UserId = model.NewId()
  1480  	o1.Message = "zz" + model.NewId() + "b"
  1481  	o1 = (<-ss.Post().Save(o1)).Data.(*model.Post)
  1482  	time.Sleep(2 * time.Millisecond)
  1483  
  1484  	o2 := &model.Post{}
  1485  	o2.ChannelId = o1.ChannelId
  1486  	o2.UserId = model.NewId()
  1487  	o2.Message = "zz" + model.NewId() + "b"
  1488  	o2 = (<-ss.Post().Save(o2)).Data.(*model.Post)
  1489  	time.Sleep(2 * time.Millisecond)
  1490  
  1491  	// deleted post
  1492  	o3 := &model.Post{}
  1493  	o3.ChannelId = model.NewId()
  1494  	o3.UserId = o1.ChannelId
  1495  	o3.Message = "zz" + model.NewId() + "b"
  1496  	o3.DeleteAt = 1
  1497  	o3 = (<-ss.Post().Save(o3)).Data.(*model.Post)
  1498  	time.Sleep(2 * time.Millisecond)
  1499  
  1500  	o4 := &model.Post{}
  1501  	o4.ChannelId = model.NewId()
  1502  	o4.UserId = model.NewId()
  1503  	o4.Message = "zz" + model.NewId() + "b"
  1504  	o4 = (<-ss.Post().Save(o4)).Data.(*model.Post)
  1505  	time.Sleep(2 * time.Millisecond)
  1506  
  1507  	r := (<-ss.Post().GetFlaggedPostsForChannel(o1.UserId, o1.ChannelId, 0, 10)).Data.(*model.PostList)
  1508  
  1509  	if len(r.Order) != 0 {
  1510  		t.Fatal("should be empty")
  1511  	}
  1512  
  1513  	preference := model.Preference{
  1514  		UserId:   o1.UserId,
  1515  		Category: model.PREFERENCE_CATEGORY_FLAGGED_POST,
  1516  		Name:     o1.Id,
  1517  		Value:    "true",
  1518  	}
  1519  
  1520  	store.Must(ss.Preference().Save(&model.Preferences{preference}))
  1521  
  1522  	r = (<-ss.Post().GetFlaggedPostsForChannel(o1.UserId, o1.ChannelId, 0, 10)).Data.(*model.PostList)
  1523  
  1524  	if len(r.Order) != 1 {
  1525  		t.Fatal("should have 1 post")
  1526  	}
  1527  
  1528  	preference.Name = o2.Id
  1529  	store.Must(ss.Preference().Save(&model.Preferences{preference}))
  1530  
  1531  	preference.Name = o3.Id
  1532  	store.Must(ss.Preference().Save(&model.Preferences{preference}))
  1533  
  1534  	r = (<-ss.Post().GetFlaggedPostsForChannel(o1.UserId, o1.ChannelId, 0, 1)).Data.(*model.PostList)
  1535  
  1536  	if len(r.Order) != 1 {
  1537  		t.Fatal("should have 1 post")
  1538  	}
  1539  
  1540  	r = (<-ss.Post().GetFlaggedPostsForChannel(o1.UserId, o1.ChannelId, 1, 1)).Data.(*model.PostList)
  1541  
  1542  	if len(r.Order) != 1 {
  1543  		t.Fatal("should have 1 post")
  1544  	}
  1545  
  1546  	r = (<-ss.Post().GetFlaggedPostsForChannel(o1.UserId, o1.ChannelId, 1000, 10)).Data.(*model.PostList)
  1547  
  1548  	if len(r.Order) != 0 {
  1549  		t.Fatal("should be empty")
  1550  	}
  1551  
  1552  	r = (<-ss.Post().GetFlaggedPostsForChannel(o1.UserId, o1.ChannelId, 0, 10)).Data.(*model.PostList)
  1553  
  1554  	if len(r.Order) != 2 {
  1555  		t.Fatal("should have 2 posts")
  1556  	}
  1557  
  1558  	preference.Name = o4.Id
  1559  	store.Must(ss.Preference().Save(&model.Preferences{preference}))
  1560  
  1561  	r = (<-ss.Post().GetFlaggedPostsForChannel(o1.UserId, o4.ChannelId, 0, 10)).Data.(*model.PostList)
  1562  
  1563  	if len(r.Order) != 1 {
  1564  		t.Fatal("should have 1 post")
  1565  	}
  1566  }
  1567  
  1568  func testPostStoreGetPostsCreatedAt(t *testing.T, ss store.Store) {
  1569  	createTime := model.GetMillis() + 1
  1570  
  1571  	o0 := &model.Post{}
  1572  	o0.ChannelId = model.NewId()
  1573  	o0.UserId = model.NewId()
  1574  	o0.Message = "zz" + model.NewId() + "b"
  1575  	o0.CreateAt = createTime
  1576  	o0 = (<-ss.Post().Save(o0)).Data.(*model.Post)
  1577  
  1578  	o1 := &model.Post{}
  1579  	o1.ChannelId = o0.ChannelId
  1580  	o1.UserId = model.NewId()
  1581  	o1.Message = "zz" + model.NewId() + "b"
  1582  	o1.CreateAt = createTime
  1583  	o1 = (<-ss.Post().Save(o1)).Data.(*model.Post)
  1584  
  1585  	o2 := &model.Post{}
  1586  	o2.ChannelId = o1.ChannelId
  1587  	o2.UserId = model.NewId()
  1588  	o2.Message = "zz" + model.NewId() + "b"
  1589  	o2.ParentId = o1.Id
  1590  	o2.RootId = o1.Id
  1591  	o2.CreateAt = createTime + 1
  1592  	_ = (<-ss.Post().Save(o2)).Data.(*model.Post)
  1593  
  1594  	o3 := &model.Post{}
  1595  	o3.ChannelId = model.NewId()
  1596  	o3.UserId = model.NewId()
  1597  	o3.Message = "zz" + model.NewId() + "b"
  1598  	o3.CreateAt = createTime
  1599  	_ = (<-ss.Post().Save(o3)).Data.(*model.Post)
  1600  
  1601  	r1 := (<-ss.Post().GetPostsCreatedAt(o1.ChannelId, createTime)).Data.([]*model.Post)
  1602  	assert.Equal(t, 2, len(r1))
  1603  }
  1604  
  1605  func testPostStoreOverwrite(t *testing.T, ss store.Store) {
  1606  	o1 := &model.Post{}
  1607  	o1.ChannelId = model.NewId()
  1608  	o1.UserId = model.NewId()
  1609  	o1.Message = "zz" + model.NewId() + "AAAAAAAAAAA"
  1610  	o1 = (<-ss.Post().Save(o1)).Data.(*model.Post)
  1611  
  1612  	o2 := &model.Post{}
  1613  	o2.ChannelId = o1.ChannelId
  1614  	o2.UserId = model.NewId()
  1615  	o2.Message = "zz" + model.NewId() + "CCCCCCCCC"
  1616  	o2.ParentId = o1.Id
  1617  	o2.RootId = o1.Id
  1618  	o2 = (<-ss.Post().Save(o2)).Data.(*model.Post)
  1619  
  1620  	o3 := &model.Post{}
  1621  	o3.ChannelId = o1.ChannelId
  1622  	o3.UserId = model.NewId()
  1623  	o3.Message = "zz" + model.NewId() + "QQQQQQQQQQ"
  1624  	o3 = (<-ss.Post().Save(o3)).Data.(*model.Post)
  1625  
  1626  	ro1 := (<-ss.Post().Get(o1.Id)).Data.(*model.PostList).Posts[o1.Id]
  1627  	ro2 := (<-ss.Post().Get(o1.Id)).Data.(*model.PostList).Posts[o2.Id]
  1628  	ro3 := (<-ss.Post().Get(o3.Id)).Data.(*model.PostList).Posts[o3.Id]
  1629  
  1630  	if ro1.Message != o1.Message {
  1631  		t.Fatal("Failed to save/get")
  1632  	}
  1633  
  1634  	o1a := &model.Post{}
  1635  	*o1a = *ro1
  1636  	o1a.Message = ro1.Message + "BBBBBBBBBB"
  1637  	if result := <-ss.Post().Overwrite(o1a); result.Err != nil {
  1638  		t.Fatal(result.Err)
  1639  	}
  1640  
  1641  	ro1a := (<-ss.Post().Get(o1.Id)).Data.(*model.PostList).Posts[o1.Id]
  1642  
  1643  	if ro1a.Message != o1a.Message {
  1644  		t.Fatal("Failed to overwrite/get")
  1645  	}
  1646  
  1647  	o2a := &model.Post{}
  1648  	*o2a = *ro2
  1649  	o2a.Message = ro2.Message + "DDDDDDD"
  1650  	if result := <-ss.Post().Overwrite(o2a); result.Err != nil {
  1651  		t.Fatal(result.Err)
  1652  	}
  1653  
  1654  	ro2a := (<-ss.Post().Get(o1.Id)).Data.(*model.PostList).Posts[o2.Id]
  1655  
  1656  	if ro2a.Message != o2a.Message {
  1657  		t.Fatal("Failed to overwrite/get")
  1658  	}
  1659  
  1660  	o3a := &model.Post{}
  1661  	*o3a = *ro3
  1662  	o3a.Message = ro3.Message + "WWWWWWW"
  1663  	if result := <-ss.Post().Overwrite(o3a); result.Err != nil {
  1664  		t.Fatal(result.Err)
  1665  	}
  1666  
  1667  	ro3a := (<-ss.Post().Get(o3.Id)).Data.(*model.PostList).Posts[o3.Id]
  1668  
  1669  	if ro3a.Message != o3a.Message && ro3a.Hashtags != o3a.Hashtags {
  1670  		t.Fatal("Failed to overwrite/get")
  1671  	}
  1672  
  1673  	o4 := store.Must(ss.Post().Save(&model.Post{
  1674  		ChannelId: model.NewId(),
  1675  		UserId:    model.NewId(),
  1676  		Message:   model.NewId(),
  1677  		Filenames: []string{"test"},
  1678  	})).(*model.Post)
  1679  
  1680  	ro4 := (<-ss.Post().Get(o4.Id)).Data.(*model.PostList).Posts[o4.Id]
  1681  
  1682  	o4a := &model.Post{}
  1683  	*o4a = *ro4
  1684  	o4a.Filenames = []string{}
  1685  	o4a.FileIds = []string{model.NewId()}
  1686  	if result := <-ss.Post().Overwrite(o4a); result.Err != nil {
  1687  		t.Fatal(result.Err)
  1688  	}
  1689  
  1690  	if ro4a := store.Must(ss.Post().Get(o4.Id)).(*model.PostList).Posts[o4.Id]; len(ro4a.Filenames) != 0 {
  1691  		t.Fatal("Failed to clear Filenames")
  1692  	} else if len(ro4a.FileIds) != 1 {
  1693  		t.Fatal("Failed to set FileIds")
  1694  	}
  1695  }
  1696  
  1697  func testPostStoreGetPostsByIds(t *testing.T, ss store.Store) {
  1698  	o1 := &model.Post{}
  1699  	o1.ChannelId = model.NewId()
  1700  	o1.UserId = model.NewId()
  1701  	o1.Message = "zz" + model.NewId() + "AAAAAAAAAAA"
  1702  	o1 = (<-ss.Post().Save(o1)).Data.(*model.Post)
  1703  
  1704  	o2 := &model.Post{}
  1705  	o2.ChannelId = o1.ChannelId
  1706  	o2.UserId = model.NewId()
  1707  	o2.Message = "zz" + model.NewId() + "CCCCCCCCC"
  1708  	o2 = (<-ss.Post().Save(o2)).Data.(*model.Post)
  1709  
  1710  	o3 := &model.Post{}
  1711  	o3.ChannelId = o1.ChannelId
  1712  	o3.UserId = model.NewId()
  1713  	o3.Message = "zz" + model.NewId() + "QQQQQQQQQQ"
  1714  	o3 = (<-ss.Post().Save(o3)).Data.(*model.Post)
  1715  
  1716  	ro1 := (<-ss.Post().Get(o1.Id)).Data.(*model.PostList).Posts[o1.Id]
  1717  	ro2 := (<-ss.Post().Get(o2.Id)).Data.(*model.PostList).Posts[o2.Id]
  1718  	ro3 := (<-ss.Post().Get(o3.Id)).Data.(*model.PostList).Posts[o3.Id]
  1719  
  1720  	postIds := []string{
  1721  		ro1.Id,
  1722  		ro2.Id,
  1723  		ro3.Id,
  1724  	}
  1725  
  1726  	if ro4 := store.Must(ss.Post().GetPostsByIds(postIds)).([]*model.Post); len(ro4) != 3 {
  1727  		t.Fatalf("Expected 3 posts in results. Got %v", len(ro4))
  1728  	}
  1729  
  1730  	store.Must(ss.Post().Delete(ro1.Id, model.GetMillis(), ""))
  1731  
  1732  	if ro5 := store.Must(ss.Post().GetPostsByIds(postIds)).([]*model.Post); len(ro5) != 3 {
  1733  		t.Fatalf("Expected 3 posts in results. Got %v", len(ro5))
  1734  	}
  1735  }
  1736  
  1737  func testPostStoreGetPostsBatchForIndexing(t *testing.T, ss store.Store) {
  1738  	c1 := &model.Channel{}
  1739  	c1.TeamId = model.NewId()
  1740  	c1.DisplayName = "Channel1"
  1741  	c1.Name = "zz" + model.NewId() + "b"
  1742  	c1.Type = model.CHANNEL_OPEN
  1743  	c1 = (<-ss.Channel().Save(c1, -1)).Data.(*model.Channel)
  1744  
  1745  	c2 := &model.Channel{}
  1746  	c2.TeamId = model.NewId()
  1747  	c2.DisplayName = "Channel2"
  1748  	c2.Name = "zz" + model.NewId() + "b"
  1749  	c2.Type = model.CHANNEL_OPEN
  1750  	c2 = (<-ss.Channel().Save(c2, -1)).Data.(*model.Channel)
  1751  
  1752  	o1 := &model.Post{}
  1753  	o1.ChannelId = c1.Id
  1754  	o1.UserId = model.NewId()
  1755  	o1.Message = "zz" + model.NewId() + "AAAAAAAAAAA"
  1756  	o1 = (<-ss.Post().Save(o1)).Data.(*model.Post)
  1757  
  1758  	o2 := &model.Post{}
  1759  	o2.ChannelId = c2.Id
  1760  	o2.UserId = model.NewId()
  1761  	o2.Message = "zz" + model.NewId() + "CCCCCCCCC"
  1762  	o2 = (<-ss.Post().Save(o2)).Data.(*model.Post)
  1763  
  1764  	o3 := &model.Post{}
  1765  	o3.ChannelId = c1.Id
  1766  	o3.UserId = model.NewId()
  1767  	o3.ParentId = o1.Id
  1768  	o3.RootId = o1.Id
  1769  	o3.Message = "zz" + model.NewId() + "QQQQQQQQQQ"
  1770  	o3 = (<-ss.Post().Save(o3)).Data.(*model.Post)
  1771  
  1772  	if r := store.Must(ss.Post().GetPostsBatchForIndexing(o1.CreateAt, model.GetMillis()+100000, 100)).([]*model.PostForIndexing); len(r) != 3 {
  1773  		t.Fatalf("Expected 3 posts in results. Got %v", len(r))
  1774  	} else {
  1775  		for _, p := range r {
  1776  			if p.Id == o1.Id {
  1777  				if p.TeamId != c1.TeamId {
  1778  					t.Fatalf("Unexpected team ID")
  1779  				}
  1780  				if p.ParentCreateAt != nil {
  1781  					t.Fatalf("Unexpected parent create at")
  1782  				}
  1783  			} else if p.Id == o2.Id {
  1784  				if p.TeamId != c2.TeamId {
  1785  					t.Fatalf("Unexpected team ID")
  1786  				}
  1787  				if p.ParentCreateAt != nil {
  1788  					t.Fatalf("Unexpected parent create at")
  1789  				}
  1790  			} else if p.Id == o3.Id {
  1791  				if p.TeamId != c1.TeamId {
  1792  					t.Fatalf("Unexpected team ID")
  1793  				}
  1794  				if *p.ParentCreateAt != o1.CreateAt {
  1795  					t.Fatalf("Unexpected parent create at")
  1796  				}
  1797  			} else {
  1798  				t.Fatalf("unexpected post returned")
  1799  			}
  1800  		}
  1801  	}
  1802  }
  1803  
  1804  func testPostStorePermanentDeleteBatch(t *testing.T, ss store.Store) {
  1805  	o1 := &model.Post{}
  1806  	o1.ChannelId = model.NewId()
  1807  	o1.UserId = model.NewId()
  1808  	o1.Message = "zz" + model.NewId() + "AAAAAAAAAAA"
  1809  	o1.CreateAt = 1000
  1810  	o1 = (<-ss.Post().Save(o1)).Data.(*model.Post)
  1811  
  1812  	o2 := &model.Post{}
  1813  	o2.ChannelId = model.NewId()
  1814  	o2.UserId = model.NewId()
  1815  	o2.Message = "zz" + model.NewId() + "AAAAAAAAAAA"
  1816  	o2.CreateAt = 1000
  1817  	o2 = (<-ss.Post().Save(o2)).Data.(*model.Post)
  1818  
  1819  	o3 := &model.Post{}
  1820  	o3.ChannelId = model.NewId()
  1821  	o3.UserId = model.NewId()
  1822  	o3.Message = "zz" + model.NewId() + "AAAAAAAAAAA"
  1823  	o3.CreateAt = 100000
  1824  	o3 = (<-ss.Post().Save(o3)).Data.(*model.Post)
  1825  
  1826  	store.Must(ss.Post().PermanentDeleteBatch(2000, 1000))
  1827  
  1828  	if p := <-ss.Post().Get(o1.Id); p.Err == nil {
  1829  		t.Fatalf("Should have not found post 1 after purge")
  1830  	}
  1831  
  1832  	if p := <-ss.Post().Get(o2.Id); p.Err == nil {
  1833  		t.Fatalf("Should have not found post 2 after purge")
  1834  	}
  1835  
  1836  	if p := <-ss.Post().Get(o3.Id); p.Err != nil {
  1837  		t.Fatalf("Should have found post 3 after purge")
  1838  	}
  1839  }
  1840  
  1841  func testPostStoreGetOldest(t *testing.T, ss store.Store) {
  1842  	o0 := &model.Post{}
  1843  	o0.ChannelId = model.NewId()
  1844  	o0.UserId = model.NewId()
  1845  	o0.Message = "zz" + model.NewId() + "b"
  1846  	o0.CreateAt = 3
  1847  	o0 = (<-ss.Post().Save(o0)).Data.(*model.Post)
  1848  
  1849  	o1 := &model.Post{}
  1850  	o1.ChannelId = o0.Id
  1851  	o1.UserId = model.NewId()
  1852  	o1.Message = "zz" + model.NewId() + "b"
  1853  	o1.CreateAt = 2
  1854  	o1 = (<-ss.Post().Save(o1)).Data.(*model.Post)
  1855  
  1856  	o2 := &model.Post{}
  1857  	o2.ChannelId = o1.ChannelId
  1858  	o2.UserId = model.NewId()
  1859  	o2.Message = "zz" + model.NewId() + "b"
  1860  	o2.CreateAt = 1
  1861  	o2 = (<-ss.Post().Save(o2)).Data.(*model.Post)
  1862  
  1863  	r1 := (<-ss.Post().GetOldest()).Data.(*model.Post)
  1864  
  1865  	assert.EqualValues(t, o2.Id, r1.Id)
  1866  }
  1867  
  1868  func testGetMaxPostSize(t *testing.T, ss store.Store) {
  1869  	assert.Equal(t, model.POST_MESSAGE_MAX_RUNES_V2, (<-ss.Post().GetMaxPostSize()).Data.(int))
  1870  	assert.Equal(t, model.POST_MESSAGE_MAX_RUNES_V2, (<-ss.Post().GetMaxPostSize()).Data.(int))
  1871  }
  1872  
  1873  func testPostStoreGetParentsForExportAfter(t *testing.T, ss store.Store) {
  1874  	t1 := model.Team{}
  1875  	t1.DisplayName = "Name"
  1876  	t1.Name = model.NewId()
  1877  	t1.Email = MakeEmail()
  1878  	t1.Type = model.TEAM_OPEN
  1879  	store.Must(ss.Team().Save(&t1))
  1880  
  1881  	c1 := model.Channel{}
  1882  	c1.TeamId = t1.Id
  1883  	c1.DisplayName = "Channel1"
  1884  	c1.Name = "zz" + model.NewId() + "b"
  1885  	c1.Type = model.CHANNEL_OPEN
  1886  	store.Must(ss.Channel().Save(&c1, -1))
  1887  
  1888  	u1 := model.User{}
  1889  	u1.Username = model.NewId()
  1890  	u1.Email = MakeEmail()
  1891  	u1.Nickname = model.NewId()
  1892  	store.Must(ss.User().Save(&u1))
  1893  
  1894  	p1 := &model.Post{}
  1895  	p1.ChannelId = c1.Id
  1896  	p1.UserId = u1.Id
  1897  	p1.Message = "zz" + model.NewId() + "AAAAAAAAAAA"
  1898  	p1.CreateAt = 1000
  1899  	p1 = (<-ss.Post().Save(p1)).Data.(*model.Post)
  1900  
  1901  	r1 := <-ss.Post().GetParentsForExportAfter(10000, strings.Repeat("0", 26))
  1902  	assert.Nil(t, r1.Err)
  1903  	d1 := r1.Data.([]*model.PostForExport)
  1904  
  1905  	found := false
  1906  	for _, p := range d1 {
  1907  		if p.Id == p1.Id {
  1908  			found = true
  1909  			assert.Equal(t, p.Id, p1.Id)
  1910  			assert.Equal(t, p.Message, p1.Message)
  1911  			assert.Equal(t, p.Username, u1.Username)
  1912  			assert.Equal(t, p.TeamName, t1.Name)
  1913  			assert.Equal(t, p.ChannelName, c1.Name)
  1914  		}
  1915  	}
  1916  	assert.True(t, found)
  1917  }
  1918  
  1919  func testPostStoreGetRepliesForExport(t *testing.T, ss store.Store) {
  1920  	t1 := model.Team{}
  1921  	t1.DisplayName = "Name"
  1922  	t1.Name = model.NewId()
  1923  	t1.Email = MakeEmail()
  1924  	t1.Type = model.TEAM_OPEN
  1925  	store.Must(ss.Team().Save(&t1))
  1926  
  1927  	c1 := model.Channel{}
  1928  	c1.TeamId = t1.Id
  1929  	c1.DisplayName = "Channel1"
  1930  	c1.Name = "zz" + model.NewId() + "b"
  1931  	c1.Type = model.CHANNEL_OPEN
  1932  	store.Must(ss.Channel().Save(&c1, -1))
  1933  
  1934  	u1 := model.User{}
  1935  	u1.Email = MakeEmail()
  1936  	u1.Nickname = model.NewId()
  1937  	store.Must(ss.User().Save(&u1))
  1938  
  1939  	p1 := &model.Post{}
  1940  	p1.ChannelId = c1.Id
  1941  	p1.UserId = u1.Id
  1942  	p1.Message = "zz" + model.NewId() + "AAAAAAAAAAA"
  1943  	p1.CreateAt = 1000
  1944  	p1 = (<-ss.Post().Save(p1)).Data.(*model.Post)
  1945  
  1946  	p2 := &model.Post{}
  1947  	p2.ChannelId = c1.Id
  1948  	p2.UserId = u1.Id
  1949  	p2.Message = "zz" + model.NewId() + "AAAAAAAAAAA"
  1950  	p2.CreateAt = 1001
  1951  	p2.ParentId = p1.Id
  1952  	p2.RootId = p1.Id
  1953  	p2 = (<-ss.Post().Save(p2)).Data.(*model.Post)
  1954  
  1955  	r1 := <-ss.Post().GetRepliesForExport(p1.Id)
  1956  	assert.Nil(t, r1.Err)
  1957  
  1958  	d1 := r1.Data.([]*model.ReplyForExport)
  1959  	assert.Len(t, d1, 1)
  1960  
  1961  	reply1 := d1[0]
  1962  	assert.Equal(t, reply1.Id, p2.Id)
  1963  	assert.Equal(t, reply1.Message, p2.Message)
  1964  	assert.Equal(t, reply1.Username, u1.Username)
  1965  
  1966  	// Checking whether replies by deleted user are exported
  1967  	u1.DeleteAt = 1002
  1968  	store.Must(ss.User().Update(&u1, false))
  1969  
  1970  	r1 = <-ss.Post().GetRepliesForExport(p1.Id)
  1971  	assert.Nil(t, r1.Err)
  1972  
  1973  	d1 = r1.Data.([]*model.ReplyForExport)
  1974  	assert.Len(t, d1, 1)
  1975  
  1976  	reply1 = d1[0]
  1977  	assert.Equal(t, reply1.Id, p2.Id)
  1978  	assert.Equal(t, reply1.Message, p2.Message)
  1979  	assert.Equal(t, reply1.Username, u1.Username)
  1980  
  1981  }
  1982  
  1983  func testPostStoreGetDirectPostParentsForExportAfter(t *testing.T, ss store.Store, s SqlSupplier) {
  1984  	teamId := model.NewId()
  1985  
  1986  	o1 := model.Channel{}
  1987  	o1.TeamId = teamId
  1988  	o1.DisplayName = "Name"
  1989  	o1.Name = "zz" + model.NewId() + "b"
  1990  	o1.Type = model.CHANNEL_DIRECT
  1991  
  1992  	u1 := &model.User{}
  1993  	u1.Email = MakeEmail()
  1994  	u1.Nickname = model.NewId()
  1995  	store.Must(ss.User().Save(u1))
  1996  	store.Must(ss.Team().SaveMember(&model.TeamMember{TeamId: model.NewId(), UserId: u1.Id}, -1))
  1997  
  1998  	u2 := &model.User{}
  1999  	u2.Email = MakeEmail()
  2000  	u2.Nickname = model.NewId()
  2001  	store.Must(ss.User().Save(u2))
  2002  	store.Must(ss.Team().SaveMember(&model.TeamMember{TeamId: model.NewId(), UserId: u2.Id}, -1))
  2003  
  2004  	m1 := model.ChannelMember{}
  2005  	m1.ChannelId = o1.Id
  2006  	m1.UserId = u1.Id
  2007  	m1.NotifyProps = model.GetDefaultChannelNotifyProps()
  2008  
  2009  	m2 := model.ChannelMember{}
  2010  	m2.ChannelId = o1.Id
  2011  	m2.UserId = u2.Id
  2012  	m2.NotifyProps = model.GetDefaultChannelNotifyProps()
  2013  
  2014  	<-ss.Channel().SaveDirectChannel(&o1, &m1, &m2)
  2015  
  2016  	p1 := &model.Post{}
  2017  	p1.ChannelId = o1.Id
  2018  	p1.UserId = u1.Id
  2019  	p1.Message = "zz" + model.NewId() + "AAAAAAAAAAA"
  2020  	p1.CreateAt = 1000
  2021  	p1 = (<-ss.Post().Save(p1)).Data.(*model.Post)
  2022  
  2023  	r1 := <-ss.Post().GetDirectPostParentsForExportAfter(10000, strings.Repeat("0", 26))
  2024  	assert.Nil(t, r1.Err)
  2025  	d1 := r1.Data.([]*model.DirectPostForExport)
  2026  
  2027  	assert.Equal(t, p1.Message, d1[0].Message)
  2028  
  2029  	// Manually truncate Channels table until testlib can handle cleanups
  2030  	s.GetMaster().Exec("TRUNCATE Channels")
  2031  }
  2032  
  2033  func testPostStoreGetDirectPostParentsForExportAfterDeleted(t *testing.T, ss store.Store, s SqlSupplier) {
  2034  	teamId := model.NewId()
  2035  
  2036  	o1 := model.Channel{}
  2037  	o1.TeamId = teamId
  2038  	o1.DisplayName = "Name"
  2039  	o1.Name = "zz" + model.NewId() + "b"
  2040  	o1.Type = model.CHANNEL_DIRECT
  2041  
  2042  	u1 := &model.User{}
  2043  	u1.DeleteAt = 1
  2044  	u1.Email = MakeEmail()
  2045  	u1.Nickname = model.NewId()
  2046  	store.Must(ss.User().Save(u1))
  2047  	store.Must(ss.Team().SaveMember(&model.TeamMember{TeamId: model.NewId(), UserId: u1.Id}, -1))
  2048  
  2049  	u2 := &model.User{}
  2050  	u2.DeleteAt = 1
  2051  	u2.Email = MakeEmail()
  2052  	u2.Nickname = model.NewId()
  2053  	store.Must(ss.User().Save(u2))
  2054  	store.Must(ss.Team().SaveMember(&model.TeamMember{TeamId: model.NewId(), UserId: u2.Id}, -1))
  2055  
  2056  	m1 := model.ChannelMember{}
  2057  	m1.ChannelId = o1.Id
  2058  	m1.UserId = u1.Id
  2059  	m1.NotifyProps = model.GetDefaultChannelNotifyProps()
  2060  
  2061  	m2 := model.ChannelMember{}
  2062  	m2.ChannelId = o1.Id
  2063  	m2.UserId = u2.Id
  2064  	m2.NotifyProps = model.GetDefaultChannelNotifyProps()
  2065  
  2066  	<-ss.Channel().SaveDirectChannel(&o1, &m1, &m2)
  2067  
  2068  	o1.DeleteAt = 1
  2069  	result := <-ss.Channel().SetDeleteAt(o1.Id, 1, 1)
  2070  	assert.Nil(t, result.Err)
  2071  
  2072  	p1 := &model.Post{}
  2073  	p1.ChannelId = o1.Id
  2074  	p1.UserId = u1.Id
  2075  	p1.Message = "zz" + model.NewId() + "BBBBBBBBBBBB"
  2076  	p1.CreateAt = 1000
  2077  	p1 = (<-ss.Post().Save(p1)).Data.(*model.Post)
  2078  
  2079  	o1a := &model.Post{}
  2080  	*o1a = *p1
  2081  	o1a.DeleteAt = 1
  2082  	o1a.Message = p1.Message + "BBBBBBBBBB"
  2083  	if result := <-ss.Post().Update(o1a, p1); result.Err != nil {
  2084  		t.Fatal(result.Err)
  2085  	}
  2086  
  2087  	r1 := <-ss.Post().GetDirectPostParentsForExportAfter(10000, strings.Repeat("0", 26))
  2088  	assert.Nil(t, r1.Err)
  2089  	d1 := r1.Data.([]*model.DirectPostForExport)
  2090  
  2091  	assert.Equal(t, 0, len(d1))
  2092  
  2093  	// Manually truncate Channels table until testlib can handle cleanups
  2094  	s.GetMaster().Exec("TRUNCATE Channels")
  2095  }
  2096  
  2097  func testPostStoreGetDirectPostParentsForExportAfterBatched(t *testing.T, ss store.Store, s SqlSupplier) {
  2098  	teamId := model.NewId()
  2099  
  2100  	o1 := model.Channel{}
  2101  	o1.TeamId = teamId
  2102  	o1.DisplayName = "Name"
  2103  	o1.Name = "zz" + model.NewId() + "b"
  2104  	o1.Type = model.CHANNEL_DIRECT
  2105  
  2106  	var postIds []string
  2107  	for i := 0; i < 150; i++ {
  2108  		u1 := &model.User{}
  2109  		u1.Email = MakeEmail()
  2110  		u1.Nickname = model.NewId()
  2111  		store.Must(ss.User().Save(u1))
  2112  		store.Must(ss.Team().SaveMember(&model.TeamMember{TeamId: model.NewId(), UserId: u1.Id}, -1))
  2113  
  2114  		u2 := &model.User{}
  2115  		u2.Email = MakeEmail()
  2116  		u2.Nickname = model.NewId()
  2117  		store.Must(ss.User().Save(u2))
  2118  		store.Must(ss.Team().SaveMember(&model.TeamMember{TeamId: model.NewId(), UserId: u2.Id}, -1))
  2119  
  2120  		m1 := model.ChannelMember{}
  2121  		m1.ChannelId = o1.Id
  2122  		m1.UserId = u1.Id
  2123  		m1.NotifyProps = model.GetDefaultChannelNotifyProps()
  2124  
  2125  		m2 := model.ChannelMember{}
  2126  		m2.ChannelId = o1.Id
  2127  		m2.UserId = u2.Id
  2128  		m2.NotifyProps = model.GetDefaultChannelNotifyProps()
  2129  
  2130  		<-ss.Channel().SaveDirectChannel(&o1, &m1, &m2)
  2131  
  2132  		p1 := &model.Post{}
  2133  		p1.ChannelId = o1.Id
  2134  		p1.UserId = u1.Id
  2135  		p1.Message = "zz" + model.NewId() + "AAAAAAAAAAA"
  2136  		p1.CreateAt = 1000
  2137  		p1 = (<-ss.Post().Save(p1)).Data.(*model.Post)
  2138  		postIds = append(postIds, p1.Id)
  2139  	}
  2140  	sort.Slice(postIds, func(i, j int) bool { return postIds[i] < postIds[j] })
  2141  
  2142  	// Get all posts
  2143  	r1 := <-ss.Post().GetDirectPostParentsForExportAfter(10000, strings.Repeat("0", 26))
  2144  	assert.Nil(t, r1.Err)
  2145  	d1 := r1.Data.([]*model.DirectPostForExport)
  2146  	assert.Equal(t, len(postIds), len(d1))
  2147  	var exportedPostIds []string
  2148  	for i := range d1 {
  2149  		exportedPostIds = append(exportedPostIds, d1[i].Id)
  2150  	}
  2151  	sort.Slice(exportedPostIds, func(i, j int) bool { return exportedPostIds[i] < exportedPostIds[j] })
  2152  	assert.ElementsMatch(t, postIds, exportedPostIds)
  2153  
  2154  	// Get 100
  2155  	r1 = <-ss.Post().GetDirectPostParentsForExportAfter(100, strings.Repeat("0", 26))
  2156  	assert.Nil(t, r1.Err)
  2157  	d1 = r1.Data.([]*model.DirectPostForExport)
  2158  	assert.Equal(t, 100, len(d1))
  2159  	exportedPostIds = []string{}
  2160  	for i := range d1 {
  2161  		exportedPostIds = append(exportedPostIds, d1[i].Id)
  2162  	}
  2163  	sort.Slice(exportedPostIds, func(i, j int) bool { return exportedPostIds[i] < exportedPostIds[j] })
  2164  	assert.ElementsMatch(t, postIds[:100], exportedPostIds)
  2165  
  2166  	// Manually truncate Channels table until testlib can handle cleanups
  2167  	s.GetMaster().Exec("TRUNCATE Channels")
  2168  }