[MM-22133] Allow exporting and importing archived channels (#23724)

Этот коммит содержится в:
Julien Tant
2023-08-25 17:55:47 -07:00
коммит произвёл GitHub
родитель f787fd6336
Коммит 9d569df9b4
22 изменённых файлов: 394 добавлений и 109 удалений

Просмотреть файл

@@ -81,6 +81,7 @@ func TestChannelStore(t *testing.T, ss store.Store, s SqlStore) {
t.Run("Delete", func(t *testing.T) { testChannelStoreDelete(t, ss) })
t.Run("GetByName", func(t *testing.T) { testChannelStoreGetByName(t, ss) })
t.Run("GetByNames", func(t *testing.T) { testChannelStoreGetByNames(t, ss) })
t.Run("GetByNamesIncludeDeleted", func(t *testing.T) { testChannelStoreGetByNamesIncludeDeleted(t, ss) })
t.Run("GetDeletedByName", func(t *testing.T) { testChannelStoreGetDeletedByName(t, ss) })
t.Run("GetDeleted", func(t *testing.T) { testChannelStoreGetDeleted(t, ss) })
t.Run("ChannelMemberStore", func(t *testing.T) { testChannelMemberStore(t, ss) })
@@ -859,6 +860,17 @@ func testChannelStoreGetByNames(t *testing.T, ss store.Store) {
_, nErr = ss.Channel().Save(&o2, -1)
require.NoError(t, nErr)
o3 := model.Channel{
TeamId: o1.TeamId,
DisplayName: "Name",
Name: NewTestId(),
Type: model.ChannelTypeOpen,
}
_, nErr = ss.Channel().Save(&o3, -1)
require.NoError(t, nErr)
nErr = ss.Channel().Delete(o3.Id, model.GetMillis())
require.NoError(t, nErr)
for index, tc := range []struct {
TeamId string
Names []string
@@ -895,6 +907,53 @@ func testChannelStoreGetByNames(t *testing.T, ss store.Store) {
assert.Empty(t, channels)
}
func testChannelStoreGetByNamesIncludeDeleted(t *testing.T, ss store.Store) {
o1 := model.Channel{
TeamId: model.NewId(),
DisplayName: "Name",
Name: NewTestId(),
Type: model.ChannelTypeOpen,
}
_, nErr := ss.Channel().Save(&o1, -1)
require.NoError(t, nErr)
o2 := model.Channel{
TeamId: o1.TeamId,
DisplayName: "Name",
Name: NewTestId(),
Type: model.ChannelTypeOpen,
}
_, nErr = ss.Channel().Save(&o2, -1)
require.NoError(t, nErr)
nErr = ss.Channel().Delete(o2.Id, model.GetMillis())
require.NoError(t, nErr, "channel should have been deleted")
for index, tc := range []struct {
TeamId string
Names []string
ExpectedIds []string
}{
{o1.TeamId, []string{o1.Name}, []string{o1.Id}},
{o1.TeamId, []string{o1.Name, o2.Name}, []string{o1.Id, o2.Id}},
{o1.TeamId, nil, nil},
{o1.TeamId, []string{"foo"}, nil},
{o1.TeamId, []string{o1.Name, "foo", o2.Name, o2.Name}, []string{o1.Id, o2.Id}},
{"", []string{o1.Name, "foo", o2.Name, o2.Name}, []string{o1.Id, o2.Id}},
{"asd", []string{o1.Name, "foo", o2.Name, o2.Name}, nil},
} {
var channels []*model.Channel
channels, err := ss.Channel().GetByNamesIncludeDeleted(tc.TeamId, tc.Names, true)
require.NoError(t, err)
var ids []string
for _, channel := range channels {
ids = append(ids, channel.Id)
}
sort.Strings(ids)
sort.Strings(tc.ExpectedIds)
assert.Equal(t, tc.ExpectedIds, ids, "tc %v", index)
}
}
func testChannelStoreGetDeletedByName(t *testing.T, ss store.Store) {
o1 := &model.Channel{}
o1.TeamId = model.NewId()
@@ -7648,7 +7707,7 @@ func testChannelStoreGetChannelMembersForExport(t *testing.T, ss store.Store) {
_, err = ss.Channel().SaveMember(&m2)
require.NoError(t, err)
d1, err := ss.Channel().GetChannelMembersForExport(u1.Id, t1.Id)
d1, err := ss.Channel().GetChannelMembersForExport(u1.Id, t1.Id, false)
assert.NoError(t, err)
assert.Len(t, d1, 1)

Просмотреть файл

@@ -674,6 +674,32 @@ func (_m *ChannelStore) GetByNames(team_id string, names []string, allowFromCach
return r0, r1
}
// GetByNamesIncludeDeleted provides a mock function with given fields: team_id, names, allowFromCache
func (_m *ChannelStore) GetByNamesIncludeDeleted(team_id string, names []string, allowFromCache bool) ([]*model.Channel, error) {
ret := _m.Called(team_id, names, allowFromCache)
var r0 []*model.Channel
var r1 error
if rf, ok := ret.Get(0).(func(string, []string, bool) ([]*model.Channel, error)); ok {
return rf(team_id, names, allowFromCache)
}
if rf, ok := ret.Get(0).(func(string, []string, bool) []*model.Channel); ok {
r0 = rf(team_id, names, allowFromCache)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]*model.Channel)
}
}
if rf, ok := ret.Get(1).(func(string, []string, bool) error); ok {
r1 = rf(team_id, names, allowFromCache)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// GetChannelCounts provides a mock function with given fields: teamID, userID
func (_m *ChannelStore) GetChannelCounts(teamID string, userID string) (*model.ChannelCounts, error) {
ret := _m.Called(teamID, userID)
@@ -700,25 +726,25 @@ func (_m *ChannelStore) GetChannelCounts(teamID string, userID string) (*model.C
return r0, r1
}
// GetChannelMembersForExport provides a mock function with given fields: userID, teamID
func (_m *ChannelStore) GetChannelMembersForExport(userID string, teamID string) ([]*model.ChannelMemberForExport, error) {
ret := _m.Called(userID, teamID)
// GetChannelMembersForExport provides a mock function with given fields: userID, teamID, includeArchivedChannel
func (_m *ChannelStore) GetChannelMembersForExport(userID string, teamID string, includeArchivedChannel bool) ([]*model.ChannelMemberForExport, error) {
ret := _m.Called(userID, teamID, includeArchivedChannel)
var r0 []*model.ChannelMemberForExport
var r1 error
if rf, ok := ret.Get(0).(func(string, string) ([]*model.ChannelMemberForExport, error)); ok {
return rf(userID, teamID)
if rf, ok := ret.Get(0).(func(string, string, bool) ([]*model.ChannelMemberForExport, error)); ok {
return rf(userID, teamID, includeArchivedChannel)
}
if rf, ok := ret.Get(0).(func(string, string) []*model.ChannelMemberForExport); ok {
r0 = rf(userID, teamID)
if rf, ok := ret.Get(0).(func(string, string, bool) []*model.ChannelMemberForExport); ok {
r0 = rf(userID, teamID, includeArchivedChannel)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]*model.ChannelMemberForExport)
}
}
if rf, ok := ret.Get(1).(func(string, string) error); ok {
r1 = rf(userID, teamID)
if rf, ok := ret.Get(1).(func(string, string, bool) error); ok {
r1 = rf(userID, teamID, includeArchivedChannel)
} else {
r1 = ret.Error(1)
}

Просмотреть файл

@@ -395,25 +395,25 @@ func (_m *PostStore) GetOldestEntityCreationTime() (int64, error) {
return r0, r1
}
// GetParentsForExportAfter provides a mock function with given fields: limit, afterID
func (_m *PostStore) GetParentsForExportAfter(limit int, afterID string) ([]*model.PostForExport, error) {
ret := _m.Called(limit, afterID)
// GetParentsForExportAfter provides a mock function with given fields: limit, afterID, includeArchivedChannels
func (_m *PostStore) GetParentsForExportAfter(limit int, afterID string, includeArchivedChannels bool) ([]*model.PostForExport, error) {
ret := _m.Called(limit, afterID, includeArchivedChannels)
var r0 []*model.PostForExport
var r1 error
if rf, ok := ret.Get(0).(func(int, string) ([]*model.PostForExport, error)); ok {
return rf(limit, afterID)
if rf, ok := ret.Get(0).(func(int, string, bool) ([]*model.PostForExport, error)); ok {
return rf(limit, afterID, includeArchivedChannels)
}
if rf, ok := ret.Get(0).(func(int, string) []*model.PostForExport); ok {
r0 = rf(limit, afterID)
if rf, ok := ret.Get(0).(func(int, string, bool) []*model.PostForExport); ok {
r0 = rf(limit, afterID, includeArchivedChannels)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]*model.PostForExport)
}
}
if rf, ok := ret.Get(1).(func(int, string) error); ok {
r1 = rf(limit, afterID)
if rf, ok := ret.Get(1).(func(int, string, bool) error); ok {
r1 = rf(limit, afterID, includeArchivedChannels)
} else {
r1 = ret.Error(1)
}

Просмотреть файл

@@ -4154,6 +4154,14 @@ func testPostStoreGetParentsForExportAfter(t *testing.T, ss store.Store) {
_, nErr := ss.Channel().Save(&c1, -1)
require.NoError(t, nErr)
c2 := model.Channel{}
c2.TeamId = t1.Id
c2.DisplayName = "Channel2"
c2.Name = NewTestId()
c2.Type = model.ChannelTypeOpen
_, nErr = ss.Channel().Save(&c2, -1)
require.NoError(t, nErr)
u1 := model.User{}
u1.Username = model.NewId()
u1.Email = MakeEmail()
@@ -4169,21 +4177,56 @@ func testPostStoreGetParentsForExportAfter(t *testing.T, ss store.Store) {
p1, nErr = ss.Post().Save(p1)
require.NoError(t, nErr)
posts, err := ss.Post().GetParentsForExportAfter(10000, strings.Repeat("0", 26))
assert.NoError(t, err)
p2 := &model.Post{}
p2.ChannelId = c2.Id
p2.UserId = u1.Id
p2.Message = NewTestId()
p2.CreateAt = 1000
p2, nErr = ss.Post().Save(p2)
require.NoError(t, nErr)
nErr = ss.Channel().Delete(c2.Id, model.GetMillis())
require.NoError(t, nErr)
found := false
for _, p := range posts {
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)
t.Run("without archived channels", func(t *testing.T) {
posts, err := ss.Post().GetParentsForExportAfter(10000, strings.Repeat("0", 26), false)
assert.NoError(t, err)
found := false
foundArchived := false
for _, p := range posts {
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)
}
if p.Id == p2.Id {
foundArchived = true
}
}
}
assert.True(t, found)
assert.True(t, found)
assert.False(t, foundArchived, "posts from archived channel should not be returned")
})
t.Run("with archived channels", func(t *testing.T) {
posts, err := ss.Post().GetParentsForExportAfter(10000, strings.Repeat("0", 26), true)
assert.NoError(t, err)
found := false
for _, p := range posts {
if p.Id == p2.Id {
found = true
assert.Equal(t, p.Id, p2.Id)
assert.Equal(t, p.Message, p2.Message)
assert.Equal(t, p.Username, u1.Username)
assert.Equal(t, p.TeamName, t1.Name)
assert.Equal(t, p.ChannelName, c2.Name)
}
}
assert.True(t, found)
})
}
func testPostStoreGetRepliesForExport(t *testing.T, ss store.Store) {