mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-10-31 16:24:11 +00:00
Create Room with knock rule (#3397)
* create knock room implementation (without SDK) * Apply suggestions from code review pr suggestions Co-authored-by: Doug <6060466+pixlwave@users.noreply.github.com> * pr suggestions --------- Co-authored-by: Doug <6060466+pixlwave@users.noreply.github.com>
This commit is contained in:
@@ -47,6 +47,7 @@ final class AppSettings {
|
||||
case pinningEnabled
|
||||
case enableOnlySignedDeviceIsolationMode
|
||||
case identityPinningViolationNotificationsEnabled
|
||||
case knockingEnabled
|
||||
}
|
||||
|
||||
private static var suiteName: String = InfoPlistReader.main.appGroupIdentifier
|
||||
@@ -282,6 +283,9 @@ final class AppSettings {
|
||||
|
||||
@UserPreference(key: UserDefaultsKeys.identityPinningViolationNotificationsEnabled, defaultValue: isDevelopmentBuild, storageType: .userDefaults(store))
|
||||
var identityPinningViolationNotificationsEnabled
|
||||
|
||||
@UserPreference(key: UserDefaultsKeys.knockingEnabled, defaultValue: false, storageType: .userDefaults(store))
|
||||
var knockingEnabled
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ extension ClientProxyMock {
|
||||
canDeactivateAccount = false
|
||||
directRoomForUserIDReturnValue = .failure(.sdkError(ClientProxyMockError.generic))
|
||||
createDirectRoomWithExpectedRoomNameReturnValue = .failure(.sdkError(ClientProxyMockError.generic))
|
||||
createRoomNameTopicIsRoomPrivateUserIDsAvatarURLReturnValue = .failure(.sdkError(ClientProxyMockError.generic))
|
||||
createRoomNameTopicIsRoomPrivateIsKnockingOnlyUserIDsAvatarURLReturnValue = .failure(.sdkError(ClientProxyMockError.generic))
|
||||
uploadMediaReturnValue = .failure(.sdkError(ClientProxyMockError.generic))
|
||||
loadUserDisplayNameReturnValue = .failure(.sdkError(ClientProxyMockError.generic))
|
||||
setUserDisplayNameReturnValue = .failure(.sdkError(ClientProxyMockError.generic))
|
||||
|
||||
@@ -2627,15 +2627,15 @@ class ClientProxyMock: ClientProxyProtocol {
|
||||
}
|
||||
//MARK: - createRoom
|
||||
|
||||
var createRoomNameTopicIsRoomPrivateUserIDsAvatarURLUnderlyingCallsCount = 0
|
||||
var createRoomNameTopicIsRoomPrivateUserIDsAvatarURLCallsCount: Int {
|
||||
var createRoomNameTopicIsRoomPrivateIsKnockingOnlyUserIDsAvatarURLUnderlyingCallsCount = 0
|
||||
var createRoomNameTopicIsRoomPrivateIsKnockingOnlyUserIDsAvatarURLCallsCount: Int {
|
||||
get {
|
||||
if Thread.isMainThread {
|
||||
return createRoomNameTopicIsRoomPrivateUserIDsAvatarURLUnderlyingCallsCount
|
||||
return createRoomNameTopicIsRoomPrivateIsKnockingOnlyUserIDsAvatarURLUnderlyingCallsCount
|
||||
} else {
|
||||
var returnValue: Int? = nil
|
||||
DispatchQueue.main.sync {
|
||||
returnValue = createRoomNameTopicIsRoomPrivateUserIDsAvatarURLUnderlyingCallsCount
|
||||
returnValue = createRoomNameTopicIsRoomPrivateIsKnockingOnlyUserIDsAvatarURLUnderlyingCallsCount
|
||||
}
|
||||
|
||||
return returnValue!
|
||||
@@ -2643,29 +2643,29 @@ class ClientProxyMock: ClientProxyProtocol {
|
||||
}
|
||||
set {
|
||||
if Thread.isMainThread {
|
||||
createRoomNameTopicIsRoomPrivateUserIDsAvatarURLUnderlyingCallsCount = newValue
|
||||
createRoomNameTopicIsRoomPrivateIsKnockingOnlyUserIDsAvatarURLUnderlyingCallsCount = newValue
|
||||
} else {
|
||||
DispatchQueue.main.sync {
|
||||
createRoomNameTopicIsRoomPrivateUserIDsAvatarURLUnderlyingCallsCount = newValue
|
||||
createRoomNameTopicIsRoomPrivateIsKnockingOnlyUserIDsAvatarURLUnderlyingCallsCount = newValue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var createRoomNameTopicIsRoomPrivateUserIDsAvatarURLCalled: Bool {
|
||||
return createRoomNameTopicIsRoomPrivateUserIDsAvatarURLCallsCount > 0
|
||||
var createRoomNameTopicIsRoomPrivateIsKnockingOnlyUserIDsAvatarURLCalled: Bool {
|
||||
return createRoomNameTopicIsRoomPrivateIsKnockingOnlyUserIDsAvatarURLCallsCount > 0
|
||||
}
|
||||
var createRoomNameTopicIsRoomPrivateUserIDsAvatarURLReceivedArguments: (name: String, topic: String?, isRoomPrivate: Bool, userIDs: [String], avatarURL: URL?)?
|
||||
var createRoomNameTopicIsRoomPrivateUserIDsAvatarURLReceivedInvocations: [(name: String, topic: String?, isRoomPrivate: Bool, userIDs: [String], avatarURL: URL?)] = []
|
||||
var createRoomNameTopicIsRoomPrivateIsKnockingOnlyUserIDsAvatarURLReceivedArguments: (name: String, topic: String?, isRoomPrivate: Bool, isKnockingOnly: Bool, userIDs: [String], avatarURL: URL?)?
|
||||
var createRoomNameTopicIsRoomPrivateIsKnockingOnlyUserIDsAvatarURLReceivedInvocations: [(name: String, topic: String?, isRoomPrivate: Bool, isKnockingOnly: Bool, userIDs: [String], avatarURL: URL?)] = []
|
||||
|
||||
var createRoomNameTopicIsRoomPrivateUserIDsAvatarURLUnderlyingReturnValue: Result<String, ClientProxyError>!
|
||||
var createRoomNameTopicIsRoomPrivateUserIDsAvatarURLReturnValue: Result<String, ClientProxyError>! {
|
||||
var createRoomNameTopicIsRoomPrivateIsKnockingOnlyUserIDsAvatarURLUnderlyingReturnValue: Result<String, ClientProxyError>!
|
||||
var createRoomNameTopicIsRoomPrivateIsKnockingOnlyUserIDsAvatarURLReturnValue: Result<String, ClientProxyError>! {
|
||||
get {
|
||||
if Thread.isMainThread {
|
||||
return createRoomNameTopicIsRoomPrivateUserIDsAvatarURLUnderlyingReturnValue
|
||||
return createRoomNameTopicIsRoomPrivateIsKnockingOnlyUserIDsAvatarURLUnderlyingReturnValue
|
||||
} else {
|
||||
var returnValue: Result<String, ClientProxyError>? = nil
|
||||
DispatchQueue.main.sync {
|
||||
returnValue = createRoomNameTopicIsRoomPrivateUserIDsAvatarURLUnderlyingReturnValue
|
||||
returnValue = createRoomNameTopicIsRoomPrivateIsKnockingOnlyUserIDsAvatarURLUnderlyingReturnValue
|
||||
}
|
||||
|
||||
return returnValue!
|
||||
@@ -2673,26 +2673,26 @@ class ClientProxyMock: ClientProxyProtocol {
|
||||
}
|
||||
set {
|
||||
if Thread.isMainThread {
|
||||
createRoomNameTopicIsRoomPrivateUserIDsAvatarURLUnderlyingReturnValue = newValue
|
||||
createRoomNameTopicIsRoomPrivateIsKnockingOnlyUserIDsAvatarURLUnderlyingReturnValue = newValue
|
||||
} else {
|
||||
DispatchQueue.main.sync {
|
||||
createRoomNameTopicIsRoomPrivateUserIDsAvatarURLUnderlyingReturnValue = newValue
|
||||
createRoomNameTopicIsRoomPrivateIsKnockingOnlyUserIDsAvatarURLUnderlyingReturnValue = newValue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var createRoomNameTopicIsRoomPrivateUserIDsAvatarURLClosure: ((String, String?, Bool, [String], URL?) async -> Result<String, ClientProxyError>)?
|
||||
var createRoomNameTopicIsRoomPrivateIsKnockingOnlyUserIDsAvatarURLClosure: ((String, String?, Bool, Bool, [String], URL?) async -> Result<String, ClientProxyError>)?
|
||||
|
||||
func createRoom(name: String, topic: String?, isRoomPrivate: Bool, userIDs: [String], avatarURL: URL?) async -> Result<String, ClientProxyError> {
|
||||
createRoomNameTopicIsRoomPrivateUserIDsAvatarURLCallsCount += 1
|
||||
createRoomNameTopicIsRoomPrivateUserIDsAvatarURLReceivedArguments = (name: name, topic: topic, isRoomPrivate: isRoomPrivate, userIDs: userIDs, avatarURL: avatarURL)
|
||||
func createRoom(name: String, topic: String?, isRoomPrivate: Bool, isKnockingOnly: Bool, userIDs: [String], avatarURL: URL?) async -> Result<String, ClientProxyError> {
|
||||
createRoomNameTopicIsRoomPrivateIsKnockingOnlyUserIDsAvatarURLCallsCount += 1
|
||||
createRoomNameTopicIsRoomPrivateIsKnockingOnlyUserIDsAvatarURLReceivedArguments = (name: name, topic: topic, isRoomPrivate: isRoomPrivate, isKnockingOnly: isKnockingOnly, userIDs: userIDs, avatarURL: avatarURL)
|
||||
DispatchQueue.main.async {
|
||||
self.createRoomNameTopicIsRoomPrivateUserIDsAvatarURLReceivedInvocations.append((name: name, topic: topic, isRoomPrivate: isRoomPrivate, userIDs: userIDs, avatarURL: avatarURL))
|
||||
self.createRoomNameTopicIsRoomPrivateIsKnockingOnlyUserIDsAvatarURLReceivedInvocations.append((name: name, topic: topic, isRoomPrivate: isRoomPrivate, isKnockingOnly: isKnockingOnly, userIDs: userIDs, avatarURL: avatarURL))
|
||||
}
|
||||
if let createRoomNameTopicIsRoomPrivateUserIDsAvatarURLClosure = createRoomNameTopicIsRoomPrivateUserIDsAvatarURLClosure {
|
||||
return await createRoomNameTopicIsRoomPrivateUserIDsAvatarURLClosure(name, topic, isRoomPrivate, userIDs, avatarURL)
|
||||
if let createRoomNameTopicIsRoomPrivateIsKnockingOnlyUserIDsAvatarURLClosure = createRoomNameTopicIsRoomPrivateIsKnockingOnlyUserIDsAvatarURLClosure {
|
||||
return await createRoomNameTopicIsRoomPrivateIsKnockingOnlyUserIDsAvatarURLClosure(name, topic, isRoomPrivate, isKnockingOnly, userIDs, avatarURL)
|
||||
} else {
|
||||
return createRoomNameTopicIsRoomPrivateUserIDsAvatarURLReturnValue
|
||||
return createRoomNameTopicIsRoomPrivateIsKnockingOnlyUserIDsAvatarURLReturnValue
|
||||
}
|
||||
}
|
||||
//MARK: - joinRoom
|
||||
|
||||
@@ -37,7 +37,8 @@ final class CreateRoomCoordinator: CoordinatorProtocol {
|
||||
createRoomParameters: parameters.createRoomParameters,
|
||||
selectedUsers: parameters.selectedUsers,
|
||||
analytics: ServiceLocator.shared.analytics,
|
||||
userIndicatorController: parameters.userIndicatorController)
|
||||
userIndicatorController: parameters.userIndicatorController,
|
||||
appSettings: ServiceLocator.shared.settings)
|
||||
}
|
||||
|
||||
func start() {
|
||||
|
||||
@@ -25,6 +25,7 @@ enum CreateRoomViewModelAction {
|
||||
}
|
||||
|
||||
struct CreateRoomViewState: BindableState {
|
||||
let isKnockingFeatureEnabled: Bool
|
||||
var selectedUsers: [UserProfileProxy]
|
||||
var bindings: CreateRoomViewStateBindings
|
||||
var avatarURL: URL?
|
||||
@@ -37,6 +38,7 @@ struct CreateRoomViewStateBindings {
|
||||
var roomName: String
|
||||
var roomTopic: String
|
||||
var isRoomPrivate: Bool
|
||||
var isKnockingOnly = false
|
||||
var showAttachmentConfirmationDialog = false
|
||||
|
||||
/// Information describing the currently displayed alert.
|
||||
|
||||
@@ -26,7 +26,8 @@ class CreateRoomViewModel: CreateRoomViewModelType, CreateRoomViewModelProtocol
|
||||
createRoomParameters: CurrentValuePublisher<CreateRoomFlowParameters, Never>,
|
||||
selectedUsers: CurrentValuePublisher<[UserProfileProxy], Never>,
|
||||
analytics: AnalyticsService,
|
||||
userIndicatorController: UserIndicatorControllerProtocol) {
|
||||
userIndicatorController: UserIndicatorControllerProtocol,
|
||||
appSettings: AppSettings) {
|
||||
let parameters = createRoomParameters.value
|
||||
|
||||
self.userSession = userSession
|
||||
@@ -36,7 +37,7 @@ class CreateRoomViewModel: CreateRoomViewModelType, CreateRoomViewModelProtocol
|
||||
|
||||
let bindings = CreateRoomViewStateBindings(roomName: parameters.name, roomTopic: parameters.topic, isRoomPrivate: parameters.isRoomPrivate)
|
||||
|
||||
super.init(initialViewState: CreateRoomViewState(selectedUsers: selectedUsers.value, bindings: bindings), mediaProvider: userSession.mediaProvider)
|
||||
super.init(initialViewState: CreateRoomViewState(isKnockingFeatureEnabled: appSettings.knockingEnabled, selectedUsers: selectedUsers.value, bindings: bindings), mediaProvider: userSession.mediaProvider)
|
||||
|
||||
createRoomParameters
|
||||
.map(\.avatarImageMedia)
|
||||
@@ -92,21 +93,28 @@ class CreateRoomViewModel: CreateRoomViewModelType, CreateRoomViewModelProtocol
|
||||
old.roomName == new.roomName && old.roomTopic == new.roomTopic && old.isRoomPrivate == new.isRoomPrivate
|
||||
}
|
||||
.sink { [weak self] bindings in
|
||||
guard let self else { return }
|
||||
createRoomParameters.name = bindings.roomName
|
||||
createRoomParameters.topic = bindings.roomTopic
|
||||
createRoomParameters.isRoomPrivate = bindings.isRoomPrivate
|
||||
guard let self = self else { return }
|
||||
updateParameters(bindings: bindings)
|
||||
actionsSubject.send(.updateDetails(createRoomParameters))
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
}
|
||||
|
||||
private func updateParameters(bindings: CreateRoomViewStateBindings) {
|
||||
createRoomParameters.name = bindings.roomName
|
||||
createRoomParameters.topic = bindings.roomTopic
|
||||
createRoomParameters.isRoomPrivate = bindings.isRoomPrivate
|
||||
createRoomParameters.isKnockingOnly = bindings.isKnockingOnly
|
||||
}
|
||||
|
||||
private func createRoom() async {
|
||||
defer {
|
||||
hideLoadingIndicator()
|
||||
}
|
||||
showLoadingIndicator()
|
||||
|
||||
// Since the parameters are throttled, we need to make sure that the latest values are used
|
||||
updateParameters(bindings: state.bindings)
|
||||
let avatarURL: URL?
|
||||
if let media = createRoomParameters.avatarImageMedia {
|
||||
switch await userSession.clientProxy.uploadMedia(media) {
|
||||
@@ -136,6 +144,8 @@ class CreateRoomViewModel: CreateRoomViewModelType, CreateRoomViewModelProtocol
|
||||
switch await userSession.clientProxy.createRoom(name: createRoomParameters.name,
|
||||
topic: createRoomParameters.topic,
|
||||
isRoomPrivate: createRoomParameters.isRoomPrivate,
|
||||
// As of right now we don't want to make private rooms with the knock rule
|
||||
isKnockingOnly: createRoomParameters.isRoomPrivate ? false : createRoomParameters.isKnockingOnly,
|
||||
userIDs: state.selectedUsers.map(\.userID),
|
||||
avatarURL: avatarURL) {
|
||||
case .success(let roomId):
|
||||
|
||||
@@ -22,6 +22,10 @@ struct CreateRoomScreen: View {
|
||||
roomSection
|
||||
topicSection
|
||||
securitySection
|
||||
if context.viewState.isKnockingFeatureEnabled,
|
||||
!context.isRoomPrivate {
|
||||
roomAccessSection
|
||||
}
|
||||
}
|
||||
.compoundList()
|
||||
.track(screen: .CreateRoom)
|
||||
@@ -151,6 +155,20 @@ struct CreateRoomScreen: View {
|
||||
}
|
||||
}
|
||||
|
||||
private var roomAccessSection: some View {
|
||||
Section {
|
||||
ListRow(label: .plain(title: L10n.screenCreateRoomAccessSectionAnyoneOptionTitle,
|
||||
description: L10n.screenCreateRoomAccessSectionAnyoneOptionDescription),
|
||||
kind: .selection(isSelected: !context.isKnockingOnly) { context.isKnockingOnly = false })
|
||||
ListRow(label: .plain(title: L10n.screenCreateRoomAccessSectionKnockingOptionTitle,
|
||||
description: L10n.screenCreateRoomAccessSectionKnockingOptionDescription),
|
||||
kind: .selection(isSelected: context.isKnockingOnly) { context.isKnockingOnly = true })
|
||||
} header: {
|
||||
Text(L10n.screenCreateRoomAccessSectionHeader.uppercased())
|
||||
.compoundListSectionHeader()
|
||||
}
|
||||
}
|
||||
|
||||
private var toolbar: some ToolbarContent {
|
||||
ToolbarItem(placement: .confirmationAction) {
|
||||
Button(L10n.actionCreate) {
|
||||
@@ -174,7 +192,8 @@ struct CreateRoom_Previews: PreviewProvider, TestablePreview {
|
||||
createRoomParameters: .init(parameters),
|
||||
selectedUsers: .init(selectedUsers),
|
||||
analytics: ServiceLocator.shared.analytics,
|
||||
userIndicatorController: UserIndicatorControllerMock())
|
||||
userIndicatorController: UserIndicatorControllerMock(),
|
||||
appSettings: ServiceLocator.shared.settings)
|
||||
}()
|
||||
|
||||
static let emtpyViewModel = {
|
||||
@@ -184,7 +203,21 @@ struct CreateRoom_Previews: PreviewProvider, TestablePreview {
|
||||
createRoomParameters: .init(parameters),
|
||||
selectedUsers: .init([]),
|
||||
analytics: ServiceLocator.shared.analytics,
|
||||
userIndicatorController: UserIndicatorControllerMock())
|
||||
userIndicatorController: UserIndicatorControllerMock(),
|
||||
appSettings: ServiceLocator.shared.settings)
|
||||
}()
|
||||
|
||||
static let publicRoomViewModel = {
|
||||
let userSession = UserSessionMock(.init(clientProxy: ClientProxyMock(.init(userID: "@userid:example.com"))))
|
||||
let parameters = CreateRoomFlowParameters(isRoomPrivate: false)
|
||||
let selectedUsers: [UserProfileProxy] = [.mockAlice, .mockBob, .mockCharlie]
|
||||
ServiceLocator.shared.settings.knockingEnabled = true
|
||||
return CreateRoomViewModel(userSession: userSession,
|
||||
createRoomParameters: .init(parameters),
|
||||
selectedUsers: .init([]),
|
||||
analytics: ServiceLocator.shared.analytics,
|
||||
userIndicatorController: UserIndicatorControllerMock(),
|
||||
appSettings: ServiceLocator.shared.settings)
|
||||
}()
|
||||
|
||||
static var previews: some View {
|
||||
@@ -196,5 +229,9 @@ struct CreateRoom_Previews: PreviewProvider, TestablePreview {
|
||||
CreateRoomScreen(context: emtpyViewModel.context)
|
||||
}
|
||||
.previewDisplayName("Create Room without users")
|
||||
NavigationStack {
|
||||
CreateRoomScreen(context: publicRoomViewModel.context)
|
||||
}
|
||||
.previewDisplayName("Create Public Room")
|
||||
}
|
||||
}
|
||||
|
||||
+1
@@ -49,6 +49,7 @@ protocol DeveloperOptionsProtocol: AnyObject {
|
||||
var enableOnlySignedDeviceIsolationMode: Bool { get set }
|
||||
var elementCallBaseURLOverride: URL? { get set }
|
||||
var identityPinningViolationNotificationsEnabled: Bool { get set }
|
||||
var knockingEnabled: Bool { get set }
|
||||
}
|
||||
|
||||
extension AppSettings: DeveloperOptionsProtocol { }
|
||||
|
||||
+7
@@ -55,6 +55,13 @@ struct DeveloperOptionsScreen: View {
|
||||
}
|
||||
}
|
||||
|
||||
Section("Join rules") {
|
||||
Toggle(isOn: $context.knockingEnabled) {
|
||||
Text("Knocking")
|
||||
Text("Experimental, still using mocked data")
|
||||
}
|
||||
}
|
||||
|
||||
Section {
|
||||
Toggle(isOn: $context.enableOnlySignedDeviceIsolationMode) {
|
||||
Text("Exclude insecure devices when sending/receiving messages")
|
||||
|
||||
@@ -365,8 +365,9 @@ class ClientProxy: ClientProxyProtocol {
|
||||
}
|
||||
}
|
||||
|
||||
func createRoom(name: String, topic: String?, isRoomPrivate: Bool, userIDs: [String], avatarURL: URL?) async -> Result<String, ClientProxyError> {
|
||||
func createRoom(name: String, topic: String?, isRoomPrivate: Bool, isKnockingOnly: Bool, userIDs: [String], avatarURL: URL?) async -> Result<String, ClientProxyError> {
|
||||
do {
|
||||
// TODO: Revisit once the SDK supports the knocking API
|
||||
let parameters = CreateRoomParameters(name: name,
|
||||
topic: topic,
|
||||
isEncrypted: isRoomPrivate,
|
||||
|
||||
@@ -138,7 +138,7 @@ protocol ClientProxyProtocol: AnyObject, MediaLoaderProtocol {
|
||||
|
||||
func createDirectRoom(with userID: String, expectedRoomName: String?) async -> Result<String, ClientProxyError>
|
||||
|
||||
func createRoom(name: String, topic: String?, isRoomPrivate: Bool, userIDs: [String], avatarURL: URL?) async -> Result<String, ClientProxyError>
|
||||
func createRoom(name: String, topic: String?, isRoomPrivate: Bool, isKnockingOnly: Bool, userIDs: [String], avatarURL: URL?) async -> Result<String, ClientProxyError>
|
||||
|
||||
func joinRoom(_ roomID: String, via: [String]) async -> Result<Void, ClientProxyError>
|
||||
|
||||
|
||||
@@ -12,5 +12,6 @@ struct CreateRoomFlowParameters {
|
||||
var name = ""
|
||||
var topic = ""
|
||||
var isRoomPrivate = true
|
||||
var isKnockingOnly = false
|
||||
var avatarImageMedia: MediaInfo?
|
||||
}
|
||||
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:a2b6822fdd0ddc3b3c87d0142377a0951e9478c2fb1a1b840204589b2bc6270e
|
||||
size 175831
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:1b805b55944beb58caccd5dbf4e98261582fe006ce8c08014bfaf26c13eea75f
|
||||
size 211876
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:0fccdc54a2d88e39353bdb49f32040749072dd17ac3c6cacc165ab6f0812d500
|
||||
size 123697
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:35ecf1e814eedd5f2d388224aee6fc885b1d9e1fe174b9199d9fe7bb9004a355
|
||||
size 164558
|
||||
@@ -29,11 +29,13 @@ class CreateRoomScreenViewModelTests: XCTestCase {
|
||||
userSession = UserSessionMock(.init(clientProxy: clientProxy))
|
||||
let parameters = CreateRoomFlowParameters()
|
||||
usersSubject.send([.mockAlice, .mockBob, .mockCharlie])
|
||||
ServiceLocator.shared.settings.knockingEnabled = true
|
||||
let viewModel = CreateRoomViewModel(userSession: userSession,
|
||||
createRoomParameters: .init(parameters),
|
||||
selectedUsers: usersSubject.asCurrentValuePublisher(),
|
||||
analytics: ServiceLocator.shared.analytics,
|
||||
userIndicatorController: UserIndicatorControllerMock())
|
||||
userIndicatorController: UserIndicatorControllerMock(),
|
||||
appSettings: ServiceLocator.shared.settings)
|
||||
self.viewModel = viewModel
|
||||
|
||||
viewModel.actions.sink { [weak self] action in
|
||||
@@ -69,4 +71,38 @@ class CreateRoomScreenViewModelTests: XCTestCase {
|
||||
context.roomName = "A"
|
||||
XCTAssertTrue(context.viewState.canCreateRoom)
|
||||
}
|
||||
|
||||
func testCreateKnockingRoom() async {
|
||||
context.roomName = "A"
|
||||
context.roomTopic = "B"
|
||||
context.isRoomPrivate = false
|
||||
context.isKnockingOnly = true
|
||||
XCTAssertTrue(context.viewState.canCreateRoom)
|
||||
|
||||
let expectation = expectation(description: "Wait for the room to be created")
|
||||
clientProxy.createRoomNameTopicIsRoomPrivateIsKnockingOnlyUserIDsAvatarURLClosure = { _, _, isPrivate, isKnockingOnly, _, _ in
|
||||
XCTAssertTrue(isKnockingOnly)
|
||||
XCTAssertFalse(isPrivate)
|
||||
defer { expectation.fulfill() }
|
||||
return .success("")
|
||||
}
|
||||
context.send(viewAction: .createRoom)
|
||||
await fulfillment(of: [expectation])
|
||||
}
|
||||
|
||||
func testCreatePrivateRoomCantHaveKnockRule() async {
|
||||
context.roomName = "A"
|
||||
context.roomTopic = "B"
|
||||
context.isRoomPrivate = true
|
||||
context.isKnockingOnly = true
|
||||
context.send(viewAction: .createRoom)
|
||||
let expectation = expectation(description: "Wait for the room to be created")
|
||||
clientProxy.createRoomNameTopicIsRoomPrivateIsKnockingOnlyUserIDsAvatarURLClosure = { _, _, isPrivate, isKnockingOnly, _, _ in
|
||||
XCTAssertFalse(isKnockingOnly)
|
||||
XCTAssertTrue(isPrivate)
|
||||
expectation.fulfill()
|
||||
return .success("")
|
||||
}
|
||||
await fulfillment(of: [expectation])
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user