two more edge cases tests

This commit is contained in:
Mauro Romito
2025-12-02 18:11:17 +01:00
committed by Mauro
parent 4b28d61d46
commit 084e11d75e
3 changed files with 81 additions and 9 deletions

View File

@@ -81,7 +81,7 @@ struct SecurityAndPrivacyScreenViewState: BindableState {
L10n.screenSecurityAndPrivacyRoomAccessSpaceMembersOptionSingleParentDescription(joinedParentSpace.name)
case .singleUnknown(let id):
L10n.screenSecurityAndPrivacyRoomAccessSpaceMembersOptionSingleParentDescription(id)
case .multiple:
case .multiple, .empty:
L10n.screenSecurityAndPrivacyRoomAccessSpaceMembersOptionMultipleParentsDescription
}
} else {
@@ -90,7 +90,9 @@ struct SecurityAndPrivacyScreenViewState: BindableState {
}
var accessSectionFooter: AttributedString? {
if bindings.desiredSettings.accessType.isSpaceUsers, isSpaceMembersOptionSelectable, selectableSpacesCount > 1 {
if bindings.desiredSettings.accessType.isSpaceUsers,
isSpaceMembersOptionSelectable,
case .multiple = spaceSelection {
Self.accessSectionFooterAttributedString
} else {
nil
@@ -104,13 +106,27 @@ struct SecurityAndPrivacyScreenViewState: BindableState {
case singleUnknown(id: String)
/// Multiple spaces are available for selection
case multiple
/// Edge case where the space members access type was found but it did not contain any space
case empty
}
var spaceSelection: SpaceSelection {
if selectableSpacesCount > 1 {
if selectableSpacesCount == 0 {
.empty
} else if selectableSpacesCount > 1 {
.multiple
} else if let joinedParent = joinedParentSpaces.first {
.singleJoined(joinedParent)
if case let .spaceUsers(ids) = currentSettings.accessType {
if ids.isEmpty {
// Edge case where the access type is already space members, but it does not contain any id
// So if the user wants to add their own parent they need to do it from the selection menu
.multiple
} else {
.singleJoined(joinedParent)
}
} else {
.singleJoined(joinedParent)
}
} else if let unknownSpaceID = currentSettings.accessType.spaceIDs.first {
// The space is not joined by the user but is currently selected
.singleUnknown(id: unknownSpaceID)

View File

@@ -245,6 +245,8 @@ class SecurityAndPrivacyScreenViewModel: SecurityAndPrivacyScreenViewModelType,
state.bindings.desiredSettings.accessType = .spaceUsers(spaceIDs: [joinedParent.id])
case .singleUnknown(let id):
state.bindings.desiredSettings.accessType = .spaceUsers(spaceIDs: [id])
case .empty:
break // Very edge case. We do nothing in this case.
case .multiple:
displayManageAuthorizedSpacesScreen()
}

View File

@@ -39,7 +39,7 @@ class SecurityAndPrivacyScreenViewModelTests: XCTestCase {
XCTAssertTrue(context.viewState.isSaveDisabled)
XCTAssertTrue(context.viewState.isSpaceMembersOptionSelectable)
guard case .singleJoined = context.viewState.spaceSelection else {
XCTFail("Expected spaceSelection to be .singleSpace")
XCTFail("Expected spaceSelection to be .singleJoined")
return
}
@@ -72,7 +72,7 @@ class SecurityAndPrivacyScreenViewModelTests: XCTestCase {
XCTAssertNil(context.viewState.accessSectionFooter)
XCTAssertTrue(context.viewState.isSaveDisabled)
guard case .singleUnknown = context.viewState.spaceSelection else {
XCTFail("Expected spaceSelection to be .singleSpace")
XCTFail("Expected spaceSelection to be .singleUnknown")
return
}
@@ -84,7 +84,7 @@ class SecurityAndPrivacyScreenViewModelTests: XCTestCase {
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")
XCTFail("Expected spaceSelection to be .singleUnknown")
return
}
}
@@ -100,7 +100,7 @@ class SecurityAndPrivacyScreenViewModelTests: XCTestCase {
XCTAssertTrue(context.viewState.isSaveDisabled)
XCTAssertTrue(context.viewState.isSpaceMembersOptionSelectable)
guard case .multiple = context.viewState.spaceSelection else {
XCTFail("Expected spaceSelection to be .singleSpace")
XCTFail("Expected spaceSelection to be .multiple")
return
}
@@ -146,7 +146,7 @@ class SecurityAndPrivacyScreenViewModelTests: XCTestCase {
XCTAssertTrue(context.viewState.isSaveDisabled)
XCTAssertTrue(context.viewState.isSpaceMembersOptionSelectable)
guard case .multiple = context.viewState.spaceSelection else {
XCTFail("Expected spaceSelection to be .singleSpace")
XCTFail("Expected spaceSelection to be .multiple")
return
}
@@ -180,6 +180,60 @@ class SecurityAndPrivacyScreenViewModelTests: XCTestCase {
await fulfillment(of: [expectation])
}
func testEmptySpaceMembersSelectionEdgeCase() async throws {
// Edge case where there is no available joined parents and the room has a restricted join rule.
// With no space ids in it
setupViewModel(isSpaceSettingsEnabled: true,
joinedParentSpaces: [],
joinRule: .restricted(rules: []))
let deferred = deferFulfillment(context.$viewState) { $0.selectableSpacesCount == 0 }
try await deferred.fulfill()
XCTAssertTrue(context.viewState.currentSettings.accessType.isSpaceUsers)
XCTAssertTrue(context.viewState.isSaveDisabled)
XCTAssertFalse(context.viewState.isSpaceMembersOptionSelectable)
XCTAssertNil(context.viewState.accessSectionFooter)
guard case .empty = context.viewState.spaceSelection else {
XCTFail("Expected spaceSelection to be .empty")
return
}
}
func testEmptySpaceMembersSelectionWithJoinedParentEdgeCase() async throws {
// Edge case where there is one available joined parent but the room has a restricted join rule.
// With no space ids in it
let singleRoom = [SpaceRoomProxyProtocol].mockSingleRoom
setupViewModel(isSpaceSettingsEnabled: true,
joinedParentSpaces: singleRoom,
joinRule: .restricted(rules: []))
let deferred = deferFulfillment(context.$viewState) { $0.selectableSpacesCount == 1 }
try await deferred.fulfill()
XCTAssertTrue(context.viewState.currentSettings.accessType.isSpaceUsers)
XCTAssertTrue(context.viewState.isSaveDisabled)
XCTAssertTrue(context.viewState.isSpaceMembersOptionSelectable)
XCTAssertNotNil(context.viewState.accessSectionFooter)
guard case .multiple = context.viewState.spaceSelection else {
XCTFail("Expected spaceSelection to be .multiple")
return
}
let deferredAction = deferFulfillment(viewModel.actionsPublisher) { action in
switch action {
case .displayManageAuthorizedSpacesScreen(let authorizedSpacesSelection):
return authorizedSpacesSelection.joinedParentSpaces.map(\.id) == singleRoom.map(\.id) &&
authorizedSpacesSelection.unknownSpacesIDs.isEmpty &&
authorizedSpacesSelection.initialSelectedIDs.isEmpty
default:
return false
}
}
context.send(viewAction: .manageSpaces)
try await deferredAction.fulfill()
}
func testSave() async throws {
setupViewModel(isSpaceSettingsEnabled: false, joinedParentSpaces: [], joinRule: .public)