Create room redesign and refactor (#4942)

This commit is contained in:
Mauro
2026-01-12 18:49:31 +01:00
committed by GitHub
parent f42c063e50
commit 4cfedefcca
77 changed files with 463 additions and 348 deletions
@@ -28,15 +28,20 @@ class CreateRoomScreenViewModelTests: XCTestCase {
clientProxy.roomForIdentifierClosure = { roomID in .joined(JoinedRoomProxyMock(.init(id: roomID))) }
userSession = UserSessionMock(.init(clientProxy: clientProxy))
ServiceLocator.shared.settings.knockingEnabled = true
let viewModel = CreateRoomScreenViewModel(userSession: userSession,
let viewModel = CreateRoomScreenViewModel(isSpace: false,
userSession: userSession,
analytics: ServiceLocator.shared.analytics,
userIndicatorController: UserIndicatorControllerMock(),
appSettings: ServiceLocator.shared.settings)
self.viewModel = viewModel
}
override func tearDown() {
AppSettings.resetAllSettings()
}
func testDefaultSecurity() {
XCTAssertTrue(context.viewState.bindings.isRoomPrivate)
XCTAssertEqual(context.viewState.bindings.selectedAccessType, .private)
}
func testCreateRoomRequirements() {
@@ -49,11 +54,11 @@ class CreateRoomScreenViewModelTests: XCTestCase {
// Given a form with a blank topic.
context.send(viewAction: .updateRoomName("A"))
context.roomTopic = ""
context.isRoomPrivate = false
context.selectedAccessType = .private
XCTAssertTrue(context.viewState.canCreateRoom)
// When creating the room.
clientProxy.createRoomNameTopicIsRoomPrivateIsKnockingOnlyUserIDsAvatarURLAliasLocalPartReturnValue = .success("1")
clientProxy.createRoomNameTopicAccessTypeIsSpaceUserIDsAvatarURLAliasLocalPartReturnValue = .success("1")
let deferred = deferFulfillment(viewModel.actions) { action in
guard case .createdRoom(let roomProxy) = action, roomProxy.id == "1" else { return false }
return true
@@ -62,26 +67,24 @@ class CreateRoomScreenViewModelTests: XCTestCase {
try await deferred.fulfill()
// Then the room should be created and a topic should not be set.
XCTAssertTrue(clientProxy.createRoomNameTopicIsRoomPrivateIsKnockingOnlyUserIDsAvatarURLAliasLocalPartCalled)
XCTAssertEqual(clientProxy.createRoomNameTopicIsRoomPrivateIsKnockingOnlyUserIDsAvatarURLAliasLocalPartReceivedArguments?.name, "A")
XCTAssertNil(clientProxy.createRoomNameTopicIsRoomPrivateIsKnockingOnlyUserIDsAvatarURLAliasLocalPartReceivedArguments?.topic,
XCTAssertTrue(clientProxy.createRoomNameTopicAccessTypeIsSpaceUserIDsAvatarURLAliasLocalPartCalled)
XCTAssertEqual(clientProxy.createRoomNameTopicAccessTypeIsSpaceUserIDsAvatarURLAliasLocalPartReceivedArguments?.name, "A")
XCTAssertNil(clientProxy.createRoomNameTopicAccessTypeIsSpaceUserIDsAvatarURLAliasLocalPartReceivedArguments?.topic,
"The topic should be sent as nil when it is empty.")
}
func testCreateKnockingRoom() async {
context.send(viewAction: .updateRoomName("A"))
context.roomTopic = "B"
context.isRoomPrivate = false
context.selectedAccessType = .askToJoin
// When setting the room as private we always reset the knocking state to the default value of false
// so we need to wait a main actor cycle to ensure the view state is updated
await Task.yield()
context.isKnockingOnly = true
XCTAssertTrue(context.viewState.canCreateRoom)
let expectation = expectation(description: "Wait for the room to be created")
clientProxy.createRoomNameTopicIsRoomPrivateIsKnockingOnlyUserIDsAvatarURLAliasLocalPartClosure = { _, _, isPrivate, isKnockingOnly, _, _, localAliasPart in
XCTAssertTrue(isKnockingOnly)
XCTAssertFalse(isPrivate)
clientProxy.createRoomNameTopicAccessTypeIsSpaceUserIDsAvatarURLAliasLocalPartClosure = { _, _, accessType, _, _, _, localAliasPart in
XCTAssertEqual(accessType, .askToJoin)
XCTAssertEqual(localAliasPart, "a")
defer { expectation.fulfill() }
return .success("")
@@ -93,7 +96,7 @@ class CreateRoomScreenViewModelTests: XCTestCase {
func testCreatePublicRoomFailsForInvalidAlias() async throws {
context.send(viewAction: .updateRoomName("A"))
context.roomTopic = "B"
context.isRoomPrivate = false
context.selectedAccessType = .public
// When setting the room as private we always reset the alias
// so we need to wait a main actor cycle to ensure the view state is updated
await Task.yield()
@@ -109,14 +112,14 @@ class CreateRoomScreenViewModelTests: XCTestCase {
// blocked it
context.send(viewAction: .createRoom)
await Task.yield()
XCTAssertFalse(clientProxy.createRoomNameTopicIsRoomPrivateIsKnockingOnlyUserIDsAvatarURLAliasLocalPartCalled)
XCTAssertFalse(clientProxy.createRoomNameTopicAccessTypeIsSpaceUserIDsAvatarURLAliasLocalPartCalled)
}
func testCreatePublicRoomFailsForExistingAlias() async throws {
clientProxy.isAliasAvailableReturnValue = .success(false)
context.send(viewAction: .updateRoomName("A"))
context.roomTopic = "B"
context.isRoomPrivate = false
context.selectedAccessType = .public
// When setting the room as private we always reset the alias
// so we need to wait a main actor cycle to ensure the view state is updated
await Task.yield()
@@ -140,27 +143,11 @@ class CreateRoomScreenViewModelTests: XCTestCase {
context.send(viewAction: .createRoom)
await fulfillment(of: [expectation])
XCTAssertEqual(clientProxy.isAliasAvailableCallsCount, 2)
XCTAssertFalse(clientProxy.createRoomNameTopicIsRoomPrivateIsKnockingOnlyUserIDsAvatarURLAliasLocalPartCalled)
}
func testCreatePrivateRoomCantHaveKnockRule() async {
context.send(viewAction: .updateRoomName("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.createRoomNameTopicIsRoomPrivateIsKnockingOnlyUserIDsAvatarURLAliasLocalPartClosure = { _, _, isPrivate, isKnockingOnly, _, _, _ in
XCTAssertFalse(isKnockingOnly)
XCTAssertTrue(isPrivate)
expectation.fulfill()
return .success("")
}
await fulfillment(of: [expectation])
XCTAssertFalse(clientProxy.createRoomNameTopicAccessTypeIsSpaceUserIDsAvatarURLAliasLocalPartCalled)
}
func testNameAndAddressSync() async {
context.isRoomPrivate = true
context.selectedAccessType = .private
await Task.yield()
context.send(viewAction: .updateRoomName("abc"))
XCTAssertEqual(context.viewState.aliasLocalPart, "abc")