MM-9728: Online migration for advanced permissions phase 2 (#8744)
* MM-9728: Online migration for advanced permissions phase 2 * Add unit tests for new store functions. * Move migration specific code to own file. * Add migration state function test. * Style fixes. * Add i18n strings. * Fix mocks. * Add TestMain to migrations package tests. * Fix typo. * Fix review comments. * Fix up the "Check if migration is done" check to actually work.
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
91557bbd97
Коммит
51bd710ecd
@@ -5,6 +5,7 @@ package storetest
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@@ -52,6 +53,7 @@ func TestChannelStore(t *testing.T, ss store.Store) {
|
||||
t.Run("GetPinnedPosts", func(t *testing.T) { testChannelStoreGetPinnedPosts(t, ss) })
|
||||
t.Run("MaxChannelsPerTeam", func(t *testing.T) { testChannelStoreMaxChannelsPerTeam(t, ss) })
|
||||
t.Run("GetChannelsByScheme", func(t *testing.T) { testChannelStoreGetChannelsByScheme(t, ss) })
|
||||
t.Run("MigrateChannelMembers", func(t *testing.T) { testChannelStoreMigrateChannelMembers(t, ss) })
|
||||
|
||||
}
|
||||
|
||||
@@ -2254,3 +2256,76 @@ func testChannelStoreGetChannelsByScheme(t *testing.T, ss store.Store) {
|
||||
d3 := res3.Data.(model.ChannelList)
|
||||
assert.Len(t, d3, 0)
|
||||
}
|
||||
|
||||
func testChannelStoreMigrateChannelMembers(t *testing.T, ss store.Store) {
|
||||
s1 := model.NewId()
|
||||
c1 := &model.Channel{
|
||||
TeamId: model.NewId(),
|
||||
DisplayName: "Name",
|
||||
Name: model.NewId(),
|
||||
Type: model.CHANNEL_OPEN,
|
||||
SchemeId: &s1,
|
||||
}
|
||||
c1 = (<-ss.Channel().Save(c1, 100)).Data.(*model.Channel)
|
||||
|
||||
cm1 := &model.ChannelMember{
|
||||
ChannelId: c1.Id,
|
||||
UserId: model.NewId(),
|
||||
ExplicitRoles: "channel_admin channel_user",
|
||||
NotifyProps: model.GetDefaultChannelNotifyProps(),
|
||||
}
|
||||
cm2 := &model.ChannelMember{
|
||||
ChannelId: c1.Id,
|
||||
UserId: model.NewId(),
|
||||
ExplicitRoles: "channel_user",
|
||||
NotifyProps: model.GetDefaultChannelNotifyProps(),
|
||||
}
|
||||
cm3 := &model.ChannelMember{
|
||||
ChannelId: c1.Id,
|
||||
UserId: model.NewId(),
|
||||
ExplicitRoles: "something_else",
|
||||
NotifyProps: model.GetDefaultChannelNotifyProps(),
|
||||
}
|
||||
|
||||
cm1 = (<-ss.Channel().SaveMember(cm1)).Data.(*model.ChannelMember)
|
||||
cm2 = (<-ss.Channel().SaveMember(cm2)).Data.(*model.ChannelMember)
|
||||
cm3 = (<-ss.Channel().SaveMember(cm3)).Data.(*model.ChannelMember)
|
||||
|
||||
lastDoneChannelId := strings.Repeat("0", 26)
|
||||
lastDoneUserId := strings.Repeat("0", 26)
|
||||
|
||||
for {
|
||||
res := <-ss.Channel().MigrateChannelMembers(lastDoneChannelId, lastDoneUserId)
|
||||
if assert.Nil(t, res.Err) {
|
||||
if res.Data == nil {
|
||||
break
|
||||
}
|
||||
data := res.Data.(map[string]string)
|
||||
lastDoneChannelId = data["ChannelId"]
|
||||
lastDoneUserId = data["UserId"]
|
||||
}
|
||||
}
|
||||
|
||||
ss.Channel().ClearCaches()
|
||||
|
||||
res1 := <-ss.Channel().GetMember(cm1.ChannelId, cm1.UserId)
|
||||
assert.Nil(t, res1.Err)
|
||||
cm1b := res1.Data.(*model.ChannelMember)
|
||||
assert.Equal(t, "", cm1b.ExplicitRoles)
|
||||
assert.True(t, cm1b.SchemeUser)
|
||||
assert.True(t, cm1b.SchemeAdmin)
|
||||
|
||||
res2 := <-ss.Channel().GetMember(cm2.ChannelId, cm2.UserId)
|
||||
assert.Nil(t, res2.Err)
|
||||
cm2b := res2.Data.(*model.ChannelMember)
|
||||
assert.Equal(t, "", cm2b.ExplicitRoles)
|
||||
assert.True(t, cm2b.SchemeUser)
|
||||
assert.False(t, cm2b.SchemeAdmin)
|
||||
|
||||
res3 := <-ss.Channel().GetMember(cm3.ChannelId, cm3.UserId)
|
||||
assert.Nil(t, res3.Err)
|
||||
cm3b := res3.Data.(*model.ChannelMember)
|
||||
assert.Equal(t, "something_else", cm3b.ExplicitRoles)
|
||||
assert.False(t, cm3b.SchemeUser)
|
||||
assert.False(t, cm3b.SchemeAdmin)
|
||||
}
|
||||
|
||||
@@ -583,6 +583,22 @@ func (_m *ChannelStore) IsUserInChannelUseCache(userId string, channelId string)
|
||||
return r0
|
||||
}
|
||||
|
||||
// MigrateChannelMembers provides a mock function with given fields: fromChannelId, fromUserId
|
||||
func (_m *ChannelStore) MigrateChannelMembers(fromChannelId string, fromUserId string) store.StoreChannel {
|
||||
ret := _m.Called(fromChannelId, fromUserId)
|
||||
|
||||
var r0 store.StoreChannel
|
||||
if rf, ok := ret.Get(0).(func(string, string) store.StoreChannel); ok {
|
||||
r0 = rf(fromChannelId, fromUserId)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(store.StoreChannel)
|
||||
}
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// PermanentDelete provides a mock function with given fields: channelId
|
||||
func (_m *ChannelStore) PermanentDelete(channelId string) store.StoreChannel {
|
||||
ret := _m.Called(channelId)
|
||||
|
||||
@@ -301,6 +301,22 @@ func (_m *TeamStore) GetTotalMemberCount(teamId string) store.StoreChannel {
|
||||
return r0
|
||||
}
|
||||
|
||||
// MigrateTeamMembers provides a mock function with given fields: fromTeamId, fromUserId
|
||||
func (_m *TeamStore) MigrateTeamMembers(fromTeamId string, fromUserId string) store.StoreChannel {
|
||||
ret := _m.Called(fromTeamId, fromUserId)
|
||||
|
||||
var r0 store.StoreChannel
|
||||
if rf, ok := ret.Get(0).(func(string, string) store.StoreChannel); ok {
|
||||
r0 = rf(fromTeamId, fromUserId)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(store.StoreChannel)
|
||||
}
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// PermanentDelete provides a mock function with given fields: teamId
|
||||
func (_m *TeamStore) PermanentDelete(teamId string) store.StoreChannel {
|
||||
ret := _m.Called(teamId)
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
package storetest
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@@ -39,6 +40,7 @@ func TestTeamStore(t *testing.T, ss store.Store) {
|
||||
t.Run("GetChannelUnreadsForTeam", func(t *testing.T) { testGetChannelUnreadsForTeam(t, ss) })
|
||||
t.Run("UpdateLastTeamIconUpdate", func(t *testing.T) { testUpdateLastTeamIconUpdate(t, ss) })
|
||||
t.Run("GetTeamsByScheme", func(t *testing.T) { testGetTeamsByScheme(t, ss) })
|
||||
t.Run("MigrateTeamMembers", func(t *testing.T) { testTeamStoreMigrateTeamMembers(t, ss) })
|
||||
}
|
||||
|
||||
func testTeamStoreSave(t *testing.T, ss store.Store) {
|
||||
@@ -1098,3 +1100,72 @@ func testGetTeamsByScheme(t *testing.T, ss store.Store) {
|
||||
d3 := res3.Data.([]*model.Team)
|
||||
assert.Len(t, d3, 0)
|
||||
}
|
||||
|
||||
func testTeamStoreMigrateTeamMembers(t *testing.T, ss store.Store) {
|
||||
s1 := model.NewId()
|
||||
t1 := &model.Team{
|
||||
DisplayName: "Name",
|
||||
Name: "z-z-z" + model.NewId() + "b",
|
||||
Email: model.NewId() + "@nowhere.com",
|
||||
Type: model.TEAM_OPEN,
|
||||
InviteId: model.NewId(),
|
||||
SchemeId: &s1,
|
||||
}
|
||||
t1 = store.Must(ss.Team().Save(t1)).(*model.Team)
|
||||
|
||||
tm1 := &model.TeamMember{
|
||||
TeamId: t1.Id,
|
||||
UserId: model.NewId(),
|
||||
ExplicitRoles: "team_admin team_user",
|
||||
}
|
||||
tm2 := &model.TeamMember{
|
||||
TeamId: t1.Id,
|
||||
UserId: model.NewId(),
|
||||
ExplicitRoles: "team_user",
|
||||
}
|
||||
tm3 := &model.TeamMember{
|
||||
TeamId: t1.Id,
|
||||
UserId: model.NewId(),
|
||||
ExplicitRoles: "something_else",
|
||||
}
|
||||
|
||||
tm1 = (<-ss.Team().SaveMember(tm1, -1)).Data.(*model.TeamMember)
|
||||
tm2 = (<-ss.Team().SaveMember(tm2, -1)).Data.(*model.TeamMember)
|
||||
tm3 = (<-ss.Team().SaveMember(tm3, -1)).Data.(*model.TeamMember)
|
||||
|
||||
lastDoneTeamId := strings.Repeat("0", 26)
|
||||
lastDoneUserId := strings.Repeat("0", 26)
|
||||
|
||||
for {
|
||||
res := <-ss.Team().MigrateTeamMembers(lastDoneTeamId, lastDoneUserId)
|
||||
if assert.Nil(t, res.Err) {
|
||||
if res.Data == nil {
|
||||
break
|
||||
}
|
||||
data := res.Data.(map[string]string)
|
||||
lastDoneTeamId = data["TeamId"]
|
||||
lastDoneUserId = data["UserId"]
|
||||
}
|
||||
}
|
||||
|
||||
res1 := <-ss.Team().GetMember(tm1.TeamId, tm1.UserId)
|
||||
assert.Nil(t, res1.Err)
|
||||
tm1b := res1.Data.(*model.TeamMember)
|
||||
assert.Equal(t, "", tm1b.ExplicitRoles)
|
||||
assert.True(t, tm1b.SchemeUser)
|
||||
assert.True(t, tm1b.SchemeAdmin)
|
||||
|
||||
res2 := <-ss.Team().GetMember(tm2.TeamId, tm2.UserId)
|
||||
assert.Nil(t, res2.Err)
|
||||
tm2b := res2.Data.(*model.TeamMember)
|
||||
assert.Equal(t, "", tm2b.ExplicitRoles)
|
||||
assert.True(t, tm2b.SchemeUser)
|
||||
assert.False(t, tm2b.SchemeAdmin)
|
||||
|
||||
res3 := <-ss.Team().GetMember(tm3.TeamId, tm3.UserId)
|
||||
assert.Nil(t, res3.Err)
|
||||
tm3b := res3.Data.(*model.TeamMember)
|
||||
assert.Equal(t, "something_else", tm3b.ExplicitRoles)
|
||||
assert.False(t, tm3b.SchemeUser)
|
||||
assert.False(t, tm3b.SchemeAdmin)
|
||||
}
|
||||
|
||||
Ссылка в новой задаче
Block a user