summaryrefslogtreecommitdiffstats
path: root/store
diff options
context:
space:
mode:
authorGeorge Goldberg <george@gberg.me>2018-09-17 15:51:26 +0100
committerGitHub <noreply@github.com>2018-09-17 15:51:26 +0100
commitab99f0656fabed8a62a8c6340be7d538cc7bf8d9 (patch)
treebb68ee1d0c743be23bba470f5d81ef11dc134182 /store
parent5786b0d6d57b90bbb0c262235dd9d19b497b5fae (diff)
downloadchat-ab99f0656fabed8a62a8c6340be7d538cc7bf8d9.tar.gz
chat-ab99f0656fabed8a62a8c6340be7d538cc7bf8d9.tar.bz2
chat-ab99f0656fabed8a62a8c6340be7d538cc7bf8d9.zip
MM-11781: Basic Data Export Command Line. (#9296)
* MM-11781: Basic Data Export Command Line. * ChannelStore new unit tests. * TeamStore new unit tests. * Unit test for new UserStore function. * Unit tests for post store new methods. * Review fixes. * Fix duplicate command name.
Diffstat (limited to 'store')
-rw-r--r--store/sqlstore/channel_store.go54
-rw-r--r--store/sqlstore/post_store.go65
-rw-r--r--store/sqlstore/team_store.go56
-rw-r--r--store/sqlstore/user_store.go11
-rw-r--r--store/store.go7
-rw-r--r--store/storetest/channel_store.go84
-rw-r--r--store/storetest/mocks/ChannelStore.go32
-rw-r--r--store/storetest/mocks/PostStore.go32
-rw-r--r--store/storetest/mocks/TeamStore.go32
-rw-r--r--store/storetest/mocks/UserStore.go16
-rw-r--r--store/storetest/post_store.go96
-rw-r--r--store/storetest/team_store.go62
-rw-r--r--store/storetest/user_store.go33
13 files changed, 580 insertions, 0 deletions
diff --git a/store/sqlstore/channel_store.go b/store/sqlstore/channel_store.go
index 4103980c5..c0c1d2c8a 100644
--- a/store/sqlstore/channel_store.go
+++ b/store/sqlstore/channel_store.go
@@ -2016,3 +2016,57 @@ func (s SqlChannelStore) IsExperimentalPublicChannelsMaterializationEnabled() bo
// See SqlChannelStoreExperimental
return false
}
+
+func (s SqlChannelStore) GetAllChannelsForExportAfter(limit int, afterId string) store.StoreChannel {
+ return store.Do(func(result *store.StoreResult) {
+ var data []*model.ChannelForExport
+ if _, err := s.GetReplica().Select(&data, `
+ SELECT
+ Channels.*,
+ Teams.Name as TeamName,
+ Schemes.Name as SchemeName
+ FROM Channels
+ INNER JOIN
+ Teams ON Channels.TeamId = Teams.Id
+ LEFT JOIN
+ Schemes ON Channels.SchemeId = Schemes.Id
+ WHERE
+ Channels.Id > :AfterId
+ AND Channels.Type IN ('O', 'P')
+ ORDER BY
+ Id
+ LIMIT :Limit`,
+ map[string]interface{}{"AfterId": afterId, "Limit": limit}); err != nil {
+ result.Err = model.NewAppError("SqlTeamStore.GetAllChannelsForExportAfter", "store.sql_channel.get_all.app_error", nil, err.Error(), http.StatusInternalServerError)
+ return
+ }
+
+ result.Data = data
+ })
+}
+
+func (s SqlChannelStore) GetChannelMembersForExport(userId string, teamId string) store.StoreChannel {
+ return store.Do(func(result *store.StoreResult) {
+ var members []*model.ChannelMemberForExport
+ _, err := s.GetReplica().Select(&members, `
+ SELECT
+ ChannelMembers.*,
+ Channels.Name as ChannelName
+ FROM
+ ChannelMembers
+ INNER JOIN
+ Channels ON ChannelMembers.ChannelId = Channels.Id
+ WHERE
+ ChannelMembers.UserId = :UserId
+ AND Channels.TeamId = :TeamId
+ AND Channels.DeleteAt = 0`,
+ map[string]interface{}{"TeamId": teamId, "UserId": userId})
+
+ if err != nil {
+ result.Err = model.NewAppError("SqlChannelStore.GetChannelMembersForExport", "store.sql_channel.get_members.app_error", nil, "teamId="+teamId+", userId="+userId+", err="+err.Error(), http.StatusInternalServerError)
+ return
+ }
+
+ result.Data = members
+ })
+}
diff --git a/store/sqlstore/post_store.go b/store/sqlstore/post_store.go
index 9cf33888d..bc85b260e 100644
--- a/store/sqlstore/post_store.go
+++ b/store/sqlstore/post_store.go
@@ -1308,3 +1308,68 @@ func (s *SqlPostStore) GetMaxPostSize() store.StoreChannel {
result.Data = s.maxPostSizeCached
})
}
+
+func (s *SqlPostStore) GetParentsForExportAfter(limit int, afterId string) store.StoreChannel {
+ return store.Do(func(result *store.StoreResult) {
+ var posts []*model.PostForExport
+ _, err1 := s.GetSearchReplica().Select(&posts, `
+ SELECT
+ p1.*,
+ Users.Username as Username,
+ Teams.Name as TeamName,
+ Channels.Name as ChannelName
+ FROM
+ Posts p1
+ INNER JOIN
+ Channels ON p1.ChannelId = Channels.Id
+ INNER JOIN
+ Teams ON Channels.TeamId = Teams.Id
+ INNER JOIN
+ Users ON p1.UserId = Users.Id
+ WHERE
+ p1.Id > :AfterId
+ AND p1.ParentId = ''
+ AND p1.DeleteAt = 0
+ AND Channels.DeleteAt = 0
+ AND Teams.DeleteAt = 0
+ AND Users.DeleteAt = 0
+ ORDER BY
+ p1.Id
+ LIMIT
+ :Limit`,
+ map[string]interface{}{"Limit": limit, "AfterId": afterId})
+
+ if err1 != nil {
+ result.Err = model.NewAppError("SqlPostStore.GetAllAfterForExport", "store.sql_post.get_posts.app_error", nil, err1.Error(), http.StatusInternalServerError)
+ } else {
+ result.Data = posts
+ }
+ })
+}
+
+func (s *SqlPostStore) GetRepliesForExport(parentId string) store.StoreChannel {
+ return store.Do(func(result *store.StoreResult) {
+ var posts []*model.ReplyForExport
+ _, err1 := s.GetSearchReplica().Select(&posts, `
+ SELECT
+ Posts.*,
+ Users.Username as Username
+ FROM
+ Posts
+ INNER JOIN
+ Users ON Posts.UserId = Users.Id
+ WHERE
+ Posts.ParentId = :ParentId
+ AND Posts.DeleteAt = 0
+ AND Users.DeleteAt = 0
+ ORDER BY
+ Posts.Id`,
+ map[string]interface{}{"ParentId": parentId})
+
+ if err1 != nil {
+ result.Err = model.NewAppError("SqlPostStore.GetAllAfterForExport", "store.sql_post.get_posts.app_error", nil, err1.Error(), http.StatusInternalServerError)
+ } else {
+ result.Data = posts
+ }
+ })
+}
diff --git a/store/sqlstore/team_store.go b/store/sqlstore/team_store.go
index 3ea6feced..b48242294 100644
--- a/store/sqlstore/team_store.go
+++ b/store/sqlstore/team_store.go
@@ -924,3 +924,59 @@ func (s SqlTeamStore) AnalyticsGetTeamCountForScheme(schemeId string) store.Stor
result.Data = count
})
}
+
+func (s SqlTeamStore) GetAllForExportAfter(limit int, afterId string) store.StoreChannel {
+ return store.Do(func(result *store.StoreResult) {
+ var data []*model.TeamForExport
+ if _, err := s.GetReplica().Select(&data, `
+ SELECT
+ Teams.*,
+ Schemes.Name as SchemeName
+ FROM
+ Teams
+ LEFT JOIN
+ Schemes ON Teams.SchemeId = Schemes.Id
+ WHERE
+ Teams.Id > :AfterId
+ ORDER BY
+ Id
+ LIMIT
+ :Limit`,
+ map[string]interface{}{"AfterId": afterId, "Limit": limit}); err != nil {
+ result.Err = model.NewAppError("SqlTeamStore.GetAllTeams", "store.sql_team.get_all.app_error", nil, err.Error(), http.StatusInternalServerError)
+ return
+ }
+
+ for _, team := range data {
+ if len(team.InviteId) == 0 {
+ team.InviteId = team.Id
+ }
+ }
+
+ result.Data = data
+ })
+}
+
+func (s SqlTeamStore) GetTeamMembersForExport(userId string) store.StoreChannel {
+ return store.Do(func(result *store.StoreResult) {
+ var members []*model.TeamMemberForExport
+ _, err := s.GetReplica().Select(&members, `
+ SELECT
+ TeamMembers.*,
+ Teams.Name as TeamName
+ FROM
+ TeamMembers
+ INNER JOIN
+ Teams ON TeamMembers.TeamId = Teams.Id
+ WHERE
+ TeamMembers.UserId = :UserId
+ AND Teams.DeleteAt = 0`,
+ map[string]interface{}{"UserId": userId})
+ if err != nil {
+ result.Err = model.NewAppError("SqlTeamStore.GetTeamMembersForExport", "store.sql_team.get_members.app_error", nil, "userId="+userId+" "+err.Error(), http.StatusInternalServerError)
+ return
+ }
+
+ result.Data = members
+ })
+}
diff --git a/store/sqlstore/user_store.go b/store/sqlstore/user_store.go
index c89c445ad..900010ce4 100644
--- a/store/sqlstore/user_store.go
+++ b/store/sqlstore/user_store.go
@@ -332,6 +332,17 @@ func (us SqlUserStore) GetAll() store.StoreChannel {
})
}
+func (us SqlUserStore) GetAllAfter(limit int, afterId string) store.StoreChannel {
+ return store.Do(func(result *store.StoreResult) {
+ var data []*model.User
+ if _, err := us.GetReplica().Select(&data, "SELECT * FROM Users WHERE Id > :AfterId ORDER BY Id LIMIT :Limit", map[string]interface{}{"AfterId": afterId, "Limit": limit}); err != nil {
+ result.Err = model.NewAppError("SqlUserStore.GetAllAfter", "store.sql_user.get.app_error", nil, err.Error(), http.StatusInternalServerError)
+ }
+
+ result.Data = data
+ })
+}
+
func (s SqlUserStore) GetEtagForAllProfiles() store.StoreChannel {
return store.Do(func(result *store.StoreResult) {
updateAt, err := s.GetReplica().SelectInt("SELECT UpdateAt FROM Users ORDER BY UpdateAt DESC LIMIT 1")
diff --git a/store/store.go b/store/store.go
index 8c731f8d5..8073b9437 100644
--- a/store/store.go
+++ b/store/store.go
@@ -111,6 +111,8 @@ type TeamStore interface {
ResetAllTeamSchemes() StoreChannel
ClearAllCustomRoleAssignments() StoreChannel
AnalyticsGetTeamCountForScheme(schemeId string) StoreChannel
+ GetAllForExportAfter(limit int, afterId string) StoreChannel
+ GetTeamMembersForExport(userId string) StoreChannel
}
type ChannelStore interface {
@@ -179,6 +181,8 @@ type ChannelStore interface {
EnableExperimentalPublicChannelsMaterialization()
DisableExperimentalPublicChannelsMaterialization()
IsExperimentalPublicChannelsMaterializationEnabled() bool
+ GetAllChannelsForExportAfter(limit int, afterId string) StoreChannel
+ GetChannelMembersForExport(userId string, teamId string) StoreChannel
}
type ChannelMemberHistoryStore interface {
@@ -217,6 +221,8 @@ type PostStore interface {
PermanentDeleteBatch(endTime int64, limit int64) StoreChannel
GetOldest() StoreChannel
GetMaxPostSize() StoreChannel
+ GetParentsForExportAfter(limit int, afterId string) StoreChannel
+ GetRepliesForExport(parentId string) StoreChannel
}
type UserStore interface {
@@ -272,6 +278,7 @@ type UserStore interface {
GetEtagForProfilesNotInTeam(teamId string) StoreChannel
ClearAllCustomRoleAssignments() StoreChannel
InferSystemInstallDate() StoreChannel
+ GetAllAfter(limit int, afterId string) StoreChannel
}
type SessionStore interface {
diff --git a/store/storetest/channel_store.go b/store/storetest/channel_store.go
index 11e058f70..636d96649 100644
--- a/store/storetest/channel_store.go
+++ b/store/storetest/channel_store.go
@@ -78,6 +78,8 @@ func TestChannelStore(t *testing.T, ss store.Store, s SqlSupplier) {
t.Run("ResetAllChannelSchemes", func(t *testing.T) { testResetAllChannelSchemes(t, ss) })
t.Run("ClearAllCustomRoleAssignments", func(t *testing.T) { testChannelStoreClearAllCustomRoleAssignments(t, ss) })
t.Run("MaterializedPublicChannels", func(t *testing.T) { testMaterializedPublicChannels(t, ss, s) })
+ t.Run("GetAllChannelsForExportAfter", func(t *testing.T) { testChannelStoreGetAllChannelsForExportAfter(t, ss) })
+ t.Run("GetChannelMembersForExport", func(t *testing.T) { testChannelStoreGetChannelMembersForExport(t, ss) })
})
}
}
@@ -2693,3 +2695,85 @@ func testMaterializedPublicChannels(t *testing.T, ss store.Store, s SqlSupplier)
require.Equal(t, &model.ChannelList{&o2, &o3, &o4}, result.Data.(*model.ChannelList))
})
}
+
+func testChannelStoreGetAllChannelsForExportAfter(t *testing.T, ss store.Store) {
+ t1 := model.Team{}
+ t1.DisplayName = "Name"
+ t1.Name = model.NewId()
+ t1.Email = MakeEmail()
+ t1.Type = model.TEAM_OPEN
+ store.Must(ss.Team().Save(&t1))
+
+ c1 := model.Channel{}
+ c1.TeamId = t1.Id
+ c1.DisplayName = "Channel1"
+ c1.Name = "zz" + model.NewId() + "b"
+ c1.Type = model.CHANNEL_OPEN
+ store.Must(ss.Channel().Save(&c1, -1))
+
+ r1 := <-ss.Channel().GetAllChannelsForExportAfter(10000, strings.Repeat("0", 26))
+ assert.Nil(t, r1.Err)
+ d1 := r1.Data.([]*model.ChannelForExport)
+
+ found := false
+ for _, c := range d1 {
+ if c.Id == c1.Id {
+ found = true
+ assert.Equal(t, t1.Id, c.TeamId)
+ assert.Nil(t, c.SchemeId)
+ assert.Equal(t, t1.Name, c.TeamName)
+ }
+ }
+ assert.True(t, found)
+}
+
+func testChannelStoreGetChannelMembersForExport(t *testing.T, ss store.Store) {
+ t1 := model.Team{}
+ t1.DisplayName = "Name"
+ t1.Name = model.NewId()
+ t1.Email = MakeEmail()
+ t1.Type = model.TEAM_OPEN
+ store.Must(ss.Team().Save(&t1))
+
+ c1 := model.Channel{}
+ c1.TeamId = t1.Id
+ c1.DisplayName = "Channel1"
+ c1.Name = "zz" + model.NewId() + "b"
+ c1.Type = model.CHANNEL_OPEN
+ store.Must(ss.Channel().Save(&c1, -1))
+
+ c2 := model.Channel{}
+ c2.TeamId = model.NewId()
+ c2.DisplayName = "Channel2"
+ c2.Name = "zz" + model.NewId() + "b"
+ c2.Type = model.CHANNEL_OPEN
+ store.Must(ss.Channel().Save(&c2, -1))
+
+ u1 := model.User{}
+ u1.Email = MakeEmail()
+ u1.Nickname = model.NewId()
+ store.Must(ss.User().Save(&u1))
+
+ m1 := model.ChannelMember{}
+ m1.ChannelId = c1.Id
+ m1.UserId = u1.Id
+ m1.NotifyProps = model.GetDefaultChannelNotifyProps()
+ store.Must(ss.Channel().SaveMember(&m1))
+
+ m2 := model.ChannelMember{}
+ m2.ChannelId = c2.Id
+ m2.UserId = u1.Id
+ m2.NotifyProps = model.GetDefaultChannelNotifyProps()
+ store.Must(ss.Channel().SaveMember(&m2))
+
+ r1 := <-ss.Channel().GetChannelMembersForExport(u1.Id, t1.Id)
+ assert.Nil(t, r1.Err)
+
+ d1 := r1.Data.([]*model.ChannelMemberForExport)
+ assert.Len(t, d1, 1)
+
+ cmfe1 := d1[0]
+ assert.Equal(t, c1.Name, cmfe1.ChannelName)
+ assert.Equal(t, c1.Id, cmfe1.ChannelId)
+ assert.Equal(t, u1.Id, cmfe1.UserId)
+}
diff --git a/store/storetest/mocks/ChannelStore.go b/store/storetest/mocks/ChannelStore.go
index c187aae6b..9db85eacf 100644
--- a/store/storetest/mocks/ChannelStore.go
+++ b/store/storetest/mocks/ChannelStore.go
@@ -218,6 +218,22 @@ func (_m *ChannelStore) GetAllChannelMembersNotifyPropsForChannel(channelId stri
return r0
}
+// GetAllChannelsForExportAfter provides a mock function with given fields: limit, afterId
+func (_m *ChannelStore) GetAllChannelsForExportAfter(limit int, afterId string) store.StoreChannel {
+ ret := _m.Called(limit, afterId)
+
+ var r0 store.StoreChannel
+ if rf, ok := ret.Get(0).(func(int, string) store.StoreChannel); ok {
+ r0 = rf(limit, afterId)
+ } else {
+ if ret.Get(0) != nil {
+ r0 = ret.Get(0).(store.StoreChannel)
+ }
+ }
+
+ return r0
+}
+
// GetByName provides a mock function with given fields: team_id, name, allowFromCache
func (_m *ChannelStore) GetByName(team_id string, name string, allowFromCache bool) store.StoreChannel {
ret := _m.Called(team_id, name, allowFromCache)
@@ -282,6 +298,22 @@ func (_m *ChannelStore) GetChannelCounts(teamId string, userId string) store.Sto
return r0
}
+// GetChannelMembersForExport provides a mock function with given fields: userId, teamId
+func (_m *ChannelStore) GetChannelMembersForExport(userId string, teamId string) store.StoreChannel {
+ ret := _m.Called(userId, teamId)
+
+ var r0 store.StoreChannel
+ if rf, ok := ret.Get(0).(func(string, string) store.StoreChannel); ok {
+ r0 = rf(userId, teamId)
+ } else {
+ if ret.Get(0) != nil {
+ r0 = ret.Get(0).(store.StoreChannel)
+ }
+ }
+
+ return r0
+}
+
// GetChannelUnread provides a mock function with given fields: channelId, userId
func (_m *ChannelStore) GetChannelUnread(channelId string, userId string) store.StoreChannel {
ret := _m.Called(channelId, userId)
diff --git a/store/storetest/mocks/PostStore.go b/store/storetest/mocks/PostStore.go
index 1c1baec7b..2e4d63089 100644
--- a/store/storetest/mocks/PostStore.go
+++ b/store/storetest/mocks/PostStore.go
@@ -194,6 +194,22 @@ func (_m *PostStore) GetOldest() store.StoreChannel {
return r0
}
+// GetParentsForExportAfter provides a mock function with given fields: limit, afterId
+func (_m *PostStore) GetParentsForExportAfter(limit int, afterId string) store.StoreChannel {
+ ret := _m.Called(limit, afterId)
+
+ var r0 store.StoreChannel
+ if rf, ok := ret.Get(0).(func(int, string) store.StoreChannel); ok {
+ r0 = rf(limit, afterId)
+ } else {
+ if ret.Get(0) != nil {
+ r0 = ret.Get(0).(store.StoreChannel)
+ }
+ }
+
+ return r0
+}
+
// GetPosts provides a mock function with given fields: channelId, offset, limit, allowFromCache
func (_m *PostStore) GetPosts(channelId string, offset int, limit int, allowFromCache bool) store.StoreChannel {
ret := _m.Called(channelId, offset, limit, allowFromCache)
@@ -306,6 +322,22 @@ func (_m *PostStore) GetPostsSince(channelId string, time int64, allowFromCache
return r0
}
+// GetRepliesForExport provides a mock function with given fields: parentId
+func (_m *PostStore) GetRepliesForExport(parentId string) store.StoreChannel {
+ ret := _m.Called(parentId)
+
+ var r0 store.StoreChannel
+ if rf, ok := ret.Get(0).(func(string) store.StoreChannel); ok {
+ r0 = rf(parentId)
+ } else {
+ if ret.Get(0) != nil {
+ r0 = ret.Get(0).(store.StoreChannel)
+ }
+ }
+
+ return r0
+}
+
// GetSingle provides a mock function with given fields: id
func (_m *PostStore) GetSingle(id string) store.StoreChannel {
ret := _m.Called(id)
diff --git a/store/storetest/mocks/TeamStore.go b/store/storetest/mocks/TeamStore.go
index 8e27e3c05..5d83eab50 100644
--- a/store/storetest/mocks/TeamStore.go
+++ b/store/storetest/mocks/TeamStore.go
@@ -109,6 +109,22 @@ func (_m *TeamStore) GetAll() store.StoreChannel {
return r0
}
+// GetAllForExportAfter provides a mock function with given fields: limit, afterId
+func (_m *TeamStore) GetAllForExportAfter(limit int, afterId string) store.StoreChannel {
+ ret := _m.Called(limit, afterId)
+
+ var r0 store.StoreChannel
+ if rf, ok := ret.Get(0).(func(int, string) store.StoreChannel); ok {
+ r0 = rf(limit, afterId)
+ } else {
+ if ret.Get(0) != nil {
+ r0 = ret.Get(0).(store.StoreChannel)
+ }
+ }
+
+ return r0
+}
+
// GetAllPage provides a mock function with given fields: offset, limit
func (_m *TeamStore) GetAllPage(offset int, limit int) store.StoreChannel {
ret := _m.Called(offset, limit)
@@ -269,6 +285,22 @@ func (_m *TeamStore) GetMembersByIds(teamId string, userIds []string) store.Stor
return r0
}
+// GetTeamMembersForExport provides a mock function with given fields: userId
+func (_m *TeamStore) GetTeamMembersForExport(userId string) store.StoreChannel {
+ ret := _m.Called(userId)
+
+ var r0 store.StoreChannel
+ if rf, ok := ret.Get(0).(func(string) store.StoreChannel); ok {
+ r0 = rf(userId)
+ } else {
+ if ret.Get(0) != nil {
+ r0 = ret.Get(0).(store.StoreChannel)
+ }
+ }
+
+ return r0
+}
+
// GetTeamsByScheme provides a mock function with given fields: schemeId, offset, limit
func (_m *TeamStore) GetTeamsByScheme(schemeId string, offset int, limit int) store.StoreChannel {
ret := _m.Called(schemeId, offset, limit)
diff --git a/store/storetest/mocks/UserStore.go b/store/storetest/mocks/UserStore.go
index 1f9f07e7d..51c37cb20 100644
--- a/store/storetest/mocks/UserStore.go
+++ b/store/storetest/mocks/UserStore.go
@@ -130,6 +130,22 @@ func (_m *UserStore) GetAll() store.StoreChannel {
return r0
}
+// GetAllAfter provides a mock function with given fields: limit, afterId
+func (_m *UserStore) GetAllAfter(limit int, afterId string) store.StoreChannel {
+ ret := _m.Called(limit, afterId)
+
+ var r0 store.StoreChannel
+ if rf, ok := ret.Get(0).(func(int, string) store.StoreChannel); ok {
+ r0 = rf(limit, afterId)
+ } else {
+ if ret.Get(0) != nil {
+ r0 = ret.Get(0).(store.StoreChannel)
+ }
+ }
+
+ return r0
+}
+
// GetAllProfiles provides a mock function with given fields: offset, limit
func (_m *UserStore) GetAllProfiles(offset int, limit int) store.StoreChannel {
ret := _m.Called(offset, limit)
diff --git a/store/storetest/post_store.go b/store/storetest/post_store.go
index 72819f49e..b93eb6628 100644
--- a/store/storetest/post_store.go
+++ b/store/storetest/post_store.go
@@ -44,6 +44,8 @@ func TestPostStore(t *testing.T, ss store.Store) {
t.Run("PermanentDeleteBatch", func(t *testing.T) { testPostStorePermanentDeleteBatch(t, ss) })
t.Run("GetOldest", func(t *testing.T) { testPostStoreGetOldest(t, ss) })
t.Run("TestGetMaxPostSize", func(t *testing.T) { testGetMaxPostSize(t, ss) })
+ t.Run("GetParentsForExportAfter", func(t *testing.T) { testPostStoreGetParentsForExportAfter(t, ss) })
+ t.Run("GetRepliesForExport", func(t *testing.T) { testPostStoreGetRepliesForExport(t, ss) })
}
func testPostStoreSave(t *testing.T, ss store.Store) {
@@ -1814,3 +1816,97 @@ func testGetMaxPostSize(t *testing.T, ss store.Store) {
assert.Equal(t, model.POST_MESSAGE_MAX_RUNES_V2, (<-ss.Post().GetMaxPostSize()).Data.(int))
assert.Equal(t, model.POST_MESSAGE_MAX_RUNES_V2, (<-ss.Post().GetMaxPostSize()).Data.(int))
}
+
+func testPostStoreGetParentsForExportAfter(t *testing.T, ss store.Store) {
+ t1 := model.Team{}
+ t1.DisplayName = "Name"
+ t1.Name = model.NewId()
+ t1.Email = MakeEmail()
+ t1.Type = model.TEAM_OPEN
+ store.Must(ss.Team().Save(&t1))
+
+ c1 := model.Channel{}
+ c1.TeamId = t1.Id
+ c1.DisplayName = "Channel1"
+ c1.Name = "zz" + model.NewId() + "b"
+ c1.Type = model.CHANNEL_OPEN
+ store.Must(ss.Channel().Save(&c1, -1))
+
+ u1 := model.User{}
+ u1.Username = model.NewId()
+ u1.Email = MakeEmail()
+ u1.Nickname = model.NewId()
+ store.Must(ss.User().Save(&u1))
+
+ p1 := &model.Post{}
+ p1.ChannelId = c1.Id
+ p1.UserId = u1.Id
+ p1.Message = "zz" + model.NewId() + "AAAAAAAAAAA"
+ p1.CreateAt = 1000
+ p1 = (<-ss.Post().Save(p1)).Data.(*model.Post)
+
+ r1 := <-ss.Post().GetParentsForExportAfter(10000, strings.Repeat("0", 26))
+ assert.Nil(t, r1.Err)
+ d1 := r1.Data.([]*model.PostForExport)
+
+ found := false
+ for _, p := range d1 {
+ if p.Id == p1.Id {
+ found = true
+ assert.Equal(t, p.Id, p1.Id)
+ assert.Equal(t, p.Message, p1.Message)
+ assert.Equal(t, p.Username, u1.Username)
+ assert.Equal(t, p.TeamName, t1.Name)
+ assert.Equal(t, p.ChannelName, c1.Name)
+ }
+ }
+ assert.True(t, found)
+}
+
+func testPostStoreGetRepliesForExport(t *testing.T, ss store.Store) {
+ t1 := model.Team{}
+ t1.DisplayName = "Name"
+ t1.Name = model.NewId()
+ t1.Email = MakeEmail()
+ t1.Type = model.TEAM_OPEN
+ store.Must(ss.Team().Save(&t1))
+
+ c1 := model.Channel{}
+ c1.TeamId = t1.Id
+ c1.DisplayName = "Channel1"
+ c1.Name = "zz" + model.NewId() + "b"
+ c1.Type = model.CHANNEL_OPEN
+ store.Must(ss.Channel().Save(&c1, -1))
+
+ u1 := model.User{}
+ u1.Email = MakeEmail()
+ u1.Nickname = model.NewId()
+ store.Must(ss.User().Save(&u1))
+
+ p1 := &model.Post{}
+ p1.ChannelId = c1.Id
+ p1.UserId = u1.Id
+ p1.Message = "zz" + model.NewId() + "AAAAAAAAAAA"
+ p1.CreateAt = 1000
+ p1 = (<-ss.Post().Save(p1)).Data.(*model.Post)
+
+ p2 := &model.Post{}
+ p2.ChannelId = c1.Id
+ p2.UserId = u1.Id
+ p2.Message = "zz" + model.NewId() + "AAAAAAAAAAA"
+ p2.CreateAt = 1001
+ p2.ParentId = p1.Id
+ p2.RootId = p1.Id
+ p2 = (<-ss.Post().Save(p2)).Data.(*model.Post)
+
+ r1 := <-ss.Post().GetRepliesForExport(p1.Id)
+ assert.Nil(t, r1.Err)
+
+ d1 := r1.Data.([]*model.ReplyForExport)
+ assert.Len(t, d1, 1)
+
+ reply1 := d1[0]
+ assert.Equal(t, reply1.Id, p2.Id)
+ assert.Equal(t, reply1.Message, p2.Message)
+ assert.Equal(t, reply1.Username, u1.Username)
+}
diff --git a/store/storetest/team_store.go b/store/storetest/team_store.go
index 1369dc69b..69b2d9eee 100644
--- a/store/storetest/team_store.go
+++ b/store/storetest/team_store.go
@@ -45,6 +45,8 @@ func TestTeamStore(t *testing.T, ss store.Store) {
t.Run("ResetAllTeamSchemes", func(t *testing.T) { testResetAllTeamSchemes(t, ss) })
t.Run("ClearAllCustomRoleAssignments", func(t *testing.T) { testTeamStoreClearAllCustomRoleAssignments(t, ss) })
t.Run("AnalyticsGetTeamCountForScheme", func(t *testing.T) { testTeamStoreAnalyticsGetTeamCountForScheme(t, ss) })
+ t.Run("GetAllForExportAfter", func(t *testing.T) { testTeamStoreGetAllForExportAfter(t, ss) })
+ t.Run("GetTeamMembersForExport", func(t *testing.T) { testTeamStoreGetTeamMembersForExport(t, ss) })
}
func testTeamStoreSave(t *testing.T, ss store.Store) {
@@ -1327,3 +1329,63 @@ func testTeamStoreAnalyticsGetTeamCountForScheme(t *testing.T, ss store.Store) {
count5 := (<-ss.Team().AnalyticsGetTeamCountForScheme(s1.Id)).Data.(int64)
assert.Equal(t, int64(2), count5)
}
+
+func testTeamStoreGetAllForExportAfter(t *testing.T, ss store.Store) {
+ t1 := model.Team{}
+ t1.DisplayName = "Name"
+ t1.Name = model.NewId()
+ t1.Email = MakeEmail()
+ t1.Type = model.TEAM_OPEN
+ store.Must(ss.Team().Save(&t1))
+
+ r1 := <-ss.Team().GetAllForExportAfter(10000, strings.Repeat("0", 26))
+ assert.Nil(t, r1.Err)
+ d1 := r1.Data.([]*model.TeamForExport)
+
+ found := false
+ for _, team := range d1 {
+ if team.Id == t1.Id {
+ found = true
+ assert.Equal(t, t1.Id, team.Id)
+ assert.Nil(t, team.SchemeId)
+ assert.Equal(t, t1.Name, team.Name)
+ }
+ }
+ assert.True(t, found)
+}
+
+func testTeamStoreGetTeamMembersForExport(t *testing.T, ss store.Store) {
+ t1 := model.Team{}
+ t1.DisplayName = "Name"
+ t1.Name = model.NewId()
+ t1.Email = MakeEmail()
+ t1.Type = model.TEAM_OPEN
+ store.Must(ss.Team().Save(&t1))
+
+ u1 := model.User{}
+ u1.Email = MakeEmail()
+ u1.Nickname = model.NewId()
+ store.Must(ss.User().Save(&u1))
+
+ u2 := model.User{}
+ u2.Email = MakeEmail()
+ u2.Nickname = model.NewId()
+ store.Must(ss.User().Save(&u2))
+
+ m1 := &model.TeamMember{TeamId: t1.Id, UserId: u1.Id}
+ store.Must(ss.Team().SaveMember(m1, -1))
+
+ m2 := &model.TeamMember{TeamId: t1.Id, UserId: u2.Id}
+ store.Must(ss.Team().SaveMember(m2, -1))
+
+ r1 := <-ss.Team().GetTeamMembersForExport(u1.Id)
+ assert.Nil(t, r1.Err)
+
+ d1 := r1.Data.([]*model.TeamMemberForExport)
+ assert.Len(t, d1, 1)
+
+ tmfe1 := d1[0]
+ assert.Equal(t, t1.Id, tmfe1.TeamId)
+ assert.Equal(t, u1.Id, tmfe1.UserId)
+ assert.Equal(t, t1.Name, tmfe1.TeamName)
+}
diff --git a/store/storetest/user_store.go b/store/storetest/user_store.go
index d1a373f9b..f3cc59946 100644
--- a/store/storetest/user_store.go
+++ b/store/storetest/user_store.go
@@ -51,6 +51,7 @@ func TestUserStore(t *testing.T, ss store.Store) {
t.Run("AnalyticsGetSystemAdminCount", func(t *testing.T) { testUserStoreAnalyticsGetSystemAdminCount(t, ss) })
t.Run("GetProfilesNotInTeam", func(t *testing.T) { testUserStoreGetProfilesNotInTeam(t, ss) })
t.Run("ClearAllCustomRoleAssignments", func(t *testing.T) { testUserStoreClearAllCustomRoleAssignments(t, ss) })
+ t.Run("GetAllAfter", func(t *testing.T) { testUserStoreGetAllAfter(t, ss) })
}
func testUserStoreSave(t *testing.T, ss store.Store) {
@@ -2164,3 +2165,35 @@ func testUserStoreClearAllCustomRoleAssignments(t *testing.T, ss store.Store) {
require.Nil(t, r4.Err)
assert.Equal(t, "", r4.Data.(*model.User).Roles)
}
+
+func testUserStoreGetAllAfter(t *testing.T, ss store.Store) {
+ u1 := model.User{
+ Email: MakeEmail(),
+ Username: model.NewId(),
+ Roles: "system_user system_admin system_post_all",
+ }
+ store.Must(ss.User().Save(&u1))
+
+ r1 := <-ss.User().GetAllAfter(10000, strings.Repeat("0", 26))
+ require.Nil(t, r1.Err)
+
+ d1 := r1.Data.([]*model.User)
+
+ found := false
+ for _, u := range d1 {
+ if u.Id == u1.Id {
+ found = true
+ assert.Equal(t, u1.Id, u.Id)
+ assert.Equal(t, u1.Email, u.Email)
+ }
+ }
+ assert.True(t, found)
+
+ r2 := <-ss.User().GetAllAfter(10000, u1.Id)
+ require.Nil(t, r2.Err)
+
+ d2 := r2.Data.([]*model.User)
+ for _, u := range d2 {
+ assert.NotEqual(t, u1.Id, u.Id)
+ }
+}