mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-02 12:07:55 +00:00
Implement Knock Logic (#3573)
* WIP RequestToJoin struct * implemented the logic to display the cells * knock request banner accept flow * mark all knocks as seen implemented * details logic * implemented accept, decline and ban in the list * added a loader and modified the stacked view of the banner * pr suggestions * updated naming and loading strings * added the initial loading state improved code and the tests * updated a string that has changed * code improvement * tests for the room screen view model * room details tests and improved the knock requests tests for the room screen * knock requests list tests * added error state alerts with retry * struct has been renamed on the sdk so I renamed it also on the app side * update SDK
This commit is contained in:
@@ -239,4 +239,116 @@ class RoomScreenViewModelTests: XCTestCase {
|
||||
// Then the call button should remain visible shown.
|
||||
XCTAssertTrue(viewModel.state.shouldShowCallButton)
|
||||
}
|
||||
|
||||
// MARK: - Knock Requests
|
||||
|
||||
func testKnockRequestBanner() async throws {
|
||||
ServiceLocator.shared.settings.knockingEnabled = true
|
||||
let roomProxyMock = JoinedRoomProxyMock(.init(knockRequestsState: .loaded([KnockRequestProxyMock(.init(eventID: "1", userID: "@alice:matrix.org", displayName: "Alice", reason: "Hello World!")),
|
||||
// This one should be filtered
|
||||
KnockRequestProxyMock(.init(eventID: "2", userID: "@bob:matrix.org", isSeen: true))]),
|
||||
joinRule: .knock))
|
||||
let viewModel = RoomScreenViewModel(clientProxy: ClientProxyMock(),
|
||||
roomProxy: roomProxyMock,
|
||||
initialSelectedPinnedEventID: nil,
|
||||
mediaProvider: MediaProviderMock(configuration: .init()),
|
||||
ongoingCallRoomIDPublisher: .init(.init(nil)),
|
||||
appMediator: AppMediatorMock.default,
|
||||
appSettings: ServiceLocator.shared.settings,
|
||||
analyticsService: ServiceLocator.shared.analytics,
|
||||
userIndicatorController: ServiceLocator.shared.userIndicatorController)
|
||||
self.viewModel = viewModel
|
||||
|
||||
var deferred = deferFulfillment(viewModel.context.$viewState) { state in
|
||||
state.shouldSeeKnockRequests &&
|
||||
state.unseenKnockRequests == [.init(displayName: "Alice", avatarURL: nil, userID: "@alice:matrix.org", reason: "Hello World!", eventID: "1")]
|
||||
}
|
||||
try await deferred.fulfill()
|
||||
|
||||
let deferredAction = deferFulfillment(viewModel.actions) { $0 == .displayKnockRequests }
|
||||
viewModel.context.send(viewAction: .viewKnockRequests)
|
||||
try await deferredAction.fulfill()
|
||||
|
||||
deferred = deferFulfillment(viewModel.context.$viewState) { state in
|
||||
state.handledEventIDs == ["1"] &&
|
||||
!state.shouldSeeKnockRequests
|
||||
}
|
||||
viewModel.context.send(viewAction: .acceptKnock(eventID: "1"))
|
||||
try await deferred.fulfill()
|
||||
}
|
||||
|
||||
func testKnockRequestBannerMarkAsSeen() async throws {
|
||||
ServiceLocator.shared.settings.knockingEnabled = true
|
||||
let roomProxyMock = JoinedRoomProxyMock(.init(knockRequestsState: .loaded([KnockRequestProxyMock(.init(eventID: "1", userID: "@alice:matrix.org", displayName: "Alice", reason: "Hello World!")),
|
||||
// This one should be filtered
|
||||
KnockRequestProxyMock(.init(eventID: "2", userID: "@bob:matrix.org"))]),
|
||||
joinRule: .knock))
|
||||
let viewModel = RoomScreenViewModel(clientProxy: ClientProxyMock(),
|
||||
roomProxy: roomProxyMock,
|
||||
initialSelectedPinnedEventID: nil,
|
||||
mediaProvider: MediaProviderMock(configuration: .init()),
|
||||
ongoingCallRoomIDPublisher: .init(.init(nil)),
|
||||
appMediator: AppMediatorMock.default,
|
||||
appSettings: ServiceLocator.shared.settings,
|
||||
analyticsService: ServiceLocator.shared.analytics,
|
||||
userIndicatorController: ServiceLocator.shared.userIndicatorController)
|
||||
self.viewModel = viewModel
|
||||
|
||||
var deferred = deferFulfillment(viewModel.context.$viewState) { state in
|
||||
state.shouldSeeKnockRequests &&
|
||||
state.unseenKnockRequests == [.init(displayName: "Alice", avatarURL: nil, userID: "@alice:matrix.org", reason: "Hello World!", eventID: "1"),
|
||||
.init(displayName: nil, avatarURL: nil, userID: "@bob:matrix.org", reason: nil, eventID: "2")]
|
||||
}
|
||||
try await deferred.fulfill()
|
||||
|
||||
deferred = deferFulfillment(viewModel.context.$viewState) { state in
|
||||
state.handledEventIDs == ["1", "2"] &&
|
||||
!state.shouldSeeKnockRequests
|
||||
}
|
||||
viewModel.context.send(viewAction: .dismissKnockRequests)
|
||||
try await deferred.fulfill()
|
||||
}
|
||||
|
||||
func testLoadingKnockRequests() async throws {
|
||||
ServiceLocator.shared.settings.knockingEnabled = true
|
||||
let roomProxyMock = JoinedRoomProxyMock(.init(knockRequestsState: .loading,
|
||||
joinRule: .knock))
|
||||
let viewModel = RoomScreenViewModel(clientProxy: ClientProxyMock(),
|
||||
roomProxy: roomProxyMock,
|
||||
initialSelectedPinnedEventID: nil,
|
||||
mediaProvider: MediaProviderMock(configuration: .init()),
|
||||
ongoingCallRoomIDPublisher: .init(.init(nil)),
|
||||
appMediator: AppMediatorMock.default,
|
||||
appSettings: ServiceLocator.shared.settings,
|
||||
analyticsService: ServiceLocator.shared.analytics,
|
||||
userIndicatorController: ServiceLocator.shared.userIndicatorController)
|
||||
self.viewModel = viewModel
|
||||
|
||||
// Loading state just does not appear at all
|
||||
let deferred = deferFulfillment(viewModel.context.$viewState) { !$0.shouldSeeKnockRequests }
|
||||
try await deferred.fulfill()
|
||||
}
|
||||
|
||||
func testKnockRequestsBannerDoesNotAppearIfUserHasNoPermission() async throws {
|
||||
ServiceLocator.shared.settings.knockingEnabled = true
|
||||
let roomProxyMock = JoinedRoomProxyMock(.init(knockRequestsState: .loaded([KnockRequestProxyMock(.init(eventID: "1", userID: "@alice:matrix.org", displayName: "Alice", reason: "Hello World!"))]),
|
||||
canUserInvite: false,
|
||||
joinRule: .knock))
|
||||
let viewModel = RoomScreenViewModel(clientProxy: ClientProxyMock(),
|
||||
roomProxy: roomProxyMock,
|
||||
initialSelectedPinnedEventID: nil,
|
||||
mediaProvider: MediaProviderMock(configuration: .init()),
|
||||
ongoingCallRoomIDPublisher: .init(.init(nil)),
|
||||
appMediator: AppMediatorMock.default,
|
||||
appSettings: ServiceLocator.shared.settings,
|
||||
analyticsService: ServiceLocator.shared.analytics,
|
||||
userIndicatorController: ServiceLocator.shared.userIndicatorController)
|
||||
self.viewModel = viewModel
|
||||
|
||||
var deferred = deferFulfillment(viewModel.context.$viewState) { state in
|
||||
state.unseenKnockRequests == [.init(displayName: "Alice", avatarURL: nil, userID: "@alice:matrix.org", reason: "Hello World!", eventID: "1")] &&
|
||||
!state.shouldSeeKnockRequests
|
||||
}
|
||||
try await deferred.fulfill()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user