updated existing preview tests and added a test for the single space cases
fixed a bug where was not possible to re-select the space members option with unknown spaces. pr suggestions
This commit is contained in:
@@ -16618,15 +16618,15 @@ class SpaceServiceProxyMock: SpaceServiceProxyProtocol, @unchecked Sendable {
|
||||
}
|
||||
//MARK: - joinedParents
|
||||
|
||||
var joinedParentsRoomIDUnderlyingCallsCount = 0
|
||||
var joinedParentsRoomIDCallsCount: Int {
|
||||
var joinedParentsChildIDUnderlyingCallsCount = 0
|
||||
var joinedParentsChildIDCallsCount: Int {
|
||||
get {
|
||||
if Thread.isMainThread {
|
||||
return joinedParentsRoomIDUnderlyingCallsCount
|
||||
return joinedParentsChildIDUnderlyingCallsCount
|
||||
} else {
|
||||
var returnValue: Int? = nil
|
||||
DispatchQueue.main.sync {
|
||||
returnValue = joinedParentsRoomIDUnderlyingCallsCount
|
||||
returnValue = joinedParentsChildIDUnderlyingCallsCount
|
||||
}
|
||||
|
||||
return returnValue!
|
||||
@@ -16634,29 +16634,29 @@ class SpaceServiceProxyMock: SpaceServiceProxyProtocol, @unchecked Sendable {
|
||||
}
|
||||
set {
|
||||
if Thread.isMainThread {
|
||||
joinedParentsRoomIDUnderlyingCallsCount = newValue
|
||||
joinedParentsChildIDUnderlyingCallsCount = newValue
|
||||
} else {
|
||||
DispatchQueue.main.sync {
|
||||
joinedParentsRoomIDUnderlyingCallsCount = newValue
|
||||
joinedParentsChildIDUnderlyingCallsCount = newValue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var joinedParentsRoomIDCalled: Bool {
|
||||
return joinedParentsRoomIDCallsCount > 0
|
||||
var joinedParentsChildIDCalled: Bool {
|
||||
return joinedParentsChildIDCallsCount > 0
|
||||
}
|
||||
var joinedParentsRoomIDReceivedRoomID: String?
|
||||
var joinedParentsRoomIDReceivedInvocations: [String] = []
|
||||
var joinedParentsChildIDReceivedChildID: String?
|
||||
var joinedParentsChildIDReceivedInvocations: [String] = []
|
||||
|
||||
var joinedParentsRoomIDUnderlyingReturnValue: Result<[SpaceRoomProxyProtocol], SpaceServiceProxyError>!
|
||||
var joinedParentsRoomIDReturnValue: Result<[SpaceRoomProxyProtocol], SpaceServiceProxyError>! {
|
||||
var joinedParentsChildIDUnderlyingReturnValue: Result<[SpaceRoomProxyProtocol], SpaceServiceProxyError>!
|
||||
var joinedParentsChildIDReturnValue: Result<[SpaceRoomProxyProtocol], SpaceServiceProxyError>! {
|
||||
get {
|
||||
if Thread.isMainThread {
|
||||
return joinedParentsRoomIDUnderlyingReturnValue
|
||||
return joinedParentsChildIDUnderlyingReturnValue
|
||||
} else {
|
||||
var returnValue: Result<[SpaceRoomProxyProtocol], SpaceServiceProxyError>? = nil
|
||||
DispatchQueue.main.sync {
|
||||
returnValue = joinedParentsRoomIDUnderlyingReturnValue
|
||||
returnValue = joinedParentsChildIDUnderlyingReturnValue
|
||||
}
|
||||
|
||||
return returnValue!
|
||||
@@ -16664,26 +16664,26 @@ class SpaceServiceProxyMock: SpaceServiceProxyProtocol, @unchecked Sendable {
|
||||
}
|
||||
set {
|
||||
if Thread.isMainThread {
|
||||
joinedParentsRoomIDUnderlyingReturnValue = newValue
|
||||
joinedParentsChildIDUnderlyingReturnValue = newValue
|
||||
} else {
|
||||
DispatchQueue.main.sync {
|
||||
joinedParentsRoomIDUnderlyingReturnValue = newValue
|
||||
joinedParentsChildIDUnderlyingReturnValue = newValue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var joinedParentsRoomIDClosure: ((String) async -> Result<[SpaceRoomProxyProtocol], SpaceServiceProxyError>)?
|
||||
var joinedParentsChildIDClosure: ((String) async -> Result<[SpaceRoomProxyProtocol], SpaceServiceProxyError>)?
|
||||
|
||||
func joinedParents(roomID: String) async -> Result<[SpaceRoomProxyProtocol], SpaceServiceProxyError> {
|
||||
joinedParentsRoomIDCallsCount += 1
|
||||
joinedParentsRoomIDReceivedRoomID = roomID
|
||||
func joinedParents(childID: String) async -> Result<[SpaceRoomProxyProtocol], SpaceServiceProxyError> {
|
||||
joinedParentsChildIDCallsCount += 1
|
||||
joinedParentsChildIDReceivedChildID = childID
|
||||
DispatchQueue.main.async {
|
||||
self.joinedParentsRoomIDReceivedInvocations.append(roomID)
|
||||
self.joinedParentsChildIDReceivedInvocations.append(childID)
|
||||
}
|
||||
if let joinedParentsRoomIDClosure = joinedParentsRoomIDClosure {
|
||||
return await joinedParentsRoomIDClosure(roomID)
|
||||
if let joinedParentsChildIDClosure = joinedParentsChildIDClosure {
|
||||
return await joinedParentsChildIDClosure(childID)
|
||||
} else {
|
||||
return joinedParentsRoomIDReturnValue
|
||||
return joinedParentsChildIDReturnValue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ extension SpaceServiceProxyMock {
|
||||
self.init()
|
||||
|
||||
joinedSpacesPublisher = .init(configuration.joinedSpaces)
|
||||
joinedParentsRoomIDReturnValue = .success(configuration.joinedParentSpaces)
|
||||
joinedParentsChildIDReturnValue = .success(configuration.joinedParentSpaces)
|
||||
spaceRoomListSpaceIDClosure = { spaceID in
|
||||
if let spaceRoomList = configuration.spaceRoomLists[spaceID] {
|
||||
.success(spaceRoomList)
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import MatrixRustSDK
|
||||
|
||||
enum SecurityAndPrivacyScreenViewModelAction {
|
||||
case displayEditAddressScreen
|
||||
@@ -39,14 +38,11 @@ struct SecurityAndPrivacyScreenViewState: BindableState {
|
||||
var canEditHistoryVisibility = false
|
||||
var joinedParentSpaces: [SpaceRoomProxyProtocol] = []
|
||||
|
||||
/// The count of the intersection between the set of joined parent spaces and the set of spaces in the current access type
|
||||
var selectableSpacesCount: Int {
|
||||
Set(joinedParentSpaces.map(\.id) + currentSettings.accessType.spaceIDs).count
|
||||
}
|
||||
|
||||
private var desiredJoinedParentSpaces: [SpaceRoomProxyProtocol] {
|
||||
joinedParentSpaces.filter { bindings.desiredSettings.accessType.spaceIDs.contains($0.id) }
|
||||
}
|
||||
|
||||
private var hasChanges: Bool {
|
||||
currentSettings != bindings.desiredSettings
|
||||
}
|
||||
@@ -111,13 +107,9 @@ struct SecurityAndPrivacyScreenViewState: BindableState {
|
||||
var spaceSelection: SpaceSelection {
|
||||
if selectableSpacesCount > 1 {
|
||||
.multiple
|
||||
} else if let desiredJoinedParent = desiredJoinedParentSpaces.first {
|
||||
// The parent space is joined by the user and is also currently selected
|
||||
.singleJoined(desiredJoinedParent)
|
||||
} else if let joinedParent = joinedParentSpaces.first {
|
||||
// The parent space is joined by the user but is not currently selected
|
||||
.singleJoined(joinedParent)
|
||||
} else if let unknownSpaceID = bindings.desiredSettings.accessType.spaceIDs.first {
|
||||
} else if let unknownSpaceID = currentSettings.accessType.spaceIDs.first {
|
||||
// The space is not joined by the user but is currently selected
|
||||
.singleUnknown(id: unknownSpaceID)
|
||||
} else {
|
||||
|
||||
@@ -47,7 +47,7 @@ class SecurityAndPrivacyScreenViewModel: SecurityAndPrivacyScreenViewModelType,
|
||||
setupRoomDirectoryVisibility()
|
||||
setupSubscriptions()
|
||||
Task {
|
||||
switch await clientProxy.spaceService.joinedParents(roomID: roomProxy.id) {
|
||||
switch await clientProxy.spaceService.joinedParents(childID: roomProxy.id) {
|
||||
case .success(let joinedParentSpaces):
|
||||
state.joinedParentSpaces = joinedParentSpaces
|
||||
case .failure:
|
||||
|
||||
@@ -242,7 +242,7 @@ struct SecurityAndPrivacyScreen_Previews: PreviewProvider, TestablePreview {
|
||||
clientProxy: ClientProxyMock(.init(userIDServerName: "matrix.org",
|
||||
spaceServiceConfiguration: .init(joinedParentSpaces: [space]))),
|
||||
userIndicatorController: UserIndicatorControllerMock(),
|
||||
appSettings: AppSettings())
|
||||
appSettings: appSettings)
|
||||
}()
|
||||
|
||||
static let multipleSpacesMembersViewModel = {
|
||||
@@ -259,7 +259,7 @@ struct SecurityAndPrivacyScreen_Previews: PreviewProvider, TestablePreview {
|
||||
clientProxy: ClientProxyMock(.init(userIDServerName: "matrix.org",
|
||||
spaceServiceConfiguration: .init(joinedParentSpaces: spaces))),
|
||||
userIndicatorController: UserIndicatorControllerMock(),
|
||||
appSettings: AppSettings())
|
||||
appSettings: appSettings)
|
||||
}()
|
||||
|
||||
static let askToJoinViewModel = {
|
||||
|
||||
@@ -49,11 +49,11 @@ class SpaceServiceProxy: SpaceServiceProxyProtocol {
|
||||
}
|
||||
}
|
||||
|
||||
func joinedParents(roomID: String) async -> Result<[SpaceRoomProxyProtocol], SpaceServiceProxyError> {
|
||||
func joinedParents(childID: String) async -> Result<[SpaceRoomProxyProtocol], SpaceServiceProxyError> {
|
||||
do {
|
||||
return try await .success(spaceService.joinedParentsOfChild(childId: roomID).map(SpaceRoomProxy.init))
|
||||
return try await .success(spaceService.joinedParentsOfChild(childId: childID).map(SpaceRoomProxy.init))
|
||||
} catch {
|
||||
MXLog.error("Failed to get joined parents for \(roomID): \(error)")
|
||||
MXLog.error("Failed to get joined parents for \(childID): \(error)")
|
||||
return .failure(.sdkError(error))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,6 @@ protocol SpaceServiceProxyProtocol {
|
||||
|
||||
func spaceRoomList(spaceID: String) async -> Result<SpaceRoomListProxyProtocol, SpaceServiceProxyError>
|
||||
func leaveSpace(spaceID: String) async -> Result<LeaveSpaceHandleProxy, SpaceServiceProxyError>
|
||||
/// Returns all the parent spaces of a room that user has joined.
|
||||
func joinedParents(roomID: String) async -> Result<[SpaceRoomProxyProtocol], SpaceServiceProxyError>
|
||||
/// Returns all the parent spaces of a child that user has joined.
|
||||
func joinedParents(childID: String) async -> Result<[SpaceRoomProxyProtocol], SpaceServiceProxyError>
|
||||
}
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:16615769f99c92cccb78bd85195c8a853050b91051847432bab85218fae918a7
|
||||
size 168851
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:4f9c1a75e0d349da93fe984d753b7a5d7d87d7c1e569a472ef791b1cd2fe09c2
|
||||
size 207133
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:daa486a48c54f6cb612065f63c8b020140374b0858b99dc4c174853d8c58ef50
|
||||
size 116280
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:2176626e57e5427a9328dee7e04bcb0c88435c67c6c4d78e9f27639b67d8faf0
|
||||
size 169819
|
||||
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:c10a822751f52c6dfd8a5983af1bb880ab940335f3162790d15625c80b347f4f
|
||||
size 200593
|
||||
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:8b22a70b9ae221e2d2f533cb487092b2de92ca7b697a9f040263da7867dfcd62
|
||||
size 246336
|
||||
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:fc11a77156dd88cda02776fa819bc685d55ee9ed1c7139b9baedca9c5460ba3f
|
||||
size 137487
|
||||
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:12aa5240ae6480e73aa483eae15cd7b259b527bed7dd02e7101b7ab1e38be77c
|
||||
size 165861
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:2c8692d0ac775372370d78d5be13fd0d4f1c52abfd8b0f139743d57f40fdd9d1
|
||||
size 155663
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:2533b636d1d9bae4ed280b5d07bd3bb0222b0b6b0fca8a5c11c327dac93f37e0
|
||||
size 186317
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:695aabf1d7b8ed63450e6b4bcc869e03b0e65db75b63dbb2da6f6a858b9e866f
|
||||
size 102182
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:16dc1a670bb862ffb6f1707b6e95bf7109613a0a7d76b677329b389a6decceb3
|
||||
size 144655
|
||||
@@ -6,6 +6,7 @@
|
||||
// Please see LICENSE files in the repository root for full details.
|
||||
//
|
||||
|
||||
import MatrixRustSDK
|
||||
import XCTest
|
||||
|
||||
@testable import ElementX
|
||||
@@ -13,8 +14,95 @@ import XCTest
|
||||
@MainActor
|
||||
class SecurityAndPrivacyScreenViewModelTests: XCTestCase {
|
||||
var viewModel: SecurityAndPrivacyScreenViewModelProtocol!
|
||||
var roomProxy: JoinedRoomProxyMock!
|
||||
|
||||
var context: SecurityAndPrivacyScreenViewModelType.Context {
|
||||
viewModel.context
|
||||
}
|
||||
|
||||
override func tearDown() {
|
||||
viewModel = nil
|
||||
roomProxy = nil
|
||||
AppSettings.resetAllSettings()
|
||||
}
|
||||
|
||||
func testSetSingleJoinedSpaceMembersAccess() async throws {
|
||||
let singleRoom = [SpaceRoomProxyProtocol].mockSingleRoom
|
||||
let space = singleRoom[0]
|
||||
setupViewModel(isSpaceSettingsEnabled: true, joinedParentSpaces: singleRoom, joinRule: .public)
|
||||
|
||||
let deferred = deferFulfillment(context.$viewState) { $0.joinedParentSpaces.count == 1 }
|
||||
try await deferred.fulfill()
|
||||
|
||||
XCTAssertEqual(context.viewState.currentSettings.accessType, .anyone)
|
||||
XCTAssertTrue(context.viewState.isSaveDisabled)
|
||||
XCTAssertTrue(context.viewState.isSpaceMembersOptionSelectable)
|
||||
guard case .singleJoined = context.viewState.spaceSelection else {
|
||||
XCTFail("Expected spaceSelection to be .singleSpace")
|
||||
return
|
||||
}
|
||||
|
||||
context.send(viewAction: .selectedSpaceMembersAccess)
|
||||
XCTAssertEqual(context.desiredSettings.accessType, .spaceUsers(spaceIDs: [space.id]))
|
||||
XCTAssertNil(context.viewState.accessSectionFooter)
|
||||
XCTAssertFalse(context.viewState.isSaveDisabled)
|
||||
|
||||
let expectation = expectation(description: "Join rule has updated")
|
||||
roomProxy.updateJoinRuleClosure = { value in
|
||||
XCTAssertEqual(value, .restricted(rules: [.roomMembership(roomId: space.id)]))
|
||||
expectation.fulfill()
|
||||
return .success(())
|
||||
}
|
||||
context.send(viewAction: .save)
|
||||
await fulfillment(of: [expectation])
|
||||
}
|
||||
|
||||
func testSingleUnknownSpaceMembersAccessCanBeReselected() async throws {
|
||||
let singleRoom = [SpaceRoomProxyProtocol].mockSingleRoom
|
||||
let space = singleRoom[0]
|
||||
setupViewModel(isSpaceSettingsEnabled: true, joinedParentSpaces: [], joinRule: .restricted(rules: [.roomMembership(roomId: space.id)]))
|
||||
|
||||
let deferred = deferFulfillment(context.$viewState) { $0.joinedParentSpaces.count == 0 }
|
||||
try await deferred.fulfill()
|
||||
|
||||
XCTAssertEqual(context.viewState.currentSettings.accessType, .spaceUsers(spaceIDs: [space.id]))
|
||||
XCTAssertEqual(context.desiredSettings, context.viewState.currentSettings)
|
||||
XCTAssertTrue(context.viewState.isSpaceMembersOptionSelectable)
|
||||
XCTAssertNil(context.viewState.accessSectionFooter)
|
||||
XCTAssertTrue(context.viewState.isSaveDisabled)
|
||||
guard case .singleUnknown = context.viewState.spaceSelection else {
|
||||
XCTFail("Expected spaceSelection to be .singleSpace")
|
||||
return
|
||||
}
|
||||
|
||||
context.desiredSettings.accessType = .anyone
|
||||
XCTAssertTrue(context.viewState.isSpaceMembersOptionSelectable)
|
||||
XCTAssertFalse(context.viewState.isSaveDisabled)
|
||||
|
||||
context.send(viewAction: .selectedSpaceMembersAccess)
|
||||
XCTAssertTrue(context.viewState.isSaveDisabled)
|
||||
XCTAssertEqual(context.desiredSettings.accessType, .spaceUsers(spaceIDs: [space.id]))
|
||||
guard case .singleUnknown = context.viewState.spaceSelection else {
|
||||
XCTFail("Expected spaceSelection to be .singleSpace")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
private func setupViewModel(isSpaceSettingsEnabled: Bool,
|
||||
joinedParentSpaces: [SpaceRoomProxyProtocol],
|
||||
joinRule: JoinRule) {
|
||||
let appSettings = AppSettings()
|
||||
appSettings.spaceSettingsEnabled = isSpaceSettingsEnabled
|
||||
roomProxy = JoinedRoomProxyMock(.init(isEncrypted: false,
|
||||
canonicalAlias: "#room:matrix.org",
|
||||
members: .allMembersAsCreator,
|
||||
joinRule: joinRule,
|
||||
isVisibleInPublicDirectory: true))
|
||||
|
||||
viewModel = SecurityAndPrivacyScreenViewModel(roomProxy: roomProxy,
|
||||
clientProxy: ClientProxyMock(.init(userIDServerName: "matrix.org",
|
||||
spaceServiceConfiguration: .init(joinedParentSpaces: joinedParentSpaces))),
|
||||
userIndicatorController: UserIndicatorControllerMock(),
|
||||
appSettings: appSettings)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user