Add support for joining rooms from a space. (#4501)

* Add support for joining rooms from a space.

Doesn't yet handle the Join button 🤔

* Handle the join button for both rooms and spaces.

Also refactor more instances of spaceRoom to spaceRoomProxy.
This commit is contained in:
Doug
2025-09-11 16:41:19 +01:00
committed by GitHub
parent 880f2060f4
commit c2ac60f1e6
30 changed files with 304 additions and 34 deletions
@@ -15,6 +15,7 @@ import MatrixRustSDK
class SpaceScreenViewModelTests: XCTestCase {
var spaceRoomListProxy: SpaceRoomListProxyMock!
let mockSpaceRooms = [SpaceRoomProxyProtocol].mockSpaceList
var clientProxy: ClientProxyMock!
var paginationStateSubject: CurrentValueSubject<SpaceRoomListPaginationState, Never> = .init(.idle(endReached: true))
var viewModel: SpaceScreenViewModelProtocol!
@@ -92,7 +93,7 @@ class SpaceScreenViewModelTests: XCTestCase {
func testSelectingSpace() async throws {
setupViewModel()
let selectedSpace = mockSpaceRooms[0]
let selectedSpace = try XCTUnwrap(mockSpaceRooms.first { $0.isSpace }, "There should be a space to select.")
let deferred = deferFulfillment(viewModel.actionsPublisher) { _ in true }
viewModel.context.send(viewAction: .spaceAction(.select(selectedSpace)))
let action = try await deferred.fulfill()
@@ -105,6 +106,76 @@ class SpaceScreenViewModelTests: XCTestCase {
}
}
func testSelectingRoom() async throws {
setupViewModel()
let selectedRoom = try XCTUnwrap(mockSpaceRooms.first { !$0.isSpace }, "There should be a room to select.")
let deferred = deferFulfillment(viewModel.actionsPublisher) { _ in true }
viewModel.context.send(viewAction: .spaceAction(.select(selectedRoom)))
let action = try await deferred.fulfill()
switch action {
case .selectRoom(let roomID) where roomID == selectedRoom.id:
break
default:
XCTFail("The action should select the room.")
}
}
func testJoiningSpace() async throws {
setupViewModel()
let selectedSpace = try XCTUnwrap(mockSpaceRooms.first { $0.isSpace }, "There should be a space to select.")
let expectation = XCTestExpectation(description: "Join room")
clientProxy.joinRoomViaClosure = { _, _ in
expectation.fulfill()
return .success(())
}
let deferred = deferFulfillment(viewModel.actionsPublisher) { _ in true }
let deferredState = deferFulfillment(viewModel.context.observe(\.viewState.joiningRoomIDs), transitionValues: [[selectedSpace.id], []])
viewModel.context.send(viewAction: .spaceAction(.join(selectedSpace)))
await fulfillment(of: [expectation])
try await deferredState.fulfill()
let action = try await deferred.fulfill()
switch action {
case .selectSpace(let spaceRoomListProxy) where spaceRoomListProxy.spaceRoomProxy.id == selectedSpace.id:
break
default:
XCTFail("The join should finish by selecting the space.")
}
}
func testJoiningRoom() async throws {
setupViewModel()
let selectedRoom = try XCTUnwrap(mockSpaceRooms.first { !$0.isSpace }, "There should be a room to select.")
let expectation = XCTestExpectation(description: "Join room")
clientProxy.joinRoomViaClosure = { _, _ in
expectation.fulfill()
return .success(())
}
let deferred = deferFulfillment(viewModel.actionsPublisher) { _ in true }
let deferredState = deferFulfillment(viewModel.context.observe(\.viewState.joiningRoomIDs), transitionValues: [[selectedRoom.id], []])
viewModel.context.send(viewAction: .spaceAction(.join(selectedRoom)))
await fulfillment(of: [expectation])
try await deferredState.fulfill()
let action = try await deferred.fulfill()
switch action {
case .selectRoom(let roomID) where roomID == selectedRoom.id:
break
default:
XCTFail("The join should finish by selecting the room.")
}
}
// MARK: - Helpers
private func setupViewModel(paginationResponses: [[SpaceRoomProxyProtocol]] = []) {
@@ -115,10 +186,12 @@ class SpaceScreenViewModelTests: XCTestCase {
let spaceServiceProxy = SpaceServiceProxyMock(.init())
spaceServiceProxy.spaceRoomListForClosure = { .success(SpaceRoomListProxyMock(.init(spaceRoomProxy: $0))) }
clientProxy = ClientProxyMock(.init())
viewModel = SpaceScreenViewModel(spaceRoomListProxy: spaceRoomListProxy,
spaceServiceProxy: spaceServiceProxy,
selectedSpaceRoomPublisher: .init(nil),
mediaProvider: MediaProviderMock(configuration: .init()),
userSession: UserSessionMock(.init(clientProxy: clientProxy)),
userIndicatorController: UserIndicatorControllerMock())
}
}