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.
Этот коммит содержится в:
George Goldberg
2018-05-14 15:59:04 +01:00
коммит произвёл GitHub
родитель 91557bbd97
Коммит 51bd710ecd
28 изменённых файлов: 1586 добавлений и 4 удалений

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

@@ -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)
}