Beam/ElementX/Sources/Mocks/JoinedRoomProxyMock.swift

190 lines
8.5 KiB
Swift

//
// Copyright 2023, 2024 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.
//
import Combine
import Foundation
import MatrixRustSDK
enum RoomProxyMockError: Error {
case generic
}
@MainActor
struct JoinedRoomProxyMockConfiguration {
var id = UUID().uuidString
var name: String?
var topic: String?
var avatarURL: URL?
var isDirect = false
var isSpace = false
var isPublic = false
var isEncrypted = true
var hasOngoingCall = true
var canonicalAlias: String?
var alternativeAliases: [String] = []
var pinnedEventIDs: Set<String> = []
var timelineStartReached = false
var members: [RoomMemberProxyMock] = .allMembers
var heroes: [RoomMemberProxyMock] = []
var knockRequestsState: KnockRequestsState = .loaded([])
var ownUserID = RoomMemberProxyMock.mockMe.userID
var inviter: RoomMemberProxyProtocol?
var canUserInvite = true
var canUserTriggerRoomNotification = false
var canUserJoinCall = true
var canUserPin = true
var shouldUseAutoUpdatingTimeline = false
var joinRule: JoinRule?
var isVisibleInPublicDirectory = false
}
extension JoinedRoomProxyMock {
@MainActor
convenience init(_ configuration: JoinedRoomProxyMockConfiguration) {
self.init()
id = configuration.id
isEncrypted = configuration.isEncrypted
timeline = TimelineProxyMock(.init(isAutoUpdating: configuration.shouldUseAutoUpdatingTimeline,
timelineStartReached: configuration.timelineStartReached))
ownUserID = configuration.ownUserID
infoPublisher = CurrentValueSubject(.init(roomInfo: .init(configuration))).asCurrentValuePublisher()
membersPublisher = CurrentValueSubject(configuration.members).asCurrentValuePublisher()
knockRequestsStatePublisher = CurrentValueSubject(configuration.knockRequestsState).asCurrentValuePublisher()
typingMembersPublisher = CurrentValueSubject([]).asCurrentValuePublisher()
identityStatusChangesPublisher = CurrentValueSubject([]).asCurrentValuePublisher()
updateMembersClosure = { }
setNameClosure = { _ in .success(()) }
setTopicClosure = { _ in .success(()) }
getMemberUserIDClosure = { [weak self] userID in
guard let member = self?.membersPublisher.value.first(where: { $0.userID == userID }) else {
return .failure(.sdkError(RoomProxyMockError.generic))
}
return .success(member)
}
ignoreDeviceTrustAndResendDevicesSendHandleReturnValue = .success(())
withdrawVerificationAndResendUserIDsSendHandleReturnValue = .success(())
flagAsUnreadReturnValue = .success(())
markAsReadReceiptTypeReturnValue = .success(())
flagAsFavouriteReturnValue = .success(())
powerLevelsReturnValue = .success(.mock)
applyPowerLevelChangesReturnValue = .success(())
resetPowerLevelsReturnValue = .success(.mock)
suggestedRoleForClosure = { [weak self] userID in
guard case .success(let member) = await self?.getMember(userID: userID) else {
return .failure(.sdkError(RoomProxyMockError.generic))
}
return .success(member.role)
}
updatePowerLevelsForUsersReturnValue = .success(())
canUserUserIDSendStateEventClosure = { [weak self] userID, _ in
.success(self?.membersPublisher.value.first { $0.userID == userID }?.role ?? .user != .user)
}
canUserInviteUserIDReturnValue = .success(configuration.canUserInvite)
canUserRedactOtherUserIDReturnValue = .success(false)
canUserRedactOwnUserIDReturnValue = .success(true)
canUserKickUserIDClosure = { [weak self] userID in
.success(self?.membersPublisher.value.first { $0.userID == userID }?.role ?? .user != .user)
}
canUserBanUserIDClosure = { [weak self] userID in
.success(self?.membersPublisher.value.first { $0.userID == userID }?.role ?? .user != .user)
}
canUserTriggerRoomNotificationUserIDReturnValue = .success(configuration.canUserTriggerRoomNotification)
canUserJoinCallUserIDReturnValue = .success(configuration.canUserJoinCall)
canUserPinOrUnpinUserIDReturnValue = .success(configuration.canUserPin)
kickUserReturnValue = .success(())
banUserReturnValue = .success(())
unbanUserReturnValue = .success(())
let widgetDriver = ElementCallWidgetDriverMock()
widgetDriver.underlyingMessagePublisher = .init()
widgetDriver.underlyingActions = PassthroughSubject().eraseToAnyPublisher()
guard let url = URL(string: "https://call.element.io/\(UUID().uuidString)#?appPrompt=false") else {
fatalError()
}
widgetDriver.startBaseURLClientIDColorSchemeReturnValue = .success(url)
elementCallWidgetDriverDeviceIDReturnValue = widgetDriver
sendCallNotificationIfNeededReturnValue = .success(())
matrixToPermalinkReturnValue = .success(.homeDirectory)
matrixToEventPermalinkReturnValue = .success(.homeDirectory)
loadDraftReturnValue = .success(nil)
clearDraftReturnValue = .success(())
sendTypingNotificationIsTypingReturnValue = .success(())
isVisibleInRoomDirectoryReturnValue = .success(configuration.isVisibleInPublicDirectory)
}
}
extension RoomInfo {
@MainActor init(_ configuration: JoinedRoomProxyMockConfiguration) {
self.init(id: configuration.id,
creator: nil,
displayName: configuration.name,
rawName: configuration.name,
topic: configuration.topic,
avatarUrl: configuration.avatarURL?.absoluteString,
isDirect: configuration.isDirect,
isPublic: configuration.isPublic,
isSpace: configuration.isSpace,
isTombstoned: false,
isFavourite: false,
canonicalAlias: configuration.canonicalAlias,
alternativeAliases: configuration.alternativeAliases,
membership: .joined,
inviter: configuration.inviter.map { RoomMember(userId: $0.userID,
displayName: $0.displayName,
avatarUrl: $0.avatarURL?.absoluteString,
membership: $0.membership,
isNameAmbiguous: false,
powerLevel: Int64($0.powerLevel),
normalizedPowerLevel: Int64($0.powerLevel),
isIgnored: $0.isIgnored,
suggestedRoleForPowerLevel: $0.role,
membershipChangeReason: $0.membershipChangeReason) },
heroes: configuration.heroes.map(RoomHero.init),
activeMembersCount: UInt64(configuration.members.filter { $0.membership == .join || $0.membership == .invite }.count),
invitedMembersCount: UInt64(configuration.members.filter { $0.membership == .invite }.count),
joinedMembersCount: UInt64(configuration.members.filter { $0.membership == .join }.count),
userPowerLevels: [:],
highlightCount: 0,
notificationCount: 0,
cachedUserDefinedNotificationMode: .allMessages,
hasRoomCall: configuration.hasOngoingCall,
activeRoomCallParticipants: [],
isMarkedUnread: false,
numUnreadMessages: 0,
numUnreadNotifications: 0,
numUnreadMentions: 0,
pinnedEventIds: Array(configuration.pinnedEventIDs),
joinRule: configuration.joinRule,
historyVisibility: .shared)
}
}
private extension RoomHero {
init(from memberProxy: RoomMemberProxyMock) {
self.init(userId: memberProxy.userID,
displayName: memberProxy.displayName,
avatarUrl: memberProxy.avatarURL?.absoluteString)
}
}