Skip to content

Add tests for downgrading a v12 room to one that doesn't support MSC4289 #794

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
141 changes: 126 additions & 15 deletions tests/v12_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -495,10 +495,9 @@ func TestMSC4289PrivilegedRoomCreators_Upgrades(t *testing.T) {
testCases := []struct {
name string
initialCreator *client.CSAPI
initialAdditionalCreators []string
initialVersion string
initialUserPLs map[string]int
entitiyDoingUpgrade *client.CSAPI
entityDoingUpgrade *client.CSAPI
newAdditionalCreators []string
// assertions
wantAdditionalCreators []string
Expand All @@ -511,7 +510,7 @@ func TestMSC4289PrivilegedRoomCreators_Upgrades(t *testing.T) {
initialUserPLs: map[string]int{
bob.UserID: 100,
},
entitiyDoingUpgrade: bob,
entityDoingUpgrade: bob,
wantAdditionalCreators: []string{},
wantNewUsersMap: map[string]int64{},
},
Expand All @@ -523,7 +522,7 @@ func TestMSC4289PrivilegedRoomCreators_Upgrades(t *testing.T) {
bob.UserID: 100,
charlie.UserID: 100,
},
entitiyDoingUpgrade: bob,
entityDoingUpgrade: bob,
wantAdditionalCreators: []string{},
wantNewUsersMap: map[string]int64{
charlie.UserID: 100,
Expand All @@ -536,7 +535,7 @@ func TestMSC4289PrivilegedRoomCreators_Upgrades(t *testing.T) {
initialUserPLs: map[string]int{
bob.UserID: 150, // bob has enough permission to upgrade
},
entitiyDoingUpgrade: bob,
entityDoingUpgrade: bob,
newAdditionalCreators: []string{charlie.UserID},
wantAdditionalCreators: []string{charlie.UserID},
wantNewUsersMap: map[string]int64{},
Expand All @@ -549,7 +548,7 @@ func TestMSC4289PrivilegedRoomCreators_Upgrades(t *testing.T) {
bob.UserID: 150, // bob has enough permission to upgrade
charlie.UserID: 50, // gets removed as he will become an additional creator
},
entitiyDoingUpgrade: bob,
entityDoingUpgrade: bob,
newAdditionalCreators: []string{charlie.UserID},
wantAdditionalCreators: []string{charlie.UserID},
wantNewUsersMap: map[string]int64{},
Expand All @@ -562,7 +561,7 @@ func TestMSC4289PrivilegedRoomCreators_Upgrades(t *testing.T) {
alice.UserID: 100,
bob.UserID: 100,
},
entitiyDoingUpgrade: alice,
entityDoingUpgrade: alice,
newAdditionalCreators: []string{bob.UserID},
wantAdditionalCreators: []string{bob.UserID},
wantNewUsersMap: map[string]int64{}, // both alice and bob are removed as they are now creators.
Expand All @@ -576,7 +575,7 @@ func TestMSC4289PrivilegedRoomCreators_Upgrades(t *testing.T) {
bob.UserID: 100,
charlie.UserID: 50,
},
entitiyDoingUpgrade: alice,
entityDoingUpgrade: alice,
newAdditionalCreators: []string{bob.UserID},
wantAdditionalCreators: []string{bob.UserID},
wantNewUsersMap: map[string]int64{
Expand All @@ -590,10 +589,6 @@ func TestMSC4289PrivilegedRoomCreators_Upgrades(t *testing.T) {
"room_version": tc.initialVersion,
"preset": "public_chat",
}
if tc.initialAdditionalCreators != nil {
must.Equal(t, tc.initialVersion, roomVersion12, "can only set additional_creators on v12")
createBody["additional_creators"] = tc.initialAdditionalCreators
}
roomID := tc.initialCreator.MustCreateRoom(t, createBody)
alice.JoinRoom(t, roomID, []spec.ServerName{"hs1"})
bob.JoinRoom(t, roomID, []spec.ServerName{"hs1"})
Expand All @@ -611,10 +606,10 @@ func TestMSC4289PrivilegedRoomCreators_Upgrades(t *testing.T) {
if tc.newAdditionalCreators != nil {
upgradeBody["additional_creators"] = tc.newAdditionalCreators
}
res := tc.entitiyDoingUpgrade.MustDo(t, "POST", []string{"_matrix", "client", "v3", "rooms", roomID, "upgrade"}, client.WithJSONBody(t, upgradeBody))
res := tc.entityDoingUpgrade.MustDo(t, "POST", []string{"_matrix", "client", "v3", "rooms", roomID, "upgrade"}, client.WithJSONBody(t, upgradeBody))
newRoomID := must.ParseJSON(t, res.Body).Get("replacement_room").Str
// New Create event assertions
createContent := tc.entitiyDoingUpgrade.MustGetStateEventContent(t, newRoomID, spec.MRoomCreate, "")
createContent := tc.entityDoingUpgrade.MustGetStateEventContent(t, newRoomID, spec.MRoomCreate, "")
createAssertions := []match.JSON{
match.JSONKeyEqual("room_version", roomVersion12),
}
Expand All @@ -629,7 +624,7 @@ func TestMSC4289PrivilegedRoomCreators_Upgrades(t *testing.T) {
t, createContent, createAssertions...,
)
// New PL assertions
plContent := tc.entitiyDoingUpgrade.MustGetStateEventContent(t, newRoomID, spec.MRoomPowerLevels, "")
plContent := tc.entityDoingUpgrade.MustGetStateEventContent(t, newRoomID, spec.MRoomPowerLevels, "")
if tc.wantNewUsersMap != nil {
plContent.Get("users").ForEach(func(key, v gjson.Result) bool {
gotVal := v.Int()
Expand All @@ -652,6 +647,122 @@ func TestMSC4289PrivilegedRoomCreators_Upgrades(t *testing.T) {
}
}

func TestMSC4289PrivilegedRoomCreators_Downgrades(t *testing.T) {
deployment := complement.Deploy(t, 1)
defer deployment.Destroy(t)
alice := deployment.Register(t, "hs1", helpers.RegistrationOpts{
LocalpartSuffix: "alice",
})
bob := deployment.Register(t, "hs1", helpers.RegistrationOpts{
LocalpartSuffix: "bob",
})

testCases := []struct {
name string
initialCreator *client.CSAPI
initialAdditionalCreators []string
newVersion string
initialPLs map[string]any
entityDoingUpgrade *client.CSAPI
// assertions
wantNewUsersMap map[string]int64
}{
{
name: "upgrading a room from v12 to v11 keeps the old room's creator user as an admin of the new room",
initialCreator: alice,
newVersion: "11",
initialPLs: map[string]any{},
entityDoingUpgrade: alice,
wantNewUsersMap: map[string]int64{
// Max PL needed to do anything in a room with no default power levels.
alice.UserID: 50,
},
},
{
name: "upgrading a room from v12 to v11 sets the old room's creator to the max power level needed to carry out any action",
initialCreator: alice,
newVersion: "11",
initialPLs: map[string]any{
"ban": 100,
},
entityDoingUpgrade: alice,
wantNewUsersMap: map[string]int64{
// Max PL needed to do anything in a room with no default power levels.
alice.UserID: 100,
},
},
{
name: "upgrading a room from v12 to v11 keeps the additional_creator users as admins of the new room",
initialCreator: alice,
initialAdditionalCreators: []string{
bob.UserID,
},
newVersion: "11",
initialPLs: map[string]any{},
entityDoingUpgrade: alice,
wantNewUsersMap: map[string]int64{
// Max PL needed to do anything in a room with no default power levels.
alice.UserID: 50,
bob.UserID: 50,
},
},
}

for _, tc := range testCases {
createBody := map[string]interface{}{
"room_version": roomVersion12,
"preset": "public_chat",
}
if tc.initialAdditionalCreators != nil {
createBody["creation_content"] = map[string]any{
"additional_creators": tc.initialAdditionalCreators,
}
}
roomID := tc.initialCreator.MustCreateRoom(t, createBody)
alice.JoinRoom(t, roomID, []spec.ServerName{"hs1"})
bob.JoinRoom(t, roomID, []spec.ServerName{"hs1"})
tc.initialCreator.SendEventSynced(t, roomID, b.Event{
Type: spec.MRoomPowerLevels,
StateKey: b.Ptr(""),
Content: tc.initialPLs,
})
upgradeBody := map[string]any{
"new_version": tc.newVersion,
}
res := tc.entityDoingUpgrade.MustDo(t, "POST", []string{"_matrix", "client", "v3", "rooms", roomID, "upgrade"}, client.WithJSONBody(t, upgradeBody))
newRoomID := must.ParseJSON(t, res.Body).Get("replacement_room").Str
// New Create event assertions
createContent := tc.entityDoingUpgrade.MustGetStateEventContent(t, newRoomID, spec.MRoomCreate, "")
createAssertions := []match.JSON{
match.JSONKeyEqual("room_version", tc.newVersion),
}
must.MatchGJSON(
t, createContent, createAssertions...,
)
// New PL assertions
plContent := tc.entityDoingUpgrade.MustGetStateEventContent(t, newRoomID, spec.MRoomPowerLevels, "")
if tc.wantNewUsersMap != nil {
plContent.Get("users").ForEach(func(key, v gjson.Result) bool {
gotVal := v.Int()
wantVal, ok := tc.wantNewUsersMap[key.Str]
if !ok {
ct.Errorf(t, "%s: upgraded room PL content, user %s has PL %v but want it missing", tc.name, key.Str, gotVal)
return true
}
if gotVal != wantVal {
ct.Errorf(t, "%s: upgraded room PL content, user %s has PL %v want %v", tc.name, key.Str, gotVal, wantVal)
}
delete(tc.wantNewUsersMap, key.Str)
return true
})
if len(tc.wantNewUsersMap) > 0 {
ct.Fatalf(t, "%s: upgraded room PL content missed these users %v", tc.name, tc.wantNewUsersMap)
}
}
t.Logf("OK: %v", tc.name)
}
}

// Test that the room ID is in fact the hash of the create event.
func TestMSC4291RoomIDAsHashOfCreateEvent(t *testing.T) {
deployment := complement.Deploy(t, 1)
Expand Down
Loading