github.com/mattermost/mattermost-server/v5@v5.39.3/store/storetest/compliance_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  	"encoding/json"
     8  	"testing"
     9  	"time"
    10  
    11  	"github.com/stretchr/testify/assert"
    12  	"github.com/stretchr/testify/require"
    13  
    14  	"github.com/mattermost/mattermost-server/v5/model"
    15  	"github.com/mattermost/mattermost-server/v5/store"
    16  )
    17  
    18  func cleanupStoreState(t *testing.T, ss store.Store) {
    19  	//remove existing users
    20  	allUsers, err := ss.User().GetAll()
    21  	require.NoError(t, err, "error cleaning all test users", err)
    22  	for _, u := range allUsers {
    23  		err = ss.User().PermanentDelete(u.Id)
    24  		require.NoError(t, err, "failed cleaning up test user %s", u.Username)
    25  
    26  		//remove all posts by this user
    27  		nErr := ss.Post().PermanentDeleteByUser(u.Id)
    28  		require.NoError(t, nErr, "failed cleaning all posts of test user %s", u.Username)
    29  	}
    30  
    31  	//remove existing channels
    32  	allChannels, nErr := ss.Channel().GetAllChannels(0, 100000, store.ChannelSearchOpts{IncludeDeleted: true})
    33  	require.NoError(t, nErr, "error cleaning all test channels", nErr)
    34  	for _, channel := range *allChannels {
    35  		nErr = ss.Channel().PermanentDelete(channel.Id)
    36  		require.NoError(t, nErr, "failed cleaning up test channel %s", channel.Id)
    37  	}
    38  
    39  	//remove existing teams
    40  	allTeams, nErr := ss.Team().GetAll()
    41  	require.NoError(t, nErr, "error cleaning all test teams", nErr)
    42  	for _, team := range allTeams {
    43  		err := ss.Team().PermanentDelete(team.Id)
    44  		require.NoError(t, err, "failed cleaning up test team %s", team.Id)
    45  	}
    46  }
    47  
    48  func TestComplianceStore(t *testing.T, ss store.Store) {
    49  	t.Run("", func(t *testing.T) { testComplianceStore(t, ss) })
    50  	t.Run("ComplianceExport", func(t *testing.T) { testComplianceExport(t, ss) })
    51  	t.Run("ComplianceExportDirectMessages", func(t *testing.T) { testComplianceExportDirectMessages(t, ss) })
    52  	t.Run("MessageExportPublicChannel", func(t *testing.T) { testMessageExportPublicChannel(t, ss) })
    53  	t.Run("MessageExportPrivateChannel", func(t *testing.T) { testMessageExportPrivateChannel(t, ss) })
    54  	t.Run("MessageExportDirectMessageChannel", func(t *testing.T) { testMessageExportDirectMessageChannel(t, ss) })
    55  	t.Run("MessageExportGroupMessageChannel", func(t *testing.T) { testMessageExportGroupMessageChannel(t, ss) })
    56  	t.Run("MessageEditExportMessage", func(t *testing.T) { testEditExportMessage(t, ss) })
    57  	t.Run("MessageEditAfterExportMessage", func(t *testing.T) { testEditAfterExportMessage(t, ss) })
    58  	t.Run("MessageDeleteExportMessage", func(t *testing.T) { testDeleteExportMessage(t, ss) })
    59  	t.Run("MessageDeleteAfterExportMessage", func(t *testing.T) { testDeleteAfterExportMessage(t, ss) })
    60  }
    61  
    62  func testComplianceStore(t *testing.T, ss store.Store) {
    63  	compliance1 := &model.Compliance{Desc: "Audit for federal subpoena case #22443", UserId: model.NewId(), Status: model.COMPLIANCE_STATUS_FAILED, StartAt: model.GetMillis() - 1, EndAt: model.GetMillis() + 1, Type: model.COMPLIANCE_TYPE_ADHOC}
    64  	_, err := ss.Compliance().Save(compliance1)
    65  	require.NoError(t, err)
    66  	time.Sleep(100 * time.Millisecond)
    67  
    68  	compliance2 := &model.Compliance{Desc: "Audit for federal subpoena case #11458", UserId: model.NewId(), Status: model.COMPLIANCE_STATUS_RUNNING, StartAt: model.GetMillis() - 1, EndAt: model.GetMillis() + 1, Type: model.COMPLIANCE_TYPE_ADHOC}
    69  	_, err = ss.Compliance().Save(compliance2)
    70  	require.NoError(t, err)
    71  	time.Sleep(100 * time.Millisecond)
    72  
    73  	compliances, _ := ss.Compliance().GetAll(0, 1000)
    74  
    75  	require.Equal(t, model.COMPLIANCE_STATUS_RUNNING, compliances[0].Status)
    76  	require.Equal(t, compliance2.Id, compliances[0].Id)
    77  
    78  	compliance2.Status = model.COMPLIANCE_STATUS_FAILED
    79  	_, err = ss.Compliance().Update(compliance2)
    80  	require.NoError(t, err)
    81  
    82  	compliances, _ = ss.Compliance().GetAll(0, 1000)
    83  
    84  	require.Equal(t, model.COMPLIANCE_STATUS_FAILED, compliances[0].Status)
    85  	require.Equal(t, compliance2.Id, compliances[0].Id)
    86  
    87  	compliances, _ = ss.Compliance().GetAll(0, 1)
    88  
    89  	require.Len(t, compliances, 1)
    90  
    91  	compliances, _ = ss.Compliance().GetAll(1, 1)
    92  
    93  	require.Len(t, compliances, 1)
    94  
    95  	rc2, _ := ss.Compliance().Get(compliance2.Id)
    96  	require.Equal(t, compliance2.Status, rc2.Status)
    97  }
    98  
    99  func testComplianceExport(t *testing.T, ss store.Store) {
   100  	time.Sleep(100 * time.Millisecond)
   101  	const (
   102  		limit = 30000
   103  	)
   104  
   105  	t1 := &model.Team{}
   106  	t1.DisplayName = "DisplayName"
   107  	t1.Name = "zz" + model.NewId() + "b"
   108  	t1.Email = MakeEmail()
   109  	t1.Type = model.TEAM_OPEN
   110  	t1, err := ss.Team().Save(t1)
   111  	require.NoError(t, err)
   112  
   113  	u1 := &model.User{}
   114  	u1.Email = MakeEmail()
   115  	u1.Username = model.NewId()
   116  	u1, err = ss.User().Save(u1)
   117  	require.NoError(t, err)
   118  	_, nErr := ss.Team().SaveMember(&model.TeamMember{TeamId: t1.Id, UserId: u1.Id}, -1)
   119  	require.NoError(t, nErr)
   120  
   121  	u2 := &model.User{}
   122  	u2.Email = MakeEmail()
   123  	u2.Username = model.NewId()
   124  	u2, err = ss.User().Save(u2)
   125  	require.NoError(t, err)
   126  	_, nErr = ss.Team().SaveMember(&model.TeamMember{TeamId: t1.Id, UserId: u2.Id}, -1)
   127  	require.NoError(t, nErr)
   128  
   129  	c1 := &model.Channel{}
   130  	c1.TeamId = t1.Id
   131  	c1.DisplayName = "Channel2"
   132  	c1.Name = "zz" + model.NewId() + "b"
   133  	c1.Type = model.CHANNEL_OPEN
   134  	c1, nErr = ss.Channel().Save(c1, -1)
   135  	require.NoError(t, nErr)
   136  
   137  	o1 := &model.Post{}
   138  	o1.ChannelId = c1.Id
   139  	o1.UserId = u1.Id
   140  	o1.CreateAt = model.GetMillis()
   141  	o1.Message = "zz" + model.NewId() + "b"
   142  	o1, nErr = ss.Post().Save(o1)
   143  	require.NoError(t, nErr)
   144  
   145  	o1a := &model.Post{}
   146  	o1a.ChannelId = c1.Id
   147  	o1a.UserId = u1.Id
   148  	o1a.CreateAt = o1.CreateAt + 10
   149  	o1a.Message = "zz" + model.NewId() + "b"
   150  	_, nErr = ss.Post().Save(o1a)
   151  	require.NoError(t, nErr)
   152  
   153  	o2 := &model.Post{}
   154  	o2.ChannelId = c1.Id
   155  	o2.UserId = u1.Id
   156  	o2.CreateAt = o1.CreateAt + 20
   157  	o2.Message = "zz" + model.NewId() + "b"
   158  	_, nErr = ss.Post().Save(o2)
   159  	require.NoError(t, nErr)
   160  
   161  	o2a := &model.Post{}
   162  	o2a.ChannelId = c1.Id
   163  	o2a.UserId = u2.Id
   164  	o2a.CreateAt = o1.CreateAt + 30
   165  	o2a.Message = "zz" + model.NewId() + "b"
   166  	o2a, nErr = ss.Post().Save(o2a)
   167  	require.NoError(t, nErr)
   168  
   169  	time.Sleep(100 * time.Millisecond)
   170  
   171  	cr1 := &model.Compliance{Desc: "test" + model.NewId(), StartAt: o1.CreateAt - 1, EndAt: o2a.CreateAt + 1}
   172  	cposts, _, nErr := ss.Compliance().ComplianceExport(cr1, model.ComplianceExportCursor{}, limit)
   173  	require.NoError(t, nErr)
   174  	assert.Len(t, cposts, 4)
   175  	assert.Equal(t, cposts[0].PostId, o1.Id)
   176  	assert.Equal(t, cposts[3].PostId, o2a.Id)
   177  
   178  	cr2 := &model.Compliance{Desc: "test" + model.NewId(), StartAt: o1.CreateAt - 1, EndAt: o2a.CreateAt + 1, Emails: u2.Email}
   179  	cposts, _, nErr = ss.Compliance().ComplianceExport(cr2, model.ComplianceExportCursor{}, limit)
   180  	require.NoError(t, nErr)
   181  	assert.Len(t, cposts, 1)
   182  	assert.Equal(t, cposts[0].PostId, o2a.Id)
   183  
   184  	cr3 := &model.Compliance{Desc: "test" + model.NewId(), StartAt: o1.CreateAt - 1, EndAt: o2a.CreateAt + 1, Emails: u2.Email + ", " + u1.Email}
   185  	cposts, _, nErr = ss.Compliance().ComplianceExport(cr3, model.ComplianceExportCursor{}, limit)
   186  	require.NoError(t, nErr)
   187  	assert.Len(t, cposts, 4)
   188  	assert.Equal(t, cposts[0].PostId, o1.Id)
   189  	assert.Equal(t, cposts[3].PostId, o2a.Id)
   190  
   191  	cr4 := &model.Compliance{Desc: "test" + model.NewId(), StartAt: o1.CreateAt - 1, EndAt: o2a.CreateAt + 1, Keywords: o2a.Message}
   192  	cposts, _, nErr = ss.Compliance().ComplianceExport(cr4, model.ComplianceExportCursor{}, limit)
   193  	require.NoError(t, nErr)
   194  	assert.Len(t, cposts, 1)
   195  	assert.Equal(t, cposts[0].PostId, o2a.Id)
   196  
   197  	cr5 := &model.Compliance{Desc: "test" + model.NewId(), StartAt: o1.CreateAt - 1, EndAt: o2a.CreateAt + 1, Keywords: o2a.Message + " " + o1.Message}
   198  	cposts, _, nErr = ss.Compliance().ComplianceExport(cr5, model.ComplianceExportCursor{}, limit)
   199  	require.NoError(t, nErr)
   200  	assert.Len(t, cposts, 2)
   201  	assert.Equal(t, cposts[0].PostId, o1.Id)
   202  
   203  	cr6 := &model.Compliance{Desc: "test" + model.NewId(), StartAt: o1.CreateAt - 1, EndAt: o2a.CreateAt + 1, Emails: u2.Email + ", " + u1.Email, Keywords: o2a.Message + " " + o1.Message}
   204  	cposts, _, nErr = ss.Compliance().ComplianceExport(cr6, model.ComplianceExportCursor{}, limit)
   205  	require.NoError(t, nErr)
   206  	assert.Len(t, cposts, 2)
   207  	assert.Equal(t, cposts[0].PostId, o1.Id)
   208  	assert.Equal(t, cposts[1].PostId, o2a.Id)
   209  
   210  	t.Run("multiple batches", func(t *testing.T) {
   211  		cr7 := &model.Compliance{Desc: "test" + model.NewId(), StartAt: o1.CreateAt - 1, EndAt: o2a.CreateAt + 1}
   212  		cursor := model.ComplianceExportCursor{}
   213  		cposts, cursor, nErr = ss.Compliance().ComplianceExport(cr7, cursor, 2)
   214  		require.NoError(t, nErr)
   215  		assert.Len(t, cposts, 2)
   216  		assert.Equal(t, cposts[0].PostId, o1.Id)
   217  		assert.Equal(t, cposts[1].PostId, o1a.Id)
   218  		cposts, _, nErr = ss.Compliance().ComplianceExport(cr7, cursor, 3)
   219  		require.NoError(t, nErr)
   220  		assert.Len(t, cposts, 2)
   221  		assert.Equal(t, cposts[0].PostId, o2.Id)
   222  		assert.Equal(t, cposts[1].PostId, o2a.Id)
   223  	})
   224  }
   225  
   226  func testComplianceExportDirectMessages(t *testing.T, ss store.Store) {
   227  	defer cleanupStoreState(t, ss)
   228  
   229  	time.Sleep(100 * time.Millisecond)
   230  	const (
   231  		limit = 30000
   232  	)
   233  
   234  	t1 := &model.Team{}
   235  	t1.DisplayName = "DisplayName"
   236  	t1.Name = "zz" + model.NewId() + "b"
   237  	t1.Email = MakeEmail()
   238  	t1.Type = model.TEAM_OPEN
   239  	t1, err := ss.Team().Save(t1)
   240  	require.NoError(t, err)
   241  
   242  	u1 := &model.User{}
   243  	u1.Email = MakeEmail()
   244  	u1.Username = model.NewId()
   245  	u1, err = ss.User().Save(u1)
   246  	require.NoError(t, err)
   247  	_, nErr := ss.Team().SaveMember(&model.TeamMember{TeamId: t1.Id, UserId: u1.Id}, -1)
   248  	require.NoError(t, nErr)
   249  
   250  	u2 := &model.User{}
   251  	u2.Email = MakeEmail()
   252  	u2.Username = model.NewId()
   253  	u2, err = ss.User().Save(u2)
   254  	require.NoError(t, err)
   255  	_, nErr = ss.Team().SaveMember(&model.TeamMember{TeamId: t1.Id, UserId: u2.Id}, -1)
   256  	require.NoError(t, nErr)
   257  
   258  	c1 := &model.Channel{}
   259  	c1.TeamId = t1.Id
   260  	c1.DisplayName = "Channel2"
   261  	c1.Name = "zz" + model.NewId() + "b"
   262  	c1.Type = model.CHANNEL_OPEN
   263  	c1, nErr = ss.Channel().Save(c1, -1)
   264  	require.NoError(t, nErr)
   265  
   266  	cDM, nErr := ss.Channel().CreateDirectChannel(u1, u2)
   267  	require.NoError(t, nErr)
   268  	o1 := &model.Post{}
   269  	o1.ChannelId = c1.Id
   270  	o1.UserId = u1.Id
   271  	o1.CreateAt = model.GetMillis()
   272  	o1.Message = "zz" + model.NewId() + "b"
   273  	o1, nErr = ss.Post().Save(o1)
   274  	require.NoError(t, nErr)
   275  
   276  	o1a := &model.Post{}
   277  	o1a.ChannelId = c1.Id
   278  	o1a.UserId = u1.Id
   279  	o1a.CreateAt = o1.CreateAt + 10
   280  	o1a.Message = "zz" + model.NewId() + "b"
   281  	_, nErr = ss.Post().Save(o1a)
   282  	require.NoError(t, nErr)
   283  
   284  	o2 := &model.Post{}
   285  	o2.ChannelId = c1.Id
   286  	o2.UserId = u1.Id
   287  	o2.CreateAt = o1.CreateAt + 20
   288  	o2.Message = "zz" + model.NewId() + "b"
   289  	_, nErr = ss.Post().Save(o2)
   290  	require.NoError(t, nErr)
   291  
   292  	o2a := &model.Post{}
   293  	o2a.ChannelId = c1.Id
   294  	o2a.UserId = u2.Id
   295  	o2a.CreateAt = o1.CreateAt + 30
   296  	o2a.Message = "zz" + model.NewId() + "b"
   297  	_, nErr = ss.Post().Save(o2a)
   298  	require.NoError(t, nErr)
   299  
   300  	o3 := &model.Post{}
   301  	o3.ChannelId = cDM.Id
   302  	o3.UserId = u1.Id
   303  	o3.CreateAt = o1.CreateAt + 40
   304  	o3.Message = "zz" + model.NewId() + "b"
   305  	o3, nErr = ss.Post().Save(o3)
   306  	require.NoError(t, nErr)
   307  
   308  	time.Sleep(100 * time.Millisecond)
   309  
   310  	cr1 := &model.Compliance{Desc: "test" + model.NewId(), StartAt: o1.CreateAt - 1, EndAt: o3.CreateAt + 1, Emails: u1.Email}
   311  	cposts, _, nErr := ss.Compliance().ComplianceExport(cr1, model.ComplianceExportCursor{}, limit)
   312  	require.NoError(t, nErr)
   313  	assert.Len(t, cposts, 4)
   314  	assert.Equal(t, cposts[0].PostId, o1.Id)
   315  	assert.Equal(t, cposts[len(cposts)-1].PostId, o3.Id)
   316  
   317  	t.Run("mix of channel and direct messages", func(t *testing.T) {
   318  		// This will "cross the boundary" between the two queries
   319  		cursor := model.ComplianceExportCursor{}
   320  		cr2 := &model.Compliance{Desc: "test" + model.NewId(), StartAt: o1.CreateAt - 1, EndAt: o3.CreateAt + 1, Emails: u1.Email}
   321  
   322  		cposts, cursor, nErr = ss.Compliance().ComplianceExport(cr2, cursor, 2)
   323  		require.NoError(t, nErr)
   324  		assert.Len(t, cposts, 2)
   325  		assert.Equal(t, cposts[0].PostId, o1.Id)
   326  		assert.Equal(t, cposts[len(cposts)-1].PostId, o1a.Id)
   327  
   328  		cposts, _, nErr = ss.Compliance().ComplianceExport(cr2, cursor, 2)
   329  		require.NoError(t, nErr)
   330  		assert.Len(t, cposts, 2)
   331  		assert.Equal(t, cposts[0].PostId, o2.Id)
   332  		assert.Equal(t, cposts[len(cposts)-1].PostId, o3.Id)
   333  
   334  		// This will exhaust the first query before moving to the next one
   335  		cursor = model.ComplianceExportCursor{}
   336  		cr3 := &model.Compliance{Desc: "test" + model.NewId(), StartAt: o1.CreateAt - 1, EndAt: o3.CreateAt + 1, Emails: u1.Email}
   337  
   338  		cposts, cursor, nErr = ss.Compliance().ComplianceExport(cr3, cursor, 3)
   339  		require.NoError(t, nErr)
   340  		assert.Len(t, cposts, 3)
   341  		assert.Equal(t, cposts[0].PostId, o1.Id)
   342  		assert.Equal(t, cposts[len(cposts)-1].PostId, o2.Id)
   343  
   344  		cposts, _, nErr = ss.Compliance().ComplianceExport(cr3, cursor, 2)
   345  		require.NoError(t, nErr)
   346  		assert.Len(t, cposts, 1)
   347  		assert.Equal(t, cposts[0].PostId, o3.Id)
   348  	})
   349  
   350  	t.Run("timestamp collision", func(t *testing.T) {
   351  		time.Sleep(100 * time.Millisecond)
   352  		nowMillis := model.GetMillis()
   353  
   354  		createPost := func(createAt int64) {
   355  			post := &model.Post{}
   356  			post.ChannelId = c1.Id
   357  			post.UserId = u1.Id
   358  			post.CreateAt = createAt
   359  			post.Message = "zz" + model.NewId() + "b"
   360  			post, nErr = ss.Post().Save(post)
   361  			require.NoError(t, nErr)
   362  		}
   363  
   364  		for i := 0; i < 3; i++ {
   365  			createPost(nowMillis)
   366  		}
   367  		for i := 0; i < 2; i++ {
   368  			createPost(nowMillis + 1)
   369  		}
   370  
   371  		cursor := model.ComplianceExportCursor{}
   372  
   373  		cr4 := &model.Compliance{Desc: "test" + model.NewId(), StartAt: nowMillis, EndAt: nowMillis + 2}
   374  		cposts, cursor, nErr = ss.Compliance().ComplianceExport(cr4, cursor, 2)
   375  		require.NoError(t, nErr)
   376  		assert.Len(t, cposts, 2)
   377  
   378  		cr5 := &model.Compliance{Desc: "test" + model.NewId(), StartAt: nowMillis, EndAt: nowMillis + 2}
   379  		cposts, _, nErr = ss.Compliance().ComplianceExport(cr5, cursor, 3)
   380  		require.NoError(t, nErr)
   381  		assert.Len(t, cposts, 3)
   382  
   383  		// range should be [inclusive, exclusive)
   384  		cursor = model.ComplianceExportCursor{}
   385  		cr6 := &model.Compliance{Desc: "test" + model.NewId(), StartAt: nowMillis, EndAt: nowMillis + 1}
   386  		cposts, _, nErr = ss.Compliance().ComplianceExport(cr6, cursor, 5)
   387  		require.NoError(t, nErr)
   388  		assert.Len(t, cposts, 3)
   389  	})
   390  }
   391  
   392  func testMessageExportPublicChannel(t *testing.T, ss store.Store) {
   393  	defer cleanupStoreState(t, ss)
   394  
   395  	// get the starting number of message export entries
   396  	startTime := model.GetMillis()
   397  	messages, _, err := ss.Compliance().MessageExport(model.MessageExportCursor{LastPostUpdateAt: startTime - 10}, 10)
   398  	require.NoError(t, err)
   399  	assert.Equal(t, 0, len(messages))
   400  
   401  	// need a team
   402  	team := &model.Team{
   403  		DisplayName: "DisplayName",
   404  		Name:        "zz" + model.NewId() + "b",
   405  		Email:       MakeEmail(),
   406  		Type:        model.TEAM_OPEN,
   407  	}
   408  	team, err = ss.Team().Save(team)
   409  	require.NoError(t, err)
   410  
   411  	// and two users that are a part of that team
   412  	user1 := &model.User{
   413  		Email:    MakeEmail(),
   414  		Username: model.NewId(),
   415  	}
   416  	user1, err = ss.User().Save(user1)
   417  	require.NoError(t, err)
   418  	_, nErr := ss.Team().SaveMember(&model.TeamMember{
   419  		TeamId: team.Id,
   420  		UserId: user1.Id,
   421  	}, -1)
   422  	require.NoError(t, nErr)
   423  
   424  	user2 := &model.User{
   425  		Email:    MakeEmail(),
   426  		Username: model.NewId(),
   427  	}
   428  	user2, err = ss.User().Save(user2)
   429  	require.NoError(t, err)
   430  	_, nErr = ss.Team().SaveMember(&model.TeamMember{
   431  		TeamId: team.Id,
   432  		UserId: user2.Id,
   433  	}, -1)
   434  	require.NoError(t, nErr)
   435  
   436  	// need a public channel
   437  	channel := &model.Channel{
   438  		TeamId:      team.Id,
   439  		Name:        model.NewId(),
   440  		DisplayName: "Public Channel",
   441  		Type:        model.CHANNEL_OPEN,
   442  	}
   443  	channel, nErr = ss.Channel().Save(channel, -1)
   444  	require.NoError(t, nErr)
   445  
   446  	// user1 posts twice in the public channel
   447  	post1 := &model.Post{
   448  		ChannelId: channel.Id,
   449  		UserId:    user1.Id,
   450  		CreateAt:  startTime,
   451  		Message:   "zz" + model.NewId() + "a",
   452  	}
   453  	post1, err = ss.Post().Save(post1)
   454  	require.NoError(t, err)
   455  
   456  	post2 := &model.Post{
   457  		ChannelId: channel.Id,
   458  		UserId:    user1.Id,
   459  		CreateAt:  startTime + 10,
   460  		Message:   "zz" + model.NewId() + "b",
   461  	}
   462  	post2, err = ss.Post().Save(post2)
   463  	require.NoError(t, err)
   464  
   465  	// fetch the message exports for both posts that user1 sent
   466  	messageExportMap := map[string]model.MessageExport{}
   467  	messages, _, err = ss.Compliance().MessageExport(model.MessageExportCursor{LastPostUpdateAt: startTime - 10}, 10)
   468  	require.NoError(t, err)
   469  	assert.Equal(t, 2, len(messages))
   470  
   471  	for _, v := range messages {
   472  		messageExportMap[*v.PostId] = *v
   473  	}
   474  
   475  	// post1 was made by user1 in channel1 and team1
   476  	assert.Equal(t, post1.Id, *messageExportMap[post1.Id].PostId)
   477  	assert.Equal(t, post1.CreateAt, *messageExportMap[post1.Id].PostCreateAt)
   478  	assert.Equal(t, post1.Message, *messageExportMap[post1.Id].PostMessage)
   479  	assert.Equal(t, channel.Id, *messageExportMap[post1.Id].ChannelId)
   480  	assert.Equal(t, channel.DisplayName, *messageExportMap[post1.Id].ChannelDisplayName)
   481  	assert.Equal(t, user1.Id, *messageExportMap[post1.Id].UserId)
   482  	assert.Equal(t, user1.Email, *messageExportMap[post1.Id].UserEmail)
   483  	assert.Equal(t, user1.Username, *messageExportMap[post1.Id].Username)
   484  
   485  	// post2 was made by user1 in channel1 and team1
   486  	assert.Equal(t, post2.Id, *messageExportMap[post2.Id].PostId)
   487  	assert.Equal(t, post2.CreateAt, *messageExportMap[post2.Id].PostCreateAt)
   488  	assert.Equal(t, post2.Message, *messageExportMap[post2.Id].PostMessage)
   489  	assert.Equal(t, channel.Id, *messageExportMap[post2.Id].ChannelId)
   490  	assert.Equal(t, channel.DisplayName, *messageExportMap[post2.Id].ChannelDisplayName)
   491  	assert.Equal(t, user1.Id, *messageExportMap[post2.Id].UserId)
   492  	assert.Equal(t, user1.Email, *messageExportMap[post2.Id].UserEmail)
   493  	assert.Equal(t, user1.Username, *messageExportMap[post2.Id].Username)
   494  }
   495  
   496  func testMessageExportPrivateChannel(t *testing.T, ss store.Store) {
   497  	defer cleanupStoreState(t, ss)
   498  
   499  	// get the starting number of message export entries
   500  	startTime := model.GetMillis()
   501  	messages, _, err := ss.Compliance().MessageExport(model.MessageExportCursor{LastPostUpdateAt: startTime - 10}, 10)
   502  	require.NoError(t, err)
   503  	assert.Equal(t, 0, len(messages))
   504  
   505  	// need a team
   506  	team := &model.Team{
   507  		DisplayName: "DisplayName",
   508  		Name:        "zz" + model.NewId() + "b",
   509  		Email:       MakeEmail(),
   510  		Type:        model.TEAM_OPEN,
   511  	}
   512  	team, err = ss.Team().Save(team)
   513  	require.NoError(t, err)
   514  
   515  	// and two users that are a part of that team
   516  	user1 := &model.User{
   517  		Email:    MakeEmail(),
   518  		Username: model.NewId(),
   519  	}
   520  	user1, err = ss.User().Save(user1)
   521  	require.NoError(t, err)
   522  	_, nErr := ss.Team().SaveMember(&model.TeamMember{
   523  		TeamId: team.Id,
   524  		UserId: user1.Id,
   525  	}, -1)
   526  	require.NoError(t, nErr)
   527  
   528  	user2 := &model.User{
   529  		Email:    MakeEmail(),
   530  		Username: model.NewId(),
   531  	}
   532  	user2, err = ss.User().Save(user2)
   533  	require.NoError(t, err)
   534  	_, nErr = ss.Team().SaveMember(&model.TeamMember{
   535  		TeamId: team.Id,
   536  		UserId: user2.Id,
   537  	}, -1)
   538  	require.NoError(t, nErr)
   539  
   540  	// need a private channel
   541  	channel := &model.Channel{
   542  		TeamId:      team.Id,
   543  		Name:        model.NewId(),
   544  		DisplayName: "Private Channel",
   545  		Type:        model.CHANNEL_PRIVATE,
   546  	}
   547  	channel, nErr = ss.Channel().Save(channel, -1)
   548  	require.NoError(t, nErr)
   549  
   550  	// user1 posts twice in the private channel
   551  	post1 := &model.Post{
   552  		ChannelId: channel.Id,
   553  		UserId:    user1.Id,
   554  		CreateAt:  startTime,
   555  		Message:   "zz" + model.NewId() + "a",
   556  	}
   557  	post1, err = ss.Post().Save(post1)
   558  	require.NoError(t, err)
   559  
   560  	post2 := &model.Post{
   561  		ChannelId: channel.Id,
   562  		UserId:    user1.Id,
   563  		CreateAt:  startTime + 10,
   564  		Message:   "zz" + model.NewId() + "b",
   565  	}
   566  	post2, err = ss.Post().Save(post2)
   567  	require.NoError(t, err)
   568  
   569  	// fetch the message exports for both posts that user1 sent
   570  	messageExportMap := map[string]model.MessageExport{}
   571  	messages, _, err = ss.Compliance().MessageExport(model.MessageExportCursor{LastPostUpdateAt: startTime - 10}, 10)
   572  	require.NoError(t, err)
   573  	assert.Equal(t, 2, len(messages))
   574  
   575  	for _, v := range messages {
   576  		messageExportMap[*v.PostId] = *v
   577  	}
   578  
   579  	// post1 was made by user1 in channel1 and team1
   580  	assert.Equal(t, post1.Id, *messageExportMap[post1.Id].PostId)
   581  	assert.Equal(t, post1.CreateAt, *messageExportMap[post1.Id].PostCreateAt)
   582  	assert.Equal(t, post1.Message, *messageExportMap[post1.Id].PostMessage)
   583  	assert.Equal(t, channel.Id, *messageExportMap[post1.Id].ChannelId)
   584  	assert.Equal(t, channel.DisplayName, *messageExportMap[post1.Id].ChannelDisplayName)
   585  	assert.Equal(t, channel.Type, *messageExportMap[post1.Id].ChannelType)
   586  	assert.Equal(t, user1.Id, *messageExportMap[post1.Id].UserId)
   587  	assert.Equal(t, user1.Email, *messageExportMap[post1.Id].UserEmail)
   588  	assert.Equal(t, user1.Username, *messageExportMap[post1.Id].Username)
   589  
   590  	// post2 was made by user1 in channel1 and team1
   591  	assert.Equal(t, post2.Id, *messageExportMap[post2.Id].PostId)
   592  	assert.Equal(t, post2.CreateAt, *messageExportMap[post2.Id].PostCreateAt)
   593  	assert.Equal(t, post2.Message, *messageExportMap[post2.Id].PostMessage)
   594  	assert.Equal(t, channel.Id, *messageExportMap[post2.Id].ChannelId)
   595  	assert.Equal(t, channel.DisplayName, *messageExportMap[post2.Id].ChannelDisplayName)
   596  	assert.Equal(t, channel.Type, *messageExportMap[post2.Id].ChannelType)
   597  	assert.Equal(t, user1.Id, *messageExportMap[post2.Id].UserId)
   598  	assert.Equal(t, user1.Email, *messageExportMap[post2.Id].UserEmail)
   599  	assert.Equal(t, user1.Username, *messageExportMap[post2.Id].Username)
   600  }
   601  
   602  func testMessageExportDirectMessageChannel(t *testing.T, ss store.Store) {
   603  	defer cleanupStoreState(t, ss)
   604  
   605  	// get the starting number of message export entries
   606  	startTime := model.GetMillis()
   607  	messages, _, err := ss.Compliance().MessageExport(model.MessageExportCursor{LastPostUpdateAt: startTime - 10}, 10)
   608  	require.NoError(t, err)
   609  	assert.Equal(t, 0, len(messages))
   610  
   611  	// need a team
   612  	team := &model.Team{
   613  		DisplayName: "DisplayName",
   614  		Name:        "zz" + model.NewId() + "b",
   615  		Email:       MakeEmail(),
   616  		Type:        model.TEAM_OPEN,
   617  	}
   618  	team, err = ss.Team().Save(team)
   619  	require.NoError(t, err)
   620  
   621  	// and two users that are a part of that team
   622  	user1 := &model.User{
   623  		Email:    MakeEmail(),
   624  		Username: model.NewId(),
   625  	}
   626  	user1, err = ss.User().Save(user1)
   627  	require.NoError(t, err)
   628  	_, nErr := ss.Team().SaveMember(&model.TeamMember{
   629  		TeamId: team.Id,
   630  		UserId: user1.Id,
   631  	}, -1)
   632  	require.NoError(t, nErr)
   633  
   634  	user2 := &model.User{
   635  		Email:    MakeEmail(),
   636  		Username: model.NewId(),
   637  	}
   638  	user2, err = ss.User().Save(user2)
   639  	require.NoError(t, err)
   640  	_, nErr = ss.Team().SaveMember(&model.TeamMember{
   641  		TeamId: team.Id,
   642  		UserId: user2.Id,
   643  	}, -1)
   644  	require.NoError(t, nErr)
   645  
   646  	// as well as a DM channel between those users
   647  	directMessageChannel, nErr := ss.Channel().CreateDirectChannel(user1, user2)
   648  	require.NoError(t, nErr)
   649  
   650  	// user1 also sends a DM to user2
   651  	post := &model.Post{
   652  		ChannelId: directMessageChannel.Id,
   653  		UserId:    user1.Id,
   654  		CreateAt:  startTime + 20,
   655  		Message:   "zz" + model.NewId() + "c",
   656  	}
   657  	post, err = ss.Post().Save(post)
   658  	require.NoError(t, err)
   659  
   660  	// fetch the message export for the post that user1 sent
   661  	messageExportMap := map[string]model.MessageExport{}
   662  	messages, _, err = ss.Compliance().MessageExport(model.MessageExportCursor{LastPostUpdateAt: startTime - 10}, 10)
   663  	require.NoError(t, err)
   664  
   665  	assert.Equal(t, 1, len(messages))
   666  
   667  	for _, v := range messages {
   668  		messageExportMap[*v.PostId] = *v
   669  	}
   670  
   671  	// post is a DM between user1 and user2
   672  	// there is no channel display name for direct messages, so we sub in the string "Direct Message" instead
   673  	assert.Equal(t, post.Id, *messageExportMap[post.Id].PostId)
   674  	assert.Equal(t, post.CreateAt, *messageExportMap[post.Id].PostCreateAt)
   675  	assert.Equal(t, post.Message, *messageExportMap[post.Id].PostMessage)
   676  	assert.Equal(t, directMessageChannel.Id, *messageExportMap[post.Id].ChannelId)
   677  	assert.Equal(t, "Direct Message", *messageExportMap[post.Id].ChannelDisplayName)
   678  	assert.Equal(t, user1.Id, *messageExportMap[post.Id].UserId)
   679  	assert.Equal(t, user1.Email, *messageExportMap[post.Id].UserEmail)
   680  	assert.Equal(t, user1.Username, *messageExportMap[post.Id].Username)
   681  }
   682  
   683  func testMessageExportGroupMessageChannel(t *testing.T, ss store.Store) {
   684  	defer cleanupStoreState(t, ss)
   685  
   686  	// get the starting number of message export entries
   687  	startTime := model.GetMillis()
   688  	messages, _, err := ss.Compliance().MessageExport(model.MessageExportCursor{LastPostUpdateAt: startTime - 10}, 10)
   689  	require.NoError(t, err)
   690  	assert.Equal(t, 0, len(messages))
   691  
   692  	// need a team
   693  	team := &model.Team{
   694  		DisplayName: "DisplayName",
   695  		Name:        "zz" + model.NewId() + "b",
   696  		Email:       MakeEmail(),
   697  		Type:        model.TEAM_OPEN,
   698  	}
   699  	team, err = ss.Team().Save(team)
   700  	require.NoError(t, err)
   701  
   702  	// and three users that are a part of that team
   703  	user1 := &model.User{
   704  		Email:    MakeEmail(),
   705  		Username: model.NewId(),
   706  	}
   707  	user1, err = ss.User().Save(user1)
   708  	require.NoError(t, err)
   709  	_, nErr := ss.Team().SaveMember(&model.TeamMember{
   710  		TeamId: team.Id,
   711  		UserId: user1.Id,
   712  	}, -1)
   713  	require.NoError(t, nErr)
   714  
   715  	user2 := &model.User{
   716  		Email:    MakeEmail(),
   717  		Username: model.NewId(),
   718  	}
   719  	user2, err = ss.User().Save(user2)
   720  	require.NoError(t, err)
   721  	_, nErr = ss.Team().SaveMember(&model.TeamMember{
   722  		TeamId: team.Id,
   723  		UserId: user2.Id,
   724  	}, -1)
   725  	require.NoError(t, nErr)
   726  
   727  	user3 := &model.User{
   728  		Email:    MakeEmail(),
   729  		Username: model.NewId(),
   730  	}
   731  	user3, err = ss.User().Save(user3)
   732  	require.NoError(t, err)
   733  	_, nErr = ss.Team().SaveMember(&model.TeamMember{
   734  		TeamId: team.Id,
   735  		UserId: user3.Id,
   736  	}, -1)
   737  	require.NoError(t, nErr)
   738  
   739  	// can't create a group channel directly, because importing app creates an import cycle, so we have to fake it
   740  	groupMessageChannel := &model.Channel{
   741  		TeamId: team.Id,
   742  		Name:   model.NewId(),
   743  		Type:   model.CHANNEL_GROUP,
   744  	}
   745  	groupMessageChannel, nErr = ss.Channel().Save(groupMessageChannel, -1)
   746  	require.NoError(t, nErr)
   747  
   748  	// user1 posts in the GM
   749  	post := &model.Post{
   750  		ChannelId: groupMessageChannel.Id,
   751  		UserId:    user1.Id,
   752  		CreateAt:  startTime + 20,
   753  		Message:   "zz" + model.NewId() + "c",
   754  	}
   755  	post, err = ss.Post().Save(post)
   756  	require.NoError(t, err)
   757  
   758  	// fetch the message export for the post that user1 sent
   759  	messageExportMap := map[string]model.MessageExport{}
   760  	messages, _, err = ss.Compliance().MessageExport(model.MessageExportCursor{LastPostUpdateAt: startTime - 10}, 10)
   761  	require.NoError(t, err)
   762  	assert.Equal(t, 1, len(messages))
   763  
   764  	for _, v := range messages {
   765  		messageExportMap[*v.PostId] = *v
   766  	}
   767  
   768  	// post is a DM between user1 and user2
   769  	// there is no channel display name for direct messages, so we sub in the string "Direct Message" instead
   770  	assert.Equal(t, post.Id, *messageExportMap[post.Id].PostId)
   771  	assert.Equal(t, post.CreateAt, *messageExportMap[post.Id].PostCreateAt)
   772  	assert.Equal(t, post.Message, *messageExportMap[post.Id].PostMessage)
   773  	assert.Equal(t, groupMessageChannel.Id, *messageExportMap[post.Id].ChannelId)
   774  	assert.Equal(t, "Group Message", *messageExportMap[post.Id].ChannelDisplayName)
   775  	assert.Equal(t, user1.Id, *messageExportMap[post.Id].UserId)
   776  	assert.Equal(t, user1.Email, *messageExportMap[post.Id].UserEmail)
   777  	assert.Equal(t, user1.Username, *messageExportMap[post.Id].Username)
   778  }
   779  
   780  //post,edit,export
   781  func testEditExportMessage(t *testing.T, ss store.Store) {
   782  	defer cleanupStoreState(t, ss)
   783  	// get the starting number of message export entries
   784  	startTime := model.GetMillis()
   785  	messages, _, err := ss.Compliance().MessageExport(model.MessageExportCursor{LastPostUpdateAt: startTime - 1}, 10)
   786  	require.NoError(t, err)
   787  	assert.Equal(t, 0, len(messages))
   788  
   789  	// need a team
   790  	team := &model.Team{
   791  		DisplayName: "DisplayName",
   792  		Name:        "zz" + model.NewId() + "b",
   793  		Email:       MakeEmail(),
   794  		Type:        model.TEAM_OPEN,
   795  	}
   796  	team, err = ss.Team().Save(team)
   797  	require.NoError(t, err)
   798  
   799  	// need a user part of that team
   800  	user1 := &model.User{
   801  		Email:    MakeEmail(),
   802  		Username: model.NewId(),
   803  	}
   804  	user1, err = ss.User().Save(user1)
   805  	require.NoError(t, err)
   806  	_, nErr := ss.Team().SaveMember(&model.TeamMember{
   807  		TeamId: team.Id,
   808  		UserId: user1.Id,
   809  	}, -1)
   810  	require.NoError(t, nErr)
   811  
   812  	// need a public channel
   813  	channel := &model.Channel{
   814  		TeamId:      team.Id,
   815  		Name:        model.NewId(),
   816  		DisplayName: "Public Channel",
   817  		Type:        model.CHANNEL_OPEN,
   818  	}
   819  	channel, nErr = ss.Channel().Save(channel, -1)
   820  	require.NoError(t, nErr)
   821  
   822  	// user1 posts in the public channel
   823  	post1 := &model.Post{
   824  		ChannelId: channel.Id,
   825  		UserId:    user1.Id,
   826  		CreateAt:  startTime,
   827  		Message:   "zz" + model.NewId() + "a",
   828  	}
   829  	post1, err = ss.Post().Save(post1)
   830  	require.NoError(t, err)
   831  
   832  	//user 1 edits the previous post
   833  	post1e := post1.Clone()
   834  	post1e.Message = "edit " + post1.Message
   835  
   836  	post1e, err = ss.Post().Update(post1e, post1)
   837  	require.NoError(t, err)
   838  
   839  	// fetch the message exports from the start
   840  	messages, _, err = ss.Compliance().MessageExport(model.MessageExportCursor{LastPostUpdateAt: startTime - 1}, 10)
   841  	require.NoError(t, err)
   842  	assert.Equal(t, 2, len(messages))
   843  
   844  	for _, v := range messages {
   845  		if *v.PostDeleteAt > 0 {
   846  			// post1 was made by user1 in channel1 and team1
   847  			assert.Equal(t, post1.Id, *v.PostId)
   848  			assert.Equal(t, post1.OriginalId, *v.PostOriginalId)
   849  			assert.Equal(t, post1.CreateAt, *v.PostCreateAt)
   850  			assert.Equal(t, post1.UpdateAt, *v.PostUpdateAt)
   851  			assert.Equal(t, post1.Message, *v.PostMessage)
   852  			assert.Equal(t, channel.Id, *v.ChannelId)
   853  			assert.Equal(t, channel.DisplayName, *v.ChannelDisplayName)
   854  			assert.Equal(t, user1.Id, *v.UserId)
   855  			assert.Equal(t, user1.Email, *v.UserEmail)
   856  			assert.Equal(t, user1.Username, *v.Username)
   857  		} else {
   858  			// post1e was made by user1 in channel1 and team1
   859  			assert.Equal(t, post1e.Id, *v.PostId)
   860  			assert.Equal(t, post1e.CreateAt, *v.PostCreateAt)
   861  			assert.Equal(t, post1e.UpdateAt, *v.PostUpdateAt)
   862  			assert.Equal(t, post1e.Message, *v.PostMessage)
   863  			assert.Equal(t, channel.Id, *v.ChannelId)
   864  			assert.Equal(t, channel.DisplayName, *v.ChannelDisplayName)
   865  			assert.Equal(t, user1.Id, *v.UserId)
   866  			assert.Equal(t, user1.Email, *v.UserEmail)
   867  			assert.Equal(t, user1.Username, *v.Username)
   868  		}
   869  	}
   870  }
   871  
   872  //post, export, edit, export
   873  func testEditAfterExportMessage(t *testing.T, ss store.Store) {
   874  	defer cleanupStoreState(t, ss)
   875  	// get the starting number of message export entries
   876  	startTime := model.GetMillis()
   877  	messages, _, err := ss.Compliance().MessageExport(model.MessageExportCursor{LastPostUpdateAt: startTime - 1}, 10)
   878  	require.NoError(t, err)
   879  	assert.Equal(t, 0, len(messages))
   880  
   881  	// need a team
   882  	team := &model.Team{
   883  		DisplayName: "DisplayName",
   884  		Name:        "zz" + model.NewId() + "b",
   885  		Email:       MakeEmail(),
   886  		Type:        model.TEAM_OPEN,
   887  	}
   888  	team, err = ss.Team().Save(team)
   889  	require.NoError(t, err)
   890  
   891  	// need a user part of that team
   892  	user1 := &model.User{
   893  		Email:    MakeEmail(),
   894  		Username: model.NewId(),
   895  	}
   896  	user1, err = ss.User().Save(user1)
   897  	require.NoError(t, err)
   898  	_, nErr := ss.Team().SaveMember(&model.TeamMember{
   899  		TeamId: team.Id,
   900  		UserId: user1.Id,
   901  	}, -1)
   902  	require.NoError(t, nErr)
   903  
   904  	// need a public channel
   905  	channel := &model.Channel{
   906  		TeamId:      team.Id,
   907  		Name:        model.NewId(),
   908  		DisplayName: "Public Channel",
   909  		Type:        model.CHANNEL_OPEN,
   910  	}
   911  	channel, nErr = ss.Channel().Save(channel, -1)
   912  	require.NoError(t, nErr)
   913  
   914  	// user1 posts in the public channel
   915  	post1 := &model.Post{
   916  		ChannelId: channel.Id,
   917  		UserId:    user1.Id,
   918  		CreateAt:  startTime,
   919  		Message:   "zz" + model.NewId() + "a",
   920  	}
   921  	post1, err = ss.Post().Save(post1)
   922  	require.NoError(t, err)
   923  
   924  	// fetch the message exports from the start
   925  	messages, _, err = ss.Compliance().MessageExport(model.MessageExportCursor{LastPostUpdateAt: startTime - 1}, 10)
   926  	require.NoError(t, err)
   927  	assert.Equal(t, 1, len(messages))
   928  
   929  	v := messages[0]
   930  	// post1 was made by user1 in channel1 and team1
   931  	assert.Equal(t, post1.Id, *v.PostId)
   932  	assert.Equal(t, post1.OriginalId, *v.PostOriginalId)
   933  	assert.Equal(t, post1.CreateAt, *v.PostCreateAt)
   934  	assert.Equal(t, post1.UpdateAt, *v.PostUpdateAt)
   935  	assert.Equal(t, post1.Message, *v.PostMessage)
   936  	assert.Equal(t, channel.Id, *v.ChannelId)
   937  	assert.Equal(t, channel.DisplayName, *v.ChannelDisplayName)
   938  	assert.Equal(t, user1.Id, *v.UserId)
   939  	assert.Equal(t, user1.Email, *v.UserEmail)
   940  	assert.Equal(t, user1.Username, *v.Username)
   941  
   942  	postEditTime := post1.UpdateAt + 1
   943  	//user 1 edits the previous post
   944  	post1e := post1.Clone()
   945  	post1e.EditAt = postEditTime
   946  	post1e.Message = "edit " + post1.Message
   947  	post1e, err = ss.Post().Update(post1e, post1)
   948  	require.NoError(t, err)
   949  
   950  	// fetch the message exports after edit
   951  	messages, _, err = ss.Compliance().MessageExport(model.MessageExportCursor{LastPostUpdateAt: postEditTime - 1}, 10)
   952  	require.NoError(t, err)
   953  	assert.Equal(t, 2, len(messages))
   954  
   955  	for _, v := range messages {
   956  		if *v.PostDeleteAt > 0 {
   957  			// post1 was made by user1 in channel1 and team1
   958  			assert.Equal(t, post1.Id, *v.PostId)
   959  			assert.Equal(t, post1.OriginalId, *v.PostOriginalId)
   960  			assert.Equal(t, post1.CreateAt, *v.PostCreateAt)
   961  			assert.Equal(t, post1.UpdateAt, *v.PostUpdateAt)
   962  			assert.Equal(t, post1.Message, *v.PostMessage)
   963  			assert.Equal(t, channel.Id, *v.ChannelId)
   964  			assert.Equal(t, channel.DisplayName, *v.ChannelDisplayName)
   965  			assert.Equal(t, user1.Id, *v.UserId)
   966  			assert.Equal(t, user1.Email, *v.UserEmail)
   967  			assert.Equal(t, user1.Username, *v.Username)
   968  		} else {
   969  			// post1e was made by user1 in channel1 and team1
   970  			assert.Equal(t, post1e.Id, *v.PostId)
   971  			assert.Equal(t, post1e.CreateAt, *v.PostCreateAt)
   972  			assert.Equal(t, post1e.UpdateAt, *v.PostUpdateAt)
   973  			assert.Equal(t, post1e.Message, *v.PostMessage)
   974  			assert.Equal(t, channel.Id, *v.ChannelId)
   975  			assert.Equal(t, channel.DisplayName, *v.ChannelDisplayName)
   976  			assert.Equal(t, user1.Id, *v.UserId)
   977  			assert.Equal(t, user1.Email, *v.UserEmail)
   978  			assert.Equal(t, user1.Username, *v.Username)
   979  		}
   980  	}
   981  }
   982  
   983  //post, delete, export
   984  func testDeleteExportMessage(t *testing.T, ss store.Store) {
   985  	defer cleanupStoreState(t, ss)
   986  	// get the starting number of message export entries
   987  	startTime := model.GetMillis()
   988  	messages, _, err := ss.Compliance().MessageExport(model.MessageExportCursor{LastPostUpdateAt: startTime - 1}, 10)
   989  	require.NoError(t, err)
   990  	assert.Equal(t, 0, len(messages))
   991  
   992  	// need a team
   993  	team := &model.Team{
   994  		DisplayName: "DisplayName",
   995  		Name:        "zz" + model.NewId() + "b",
   996  		Email:       MakeEmail(),
   997  		Type:        model.TEAM_OPEN,
   998  	}
   999  	team, err = ss.Team().Save(team)
  1000  	require.NoError(t, err)
  1001  
  1002  	// need a user part of that team
  1003  	user1 := &model.User{
  1004  		Email:    MakeEmail(),
  1005  		Username: model.NewId(),
  1006  	}
  1007  	user1, err = ss.User().Save(user1)
  1008  	require.NoError(t, err)
  1009  	_, nErr := ss.Team().SaveMember(&model.TeamMember{
  1010  		TeamId: team.Id,
  1011  		UserId: user1.Id,
  1012  	}, -1)
  1013  	require.NoError(t, nErr)
  1014  
  1015  	// need a public channel
  1016  	channel := &model.Channel{
  1017  		TeamId:      team.Id,
  1018  		Name:        model.NewId(),
  1019  		DisplayName: "Public Channel",
  1020  		Type:        model.CHANNEL_OPEN,
  1021  	}
  1022  	channel, nErr = ss.Channel().Save(channel, -1)
  1023  	require.NoError(t, nErr)
  1024  
  1025  	// user1 posts in the public channel
  1026  	post1 := &model.Post{
  1027  		ChannelId: channel.Id,
  1028  		UserId:    user1.Id,
  1029  		CreateAt:  startTime,
  1030  		Message:   "zz" + model.NewId() + "a",
  1031  	}
  1032  	post1, err = ss.Post().Save(post1)
  1033  	require.NoError(t, err)
  1034  
  1035  	//user 1 deletes the previous post
  1036  	postDeleteTime := post1.UpdateAt + 1
  1037  	err = ss.Post().Delete(post1.Id, postDeleteTime, user1.Id)
  1038  	require.NoError(t, err)
  1039  
  1040  	// fetch the message exports from the start
  1041  	messages, _, err = ss.Compliance().MessageExport(model.MessageExportCursor{LastPostUpdateAt: startTime - 1}, 10)
  1042  	require.NoError(t, err)
  1043  	assert.Equal(t, 1, len(messages))
  1044  
  1045  	v := messages[0]
  1046  	// post1 was made and deleted by user1 in channel1 and team1
  1047  	assert.Equal(t, post1.Id, *v.PostId)
  1048  	assert.Equal(t, post1.OriginalId, *v.PostOriginalId)
  1049  	assert.Equal(t, post1.CreateAt, *v.PostCreateAt)
  1050  	assert.Equal(t, postDeleteTime, *v.PostUpdateAt)
  1051  	assert.NotNil(t, v.PostProps)
  1052  
  1053  	props := map[string]interface{}{}
  1054  	e := json.Unmarshal([]byte(*v.PostProps), &props)
  1055  	require.NoError(t, e)
  1056  
  1057  	_, ok := props[model.POST_PROPS_DELETE_BY]
  1058  	assert.True(t, ok)
  1059  
  1060  	assert.Equal(t, post1.Message, *v.PostMessage)
  1061  	assert.Equal(t, channel.Id, *v.ChannelId)
  1062  	assert.Equal(t, channel.DisplayName, *v.ChannelDisplayName)
  1063  	assert.Equal(t, user1.Id, *v.UserId)
  1064  	assert.Equal(t, user1.Email, *v.UserEmail)
  1065  	assert.Equal(t, user1.Username, *v.Username)
  1066  }
  1067  
  1068  //post,export,delete,export
  1069  func testDeleteAfterExportMessage(t *testing.T, ss store.Store) {
  1070  	defer cleanupStoreState(t, ss)
  1071  	// get the starting number of message export entries
  1072  	startTime := model.GetMillis()
  1073  	messages, _, err := ss.Compliance().MessageExport(model.MessageExportCursor{LastPostUpdateAt: startTime - 1}, 10)
  1074  	require.NoError(t, err)
  1075  	assert.Equal(t, 0, len(messages))
  1076  
  1077  	// need a team
  1078  	team := &model.Team{
  1079  		DisplayName: "DisplayName",
  1080  		Name:        "zz" + model.NewId() + "b",
  1081  		Email:       MakeEmail(),
  1082  		Type:        model.TEAM_OPEN,
  1083  	}
  1084  	team, err = ss.Team().Save(team)
  1085  	require.NoError(t, err)
  1086  
  1087  	// need a user part of that team
  1088  	user1 := &model.User{
  1089  		Email:    MakeEmail(),
  1090  		Username: model.NewId(),
  1091  	}
  1092  	user1, err = ss.User().Save(user1)
  1093  	require.NoError(t, err)
  1094  	_, nErr := ss.Team().SaveMember(&model.TeamMember{
  1095  		TeamId: team.Id,
  1096  		UserId: user1.Id,
  1097  	}, -1)
  1098  	require.NoError(t, nErr)
  1099  
  1100  	// need a public channel
  1101  	channel := &model.Channel{
  1102  		TeamId:      team.Id,
  1103  		Name:        model.NewId(),
  1104  		DisplayName: "Public Channel",
  1105  		Type:        model.CHANNEL_OPEN,
  1106  	}
  1107  	channel, nErr = ss.Channel().Save(channel, -1)
  1108  	require.NoError(t, nErr)
  1109  
  1110  	// user1 posts in the public channel
  1111  	post1 := &model.Post{
  1112  		ChannelId: channel.Id,
  1113  		UserId:    user1.Id,
  1114  		CreateAt:  startTime,
  1115  		Message:   "zz" + model.NewId() + "a",
  1116  	}
  1117  	post1, err = ss.Post().Save(post1)
  1118  	require.NoError(t, err)
  1119  
  1120  	// fetch the message exports from the start
  1121  	messages, _, err = ss.Compliance().MessageExport(model.MessageExportCursor{LastPostUpdateAt: startTime - 1}, 10)
  1122  	require.NoError(t, err)
  1123  	assert.Equal(t, 1, len(messages))
  1124  
  1125  	v := messages[0]
  1126  	// post1 was created by user1 in channel1 and team1
  1127  	assert.Equal(t, post1.Id, *v.PostId)
  1128  	assert.Equal(t, post1.OriginalId, *v.PostOriginalId)
  1129  	assert.Equal(t, post1.CreateAt, *v.PostCreateAt)
  1130  	assert.Equal(t, post1.UpdateAt, *v.PostUpdateAt)
  1131  	assert.Equal(t, post1.Message, *v.PostMessage)
  1132  	assert.Equal(t, channel.Id, *v.ChannelId)
  1133  	assert.Equal(t, channel.DisplayName, *v.ChannelDisplayName)
  1134  	assert.Equal(t, user1.Id, *v.UserId)
  1135  	assert.Equal(t, user1.Email, *v.UserEmail)
  1136  	assert.Equal(t, user1.Username, *v.Username)
  1137  
  1138  	//user 1 deletes the previous post
  1139  	postDeleteTime := post1.UpdateAt + 1
  1140  	err = ss.Post().Delete(post1.Id, postDeleteTime, user1.Id)
  1141  	require.NoError(t, err)
  1142  
  1143  	// fetch the message exports after delete
  1144  	messages, _, err = ss.Compliance().MessageExport(model.MessageExportCursor{LastPostUpdateAt: postDeleteTime - 1}, 10)
  1145  	require.NoError(t, err)
  1146  	assert.Equal(t, 1, len(messages))
  1147  
  1148  	v = messages[0]
  1149  	// post1 was created and deleted by user1 in channel1 and team1
  1150  	assert.Equal(t, post1.Id, *v.PostId)
  1151  	assert.Equal(t, post1.OriginalId, *v.PostOriginalId)
  1152  	assert.Equal(t, post1.CreateAt, *v.PostCreateAt)
  1153  	assert.Equal(t, postDeleteTime, *v.PostUpdateAt)
  1154  	assert.NotNil(t, v.PostProps)
  1155  
  1156  	props := map[string]interface{}{}
  1157  	e := json.Unmarshal([]byte(*v.PostProps), &props)
  1158  	require.NoError(t, e)
  1159  
  1160  	_, ok := props[model.POST_PROPS_DELETE_BY]
  1161  	assert.True(t, ok)
  1162  
  1163  	assert.Equal(t, post1.Message, *v.PostMessage)
  1164  	assert.Equal(t, channel.Id, *v.ChannelId)
  1165  	assert.Equal(t, channel.DisplayName, *v.ChannelDisplayName)
  1166  	assert.Equal(t, user1.Id, *v.UserId)
  1167  	assert.Equal(t, user1.Email, *v.UserEmail)
  1168  	assert.Equal(t, user1.Username, *v.Username)
  1169  }