mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-03 06:55:59 +00:00
Fix various bugs in the moderation feature. (#2608)
* Fix search field string. * Show your own user as an Admin when changing roles. * Also show invited users when changing roles. * Don't allow admin's to kick/ban other admins or themselves. * Fix a bug when left members were counted as admins/moderators. * Show when a member is pending. * Add sections to the change role screen.
This commit is contained in:
@@ -31,8 +31,10 @@ class RoomChangeRolesScreenViewModelTests: XCTestCase {
|
||||
setupViewModel(mode: .administrator)
|
||||
XCTAssertEqual(context.viewState.membersToPromote, [])
|
||||
XCTAssertEqual(context.viewState.membersToDemote, [])
|
||||
XCTAssertEqual(context.viewState.members, context.viewState.visibleMembers)
|
||||
XCTAssertEqual(context.viewState.membersWithRole.count, 1)
|
||||
XCTAssertEqual(context.viewState.administrators, context.viewState.visibleAdministrators)
|
||||
XCTAssertEqual(context.viewState.moderators, context.viewState.visibleModerators)
|
||||
XCTAssertEqual(context.viewState.users, context.viewState.visibleUsers)
|
||||
XCTAssertEqual(context.viewState.membersWithRole.count, 2)
|
||||
XCTAssertEqual(context.viewState.membersWithRole.first?.id, RoomMemberProxyMock.mockAdmin.userID)
|
||||
XCTAssertFalse(context.viewState.hasChanges)
|
||||
XCTAssertFalse(context.viewState.isSearching)
|
||||
@@ -42,7 +44,9 @@ class RoomChangeRolesScreenViewModelTests: XCTestCase {
|
||||
setupViewModel(mode: .moderator)
|
||||
XCTAssertEqual(context.viewState.membersToPromote, [])
|
||||
XCTAssertEqual(context.viewState.membersToDemote, [])
|
||||
XCTAssertEqual(context.viewState.members, context.viewState.visibleMembers)
|
||||
XCTAssertEqual(context.viewState.administrators, context.viewState.visibleAdministrators)
|
||||
XCTAssertEqual(context.viewState.moderators, context.viewState.visibleModerators)
|
||||
XCTAssertEqual(context.viewState.users, context.viewState.visibleUsers)
|
||||
XCTAssertEqual(context.viewState.membersWithRole.count, 1)
|
||||
XCTAssertEqual(context.viewState.membersWithRole.first?.id, RoomMemberProxyMock.mockModerator.userID)
|
||||
XCTAssertFalse(context.viewState.hasChanges)
|
||||
@@ -51,7 +55,7 @@ class RoomChangeRolesScreenViewModelTests: XCTestCase {
|
||||
|
||||
func testToggleUserOn() {
|
||||
testInitialStateModerators()
|
||||
guard let firstUser = context.viewState.members.first(where: { !context.viewState.isMemberSelected($0) }) else {
|
||||
guard let firstUser = context.viewState.users.first(where: { !context.viewState.isMemberSelected($0) }) else {
|
||||
XCTFail("There should be a regular user available to promote.")
|
||||
return
|
||||
}
|
||||
@@ -150,7 +154,7 @@ class RoomChangeRolesScreenViewModelTests: XCTestCase {
|
||||
// Given the change roles view model for moderators.
|
||||
setupViewModel(mode: .moderator)
|
||||
|
||||
guard let firstUser = context.viewState.members.first(where: { !context.viewState.isMemberSelected($0) }),
|
||||
guard let firstUser = context.viewState.users.first(where: { !context.viewState.isMemberSelected($0) }),
|
||||
let existingModerator = context.viewState.membersWithRole.first else {
|
||||
XCTFail("There should be a regular user and a moderator to begin with.")
|
||||
return
|
||||
@@ -175,7 +179,7 @@ class RoomChangeRolesScreenViewModelTests: XCTestCase {
|
||||
setupViewModel(mode: .administrator)
|
||||
XCTAssertNil(context.alertInfo)
|
||||
|
||||
guard let firstUser = context.viewState.members.first(where: { !context.viewState.isMemberSelected($0) }) else {
|
||||
guard let firstUser = context.viewState.users.first(where: { !context.viewState.isMemberSelected($0) }) else {
|
||||
XCTFail("There should be a regular user to begin with.")
|
||||
return
|
||||
}
|
||||
|
||||
+126
-3
@@ -126,8 +126,128 @@ class RoomMembersListScreenViewModelTests: XCTestCase {
|
||||
XCTAssertEqual(viewModel.state.visibleJoinedMembers.count, 0)
|
||||
}
|
||||
|
||||
func testKickMember() async throws {
|
||||
func testSelectUserAsUser() async throws {
|
||||
// Given the room list viewed as a regular user.
|
||||
setup(with: .allMembers)
|
||||
let deferred = deferFulfillment(context.$viewState) { !$0.visibleInvitedMembers.isEmpty }
|
||||
try await deferred.fulfill()
|
||||
|
||||
// When tapping on another user in the list.
|
||||
let memberDetailsAction = deferFulfillment(viewModel.actions) { $0.isSelectMember }
|
||||
guard let user = viewModel.state.visibleJoinedMembers.first(where: { $0.role == .user && $0.id != RoomMemberProxyMock.mockMe.userID }) else {
|
||||
XCTFail("Expected to find a regular user.")
|
||||
return
|
||||
}
|
||||
context.send(viewAction: .selectMember(user))
|
||||
|
||||
// Then the member's details should be shown.
|
||||
try await memberDetailsAction.fulfill()
|
||||
XCTAssertNil(context.memberToManage)
|
||||
}
|
||||
|
||||
func testSelectUserAsAdmin() async throws {
|
||||
// Given the room list viewed as an admin.
|
||||
setup(with: .allMembersAsAdmin)
|
||||
var deferred = deferFulfillment(context.$viewState) { !$0.visibleInvitedMembers.isEmpty }
|
||||
try await deferred.fulfill()
|
||||
XCTAssertNil(context.memberToManage)
|
||||
|
||||
// When tapping on a user in the list.
|
||||
deferred = deferFulfillment(context.$viewState) { $0.bindings.memberToManage != nil }
|
||||
guard let user = viewModel.state.visibleJoinedMembers.first(where: { $0.role == .user && $0.id != RoomMemberProxyMock.mockMe.userID }) else {
|
||||
XCTFail("Expected to find a regular user.")
|
||||
return
|
||||
}
|
||||
context.send(viewAction: .selectMember(user))
|
||||
try await deferred.fulfill()
|
||||
|
||||
// Then member management should be shown for that user.
|
||||
XCTAssertEqual(context.memberToManage?.member, user)
|
||||
XCTAssertEqual(context.memberToManage?.actions, [.kick, .ban])
|
||||
}
|
||||
|
||||
func testSelectModeratorAsAdmin() async throws {
|
||||
// Given the room list viewed as an admin.
|
||||
setup(with: .allMembersAsAdmin)
|
||||
var deferred = deferFulfillment(context.$viewState) { !$0.visibleInvitedMembers.isEmpty }
|
||||
try await deferred.fulfill()
|
||||
XCTAssertNil(context.memberToManage)
|
||||
|
||||
// When tapping on a moderator in the list.
|
||||
deferred = deferFulfillment(context.$viewState) { $0.bindings.memberToManage != nil }
|
||||
guard let moderator = viewModel.state.visibleJoinedMembers.first(where: { $0.role == .moderator }) else {
|
||||
XCTFail("Expected to find a moderator.")
|
||||
return
|
||||
}
|
||||
context.send(viewAction: .selectMember(moderator))
|
||||
try await deferred.fulfill()
|
||||
|
||||
// Then member management should be shown for the moderator.
|
||||
XCTAssertEqual(context.memberToManage?.member, moderator)
|
||||
XCTAssertEqual(context.memberToManage?.actions, [.kick, .ban])
|
||||
}
|
||||
|
||||
func testSelectAdminAsAdmin() async throws {
|
||||
// Given the room list viewed as an admin.
|
||||
setup(with: .allMembersAsAdmin)
|
||||
let deferred = deferFulfillment(context.$viewState) { !$0.visibleInvitedMembers.isEmpty }
|
||||
try await deferred.fulfill()
|
||||
|
||||
// When tapping on another administrator in the list.
|
||||
let memberDetailsAction = deferFulfillment(viewModel.actions) { $0.isSelectMember }
|
||||
guard let admin = viewModel.state.visibleJoinedMembers.first(where: { $0.role == .administrator && $0.id != RoomMemberProxyMock.mockMe.userID }) else {
|
||||
XCTFail("Expected to find another admin.")
|
||||
return
|
||||
}
|
||||
context.send(viewAction: .selectMember(admin))
|
||||
|
||||
// Then the administrator's details should be shown.
|
||||
try await memberDetailsAction.fulfill()
|
||||
XCTAssertNil(context.memberToManage)
|
||||
}
|
||||
|
||||
func testSelectOwnMemberAsAdmin() async throws {
|
||||
// Given the room list viewed as an admin.
|
||||
setup(with: .allMembersAsAdmin)
|
||||
let deferred = deferFulfillment(context.$viewState) { !$0.visibleInvitedMembers.isEmpty }
|
||||
try await deferred.fulfill()
|
||||
|
||||
// When tapping on yourself in the list.
|
||||
let memberDetailsAction = deferFulfillment(viewModel.actions) { $0.isSelectMember }
|
||||
guard let ownMember = viewModel.state.visibleJoinedMembers.first(where: { $0.id == RoomMemberProxyMock.mockMe.userID }) else {
|
||||
XCTFail("Expected to find own user admin.")
|
||||
return
|
||||
}
|
||||
context.send(viewAction: .selectMember(ownMember))
|
||||
|
||||
// Then your member's details should be shown.
|
||||
try await memberDetailsAction.fulfill()
|
||||
XCTAssertNil(context.memberToManage)
|
||||
}
|
||||
|
||||
func testSelectBannedMember() async throws {
|
||||
// Given the room list viewed as an admin.
|
||||
setup(with: .allMembersAsAdmin + RoomMemberProxyMock.mockBanned)
|
||||
var deferred = deferFulfillment(context.$viewState) { !$0.visibleInvitedMembers.isEmpty }
|
||||
try await deferred.fulfill()
|
||||
XCTAssertNil(context.alertInfo)
|
||||
|
||||
// When tapping on a banned member in the list.
|
||||
deferred = deferFulfillment(context.$viewState) { $0.bindings.alertInfo != nil }
|
||||
guard let bannedMember = viewModel.state.visibleBannedMembers.first else {
|
||||
XCTFail("Expected to find a banned user.")
|
||||
return
|
||||
}
|
||||
context.send(viewAction: .selectMember(bannedMember))
|
||||
|
||||
// Then an alert should be shown to unban the user.
|
||||
try await deferred.fulfill()
|
||||
XCTAssertNil(context.memberToManage)
|
||||
XCTAssertNotNil(context.alertInfo)
|
||||
}
|
||||
|
||||
func testKickMember() async throws {
|
||||
setup(with: .allMembersAsAdmin)
|
||||
let deferred = deferFulfillment(context.$viewState) { !$0.visibleJoinedMembers.isEmpty }
|
||||
try await deferred.fulfill()
|
||||
|
||||
@@ -140,7 +260,7 @@ class RoomMembersListScreenViewModelTests: XCTestCase {
|
||||
}
|
||||
|
||||
func testBanMember() async throws {
|
||||
setup(with: .allMembers)
|
||||
setup(with: .allMembersAsAdmin)
|
||||
let deferred = deferFulfillment(context.$viewState) { !$0.visibleJoinedMembers.isEmpty }
|
||||
try await deferred.fulfill()
|
||||
|
||||
@@ -153,7 +273,7 @@ class RoomMembersListScreenViewModelTests: XCTestCase {
|
||||
}
|
||||
|
||||
func testUnbanMember() async throws {
|
||||
setup(with: .allMembers)
|
||||
setup(with: .allMembersAsAdmin)
|
||||
let deferred = deferFulfillment(context.$viewState) { !$0.visibleJoinedMembers.isEmpty }
|
||||
try await deferred.fulfill()
|
||||
|
||||
@@ -166,6 +286,9 @@ class RoomMembersListScreenViewModelTests: XCTestCase {
|
||||
}
|
||||
|
||||
private func setup(with members: [RoomMemberProxyMock]) {
|
||||
AppSettings.resetAllSettings()
|
||||
ServiceLocator.shared.settings.roomModerationEnabled = true
|
||||
|
||||
roomProxy = RoomProxyMock(with: .init(name: "test", members: members))
|
||||
viewModel = .init(roomProxy: roomProxy,
|
||||
mediaProvider: MockMediaProvider(),
|
||||
Reference in New Issue
Block a user