mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-04 19:44:05 +00:00
Implemented adding the room to the space after selection, and the editableSpace proxied API. Also updated and added tests.
This commit is contained in:
@@ -17100,6 +17100,70 @@ class SpaceServiceProxyMock: SpaceServiceProxyProtocol, @unchecked Sendable {
|
|||||||
return joinedParentsChildIDReturnValue
|
return joinedParentsChildIDReturnValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//MARK: - editableSpaces
|
||||||
|
|
||||||
|
var editableSpacesUnderlyingCallsCount = 0
|
||||||
|
var editableSpacesCallsCount: Int {
|
||||||
|
get {
|
||||||
|
if Thread.isMainThread {
|
||||||
|
return editableSpacesUnderlyingCallsCount
|
||||||
|
} else {
|
||||||
|
var returnValue: Int? = nil
|
||||||
|
DispatchQueue.main.sync {
|
||||||
|
returnValue = editableSpacesUnderlyingCallsCount
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
if Thread.isMainThread {
|
||||||
|
editableSpacesUnderlyingCallsCount = newValue
|
||||||
|
} else {
|
||||||
|
DispatchQueue.main.sync {
|
||||||
|
editableSpacesUnderlyingCallsCount = newValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var editableSpacesCalled: Bool {
|
||||||
|
return editableSpacesCallsCount > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
var editableSpacesUnderlyingReturnValue: [SpaceServiceRoomProtocol]!
|
||||||
|
var editableSpacesReturnValue: [SpaceServiceRoomProtocol]! {
|
||||||
|
get {
|
||||||
|
if Thread.isMainThread {
|
||||||
|
return editableSpacesUnderlyingReturnValue
|
||||||
|
} else {
|
||||||
|
var returnValue: [SpaceServiceRoomProtocol]? = nil
|
||||||
|
DispatchQueue.main.sync {
|
||||||
|
returnValue = editableSpacesUnderlyingReturnValue
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
if Thread.isMainThread {
|
||||||
|
editableSpacesUnderlyingReturnValue = newValue
|
||||||
|
} else {
|
||||||
|
DispatchQueue.main.sync {
|
||||||
|
editableSpacesUnderlyingReturnValue = newValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var editableSpacesClosure: (() async -> [SpaceServiceRoomProtocol])?
|
||||||
|
|
||||||
|
func editableSpaces() async -> [SpaceServiceRoomProtocol] {
|
||||||
|
editableSpacesCallsCount += 1
|
||||||
|
if let editableSpacesClosure = editableSpacesClosure {
|
||||||
|
return await editableSpacesClosure()
|
||||||
|
} else {
|
||||||
|
return editableSpacesReturnValue
|
||||||
|
}
|
||||||
|
}
|
||||||
//MARK: - addChild
|
//MARK: - addChild
|
||||||
|
|
||||||
var addChildToUnderlyingCallsCount = 0
|
var addChildToUnderlyingCallsCount = 0
|
||||||
|
|||||||
@@ -111,6 +111,7 @@ extension [SpaceServiceRoomProtocol] {
|
|||||||
childrenCount: 1,
|
childrenCount: 1,
|
||||||
joinedMembersCount: 500,
|
joinedMembersCount: 500,
|
||||||
canonicalAlias: "#the-foundation:matrix.org",
|
canonicalAlias: "#the-foundation:matrix.org",
|
||||||
|
joinRule: .private,
|
||||||
state: .joined)),
|
state: .joined)),
|
||||||
SpaceServiceRoomMock(.init(id: "space2",
|
SpaceServiceRoomMock(.init(id: "space2",
|
||||||
name: "The Second Foundation",
|
name: "The Second Foundation",
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ extension SpaceServiceProxyMock {
|
|||||||
var topLevelSpaces: [SpaceServiceRoomProtocol] = []
|
var topLevelSpaces: [SpaceServiceRoomProtocol] = []
|
||||||
var spaceFilters: [SpaceServiceFilter] = []
|
var spaceFilters: [SpaceServiceFilter] = []
|
||||||
var joinedParentSpaces: [SpaceServiceRoomProtocol] = []
|
var joinedParentSpaces: [SpaceServiceRoomProtocol] = []
|
||||||
|
var editableSpaces: [SpaceServiceRoomProtocol] = []
|
||||||
var spaceRoomLists: [String: SpaceRoomListProxyMock] = [:]
|
var spaceRoomLists: [String: SpaceRoomListProxyMock] = [:]
|
||||||
var leaveSpaceRooms: [LeaveSpaceRoom] = []
|
var leaveSpaceRooms: [LeaveSpaceRoom] = []
|
||||||
}
|
}
|
||||||
@@ -27,6 +28,7 @@ extension SpaceServiceProxyMock {
|
|||||||
spaceFilterPublisher = .init(configuration.spaceFilters)
|
spaceFilterPublisher = .init(configuration.spaceFilters)
|
||||||
|
|
||||||
joinedParentsChildIDReturnValue = .success(configuration.joinedParentSpaces)
|
joinedParentsChildIDReturnValue = .success(configuration.joinedParentSpaces)
|
||||||
|
editableSpacesReturnValue = configuration.editableSpaces
|
||||||
spaceRoomListSpaceIDClosure = { spaceID in
|
spaceRoomListSpaceIDClosure = { spaceID in
|
||||||
if let spaceRoomList = configuration.spaceRoomLists[spaceID] {
|
if let spaceRoomList = configuration.spaceRoomLists[spaceID] {
|
||||||
.success(spaceRoomList)
|
.success(spaceRoomList)
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ struct CreateRoomScreenViewState: BindableState {
|
|||||||
let isKnockingFeatureEnabled: Bool
|
let isKnockingFeatureEnabled: Bool
|
||||||
let canSelectSpace: Bool
|
let canSelectSpace: Bool
|
||||||
var aliasLocalPart: String
|
var aliasLocalPart: String
|
||||||
var topLevelSpaces: [SpaceServiceRoomProtocol]
|
var editableSpaces: [SpaceServiceRoomProtocol] = []
|
||||||
var bindings: CreateRoomScreenViewStateBindings
|
var bindings: CreateRoomScreenViewStateBindings
|
||||||
var avatarMediaInfo: MediaInfo? {
|
var avatarMediaInfo: MediaInfo? {
|
||||||
didSet {
|
didSet {
|
||||||
|
|||||||
@@ -61,11 +61,16 @@ class CreateRoomScreenViewModel: CreateRoomScreenViewModelType, CreateRoomScreen
|
|||||||
isKnockingFeatureEnabled: appSettings.knockingEnabled,
|
isKnockingFeatureEnabled: appSettings.knockingEnabled,
|
||||||
canSelectSpace: canSelectSpace,
|
canSelectSpace: canSelectSpace,
|
||||||
aliasLocalPart: roomAliasNameFromRoomDisplayName(roomName: ""),
|
aliasLocalPart: roomAliasNameFromRoomDisplayName(roomName: ""),
|
||||||
topLevelSpaces: canSelectSpace ? userSession.clientProxy.spaceService.topLevelSpacesPublisher.value : [],
|
|
||||||
bindings: bindings),
|
bindings: bindings),
|
||||||
mediaProvider: userSession.mediaProvider)
|
mediaProvider: userSession.mediaProvider)
|
||||||
|
|
||||||
setupBindings()
|
setupBindings()
|
||||||
|
|
||||||
|
if canSelectSpace {
|
||||||
|
Task {
|
||||||
|
state.editableSpaces = await userSession.clientProxy.spaceService.editableSpaces()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Public
|
// MARK: - Public
|
||||||
@@ -195,15 +200,6 @@ class CreateRoomScreenViewModel: CreateRoomScreenViewModelType, CreateRoomScreen
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.store(in: &cancellables)
|
.store(in: &cancellables)
|
||||||
|
|
||||||
if state.canSelectSpace {
|
|
||||||
userSession
|
|
||||||
.clientProxy
|
|
||||||
.spaceService
|
|
||||||
.topLevelSpacesPublisher
|
|
||||||
.weakAssign(to: \.state.topLevelSpaces, on: self)
|
|
||||||
.store(in: &cancellables)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private func createRoom() async {
|
private func createRoom() async {
|
||||||
@@ -277,15 +273,21 @@ class CreateRoomScreenViewModel: CreateRoomScreenViewModelType, CreateRoomScreen
|
|||||||
|
|
||||||
var spaceRoomListProxy: SpaceRoomListProxyProtocol?
|
var spaceRoomListProxy: SpaceRoomListProxyProtocol?
|
||||||
if state.isSpace {
|
if state.isSpace {
|
||||||
switch await userSession.clientProxy.spaceService.spaceRoomList(spaceID: roomProxy.id) {
|
switch await userSession.clientProxy.spaceService.spaceRoomList(spaceID: roomID) {
|
||||||
case .success(let value):
|
case .success(let value):
|
||||||
spaceRoomListProxy = value
|
spaceRoomListProxy = value
|
||||||
case .failure:
|
case .failure:
|
||||||
MXLog.error("Failed to get space room list for newly created space with id: \(roomProxy.id)")
|
MXLog.error("Failed to get space room list for newly created space with id: \(roomID)")
|
||||||
userIndicatorController.submitIndicator(.init(title: L10n.errorUnknown))
|
userIndicatorController.submitIndicator(.init(title: L10n.errorUnknown))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let selectedSpace = state.bindings.selectedSpace,
|
||||||
|
case .failure = await userSession.clientProxy.spaceService.addChild(roomID, to: selectedSpace.id) {
|
||||||
|
MXLog.error("Failed to add the created room with id: \(roomID) to the space with id: \(selectedSpace.id)")
|
||||||
|
userIndicatorController.submitIndicator(.init(title: L10n.errorUnknown))
|
||||||
|
}
|
||||||
|
|
||||||
actionsSubject.send(.createdRoom(roomProxy, spaceRoomListProxy))
|
actionsSubject.send(.createdRoom(roomProxy, spaceRoomListProxy))
|
||||||
case .failure:
|
case .failure:
|
||||||
state.bindings.alertInfo = AlertInfo(id: .failedCreatingRoom,
|
state.bindings.alertInfo = AlertInfo(id: .failedCreatingRoom,
|
||||||
|
|||||||
@@ -236,8 +236,11 @@ struct CreateRoomScreen: View {
|
|||||||
} else {
|
} else {
|
||||||
ListRow(label: .default(title: L10n.screenCreateRoomSpaceSelectionNoSpaceTitle,
|
ListRow(label: .default(title: L10n.screenCreateRoomSpaceSelectionNoSpaceTitle,
|
||||||
description: L10n.screenCreateRoomSpaceSelectionNoSpaceDescription,
|
description: L10n.screenCreateRoomSpaceSelectionNoSpaceDescription,
|
||||||
icon: \.home,
|
icon: CompoundIcon(\.homeSolid, size: .small, relativeTo: .body)
|
||||||
iconAlignment: .top),
|
.foregroundColor(.compound.iconPrimary)
|
||||||
|
.background(.compound.bgSubtleSecondary)
|
||||||
|
.scaledFrame(size: 32)
|
||||||
|
.clipAvatar(isSpace: true, size: 32)),
|
||||||
kind: .navigationLink {
|
kind: .navigationLink {
|
||||||
context.showSpaceSelectionSheet = true
|
context.showSpaceSelectionSheet = true
|
||||||
})
|
})
|
||||||
@@ -446,6 +449,56 @@ struct CreateRoom_Previews: PreviewProvider, TestablePreview {
|
|||||||
viewModel.context.send(viewAction: .updateAliasLocalPart("existing"))
|
viewModel.context.send(viewAction: .updateAliasLocalPart("existing"))
|
||||||
return viewModel
|
return viewModel
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
static let selectedSpaceViewModel = {
|
||||||
|
AppSettings.resetAllSettings()
|
||||||
|
let mockedSpace = SpaceServiceRoomMock(.init(name: "Awesome Space", isSpace: true, joinRule: .private))
|
||||||
|
let userSession = UserSessionMock(.init(clientProxy: ClientProxyMock(.init(userID: "@userid:example.com"))))
|
||||||
|
return CreateRoomScreenViewModel(isSpace: false,
|
||||||
|
spaceSelectionMode: .selected(mockedSpace),
|
||||||
|
shouldShowCancelButton: false,
|
||||||
|
userSession: userSession,
|
||||||
|
analytics: ServiceLocator.shared.analytics,
|
||||||
|
userIndicatorController: UserIndicatorControllerMock(),
|
||||||
|
appSettings: ServiceLocator.shared.settings)
|
||||||
|
}()
|
||||||
|
|
||||||
|
static let selectedSpaceWithListViewModel = {
|
||||||
|
let clientProxy = ClientProxyMock(.init(userID: "@userid:example.com"))
|
||||||
|
let spaces = [SpaceServiceRoomProtocol].mockJoinedSpaces2
|
||||||
|
clientProxy.spaceService = SpaceServiceProxyMock(.init(editableSpaces: spaces))
|
||||||
|
let userSession = UserSessionMock(.init(clientProxy: clientProxy))
|
||||||
|
|
||||||
|
let viewModel = CreateRoomScreenViewModel(isSpace: false,
|
||||||
|
spaceSelectionMode: .list,
|
||||||
|
shouldShowCancelButton: false,
|
||||||
|
userSession: userSession,
|
||||||
|
analytics: ServiceLocator.shared.analytics,
|
||||||
|
userIndicatorController: UserIndicatorControllerMock(),
|
||||||
|
appSettings: ServiceLocator.shared.settings)
|
||||||
|
|
||||||
|
viewModel.context.selectedSpace = spaces[0]
|
||||||
|
return viewModel
|
||||||
|
}()
|
||||||
|
|
||||||
|
static let selectedSpaceWithAskToJoinViewModel = {
|
||||||
|
AppSettings.resetAllSettings()
|
||||||
|
let appSettings = AppSettings()
|
||||||
|
appSettings.knockingEnabled = true
|
||||||
|
|
||||||
|
let mockedSpace = SpaceServiceRoomMock(.init(name: "Awesome Space", isSpace: true, joinRule: .private))
|
||||||
|
let userSession = UserSessionMock(.init(clientProxy: ClientProxyMock(.init(userID: "@userid:example.com"))))
|
||||||
|
let viewModel = CreateRoomScreenViewModel(isSpace: false,
|
||||||
|
spaceSelectionMode: .selected(mockedSpace),
|
||||||
|
shouldShowCancelButton: false,
|
||||||
|
userSession: userSession,
|
||||||
|
analytics: ServiceLocator.shared.analytics,
|
||||||
|
userIndicatorController: UserIndicatorControllerMock(),
|
||||||
|
appSettings: appSettings)
|
||||||
|
|
||||||
|
viewModel.context.selectedAccessType = .askToJoinWithSpaceMembers
|
||||||
|
return viewModel
|
||||||
|
}()
|
||||||
|
|
||||||
static var previews: some View {
|
static var previews: some View {
|
||||||
NavigationStack {
|
NavigationStack {
|
||||||
@@ -491,5 +544,20 @@ struct CreateRoom_Previews: PreviewProvider, TestablePreview {
|
|||||||
}
|
}
|
||||||
.snapshotPreferences(expect: publicRoomExistingAliasViewModel.context.$viewState.map { !$0.aliasErrors.isEmpty })
|
.snapshotPreferences(expect: publicRoomExistingAliasViewModel.context.$viewState.map { !$0.aliasErrors.isEmpty })
|
||||||
.previewDisplayName("Create Public Room, existing alias")
|
.previewDisplayName("Create Public Room, existing alias")
|
||||||
|
|
||||||
|
NavigationStack {
|
||||||
|
CreateRoomScreen(context: selectedSpaceViewModel.context)
|
||||||
|
}
|
||||||
|
.previewDisplayName("Create Room with already selected Space")
|
||||||
|
|
||||||
|
NavigationStack {
|
||||||
|
CreateRoomScreen(context: selectedSpaceWithListViewModel.context)
|
||||||
|
}
|
||||||
|
.previewDisplayName("Create Room with a selected Space from the list")
|
||||||
|
|
||||||
|
NavigationStack {
|
||||||
|
CreateRoomScreen(context: selectedSpaceWithAskToJoinViewModel.context)
|
||||||
|
}
|
||||||
|
.previewDisplayName("Create Knockable Room with already selected Space")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,12 +26,16 @@ struct CreateRoomSpaceSelectionSheet: View {
|
|||||||
Section {
|
Section {
|
||||||
ListRow(label: .default(title: L10n.screenCreateRoomSpaceSelectionNoSpaceTitle,
|
ListRow(label: .default(title: L10n.screenCreateRoomSpaceSelectionNoSpaceTitle,
|
||||||
description: L10n.screenCreateRoomSpaceSelectionNoSpaceDescription,
|
description: L10n.screenCreateRoomSpaceSelectionNoSpaceDescription,
|
||||||
icon: \.home),
|
icon: CompoundIcon(\.homeSolid, size: .small, relativeTo: .body)
|
||||||
|
.foregroundColor(.compound.iconPrimary)
|
||||||
|
.background(.compound.bgSubtleSecondary)
|
||||||
|
.scaledFrame(size: 32)
|
||||||
|
.clipAvatar(isSpace: true, size: 32)),
|
||||||
kind: .selection(isSelected: context.selectedSpace == nil) {
|
kind: .selection(isSelected: context.selectedSpace == nil) {
|
||||||
context.selectedSpace = nil
|
context.selectedSpace = nil
|
||||||
dismiss()
|
dismiss()
|
||||||
})
|
})
|
||||||
ForEach(context.viewState.topLevelSpaces, id: \.id) { space in
|
ForEach(context.viewState.editableSpaces, id: \.id) { space in
|
||||||
ListRow(label: .avatar(title: space.name,
|
ListRow(label: .avatar(title: space.name,
|
||||||
description: space.canonicalAlias,
|
description: space.canonicalAlias,
|
||||||
icon: RoomAvatarImage(avatar: space.avatar,
|
icon: RoomAvatarImage(avatar: space.avatar,
|
||||||
@@ -66,7 +70,7 @@ struct CreateRoomSpaceSelectionSheet: View {
|
|||||||
struct CreateRoomSpaceSelectionSheet_Previews: PreviewProvider, TestablePreview {
|
struct CreateRoomSpaceSelectionSheet_Previews: PreviewProvider, TestablePreview {
|
||||||
static let viewModel = {
|
static let viewModel = {
|
||||||
let clientProxy = ClientProxyMock(.init(userID: "@userid:example.com"))
|
let clientProxy = ClientProxyMock(.init(userID: "@userid:example.com"))
|
||||||
clientProxy.spaceService = SpaceServiceProxyMock(.init(topLevelSpaces: .mockJoinedSpaces2))
|
clientProxy.spaceService = SpaceServiceProxyMock(.init(editableSpaces: .mockJoinedSpaces2))
|
||||||
let userSession = UserSessionMock(.init(clientProxy: clientProxy))
|
let userSession = UserSessionMock(.init(clientProxy: clientProxy))
|
||||||
|
|
||||||
return CreateRoomScreenViewModel(isSpace: false,
|
return CreateRoomScreenViewModel(isSpace: false,
|
||||||
@@ -80,5 +84,6 @@ struct CreateRoomSpaceSelectionSheet_Previews: PreviewProvider, TestablePreview
|
|||||||
|
|
||||||
static var previews: some View {
|
static var previews: some View {
|
||||||
CreateRoomSpaceSelectionSheet(context: viewModel.context)
|
CreateRoomSpaceSelectionSheet(context: viewModel.context)
|
||||||
|
.snapshotPreferences(expect: viewModel.context.$viewState.map { $0.editableSpaces.count > 0 })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,6 +77,10 @@ class SpaceServiceProxy: SpaceServiceProxyProtocol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func editableSpaces() async -> [SpaceServiceRoomProtocol] {
|
||||||
|
await spaceService.editableSpaces().map(SpaceServiceRoom.init)
|
||||||
|
}
|
||||||
|
|
||||||
func addChild(_ childID: String, to spaceID: String) async -> Result<Void, SpaceServiceProxyError> {
|
func addChild(_ childID: String, to spaceID: String) async -> Result<Void, SpaceServiceProxyError> {
|
||||||
do {
|
do {
|
||||||
return try await .success(spaceService.addChildToSpace(childId: childID, spaceId: spaceID))
|
return try await .success(spaceService.addChildToSpace(childId: childID, spaceId: spaceID))
|
||||||
@@ -94,7 +98,7 @@ class SpaceServiceProxy: SpaceServiceProxyProtocol {
|
|||||||
return .failure(.sdkError(error))
|
return .failure(.sdkError(error))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Private
|
// MARK: - Private
|
||||||
|
|
||||||
private func handleSpaceListUpdates(_ updates: [SpaceListUpdate]) {
|
private func handleSpaceListUpdates(_ updates: [SpaceListUpdate]) {
|
||||||
|
|||||||
@@ -52,6 +52,8 @@ protocol SpaceServiceProxyProtocol {
|
|||||||
func leaveSpace(spaceID: String) async -> Result<LeaveSpaceHandleProxy, SpaceServiceProxyError>
|
func leaveSpace(spaceID: String) async -> Result<LeaveSpaceHandleProxy, SpaceServiceProxyError>
|
||||||
/// Returns all the parent spaces of a child that user has joined.
|
/// Returns all the parent spaces of a child that user has joined.
|
||||||
func joinedParents(childID: String) async -> Result<[SpaceServiceRoomProtocol], SpaceServiceProxyError>
|
func joinedParents(childID: String) async -> Result<[SpaceServiceRoomProtocol], SpaceServiceProxyError>
|
||||||
|
/// Returns all the parent spaces that can be edited by the user
|
||||||
|
func editableSpaces() async -> [SpaceServiceRoomProtocol]
|
||||||
|
|
||||||
/// Adds a room (or space) as a child of another space.
|
/// Adds a room (or space) as a child of another space.
|
||||||
func addChild(_ childID: String, to spaceID: String) async -> Result<Void, SpaceServiceProxyError>
|
func addChild(_ childID: String, to spaceID: String) async -> Result<Void, SpaceServiceProxyError>
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:aa327c6149879d4aa96fa4c5574bac7486fc6abfaa003ae74596c8b88adf6b0b
|
oid sha256:cd25013fbbabd76733d42f38aeabefbe579800c005892e1201b65d894dba3a71
|
||||||
size 156228
|
size 165592
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:704b115de7bad6d64ea253ea261a8812e536622dc32280a11e91a3bdc9473340
|
oid sha256:2a4261ad92874c8d26ff1030dd9dc0b40e4f49c75f535cc4116b56b72a12764f
|
||||||
size 186268
|
size 200632
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:66f4d91f70ce033d8c6553479ecf7471d53ffdb181986cea4c9032701a595c25
|
oid sha256:9c848aa3b95b5a7d2bcd21ff7cb84fadd32cfcb7fad9d02a267d7eb20b5cd975
|
||||||
size 106657
|
size 114307
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:0c355007d6ac8f669a701f0ef534e6e381895722d3c495be9e4ef49d20a7de79
|
oid sha256:b6f0109d908c6f92b2066be1ec631366d6fe170304eee39716c60da61b9a50e8
|
||||||
size 143489
|
size 134090
|
||||||
|
|||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:023c513c47df068c3bc47b4b06f028e630048d7289636dc9b9dac1433abcf442
|
||||||
|
size 139154
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:e35b0f0e56364235d60bd8688b7272664ce6c294eb0642d51967d9138289715c
|
||||||
|
size 165021
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:2482a63567a5a2ccb6f415e3dca4c05f697affecb9fc05e160c69c17c6020b9e
|
||||||
|
size 89586
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:409ca12c1ad636585be6fef0e1a25cdc17a57a1af00358131ff74995c65e0a26
|
||||||
|
size 120101
|
||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:31efa5cc91a3b0a623056e85e8d5e0c6544a464d959b29ef771e2c9fa2843d7e
|
oid sha256:783ef584086fb642ea70add67521b336e4bcf48e87d67bbc321bc05cb8801341
|
||||||
size 156446
|
size 165850
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:e638ad86f90e438978096a9fc928f85b6ca0d883f02221978307fe3068e20e35
|
oid sha256:353482a407588083863c271a0da9fa000e0b2f28db930a1ac355c995377d9cda
|
||||||
size 188066
|
size 202463
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:9b51dfc640af59dd5b3564148d48a1267e9423b1c77fb02edc4607d91d10910b
|
oid sha256:d6709be30e596cf5ab8a7a36be93ca3710b801e290c0aad8756dd5002fae6cba
|
||||||
size 108742
|
size 116153
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:8b8b277cc422ac3f6fba5b7b555e42c18d2b6ecde65a36eba6c4b63279fb80b5
|
oid sha256:d478eac4ccdc9e70cb83450b771ec600c1aa944ee246cf2de35a76f34fdba02e
|
||||||
size 145650
|
size 148446
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:b71055f825775861294542ae166fbe7013800fc3672ce4d39ab4419716eedf45
|
oid sha256:857dac4f0f576d660c86a344a754ae948f1c87344ea02c983ab90f81fc67f2bb
|
||||||
size 141129
|
size 150715
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:d2b85ce0989c5e068e489de22275aeaf723e51fe6b18cb304d16b831e8e8f368
|
oid sha256:a8ba3dcce7b0b2b1f55a795a0f701882a787b8f2ef8b7cf61aef21fa19b2aff7
|
||||||
size 164236
|
size 178610
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:a5adc15a61b998447a66a4696b59f89413381583c4455be02b1f28594701b986
|
oid sha256:41b047f803117538ea8bd7cdc15464d825d3e86226ceab49fd7925fa8ca53506
|
||||||
size 89299
|
size 98304
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:5823312ac25afe1b349f8eda8807299d6c30656e961d387c01e544eda40e6c4e
|
oid sha256:704cc86d9b1ee34f09b9327d935efa3e40654381e4bbbe510167f54ec44afb7f
|
||||||
size 116112
|
size 127362
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:400c0c0ed48ced1122851b21a6d3e9e48f0985635711fec7e4abe8660994a6b1
|
oid sha256:2629190bbf8a4101ac0a3cc07ce246d10727c043f6b691c15bdb727ae380f04e
|
||||||
size 159870
|
size 169245
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:575f32a8b119f2ffbaf6e234b9ea23366850ea245f3f63403a9ba0a2691a2a3b
|
oid sha256:5f93aab61df326b141ce7ceebde1ff99f0b7fb82610c1c45d7ed7c6a1d636439
|
||||||
size 195889
|
size 210144
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:9002a2ad841596a8e206326fa282b131b750cc556e57a8b8fbf355318106e6ac
|
oid sha256:b75b9be2f855101eb35fd48c8219b4dcfc4cd3bcc850683297b5ef6aec2f0a6b
|
||||||
size 110759
|
size 118048
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:fab82b9e91cb4b3bad0a3bd13e1b2077a992473889ddb62297d0c902d724e104
|
oid sha256:cdfac096c01f4cb5ea50c834ecd573d3761a77e20fd71e14ce22368beef01180
|
||||||
size 150819
|
size 147952
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:9db61c6bde46ef08cfd7d1aceb50f379544053024ac4633d1234c863c98c066a
|
oid sha256:6d19bc6c512bc48a5493b1e3eb8785c33b165daa51a529449c674fed1287ee25
|
||||||
size 123222
|
size 132860
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:e287da07572fd2bd3424894537844637e57629235b372108a8d99ae1b0994b1b
|
oid sha256:81c651fb4c443c1442fc6b8fccd168e901fb16f994428c44951f57f187a1a38e
|
||||||
size 140788
|
size 155183
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:8b820693bf00b97aaa0a797808106267ce741e495bba57936de8082dc4745bbf
|
oid sha256:a0ae349c1658b8ff32004e524ff2f16e31c013dae9e6ea9e4a6e3bd0e3756e64
|
||||||
size 73369
|
size 81447
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:ff2841d40e79e09cc472837c7ff350082d6d60894539302056c0d20f645264b1
|
oid sha256:064a83888029fc47666e0b110fc4260e436499aba4a527c02bfa9493b889a6fa
|
||||||
size 90112
|
size 100906
|
||||||
|
|||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:11421d65287250704b17af8ff783882e61e524f1ad7dd7e332bb308a9fa2b8a0
|
||||||
|
size 148258
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:7e45145df3773cfb4f0852576406e6fb9c1ae168539dedaccb000df45681b5af
|
||||||
|
size 168502
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:d90ac6bdafa18434682cf09e1434fe73358acea095b388902bbc06a43eb4355d
|
||||||
|
size 95080
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:2b46eb0c44ad26ec12798e0e6a55295e11374141766b856f4eca29b67b519578
|
||||||
|
size 115710
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:6cd61bb621776260dbb0d91621b0bfaa1aa6d5c19511771fa55b3237130b10ad
|
||||||
|
size 126389
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:1406d5b6cff0b0b73f1b012a58ce8bb306de648d1bfff626fbf68ec14cc86301
|
||||||
|
size 145450
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:9aff42b3a7cf336f604a40d5f9c5f87aedac8e7656cb9429efb2dbec6ef0738e
|
||||||
|
size 75993
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:7830c4f7a205182d1fc62ddedaa79098b869af45366fbf49de08d42bad646a24
|
||||||
|
size 95487
|
||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:dcbee0919af7296c78578076842b77cea64add28137e6d6bf27e1837563c9eab
|
oid sha256:d4c40aa821fba074dc2c45d68dad1ea5c4133209b940321a8126ae8da4af8b87
|
||||||
size 156762
|
size 166423
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:dd2792d7127bb9e498a814189fb5c5dfa2b270dd333cea7623ea2b9905ee981f
|
oid sha256:7ef469565f325404cbbe1ccd024681bf7779a74055b34402666f31df309163c0
|
||||||
size 174527
|
size 188779
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:d9d45b7c4d6aebb9c72558ed440ee099c756eb6b0196a5657d7da85557853d39
|
oid sha256:a9cb09216e7c5a198c106c2654a34f449e74d536129256fde1ad9a06bb9063c3
|
||||||
size 105940
|
size 114073
|
||||||
|
|||||||
+2
-2
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:3be54af6b52da9441294266c11a08bcaf85abfd2005e6ecc795e6e2d1b9b6cf6
|
oid sha256:f06e5655fe4409ddc5eed23ffec370d3e9bb6e95d5cf60dfcaa8af1a86ef6135
|
||||||
size 122952
|
size 133808
|
||||||
|
|||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:30039d5e15ac969e75c966de760a6e3d28659c29a06555c335f6ba8ab4bd0055
|
||||||
|
size 108672
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:47977fb6d9fb4357cf81cf6724a1a54102ee949a5dd4c4e0fc1ef53160f87328
|
||||||
|
size 111545
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:c17b4ed900e67eab1d9ab41496c4dd228c1ddd5aa6ac80bb16d5d99e1c02c884
|
||||||
|
size 65065
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:14ab4d7d5890e6838282885e34d232e520a1ce631eae54d88c09b4cc0fc34700
|
||||||
|
size 67699
|
||||||
@@ -15,6 +15,7 @@ import XCTest
|
|||||||
class CreateRoomScreenViewModelTests: XCTestCase {
|
class CreateRoomScreenViewModelTests: XCTestCase {
|
||||||
var viewModel: CreateRoomScreenViewModelProtocol!
|
var viewModel: CreateRoomScreenViewModelProtocol!
|
||||||
var clientProxy: ClientProxyMock!
|
var clientProxy: ClientProxyMock!
|
||||||
|
var spaceService: SpaceServiceProxyMock!
|
||||||
var userSession: UserSessionMock!
|
var userSession: UserSessionMock!
|
||||||
|
|
||||||
private let usersSubject = CurrentValueSubject<[UserProfileProxy], Never>([])
|
private let usersSubject = CurrentValueSubject<[UserProfileProxy], Never>([])
|
||||||
@@ -23,39 +24,31 @@ class CreateRoomScreenViewModelTests: XCTestCase {
|
|||||||
viewModel.context
|
viewModel.context
|
||||||
}
|
}
|
||||||
|
|
||||||
override func setUpWithError() throws {
|
|
||||||
clientProxy = ClientProxyMock(.init(userIDServerName: "matrix.org", userID: "@a:b.com"))
|
|
||||||
clientProxy.roomForIdentifierClosure = { roomID in .joined(JoinedRoomProxyMock(.init(id: roomID))) }
|
|
||||||
userSession = UserSessionMock(.init(clientProxy: clientProxy))
|
|
||||||
ServiceLocator.shared.settings.knockingEnabled = true
|
|
||||||
let viewModel = CreateRoomScreenViewModel(isSpace: false,
|
|
||||||
spaceSelectionMode: .list,
|
|
||||||
shouldShowCancelButton: false,
|
|
||||||
userSession: userSession,
|
|
||||||
analytics: ServiceLocator.shared.analytics,
|
|
||||||
userIndicatorController: UserIndicatorControllerMock(),
|
|
||||||
appSettings: ServiceLocator.shared.settings)
|
|
||||||
self.viewModel = viewModel
|
|
||||||
}
|
|
||||||
|
|
||||||
override func tearDown() {
|
override func tearDown() {
|
||||||
AppSettings.resetAllSettings()
|
AppSettings.resetAllSettings()
|
||||||
viewModel = nil
|
viewModel = nil
|
||||||
clientProxy = nil
|
clientProxy = nil
|
||||||
|
spaceService = nil
|
||||||
userSession = nil
|
userSession = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func testDefaultSecurity() {
|
func testDefaultState() {
|
||||||
|
setup()
|
||||||
XCTAssertEqual(context.viewState.bindings.selectedAccessType, .private)
|
XCTAssertEqual(context.viewState.bindings.selectedAccessType, .private)
|
||||||
|
XCTAssertNil(context.selectedSpace)
|
||||||
|
XCTAssertEqual(context.viewState.availableAccessTypes, [.public, .askToJoin, .private])
|
||||||
|
XCTAssertTrue(context.viewState.canSelectSpace)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testCreateRoomRequirements() {
|
func testCreateRoomRequirements() {
|
||||||
|
setup()
|
||||||
XCTAssertFalse(context.viewState.canCreateRoom)
|
XCTAssertFalse(context.viewState.canCreateRoom)
|
||||||
context.send(viewAction: .updateRoomName("A"))
|
context.send(viewAction: .updateRoomName("A"))
|
||||||
XCTAssertTrue(context.viewState.canCreateRoom)
|
XCTAssertTrue(context.viewState.canCreateRoom)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testCreateRoom() async throws {
|
func testCreateRoom() async throws {
|
||||||
|
setup()
|
||||||
// Given a form with a blank topic.
|
// Given a form with a blank topic.
|
||||||
context.send(viewAction: .updateRoomName("A"))
|
context.send(viewAction: .updateRoomName("A"))
|
||||||
context.roomTopic = ""
|
context.roomTopic = ""
|
||||||
@@ -76,9 +69,11 @@ class CreateRoomScreenViewModelTests: XCTestCase {
|
|||||||
XCTAssertEqual(clientProxy.createRoomNameTopicAccessTypeIsSpaceUserIDsAvatarURLAliasLocalPartReceivedArguments?.name, "A")
|
XCTAssertEqual(clientProxy.createRoomNameTopicAccessTypeIsSpaceUserIDsAvatarURLAliasLocalPartReceivedArguments?.name, "A")
|
||||||
XCTAssertNil(clientProxy.createRoomNameTopicAccessTypeIsSpaceUserIDsAvatarURLAliasLocalPartReceivedArguments?.topic,
|
XCTAssertNil(clientProxy.createRoomNameTopicAccessTypeIsSpaceUserIDsAvatarURLAliasLocalPartReceivedArguments?.topic,
|
||||||
"The topic should be sent as nil when it is empty.")
|
"The topic should be sent as nil when it is empty.")
|
||||||
|
XCTAssertEqual(clientProxy.createRoomNameTopicAccessTypeIsSpaceUserIDsAvatarURLAliasLocalPartReceivedArguments?.accessType, .private)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testCreateSpace() async throws {
|
func testCreateSpace() async throws {
|
||||||
|
setup(isSpace: true)
|
||||||
clientProxy = ClientProxyMock(.init(userIDServerName: "matrix.org",
|
clientProxy = ClientProxyMock(.init(userIDServerName: "matrix.org",
|
||||||
userID: "@a:b.com",
|
userID: "@a:b.com",
|
||||||
spaceServiceConfiguration: .init(spaceRoomLists: ["1": .init()])))
|
spaceServiceConfiguration: .init(spaceRoomLists: ["1": .init()])))
|
||||||
@@ -116,9 +111,11 @@ class CreateRoomScreenViewModelTests: XCTestCase {
|
|||||||
XCTAssertEqual(clientProxy.createRoomNameTopicAccessTypeIsSpaceUserIDsAvatarURLAliasLocalPartReceivedArguments?.name, "A")
|
XCTAssertEqual(clientProxy.createRoomNameTopicAccessTypeIsSpaceUserIDsAvatarURLAliasLocalPartReceivedArguments?.name, "A")
|
||||||
XCTAssertNil(clientProxy.createRoomNameTopicAccessTypeIsSpaceUserIDsAvatarURLAliasLocalPartReceivedArguments?.topic,
|
XCTAssertNil(clientProxy.createRoomNameTopicAccessTypeIsSpaceUserIDsAvatarURLAliasLocalPartReceivedArguments?.topic,
|
||||||
"The topic should be sent as nil when it is empty.")
|
"The topic should be sent as nil when it is empty.")
|
||||||
|
XCTAssertEqual(clientProxy.createRoomNameTopicAccessTypeIsSpaceUserIDsAvatarURLAliasLocalPartReceivedArguments?.accessType, .private)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testCreateKnockingRoom() async {
|
func testCreateKnockingRoom() async {
|
||||||
|
setup()
|
||||||
context.send(viewAction: .updateRoomName("A"))
|
context.send(viewAction: .updateRoomName("A"))
|
||||||
context.roomTopic = "B"
|
context.roomTopic = "B"
|
||||||
context.selectedAccessType = .askToJoin
|
context.selectedAccessType = .askToJoin
|
||||||
@@ -139,6 +136,7 @@ class CreateRoomScreenViewModelTests: XCTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func testCreatePublicRoomFailsForInvalidAlias() async throws {
|
func testCreatePublicRoomFailsForInvalidAlias() async throws {
|
||||||
|
setup()
|
||||||
context.send(viewAction: .updateRoomName("A"))
|
context.send(viewAction: .updateRoomName("A"))
|
||||||
context.roomTopic = "B"
|
context.roomTopic = "B"
|
||||||
context.selectedAccessType = .public
|
context.selectedAccessType = .public
|
||||||
@@ -161,6 +159,7 @@ class CreateRoomScreenViewModelTests: XCTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func testCreatePublicRoomFailsForExistingAlias() async throws {
|
func testCreatePublicRoomFailsForExistingAlias() async throws {
|
||||||
|
setup()
|
||||||
clientProxy.isAliasAvailableReturnValue = .success(false)
|
clientProxy.isAliasAvailableReturnValue = .success(false)
|
||||||
context.send(viewAction: .updateRoomName("A"))
|
context.send(viewAction: .updateRoomName("A"))
|
||||||
context.roomTopic = "B"
|
context.roomTopic = "B"
|
||||||
@@ -192,6 +191,7 @@ class CreateRoomScreenViewModelTests: XCTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func testNameAndAddressSync() async {
|
func testNameAndAddressSync() async {
|
||||||
|
setup()
|
||||||
context.selectedAccessType = .private
|
context.selectedAccessType = .private
|
||||||
await Task.yield()
|
await Task.yield()
|
||||||
context.send(viewAction: .updateRoomName("abc"))
|
context.send(viewAction: .updateRoomName("abc"))
|
||||||
@@ -221,4 +221,131 @@ class CreateRoomScreenViewModelTests: XCTestCase {
|
|||||||
XCTAssertEqual(context.viewState.aliasLocalPart, "hello-matrix!")
|
XCTAssertEqual(context.viewState.aliasLocalPart, "hello-matrix!")
|
||||||
XCTAssertEqual(context.viewState.roomName, "Hello# Matrix!")
|
XCTAssertEqual(context.viewState.roomName, "Hello# Matrix!")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func testCreateRoomInASelectedSpaceFromTheList() async throws {
|
||||||
|
let spaces = [SpaceServiceRoomProtocol].mockJoinedSpaces2
|
||||||
|
setup()
|
||||||
|
|
||||||
|
// Given a form with a blank topic.
|
||||||
|
context.send(viewAction: .updateRoomName("A"))
|
||||||
|
context.roomTopic = ""
|
||||||
|
context.selectedAccessType = .public
|
||||||
|
XCTAssertTrue(context.viewState.canCreateRoom)
|
||||||
|
XCTAssertNil(context.selectedSpace)
|
||||||
|
XCTAssertEqual(context.viewState.availableAccessTypes, [.public, .askToJoin, .private])
|
||||||
|
XCTAssertTrue(context.viewState.canSelectSpace)
|
||||||
|
|
||||||
|
var deferred = deferFulfillment(context.$viewState) { viewState in
|
||||||
|
viewState.editableSpaces.map(\.id) == spaces.map(\.id)
|
||||||
|
}
|
||||||
|
try await deferred.fulfill()
|
||||||
|
|
||||||
|
context.selectedSpace = spaces[0]
|
||||||
|
deferred = deferFulfillment(context.$viewState) { viewState in
|
||||||
|
viewState.bindings.selectedSpace?.id == spaces[0].id &&
|
||||||
|
viewState.availableAccessTypes == [.spaceMembers, .askToJoinWithSpaceMembers, .private] &&
|
||||||
|
// The value should reset since the original one is not available anymore
|
||||||
|
viewState.bindings.selectedAccessType == .private
|
||||||
|
}
|
||||||
|
try await deferred.fulfill()
|
||||||
|
|
||||||
|
// When creating the room.
|
||||||
|
clientProxy.createRoomNameTopicAccessTypeIsSpaceUserIDsAvatarURLAliasLocalPartReturnValue = .success("1")
|
||||||
|
let expectation = expectation(description: "Wait for the addChild function to be called")
|
||||||
|
spaceService.addChildToClosure = { roomID, spaceID in
|
||||||
|
defer { expectation.fulfill() }
|
||||||
|
XCTAssertEqual(roomID, "1")
|
||||||
|
XCTAssertEqual(spaceID, spaces[0].id)
|
||||||
|
return .success(())
|
||||||
|
}
|
||||||
|
|
||||||
|
let deferredAction = deferFulfillment(viewModel.actions) { action in
|
||||||
|
guard case .createdRoom(let roomProxy, nil) = action, roomProxy.id == "1" else { return false }
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
context.send(viewAction: .createRoom)
|
||||||
|
|
||||||
|
await fulfillment(of: [expectation])
|
||||||
|
try await deferredAction.fulfill()
|
||||||
|
|
||||||
|
// Then the room should be created and a topic should not be set.
|
||||||
|
XCTAssertTrue(clientProxy.createRoomNameTopicAccessTypeIsSpaceUserIDsAvatarURLAliasLocalPartCalled)
|
||||||
|
XCTAssertEqual(clientProxy.createRoomNameTopicAccessTypeIsSpaceUserIDsAvatarURLAliasLocalPartReceivedArguments?.name, "A")
|
||||||
|
XCTAssertEqual(clientProxy.createRoomNameTopicAccessTypeIsSpaceUserIDsAvatarURLAliasLocalPartReceivedArguments?.accessType, .private)
|
||||||
|
XCTAssertNil(clientProxy.createRoomNameTopicAccessTypeIsSpaceUserIDsAvatarURLAliasLocalPartReceivedArguments?.topic,
|
||||||
|
"The topic should be sent as nil when it is empty.")
|
||||||
|
}
|
||||||
|
|
||||||
|
func testCreateRoomInAnAlreadySelectedSpace() async throws {
|
||||||
|
let space = SpaceServiceRoomMock(.init(isSpace: true, joinRule: .private))
|
||||||
|
setup(spacesSelectionMode: .selected(space))
|
||||||
|
|
||||||
|
// Given a form with a blank topic.
|
||||||
|
context.send(viewAction: .updateRoomName("A"))
|
||||||
|
context.roomTopic = ""
|
||||||
|
context.selectedAccessType = .spaceMembers
|
||||||
|
XCTAssertTrue(context.viewState.canCreateRoom)
|
||||||
|
XCTAssertEqual(context.selectedSpace?.id, space.id)
|
||||||
|
XCTAssertEqual(context.viewState.availableAccessTypes, [.spaceMembers, .askToJoinWithSpaceMembers, .private])
|
||||||
|
XCTAssertFalse(context.viewState.canSelectSpace)
|
||||||
|
|
||||||
|
// When creating the room.
|
||||||
|
clientProxy.createRoomNameTopicAccessTypeIsSpaceUserIDsAvatarURLAliasLocalPartReturnValue = .success("1")
|
||||||
|
let expectation = expectation(description: "Wait for the addChild function to be called")
|
||||||
|
spaceService.addChildToClosure = { roomID, spaceID in
|
||||||
|
defer { expectation.fulfill() }
|
||||||
|
XCTAssertEqual(roomID, "1")
|
||||||
|
XCTAssertEqual(spaceID, space.id)
|
||||||
|
return .success(())
|
||||||
|
}
|
||||||
|
|
||||||
|
let deferredAction = deferFulfillment(viewModel.actions) { action in
|
||||||
|
guard case .createdRoom(let roomProxy, nil) = action, roomProxy.id == "1" else { return false }
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
context.send(viewAction: .createRoom)
|
||||||
|
|
||||||
|
await fulfillment(of: [expectation])
|
||||||
|
try await deferredAction.fulfill()
|
||||||
|
|
||||||
|
// Then the room should be created and a topic should not be set.
|
||||||
|
XCTAssertTrue(clientProxy.createRoomNameTopicAccessTypeIsSpaceUserIDsAvatarURLAliasLocalPartCalled)
|
||||||
|
XCTAssertEqual(clientProxy.createRoomNameTopicAccessTypeIsSpaceUserIDsAvatarURLAliasLocalPartReceivedArguments?.name, "A")
|
||||||
|
XCTAssertEqual(clientProxy.createRoomNameTopicAccessTypeIsSpaceUserIDsAvatarURLAliasLocalPartReceivedArguments?.accessType, .spaceMembers(spaceID: space.id))
|
||||||
|
XCTAssertNil(clientProxy.createRoomNameTopicAccessTypeIsSpaceUserIDsAvatarURLAliasLocalPartReceivedArguments?.topic,
|
||||||
|
"The topic should be sent as nil when it is empty.")
|
||||||
|
}
|
||||||
|
|
||||||
|
func testCreateRoomInAnPublicSpaceAvailableTypes() async throws {
|
||||||
|
let space = SpaceServiceRoomMock(.init(isSpace: true, joinRule: .public))
|
||||||
|
setup(spacesSelectionMode: .selected(space))
|
||||||
|
|
||||||
|
// Given a form with a blank topic.
|
||||||
|
context.send(viewAction: .updateRoomName("A"))
|
||||||
|
context.roomTopic = ""
|
||||||
|
context.selectedAccessType = .spaceMembers
|
||||||
|
XCTAssertTrue(context.viewState.canCreateRoom)
|
||||||
|
XCTAssertEqual(context.selectedSpace?.id, space.id)
|
||||||
|
XCTAssertEqual(context.viewState.availableAccessTypes, [.public, .askToJoin, .private])
|
||||||
|
XCTAssertFalse(context.viewState.canSelectSpace)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func setup(isSpace: Bool = false, spacesSelectionMode: CreateRoomScreenSpaceSelectionMode = .list) {
|
||||||
|
spaceService = SpaceServiceProxyMock(.init(editableSpaces: .mockJoinedSpaces2,
|
||||||
|
spaceRoomLists: ["1": .init()]))
|
||||||
|
clientProxy = ClientProxyMock(.init(userIDServerName: "matrix.org",
|
||||||
|
userID: "@a:b.com"))
|
||||||
|
clientProxy.spaceService = spaceService
|
||||||
|
clientProxy.roomForIdentifierClosure = { roomID in .joined(JoinedRoomProxyMock(.init(id: roomID))) }
|
||||||
|
userSession = UserSessionMock(.init(clientProxy: clientProxy))
|
||||||
|
ServiceLocator.shared.settings.knockingEnabled = true
|
||||||
|
let viewModel = CreateRoomScreenViewModel(isSpace: isSpace,
|
||||||
|
spaceSelectionMode: spacesSelectionMode,
|
||||||
|
shouldShowCancelButton: false,
|
||||||
|
userSession: userSession,
|
||||||
|
analytics: ServiceLocator.shared.analytics,
|
||||||
|
userIndicatorController: UserIndicatorControllerMock(),
|
||||||
|
appSettings: ServiceLocator.shared.settings)
|
||||||
|
self.viewModel = viewModel
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user