diff --git a/ElementX.xcodeproj/project.pbxproj b/ElementX.xcodeproj/project.pbxproj index 8893c2891..5319bcf5d 100644 --- a/ElementX.xcodeproj/project.pbxproj +++ b/ElementX.xcodeproj/project.pbxproj @@ -168,6 +168,7 @@ 1A70A2199394B5EC660934A5 /* MatrixRustSDK in Frameworks */ = {isa = PBXBuildFile; productRef = A678E40E917620059695F067 /* MatrixRustSDK */; }; 1A83DD22F3E6F76B13B6E2F9 /* VideoRoomTimelineItemContent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8C8616254EE40CA8BA5E9BC2 /* VideoRoomTimelineItemContent.swift */; }; 1AB3D8563AB12635250A6A6E /* StaticLocationScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = C15E0017717EAE3A1D02D005 /* StaticLocationScreenCoordinator.swift */; }; + 1AE4532D92E6ED42BFE87064 /* JoinRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = A566F8F2C27B99E1FB80C69B /* JoinRule.swift */; }; 1AE4AEA0FA8DEF52671832E0 /* RoomTimelineItemProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED1D792EB82506A19A72C8DE /* RoomTimelineItemProtocol.swift */; }; 1AF4A82B4332CAD2DB3EB5DA /* TopBannerModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78483F0143E185EDC6ECD741 /* TopBannerModifier.swift */; }; 1B2DADC008EE211AF1DA5292 /* NotificationManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30ED584467DB380E3CEFB1DB /* NotificationManagerTests.swift */; }; @@ -2448,6 +2449,7 @@ A4D09290C6791D6EF04F569E /* LinkNewDeviceScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LinkNewDeviceScreenModels.swift; sourceTree = ""; }; A4D9DF4F2DF3507F99B5B97B /* LabsScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabsScreenViewModel.swift; sourceTree = ""; }; A54AAF72E821B4084B7E4298 /* PinnedEventsTimelineFlowCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PinnedEventsTimelineFlowCoordinator.swift; sourceTree = ""; }; + A566F8F2C27B99E1FB80C69B /* JoinRule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JoinRule.swift; sourceTree = ""; }; A6B19D10B102956066AF117B /* PollOptionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PollOptionView.swift; sourceTree = ""; }; A6B891A6DA826E2461DBB40F /* PHGPostHogConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PHGPostHogConfiguration.swift; sourceTree = ""; }; A6C11AD9813045E44F950410 /* ElementCallWidgetDriverProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ElementCallWidgetDriverProtocol.swift; sourceTree = ""; }; @@ -4027,6 +4029,7 @@ C30F45308428A4D9FFDB2FB8 /* BannedRoomProxy.swift */, 0E95B3BDB80531C85CD50AE6 /* InvitedRoomProxy.swift */, 07C6B0B087FE6601C3F77816 /* JoinedRoomProxy.swift */, + A566F8F2C27B99E1FB80C69B /* JoinRule.swift */, 858DA81F2ACF484B7CAD6AE4 /* KnockedRoomProxy.swift */, 8F062DD2CCD95DC33528A16F /* KnockRequestProxy.swift */, C07851F4EA81AA3339806A7B /* KnockRequestProxyProtocol.swift */, @@ -8161,6 +8164,7 @@ DEDBD3E9CFCC9F20CAC79881 /* JoinRoomScreenModels.swift in Sources */, EF47D802A404A53F15D5D4B6 /* JoinRoomScreenViewModel.swift in Sources */, 7B66DA4E7E5FE4D1A0FCEAA4 /* JoinRoomScreenViewModelProtocol.swift in Sources */, + 1AE4532D92E6ED42BFE87064 /* JoinRule.swift in Sources */, F16EED85E30B83878FBC6629 /* JoinedMembersBadgeView.swift in Sources */, 261261778DEFAEFC042B875E /* JoinedRoomProxy.swift in Sources */, 7D249465ED00988EEEC14E05 /* JoinedRoomProxyMock.swift in Sources */, diff --git a/ElementX/Sources/Mocks/RoomPreviewProxyMock.swift b/ElementX/Sources/Mocks/RoomPreviewProxyMock.swift index 77b85fc27..f7b4da61c 100644 --- a/ElementX/Sources/Mocks/RoomPreviewProxyMock.swift +++ b/ElementX/Sources/Mocks/RoomPreviewProxyMock.swift @@ -80,7 +80,7 @@ extension RoomPreviewProxyMock { roomType: configuration.roomType, isHistoryWorldReadable: nil, membership: configuration.membership, - joinRule: configuration.joinRule, + joinRule: configuration.joinRule.rustValue, isDirect: configuration.isDirect, heroes: nil)) diff --git a/ElementX/Sources/Mocks/SDK/LeaveSpaceHandleSDKMock.swift b/ElementX/Sources/Mocks/SDK/LeaveSpaceHandleSDKMock.swift index baae94987..fef5ebe43 100644 --- a/ElementX/Sources/Mocks/SDK/LeaveSpaceHandleSDKMock.swift +++ b/ElementX/Sources/Mocks/SDK/LeaveSpaceHandleSDKMock.swift @@ -56,7 +56,7 @@ extension [LeaveSpaceRoom] { name: "Sound", isSpace: false, memberCount: 20, - joinRule: .private), + joinRule: .invite), isLastOwner: false, areCreatorsPrivileged: false), LeaveSpaceRoom(spaceRoom: SpaceRoom(id: "3", @@ -70,7 +70,7 @@ extension [LeaveSpaceRoom] { name: "The Theatre", isSpace: true, memberCount: 100, - joinRule: .private, + joinRule: .invite, childrenCount: 20), isLastOwner: false, areCreatorsPrivileged: false), @@ -78,7 +78,7 @@ extension [LeaveSpaceRoom] { name: "Bookings", isSpace: false, memberCount: 200, - joinRule: .private, + joinRule: .invite, childrenCount: 0), isLastOwner: true, areCreatorsPrivileged: false), @@ -160,7 +160,7 @@ private extension SpaceRoom { avatarUrl: avatarURL?.absoluteString, roomType: isSpace ? .space : .room, numJoinedMembers: memberCount, - joinRule: joinRule, + joinRule: joinRule?.rustValue, worldReadable: true, guestCanJoin: false, isDirect: isDirect, diff --git a/ElementX/Sources/Screens/CreateRoomScreen/View/CreateRoomScreen.swift b/ElementX/Sources/Screens/CreateRoomScreen/View/CreateRoomScreen.swift index f5185f235..1bdf1ca35 100644 --- a/ElementX/Sources/Screens/CreateRoomScreen/View/CreateRoomScreen.swift +++ b/ElementX/Sources/Screens/CreateRoomScreen/View/CreateRoomScreen.swift @@ -379,7 +379,7 @@ struct CreateRoom_Previews: PreviewProvider, TestablePreview { static let selectedSpaceViewModel = makeViewModel(selectionMode: .preSelected(SpaceServiceRoom.mock(name: "Awesome Space", isSpace: true, - joinRule: .private))) + joinRule: .invite))) static let selectedSpaceWithListViewModel = { let viewModel = makeViewModel() @@ -391,7 +391,7 @@ struct CreateRoom_Previews: PreviewProvider, TestablePreview { let viewModel = makeViewModel(isKnockingEnabled: true, selectionMode: .preSelected(SpaceServiceRoom.mock(name: "Awesome Space", isSpace: true, - joinRule: .private))) + joinRule: .invite))) viewModel.context.selectedAccessType = .askToJoinWithSpaceMembers return viewModel }() diff --git a/ElementX/Sources/Screens/JoinRoomScreen/JoinRoomScreenViewModel.swift b/ElementX/Sources/Screens/JoinRoomScreen/JoinRoomScreenViewModel.swift index 2fd9ca0d5..748da41dd 100644 --- a/ElementX/Sources/Screens/JoinRoomScreen/JoinRoomScreenViewModel.swift +++ b/ElementX/Sources/Screens/JoinRoomScreen/JoinRoomScreenViewModel.swift @@ -235,7 +235,7 @@ class JoinRoomScreenViewModel: JoinRoomScreenViewModelType, JoinRoomScreenViewMo state.mode = .banned(sender: nil, reason: nil) default: switch spaceServiceRoom.joinRule { - case .private, .invite: + case .invite: state.mode = .inviteRequired case .knock, .knockRestricted: state.mode = appSettings.knockingEnabled ? .knockable : .joinable @@ -258,7 +258,7 @@ class JoinRoomScreenViewModel: JoinRoomScreenViewModelType, JoinRoomScreenViewMo reason: membershipDetails?.ownRoomMember.membershipChangeReason) default: switch roomPreview.info.joinRule { - case .private, .invite: + case .invite: state.mode = .inviteRequired case .knock, .knockRestricted: state.mode = appSettings.knockingEnabled ? .knockable : .joinable diff --git a/ElementX/Sources/Screens/SecurityAndPrivacyScreen/SecurityAndPrivacyScreenViewModel.swift b/ElementX/Sources/Screens/SecurityAndPrivacyScreen/SecurityAndPrivacyScreenViewModel.swift index 37afdd932..bdf3e6188 100644 --- a/ElementX/Sources/Screens/SecurityAndPrivacyScreen/SecurityAndPrivacyScreenViewModel.swift +++ b/ElementX/Sources/Screens/SecurityAndPrivacyScreen/SecurityAndPrivacyScreenViewModel.swift @@ -350,9 +350,9 @@ private extension SecurityAndPrivacyRoomAccessType { case .anyone: .public case .spaceMembers(let spaceIDs): - .restricted(rules: spaceIDs.map { .roomMembership(roomId: $0) }) + .restricted(rules: spaceIDs.map { .roomMembership(roomID: $0) }) case .askToJoinWithSpaceMembers(let spaceIDs): - .knockRestricted(rules: spaceIDs.map { .roomMembership(roomId: $0) }) + .knockRestricted(rules: spaceIDs.map { .roomMembership(roomID: $0) }) } } } diff --git a/ElementX/Sources/Screens/SecurityAndPrivacyScreen/View/SecurityAndPrivacyScreen.swift b/ElementX/Sources/Screens/SecurityAndPrivacyScreen/View/SecurityAndPrivacyScreen.swift index f669a378c..db4b5dd2c 100644 --- a/ElementX/Sources/Screens/SecurityAndPrivacyScreen/View/SecurityAndPrivacyScreen.swift +++ b/ElementX/Sources/Screens/SecurityAndPrivacyScreen/View/SecurityAndPrivacyScreen.swift @@ -269,7 +269,7 @@ struct SecurityAndPrivacyScreen_Previews: PreviewProvider, TestablePreview { return SecurityAndPrivacyScreenViewModel(roomProxy: JoinedRoomProxyMock(.init(isEncrypted: false, canonicalAlias: "#room:matrix.org", members: .allMembersAsCreator, - joinRule: .restricted(rules: [.roomMembership(roomId: space.id)]), + joinRule: .restricted(rules: [.roomMembership(roomID: space.id)]), isVisibleInPublicDirectory: true)), clientProxy: ClientProxyMock(.init(userIDServerName: "matrix.org", spaceServiceConfiguration: .init(joinedParentSpaces: [space]))), @@ -286,7 +286,7 @@ struct SecurityAndPrivacyScreen_Previews: PreviewProvider, TestablePreview { return SecurityAndPrivacyScreenViewModel(roomProxy: JoinedRoomProxyMock(.init(isEncrypted: false, canonicalAlias: "#room:matrix.org", members: .allMembersAsCreator, - joinRule: .restricted(rules: spaces.map { .roomMembership(roomId: $0.id) }), + joinRule: .restricted(rules: spaces.map { .roomMembership(roomID: $0.id) }), isVisibleInPublicDirectory: true)), clientProxy: ClientProxyMock(.init(userIDServerName: "matrix.org", spaceServiceConfiguration: .init(joinedParentSpaces: spaces))), @@ -319,7 +319,7 @@ struct SecurityAndPrivacyScreen_Previews: PreviewProvider, TestablePreview { return SecurityAndPrivacyScreenViewModel(roomProxy: JoinedRoomProxyMock(.init(isEncrypted: false, canonicalAlias: "#room:matrix.org", members: .allMembersAsCreator, - joinRule: .knockRestricted(rules: [.roomMembership(roomId: space.id)]), + joinRule: .knockRestricted(rules: [.roomMembership(roomID: space.id)]), isVisibleInPublicDirectory: true)), clientProxy: ClientProxyMock(.init(userIDServerName: "matrix.org", spaceServiceConfiguration: .init(joinedParentSpaces: [space]))), @@ -337,7 +337,7 @@ struct SecurityAndPrivacyScreen_Previews: PreviewProvider, TestablePreview { return SecurityAndPrivacyScreenViewModel(roomProxy: JoinedRoomProxyMock(.init(isEncrypted: false, canonicalAlias: "#room:matrix.org", members: .allMembersAsCreator, - joinRule: .knockRestricted(rules: spaces.map { .roomMembership(roomId: $0.id) }), + joinRule: .knockRestricted(rules: spaces.map { .roomMembership(roomID: $0.id) }), isVisibleInPublicDirectory: true)), clientProxy: ClientProxyMock(.init(userIDServerName: "matrix.org", spaceServiceConfiguration: .init(joinedParentSpaces: spaces))), diff --git a/ElementX/Sources/Screens/Spaces/Common/SpaceHeaderView.swift b/ElementX/Sources/Screens/Spaces/Common/SpaceHeaderView.swift index 20dc8a942..5677c611c 100644 --- a/ElementX/Sources/Screens/Spaces/Common/SpaceHeaderView.swift +++ b/ElementX/Sources/Screens/Spaces/Common/SpaceHeaderView.swift @@ -141,7 +141,7 @@ struct SpaceHeaderView_Previews: PreviewProvider, TestablePreview { "Interdum mauris ultrices tincidunt proin morbi erat aenean risus nibh.", "Diam amet sit fermentum vulputate faucibus."].joined(separator: " "), canonicalAlias: "#subspace:matrix.org", - joinRule: .knockRestricted(rules: [.roomMembership(roomId: "")])) + joinRule: .knockRestricted(rules: [.roomMembership(roomID: "")])) ] } } diff --git a/ElementX/Sources/Screens/Spaces/LeaveSpace/View/LeaveSpaceView.swift b/ElementX/Sources/Screens/Spaces/LeaveSpace/View/LeaveSpaceView.swift index a16e265f7..31ab6e469 100644 --- a/ElementX/Sources/Screens/Spaces/LeaveSpace/View/LeaveSpaceView.swift +++ b/ElementX/Sources/Screens/Spaces/LeaveSpace/View/LeaveSpaceView.swift @@ -156,7 +156,7 @@ struct LeaveSpaceView_Previews: PreviewProvider, TestablePreview { joinedMembersCount: 76, heroes: [.mockDan, .mockBob, .mockCharlie, .mockVerbose], topic: "Description of the space goes right here. Lorem ipsum dolor sit amet consectetur. Leo viverra morbi habitant in.", - joinRule: .knockRestricted(rules: [.roomMembership(roomId: "")])) + joinRule: .knockRestricted(rules: [.roomMembership(roomID: "")])) static func makeViewModel(mode: LeaveSpaceHandleProxy.Mode) -> LeaveSpaceViewModel { let rooms: [LeaveSpaceRoom] = switch mode { diff --git a/ElementX/Sources/Screens/Spaces/SpaceScreen/View/SpaceScreen.swift b/ElementX/Sources/Screens/Spaces/SpaceScreen/View/SpaceScreen.swift index cb40fae8d..1c77b1a11 100644 --- a/ElementX/Sources/Screens/Spaces/SpaceScreen/View/SpaceScreen.swift +++ b/ElementX/Sources/Screens/Spaces/SpaceScreen/View/SpaceScreen.swift @@ -220,7 +220,7 @@ struct SpaceScreen_Previews: PreviewProvider, TestablePreview { heroes: [.mockDan, .mockBob, .mockCharlie, .mockVerbose], topic: "Description of the space goes right here. Lorem ipsum dolor sit amet consectetur. Leo viverra morbi habitant in.", canonicalAlias: "#engineering-team:element.io", - joinRule: .knockRestricted(rules: [.roomMembership(roomId: "")])) + joinRule: .knockRestricted(rules: [.roomMembership(roomID: "")])) let spaceRoomListProxy = SpaceRoomListProxyMock(.init(spaceServiceRoom: spaceServiceRoom, initialSpaceRooms: isNewSpace ? [] : .mockSpaceList)) diff --git a/ElementX/Sources/Services/Client/ClientProxy.swift b/ElementX/Sources/Services/Client/ClientProxy.swift index 85977e24d..6c6aaf3ed 100644 --- a/ElementX/Sources/Services/Client/ClientProxy.swift +++ b/ElementX/Sources/Services/Client/ClientProxy.swift @@ -559,7 +559,7 @@ class ClientProxy: ClientProxyProtocol { invite: userIDs, avatar: avatarURL?.absoluteString, powerLevelContentOverride: powerLevelContentOverride, - joinRuleOverride: accessType.joinRuleOverride, + joinRuleOverride: accessType.joinRuleOverride?.rustValue, historyVisibilityOverride: accessType.historyVisibilityOverride, // This is an FFI naming mistake, what is required is the `aliasLocalPart` not the whole alias canonicalAlias: aliasLocalPart, @@ -1432,9 +1432,9 @@ private extension CreateRoomAccessType { case .askToJoin: .knock case .spaceMembers(let spaceID): - .restricted(rules: [.roomMembership(roomId: spaceID)]) + .restricted(rules: [.roomMembership(roomID: spaceID)]) case .askToJoinWithSpaceMembers(let spaceID): - .knockRestricted(rules: [.roomMembership(roomId: spaceID)]) + .knockRestricted(rules: [.roomMembership(roomID: spaceID)]) case .private, .public: nil } diff --git a/ElementX/Sources/Services/Room/JoinRule.swift b/ElementX/Sources/Services/Room/JoinRule.swift new file mode 100644 index 000000000..712718b49 --- /dev/null +++ b/ElementX/Sources/Services/Room/JoinRule.swift @@ -0,0 +1,74 @@ +// +// Copyright 2026 Element Creations Ltd. +// +// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. +// Please see LICENSE files in the repository root for full details. +// + +import Foundation +import MatrixRustSDK + +/// The rule used for users wishing to join a room. +public enum JoinRule: Equatable, Hashable { + /// Anyone can join the room without any prior action. + case `public` + /// A user who wishes to join the room must first receive an invite. + case invite + /// Users can join the room if they are invited, or they can request an invite to the room. + /// + /// They can be allowed (invited) or denied (kicked/banned) access. + case knock + /// Users can join the room if they are invited, or if they meet any of the conditions described + /// in a set of ``AllowRule``s. + case restricted(rules: [AllowRule]) + /// Users can join the room if they are invited, or if they meet any of the conditions described + /// in a set of ``AllowRule``s, or they can request an invite to the room. + case knockRestricted(rules: [AllowRule]) + /// A custom join rule, up for interpretation by the consumer. + case custom(rawValue: String) + + init(rustValue: MatrixRustSDK.JoinRule) { + self = switch rustValue { + case .public: .public + case .invite: .invite + case .knock: .knock + case .private: .invite // Assume .private is .invite – private shouldn't be used (see MSC4413). + case .restricted(let rules): .restricted(rules: rules.map(AllowRule.init)) + case .knockRestricted(let rules): .knockRestricted(rules: rules.map(AllowRule.init)) + case .custom(let rawValue): .custom(rawValue: rawValue) + } + } + + var rustValue: MatrixRustSDK.JoinRule { + switch self { + case .public: .public + case .invite: .invite + case .knock: .knock + case .restricted(rules: let rules): .restricted(rules: rules.map(\.rustValue)) + case .knockRestricted(rules: let rules): .knockRestricted(rules: rules.map(\.rustValue)) + case .custom(let rawValue): .custom(repr: rawValue) + } + } +} + +/// An allow rule which defines a condition that allows joining a room. +public enum AllowRule: Equatable, Hashable { + /// Only a member of the `room_id` Room can join the one this rule is used in. + case roomMembership(roomID: String) + /// A custom allow rule implementation, containing its JSON representation as a `String`. + case custom(json: String) + + init(rustValue: MatrixRustSDK.AllowRule) { + self = switch rustValue { + case .roomMembership(let roomID): .roomMembership(roomID: roomID) + case .custom(let json): .custom(json: json) + } + } + + var rustValue: MatrixRustSDK.AllowRule { + switch self { + case .roomMembership(let roomID): .roomMembership(roomId: roomID) + case .custom(let json): .custom(json: json) + } + } +} diff --git a/ElementX/Sources/Services/Room/JoinedRoomProxy.swift b/ElementX/Sources/Services/Room/JoinedRoomProxy.swift index 96bf370f3..532016805 100644 --- a/ElementX/Sources/Services/Room/JoinedRoomProxy.swift +++ b/ElementX/Sources/Services/Room/JoinedRoomProxy.swift @@ -479,7 +479,7 @@ class JoinedRoomProxy: JoinedRoomProxyProtocol { func updateJoinRule(_ rule: JoinRule) async -> Result { do { - try await room.updateJoinRules(newRule: rule) + try await room.updateJoinRules(newRule: rule.rustValue) return .success(()) } catch { MXLog.error("Failed updating join rule with error: \(error)") diff --git a/ElementX/Sources/Services/Room/RoomInfoProxy.swift b/ElementX/Sources/Services/Room/RoomInfoProxy.swift index f2055a45f..8d34ad0b6 100644 --- a/ElementX/Sources/Services/Room/RoomInfoProxy.swift +++ b/ElementX/Sources/Services/Room/RoomInfoProxy.swift @@ -135,7 +135,7 @@ struct RoomInfoProxy: RoomInfoProxyProtocol { } var joinRule: JoinRule? { - roomInfo.joinRule + roomInfo.joinRule.map(JoinRule.init) } var historyVisibility: RoomHistoryVisibility { @@ -193,7 +193,7 @@ struct RoomPreviewInfoProxy: BaseRoomInfoProxyProtocol { } var joinRule: JoinRule? { - roomPreviewInfo.joinRule + roomPreviewInfo.joinRule.map(JoinRule.init) } var membership: Membership? { diff --git a/ElementX/Sources/Services/Room/RoomInfoProxyProtocol.swift b/ElementX/Sources/Services/Room/RoomInfoProxyProtocol.swift index 6c10744e7..d7d0fac93 100644 --- a/ElementX/Sources/Services/Room/RoomInfoProxyProtocol.swift +++ b/ElementX/Sources/Services/Room/RoomInfoProxyProtocol.swift @@ -90,7 +90,7 @@ extension RoomInfoProxyProtocol { } return switch joinRule { - case .invite, .knock, .restricted, .knockRestricted, .private: + case .invite, .knock, .restricted, .knockRestricted: true case .public: false diff --git a/ElementX/Sources/Services/Spaces/SpaceServiceRoom.swift b/ElementX/Sources/Services/Spaces/SpaceServiceRoom.swift index 26d89893e..a01d6b685 100644 --- a/ElementX/Sources/Services/Spaces/SpaceServiceRoom.swift +++ b/ElementX/Sources/Services/Spaces/SpaceServiceRoom.swift @@ -53,7 +53,7 @@ struct SpaceServiceRoom { .public case .restricted, .knockRestricted: .restricted - case .invite, .knock, .private, .custom: + case .invite, .knock, .custom: .private case .none: .none @@ -77,7 +77,7 @@ extension SpaceServiceRoom { topic = spaceRoom.topic canonicalAlias = spaceRoom.canonicalAlias - joinRule = spaceRoom.joinRule + joinRule = spaceRoom.joinRule.map(JoinRule.init) worldReadable = spaceRoom.worldReadable guestCanJoin = spaceRoom.guestCanJoin state = spaceRoom.state @@ -130,10 +130,10 @@ extension SpaceServiceRoom { case .restricted: joinRule = .restricted(rules: []) case .inviteRequired: - joinRule = .private + joinRule = .invite case .invited: state = .invited - joinRule = .private + joinRule = .invite case .knockable: joinRule = .knock case .knocked: @@ -218,7 +218,7 @@ extension [SpaceServiceRoom] { childrenCount: 1, joinedMembersCount: 500, canonicalAlias: "#the-foundation:matrix.org", - joinRule: .private, + joinRule: .invite, state: .joined), SpaceServiceRoom.mock(id: "space2", name: "The Second Foundation", diff --git a/UnitTests/Sources/CreateRoomViewModelTests.swift b/UnitTests/Sources/CreateRoomViewModelTests.swift index 349cdbc17..032cecad1 100644 --- a/UnitTests/Sources/CreateRoomViewModelTests.swift +++ b/UnitTests/Sources/CreateRoomViewModelTests.swift @@ -271,7 +271,7 @@ class CreateRoomScreenViewModelTests: XCTestCase { } func testCreateRoomInAnAlreadySelectedSpace() async throws { - let space = SpaceServiceRoom.mock(isSpace: true, joinRule: .private) + let space = SpaceServiceRoom.mock(isSpace: true, joinRule: .invite) setup(spacesSelectionMode: .preSelected(space)) context.send(viewAction: .updateRoomName("A")) diff --git a/UnitTests/Sources/SecurityAndPrivacyScreenViewModelTests.swift b/UnitTests/Sources/SecurityAndPrivacyScreenViewModelTests.swift index c2d482bb5..0e3eab11b 100644 --- a/UnitTests/Sources/SecurityAndPrivacyScreenViewModelTests.swift +++ b/UnitTests/Sources/SecurityAndPrivacyScreenViewModelTests.swift @@ -50,7 +50,7 @@ class SecurityAndPrivacyScreenViewModelTests: XCTestCase { let expectation = expectation(description: "Join rule has updated") roomProxy.updateJoinRuleClosure = { value in - XCTAssertEqual(value, .restricted(rules: [.roomMembership(roomId: space.id)])) + XCTAssertEqual(value, .restricted(rules: [.roomMembership(roomID: space.id)])) expectation.fulfill() return .success(()) } @@ -81,7 +81,7 @@ class SecurityAndPrivacyScreenViewModelTests: XCTestCase { let expectation = expectation(description: "Join rule has updated") roomProxy.updateJoinRuleClosure = { value in - XCTAssertEqual(value, .knockRestricted(rules: [.roomMembership(roomId: space.id)])) + XCTAssertEqual(value, .knockRestricted(rules: [.roomMembership(roomID: space.id)])) expectation.fulfill() return .success(()) } @@ -92,7 +92,7 @@ class SecurityAndPrivacyScreenViewModelTests: XCTestCase { func testSingleUnknownSpaceMembersAccessCanBeReselected() async throws { let singleRoom = [SpaceServiceRoom].mockSingleRoom let space = singleRoom[0] - setupViewModel(joinedParentSpaces: [], joinRule: .restricted(rules: [.roomMembership(roomId: space.id)])) + setupViewModel(joinedParentSpaces: [], joinRule: .restricted(rules: [.roomMembership(roomID: space.id)])) let deferred = deferFulfillment(context.$viewState) { $0.selectableJoinedSpaces.count == 0 } try await deferred.fulfill() @@ -156,7 +156,7 @@ class SecurityAndPrivacyScreenViewModelTests: XCTestCase { let expectation = expectation(description: "Join rule has updated") roomProxy.updateJoinRuleClosure = { value in - XCTAssertEqual(value, .restricted(rules: [.roomMembership(roomId: spaces[0].id)])) + XCTAssertEqual(value, .restricted(rules: [.roomMembership(roomID: spaces[0].id)])) expectation.fulfill() return .success(()) } @@ -200,7 +200,7 @@ class SecurityAndPrivacyScreenViewModelTests: XCTestCase { let expectation = expectation(description: "Join rule has updated") roomProxy.updateJoinRuleClosure = { value in - XCTAssertEqual(value, .knockRestricted(rules: [.roomMembership(roomId: spaces[0].id)])) + XCTAssertEqual(value, .knockRestricted(rules: [.roomMembership(roomID: spaces[0].id)])) expectation.fulfill() return .success(()) } @@ -211,7 +211,7 @@ class SecurityAndPrivacyScreenViewModelTests: XCTestCase { func testMultipleSpacesMembersSelection() async throws { let spaces = [SpaceServiceRoom].mockJoinedSpaces2 setupViewModel(joinedParentSpaces: spaces, - joinRule: .restricted(rules: [.roomMembership(roomId: "unknownSpaceID")])) + joinRule: .restricted(rules: [.roomMembership(roomID: "unknownSpaceID")])) let deferred = deferFulfillment(context.$viewState) { $0.selectableSpacesCount == 4 } try await deferred.fulfill() @@ -246,7 +246,7 @@ class SecurityAndPrivacyScreenViewModelTests: XCTestCase { let expectation = expectation(description: "Join rule has updated") roomProxy.updateJoinRuleClosure = { value in - XCTAssertEqual(value, .restricted(rules: [.roomMembership(roomId: spaces[0].id), .roomMembership(roomId: "unknownSpaceID")])) + XCTAssertEqual(value, .restricted(rules: [.roomMembership(roomID: spaces[0].id), .roomMembership(roomID: "unknownSpaceID")])) expectation.fulfill() return .success(()) } @@ -261,8 +261,8 @@ class SecurityAndPrivacyScreenViewModelTests: XCTestCase { let allSpaces = joinedParentSpaces + singleRoom setupViewModel(joinedParentSpaces: joinedParentSpaces, topLevelSpaces: allSpaces, - joinRule: .restricted(rules: [.roomMembership(roomId: space.id), - .roomMembership(roomId: "unknownSpaceID")])) + joinRule: .restricted(rules: [.roomMembership(roomID: space.id), + .roomMembership(roomID: "unknownSpaceID")])) let deferred = deferFulfillment(context.$viewState) { $0.selectableSpacesCount == 5 } try await deferred.fulfill() @@ -425,7 +425,7 @@ class SecurityAndPrivacyScreenViewModelTests: XCTestCase { private func setupViewModel(joinedParentSpaces: [SpaceServiceRoom], topLevelSpaces: [SpaceServiceRoom] = [], - joinRule: JoinRule) { + joinRule: ElementX.JoinRule) { let appSettings = AppSettings() appSettings.spaceSettingsEnabled = true appSettings.knockingEnabled = true