mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-02 21:33:26 +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:
@@ -23,7 +23,7 @@ class HomeScreenRoomTests: XCTestCase {
|
||||
hasOngoingCall: Bool) {
|
||||
roomSummary = RoomSummary(roomListItem: .init(noPointer: .init()),
|
||||
id: "Test room",
|
||||
joinRequestType: nil,
|
||||
knockRequestType: nil,
|
||||
name: "Test room",
|
||||
isDirect: false,
|
||||
avatarURL: nil,
|
||||
|
||||
@@ -18,6 +18,209 @@ class KnockRequestsListScreenViewModelTests: XCTestCase {
|
||||
}
|
||||
|
||||
override func setUpWithError() throws {
|
||||
viewModel = KnockRequestsListScreenViewModel(roomProxy: JoinedRoomProxyMock(.init()), mediaProvider: MediaProviderMock())
|
||||
AppSettings.resetAllSettings()
|
||||
}
|
||||
|
||||
func testLoadingState() async throws {
|
||||
let roomProxyMock = JoinedRoomProxyMock(.init(knockRequestsState: .loading, joinRule: .knock))
|
||||
viewModel = KnockRequestsListScreenViewModel(roomProxy: roomProxyMock,
|
||||
mediaProvider: MediaProviderMock(),
|
||||
userIndicatorController: UserIndicatorControllerMock())
|
||||
|
||||
let deferred = deferFulfillment(context.$viewState) { state in
|
||||
!state.shouldDisplayRequests &&
|
||||
state.isKnockableRoom &&
|
||||
state.canAccept &&
|
||||
!state.canBan &&
|
||||
!state.canDecline &&
|
||||
state.isLoading &&
|
||||
!state.shouldDisplayEmptyView
|
||||
}
|
||||
try await deferred.fulfill()
|
||||
}
|
||||
|
||||
func testEmptyState() async throws {
|
||||
let roomProxyMock = JoinedRoomProxyMock(.init(knockRequestsState: .loaded([]), joinRule: .knock))
|
||||
viewModel = KnockRequestsListScreenViewModel(roomProxy: roomProxyMock,
|
||||
mediaProvider: MediaProviderMock(),
|
||||
userIndicatorController: UserIndicatorControllerMock())
|
||||
|
||||
let deferred = deferFulfillment(context.$viewState) { state in
|
||||
!state.shouldDisplayRequests &&
|
||||
state.isKnockableRoom &&
|
||||
state.canAccept &&
|
||||
!state.canBan &&
|
||||
!state.canDecline &&
|
||||
!state.isLoading &&
|
||||
state.shouldDisplayEmptyView
|
||||
}
|
||||
try await deferred.fulfill()
|
||||
}
|
||||
|
||||
func testLoadedState() async throws {
|
||||
let roomProxyMock = JoinedRoomProxyMock(.init(members: [.mockAdmin],
|
||||
knockRequestsState: .loaded([KnockRequestProxyMock(.init(eventID: "1", userID: "@alice:matrix.org")),
|
||||
KnockRequestProxyMock(.init(eventID: "2", userID: "@bob:matrix.org")),
|
||||
KnockRequestProxyMock(.init(eventID: "3", userID: "@charlie:matrix.org")),
|
||||
KnockRequestProxyMock(.init(eventID: "4", userID: "@dan:matrix.org"))]),
|
||||
ownUserID: RoomMemberProxyMock.mockAdmin.userID,
|
||||
joinRule: .knock))
|
||||
viewModel = KnockRequestsListScreenViewModel(roomProxy: roomProxyMock,
|
||||
mediaProvider: MediaProviderMock(),
|
||||
userIndicatorController: UserIndicatorControllerMock())
|
||||
|
||||
var deferred = deferFulfillment(context.$viewState) { state in
|
||||
state.shouldDisplayRequests &&
|
||||
state.isKnockableRoom &&
|
||||
state.canAccept &&
|
||||
state.canBan &&
|
||||
state.canDecline &&
|
||||
!state.isLoading &&
|
||||
!state.shouldDisplayEmptyView &&
|
||||
state.displayedRequests.count == 4 &&
|
||||
state.handledEventIDs.isEmpty &&
|
||||
state.shouldDisplayAcceptAllButton
|
||||
}
|
||||
try await deferred.fulfill()
|
||||
|
||||
deferred = deferFulfillment(context.$viewState) { state in
|
||||
state.shouldDisplayRequests &&
|
||||
state.handledEventIDs == ["1"] &&
|
||||
!state.shouldDisplayEmptyView &&
|
||||
state.displayedRequests.count == 3 &&
|
||||
state.shouldDisplayAcceptAllButton
|
||||
}
|
||||
context.send(viewAction: .acceptRequest(eventID: "1"))
|
||||
try await deferred.fulfill()
|
||||
|
||||
deferred = deferFulfillment(context.$viewState) { state in
|
||||
state.bindings.alertInfo?.id == .declineRequest
|
||||
}
|
||||
context.send(viewAction: .declineRequest(eventID: "2"))
|
||||
try await deferred.fulfill()
|
||||
|
||||
guard let declineAlertInfo = context.alertInfo else {
|
||||
XCTFail("Can't be nil")
|
||||
return
|
||||
}
|
||||
deferred = deferFulfillment(context.$viewState) { state in
|
||||
state.shouldDisplayRequests &&
|
||||
state.handledEventIDs == ["1", "2"] &&
|
||||
!state.shouldDisplayEmptyView &&
|
||||
state.displayedRequests.count == 2 &&
|
||||
state.shouldDisplayAcceptAllButton
|
||||
}
|
||||
declineAlertInfo.primaryButton.action?()
|
||||
try await deferred.fulfill()
|
||||
|
||||
deferred = deferFulfillment(context.$viewState) { state in
|
||||
state.bindings.alertInfo?.id == .declineAndBan
|
||||
}
|
||||
context.send(viewAction: .ban(eventID: "3"))
|
||||
try await deferred.fulfill()
|
||||
|
||||
guard let banAlertInfo = context.alertInfo else {
|
||||
XCTFail("Can't be nil")
|
||||
return
|
||||
}
|
||||
deferred = deferFulfillment(context.$viewState) { state in
|
||||
state.shouldDisplayRequests &&
|
||||
state.handledEventIDs == ["1", "2", "3"] &&
|
||||
!state.shouldDisplayEmptyView &&
|
||||
state.displayedRequests.count == 1 &&
|
||||
!state.shouldDisplayAcceptAllButton
|
||||
}
|
||||
banAlertInfo.primaryButton.action?()
|
||||
try await deferred.fulfill()
|
||||
}
|
||||
|
||||
func testAcceptAll() async throws {
|
||||
let roomProxyMock = JoinedRoomProxyMock(.init(knockRequestsState: .loaded([KnockRequestProxyMock(.init(eventID: "1", userID: "@alice:matrix.org")),
|
||||
KnockRequestProxyMock(.init(eventID: "2", userID: "@bob:matrix.org")),
|
||||
KnockRequestProxyMock(.init(eventID: "3", userID: "@charlie:matrix.org")),
|
||||
KnockRequestProxyMock(.init(eventID: "4", userID: "@dan:matrix.org"))]),
|
||||
joinRule: .knock))
|
||||
viewModel = KnockRequestsListScreenViewModel(roomProxy: roomProxyMock,
|
||||
mediaProvider: MediaProviderMock(),
|
||||
userIndicatorController: UserIndicatorControllerMock())
|
||||
|
||||
var deferred = deferFulfillment(context.$viewState) { state in
|
||||
state.shouldDisplayRequests &&
|
||||
state.isKnockableRoom &&
|
||||
state.canAccept &&
|
||||
!state.canBan &&
|
||||
!state.canDecline &&
|
||||
!state.isLoading &&
|
||||
!state.shouldDisplayEmptyView &&
|
||||
state.displayedRequests.count == 4 &&
|
||||
state.handledEventIDs.isEmpty &&
|
||||
state.shouldDisplayAcceptAllButton
|
||||
}
|
||||
try await deferred.fulfill()
|
||||
|
||||
deferred = deferFulfillment(context.$viewState) { state in
|
||||
state.bindings.alertInfo?.id == .acceptAllRequests
|
||||
}
|
||||
context.send(viewAction: .acceptAllRequests)
|
||||
try await deferred.fulfill()
|
||||
|
||||
guard let alertInfo = context.alertInfo else {
|
||||
XCTFail("Can't be nil")
|
||||
return
|
||||
}
|
||||
|
||||
deferred = deferFulfillment(context.$viewState) { state in
|
||||
!state.shouldDisplayRequests &&
|
||||
state.handledEventIDs == ["1", "2", "3", "4"] &&
|
||||
!state.isLoading &&
|
||||
state.shouldDisplayEmptyView
|
||||
}
|
||||
alertInfo.primaryButton.action?()
|
||||
try await deferred.fulfill()
|
||||
}
|
||||
|
||||
func testLoadedStateBecomesEmptyIfTheJoinRuleIsNotKnocking() async throws {
|
||||
// If there is a sudden change in the rule, but the requests are still published, we want to hide all of them and show the empty view
|
||||
let roomProxyMock = JoinedRoomProxyMock(.init(members: [.mockAdmin],
|
||||
knockRequestsState: .loaded([KnockRequestProxyMock(.init(eventID: "1", userID: "@alice:matrix.org")),
|
||||
KnockRequestProxyMock(.init(eventID: "2", userID: "@bob:matrix.org")),
|
||||
KnockRequestProxyMock(.init(eventID: "3", userID: "@charlie:matrix.org")),
|
||||
KnockRequestProxyMock(.init(eventID: "4", userID: "@dan:matrix.org"))]),
|
||||
ownUserID: RoomMemberProxyMock.mockAdmin.userID,
|
||||
joinRule: .invite))
|
||||
viewModel = KnockRequestsListScreenViewModel(roomProxy: roomProxyMock,
|
||||
mediaProvider: MediaProviderMock(),
|
||||
userIndicatorController: UserIndicatorControllerMock())
|
||||
|
||||
let deferred = deferFulfillment(context.$viewState) { state in
|
||||
!state.shouldDisplayRequests &&
|
||||
state.shouldDisplayEmptyView &&
|
||||
!state.isLoading &&
|
||||
!state.isKnockableRoom
|
||||
}
|
||||
try await deferred.fulfill()
|
||||
}
|
||||
|
||||
func testLoadedStateBecomesEmptyIfPermissionsAreRemoved() async throws {
|
||||
// If there is a sudden change in permissions, and the user can't do any other action, we hide all the requests and shoe the empty view
|
||||
let roomProxyMock = JoinedRoomProxyMock(.init(knockRequestsState: .loaded([KnockRequestProxyMock(.init(eventID: "1", userID: "@alice:matrix.org")),
|
||||
KnockRequestProxyMock(.init(eventID: "2", userID: "@bob:matrix.org")),
|
||||
KnockRequestProxyMock(.init(eventID: "3", userID: "@charlie:matrix.org")),
|
||||
KnockRequestProxyMock(.init(eventID: "4", userID: "@dan:matrix.org"))]),
|
||||
canUserInvite: false,
|
||||
joinRule: .knock))
|
||||
viewModel = KnockRequestsListScreenViewModel(roomProxy: roomProxyMock,
|
||||
mediaProvider: MediaProviderMock(),
|
||||
userIndicatorController: UserIndicatorControllerMock())
|
||||
|
||||
let deferred = deferFulfillment(context.$viewState) { state in
|
||||
!state.shouldDisplayRequests &&
|
||||
state.shouldDisplayEmptyView &&
|
||||
!state.canAccept &&
|
||||
!state.canBan &&
|
||||
!state.canDecline &&
|
||||
!state.isLoading
|
||||
}
|
||||
try await deferred.fulfill()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ class LoggingTests: XCTestCase {
|
||||
let heroName = "Pseudonym"
|
||||
let roomSummary = RoomSummary(roomListItem: .init(noPointer: .init()),
|
||||
id: "myroomid",
|
||||
joinRequestType: nil,
|
||||
knockRequestType: nil,
|
||||
name: roomName,
|
||||
isDirect: true,
|
||||
avatarURL: nil,
|
||||
|
||||
@@ -21,6 +21,7 @@ class RoomDetailsScreenViewModelTests: XCTestCase {
|
||||
var cancellables = Set<AnyCancellable>()
|
||||
|
||||
override func setUp() {
|
||||
AppSettings.resetAllSettings()
|
||||
cancellables.removeAll()
|
||||
roomProxyMock = JoinedRoomProxyMock(.init(name: "Test"))
|
||||
notificationSettingsProxyMock = NotificationSettingsProxyMock(with: NotificationSettingsProxyMockConfiguration())
|
||||
@@ -33,8 +34,6 @@ class RoomDetailsScreenViewModelTests: XCTestCase {
|
||||
attributedStringBuilder: AttributedStringBuilder(mentionBuilder: MentionBuilder()),
|
||||
appMediator: AppMediatorMock.default,
|
||||
appSettings: ServiceLocator.shared.settings)
|
||||
|
||||
AppSettings.resetAllSettings()
|
||||
}
|
||||
|
||||
func testLeaveRoomTappedWhenPublic() async throws {
|
||||
@@ -672,4 +671,99 @@ class RoomDetailsScreenViewModelTests: XCTestCase {
|
||||
XCTFail("invalid state")
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Knock Requests
|
||||
|
||||
func testKnockRequestsCounter() async throws {
|
||||
ServiceLocator.shared.settings.knockingEnabled = true
|
||||
let mockedRequests: [KnockRequestProxyMock] = [.init(), .init()]
|
||||
roomProxyMock = JoinedRoomProxyMock(.init(name: "Test", isDirect: false, isPublic: false, knockRequestsState: .loaded(mockedRequests), joinRule: .knock))
|
||||
viewModel = RoomDetailsScreenViewModel(roomProxy: roomProxyMock,
|
||||
clientProxy: ClientProxyMock(.init()),
|
||||
mediaProvider: MediaProviderMock(configuration: .init()),
|
||||
analyticsService: ServiceLocator.shared.analytics,
|
||||
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
||||
notificationSettingsProxy: notificationSettingsProxyMock,
|
||||
attributedStringBuilder: AttributedStringBuilder(mentionBuilder: MentionBuilder()),
|
||||
appMediator: AppMediatorMock.default,
|
||||
appSettings: ServiceLocator.shared.settings)
|
||||
|
||||
let deferred = deferFulfillment(context.$viewState) { state in
|
||||
state.knockRequestsCount == 2 && state.canSeeKnockingRequests
|
||||
}
|
||||
try await deferred.fulfill()
|
||||
|
||||
let deferredAction = deferFulfillment(viewModel.actions) { $0 == .displayKnockingRequests }
|
||||
context.send(viewAction: .processTapRequestsToJoin)
|
||||
try await deferredAction.fulfill()
|
||||
}
|
||||
|
||||
func testKnockRequestsCounterIsLoading() async throws {
|
||||
ServiceLocator.shared.settings.knockingEnabled = true
|
||||
roomProxyMock = JoinedRoomProxyMock(.init(name: "Test", isDirect: false, isPublic: false, knockRequestsState: .loading, joinRule: .knock))
|
||||
viewModel = RoomDetailsScreenViewModel(roomProxy: roomProxyMock,
|
||||
clientProxy: ClientProxyMock(.init()),
|
||||
mediaProvider: MediaProviderMock(configuration: .init()),
|
||||
analyticsService: ServiceLocator.shared.analytics,
|
||||
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
||||
notificationSettingsProxy: notificationSettingsProxyMock,
|
||||
attributedStringBuilder: AttributedStringBuilder(mentionBuilder: MentionBuilder()),
|
||||
appMediator: AppMediatorMock.default,
|
||||
appSettings: ServiceLocator.shared.settings)
|
||||
|
||||
let deferred = deferFulfillment(context.$viewState) { state in
|
||||
state.knockRequestsCount == 0 && state.canSeeKnockingRequests
|
||||
}
|
||||
|
||||
try await deferred.fulfill()
|
||||
}
|
||||
|
||||
func testKnockRequestsCounterIsNotShownIfNoPermissions() async throws {
|
||||
ServiceLocator.shared.settings.knockingEnabled = true
|
||||
let mockedRequests: [KnockRequestProxyMock] = [.init(), .init()]
|
||||
roomProxyMock = JoinedRoomProxyMock(.init(name: "Test", isDirect: false, isPublic: false, knockRequestsState: .loaded(mockedRequests), canUserInvite: false, joinRule: .knock))
|
||||
viewModel = RoomDetailsScreenViewModel(roomProxy: roomProxyMock,
|
||||
clientProxy: ClientProxyMock(.init()),
|
||||
mediaProvider: MediaProviderMock(configuration: .init()),
|
||||
analyticsService: ServiceLocator.shared.analytics,
|
||||
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
||||
notificationSettingsProxy: notificationSettingsProxyMock,
|
||||
attributedStringBuilder: AttributedStringBuilder(mentionBuilder: MentionBuilder()),
|
||||
appMediator: AppMediatorMock.default,
|
||||
appSettings: ServiceLocator.shared.settings)
|
||||
|
||||
let deferred = deferFulfillment(context.$viewState) { state in
|
||||
state.knockRequestsCount == 2 &&
|
||||
state.dmRecipient == nil &&
|
||||
!state.canSeeKnockingRequests &&
|
||||
!state.canInviteUsers
|
||||
}
|
||||
|
||||
try await deferred.fulfill()
|
||||
}
|
||||
|
||||
func testKnockRequestsCounterIsNotShownIfDM() async throws {
|
||||
ServiceLocator.shared.settings.knockingEnabled = true
|
||||
let mockedRequests: [KnockRequestProxyMock] = [.init(), .init()]
|
||||
let mockedMembers: [RoomMemberProxyMock] = [.mockMe, .mockAlice]
|
||||
roomProxyMock = JoinedRoomProxyMock(.init(name: "Test", isDirect: true, isPublic: false, members: mockedMembers, knockRequestsState: .loaded(mockedRequests), joinRule: .knock))
|
||||
viewModel = RoomDetailsScreenViewModel(roomProxy: roomProxyMock,
|
||||
clientProxy: ClientProxyMock(.init()),
|
||||
mediaProvider: MediaProviderMock(configuration: .init()),
|
||||
analyticsService: ServiceLocator.shared.analytics,
|
||||
userIndicatorController: ServiceLocator.shared.userIndicatorController,
|
||||
notificationSettingsProxy: notificationSettingsProxyMock,
|
||||
attributedStringBuilder: AttributedStringBuilder(mentionBuilder: MentionBuilder()),
|
||||
appMediator: AppMediatorMock.default,
|
||||
appSettings: ServiceLocator.shared.settings)
|
||||
|
||||
let deferred = deferFulfillment(context.$viewState) { state in
|
||||
state.knockRequestsCount == 2 &&
|
||||
!state.canSeeKnockingRequests &&
|
||||
state.dmRecipient != nil &&
|
||||
state.canInviteUsers
|
||||
}
|
||||
|
||||
try await deferred.fulfill()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ class RoomSummaryTests: XCTestCase {
|
||||
func makeSummary(isDirect: Bool, hasRoomAvatar: Bool) -> RoomSummary {
|
||||
RoomSummary(roomListItem: .init(noPointer: .init()),
|
||||
id: roomDetails.id,
|
||||
joinRequestType: nil,
|
||||
knockRequestType: nil,
|
||||
name: roomDetails.name,
|
||||
isDirect: isDirect,
|
||||
avatarURL: hasRoomAvatar ? roomDetails.avatarURL : nil,
|
||||
|
||||
Reference in New Issue
Block a user