mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-10-31 16:24:11 +00:00
1a72a4e17b
* Extract a shared helper for loading a media preview The four screens that show a fullscreen avatar each had their own copy of the same load-and-wrap logic. Move it to MediaPreviewItem.load, with the mime type as a parameter defaulting to JPEG, and leave each screen's loading indicator where it is. Signed-off-by: Daniel Anderson <daniel.anderson@toptal.com> * Only dismiss a QuickLook preview that is still presented UIKit forwards dismiss() up the presentation chain when the receiver has nothing presented, so dismissing the avatar view was dismissing the profile details sheet also. Signed-off-by: Daniel Anderson <daniel.anderson@toptal.com> * Allow tapping the avatar in the room member bottom sheet to view it fullscreen Signed-off-by: Daniel Anderson <daniel.anderson@toptal.com> --------- Signed-off-by: Daniel Anderson <daniel.anderson@toptal.com>
119 lines
6.1 KiB
Swift
119 lines
6.1 KiB
Swift
//
|
|
// Copyright 2025 Element Creations Ltd.
|
|
// Copyright 2025 New Vector Ltd.
|
|
//
|
|
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
|
// Please see LICENSE files in the repository root for full details.
|
|
//
|
|
|
|
@testable import ElementX
|
|
import Testing
|
|
|
|
@MainActor
|
|
struct ManageRoomMemberSheetViewModelTests {
|
|
private var viewModel: ManageRoomMemberSheetViewModel!
|
|
private var context: ManageRoomMemberSheetViewModel.Context! {
|
|
viewModel.context
|
|
}
|
|
|
|
@Test
|
|
mutating func kick() async throws {
|
|
let testReason = "Kick Test"
|
|
let roomProxy = JoinedRoomProxyMock(.init(members: [RoomMemberProxyMock.mockAdmin, RoomMemberProxyMock.mockAlice]))
|
|
var kickCalled = false
|
|
roomProxy.kickUserReasonClosure = { userID, reason in
|
|
kickCalled = true
|
|
#expect(userID == RoomMemberProxyMock.mockAlice.userID)
|
|
#expect(reason == testReason)
|
|
return .success(())
|
|
}
|
|
|
|
viewModel = ManageRoomMemberSheetViewModel(memberDetails: .memberDetails(roomMember: .init(withProxy: RoomMemberProxyMock.mockAlice)),
|
|
permissions: .init(canKick: true, canBan: true, ownPowerLevel: RoomMemberProxyMock.mockAdmin.powerLevel),
|
|
roomProxy: roomProxy,
|
|
userIndicatorController: UserIndicatorControllerMock(),
|
|
analyticsService: AnalyticsServiceMock(.init()),
|
|
mediaProvider: MediaProviderMock(.init()))
|
|
|
|
let deferred = deferFulfillment(context.observe(\.viewState.bindings.alertInfo)) { $0 != nil }
|
|
let deferredAction = deferFulfillment(viewModel.actions) { action in
|
|
action == .dismiss(shouldShowDetails: false)
|
|
}
|
|
context.send(viewAction: .kick)
|
|
try await deferred.fulfill()
|
|
|
|
context.alertInfo?.textFields?[0].text.wrappedValue = testReason
|
|
context.alertInfo?.secondaryButton?.action?()
|
|
try await deferredAction.fulfill()
|
|
#expect(kickCalled)
|
|
}
|
|
|
|
@Test
|
|
mutating func ban() async throws {
|
|
let testReason = "Ban Test"
|
|
let roomProxy = JoinedRoomProxyMock(.init(members: [RoomMemberProxyMock.mockAdmin, RoomMemberProxyMock.mockAlice]))
|
|
var banCalled = false
|
|
roomProxy.banUserReasonClosure = { userID, reason in
|
|
banCalled = true
|
|
#expect(userID == RoomMemberProxyMock.mockAlice.userID)
|
|
#expect(reason == testReason)
|
|
return .success(())
|
|
}
|
|
|
|
viewModel = ManageRoomMemberSheetViewModel(memberDetails: .memberDetails(roomMember: .init(withProxy: RoomMemberProxyMock.mockAlice)),
|
|
permissions: .init(canKick: true, canBan: true, ownPowerLevel: RoomMemberProxyMock.mockAdmin.powerLevel),
|
|
roomProxy: roomProxy,
|
|
userIndicatorController: UserIndicatorControllerMock(),
|
|
analyticsService: AnalyticsServiceMock(.init()),
|
|
mediaProvider: MediaProviderMock(.init()))
|
|
|
|
let deferred = deferFulfillment(context.observe(\.viewState.bindings.alertInfo)) { $0 != nil }
|
|
context.send(viewAction: .ban)
|
|
try await deferred.fulfill()
|
|
|
|
let deferredAction = deferFulfillment(viewModel.actions) { action in
|
|
action == .dismiss(shouldShowDetails: false)
|
|
}
|
|
context.alertInfo?.textFields?[0].text.wrappedValue = testReason
|
|
context.alertInfo?.secondaryButton?.action?()
|
|
try await deferredAction.fulfill()
|
|
#expect(banCalled)
|
|
}
|
|
|
|
@Test
|
|
mutating func displayDetails() async throws {
|
|
let roomProxy = JoinedRoomProxyMock(.init(members: [RoomMemberProxyMock.mockAdmin, RoomMemberProxyMock.mockAlice]))
|
|
viewModel = ManageRoomMemberSheetViewModel(memberDetails: .memberDetails(roomMember: .init(withProxy: RoomMemberProxyMock.mockAlice)),
|
|
permissions: .init(canKick: true, canBan: true, ownPowerLevel: RoomMemberProxyMock.mockAdmin.powerLevel),
|
|
roomProxy: roomProxy,
|
|
userIndicatorController: UserIndicatorControllerMock(),
|
|
analyticsService: AnalyticsServiceMock(.init()),
|
|
mediaProvider: MediaProviderMock(.init()))
|
|
|
|
let deferredAction = deferFulfillment(viewModel.actions) { action in
|
|
action == .dismiss(shouldShowDetails: true)
|
|
}
|
|
context.send(viewAction: .displayDetails)
|
|
try await deferredAction.fulfill()
|
|
#expect(context.alertInfo == nil)
|
|
}
|
|
|
|
@Test
|
|
mutating func displayAvatar() async throws {
|
|
let member = RoomMemberDetails(withProxy: RoomMemberProxyMock.mockDan)
|
|
viewModel = ManageRoomMemberSheetViewModel(memberDetails: .memberDetails(roomMember: member),
|
|
permissions: .init(canKick: true, canBan: true, ownPowerLevel: RoomMemberProxyMock.mockAdmin.powerLevel),
|
|
roomProxy: JoinedRoomProxyMock(.init()),
|
|
userIndicatorController: UserIndicatorControllerMock(),
|
|
analyticsService: AnalyticsServiceMock(.init()),
|
|
mediaProvider: MediaProviderMock(.init()))
|
|
|
|
let avatarURL = try #require(member.avatarURL)
|
|
let deferred = deferFulfillment(context.observe(\.viewState.bindings.mediaPreviewItem)) { $0 != nil }
|
|
context.send(viewAction: .displayAvatar(avatarURL))
|
|
try await deferred.fulfill()
|
|
|
|
#expect(context.mediaPreviewItem?.previewItemTitle == member.name)
|
|
}
|
|
}
|