AzureCommunicationUI/AzureCommunicationUIDemoApp/Sources/Mockings/CallingSDKEventsHandlerMocking.swift (255 lines of code) (raw):
//
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
//
import Foundation
#if DEBUG
@testable import AzureCommunicationUICalling
@testable import AzureCommunicationCommon
class CallingSDKEventsHandlerMocking: CallingSDKEventsHandler {
enum Constants {
static let nanosecondsInSecond: UInt64 = 1_000_000_000
}
private var remoteParticipantsMocking: [ParticipantInfoModel] = []
func joinCall() {
Task { @MainActor [weak self] in
try await Task<Never, Never>.sleep(nanoseconds: 2 * Constants.nanosecondsInSecond)
self?.callInfoSubject.send(CallInfoModel(status: .connected,
internalError: nil,
callEndReasonCode: nil,
callEndReasonSubCode: nil))
}
}
func joinLobby() {
Task { @MainActor [weak self] in
try await Task<Never, Never>.sleep(nanoseconds: 2 * Constants.nanosecondsInSecond)
self?.callInfoSubject.send(CallInfoModel(status: .inLobby,
internalError: nil,
callEndReasonCode: nil,
callEndReasonSubCode: nil))
}
}
func endCall() {
Task { @MainActor [weak self] in
self?.callInfoSubject.send(CallInfoModel(status: .disconnected,
internalError: nil,
callEndReasonCode: nil,
callEndReasonSubCode: nil))
}
}
func holdCall() {
Task { @MainActor [weak self] in
self?.callInfoSubject.send(CallInfoModel(status: .localHold,
internalError: nil,
callEndReasonCode: nil,
callEndReasonSubCode: nil))
}
}
func resumeCall() {
Task { @MainActor [weak self] in
self?.callInfoSubject.send(CallInfoModel(status: .connected,
internalError: nil,
callEndReasonCode: nil,
callEndReasonSubCode: nil))
}
}
func muteLocalMic() {
Task { @MainActor [weak self] in
self?.isLocalUserMutedSubject.send(true)
}
}
func unmuteLocalMic() {
Task { @MainActor [weak self] in
self?.isLocalUserMutedSubject.send(false)
}
}
func transcriptionOn() {
Task { @MainActor [weak self] in
self?.isTranscriptionActiveSubject.send(true)
}
}
func transcriptionOff() {
Task { @MainActor [weak self] in
self?.isTranscriptionActiveSubject.send(false)
}
}
func recordingOn() {
Task { @MainActor [weak self] in
self?.isRecordingActiveSubject.send(true)
}
}
func recordingOff() {
Task { @MainActor [weak self] in
self?.isRecordingActiveSubject.send(false)
}
}
func addParticipant(status: ParticipantStatus = .connected) {
Task { @MainActor [weak self] in
guard let self else {
return
}
let participantNameIdentifier = "RM-\(self.remoteParticipantsMocking.count + 1)"
let newParticipant = ParticipantInfoModel(displayName: participantNameIdentifier,
isSpeaking: false,
isTypingRtt: false,
isMuted: true,
isRemoteUser: true,
userIdentifier: participantNameIdentifier,
status: status,
screenShareVideoStreamModel: nil,
cameraVideoStreamModel: nil)
self.remoteParticipantsMocking.append(newParticipant)
self.participantsInfoListSubject.send(self.remoteParticipantsMocking)
}
}
func removeParticipant() {
Task { @MainActor [weak self] in
guard let self,
!self.remoteParticipantsMocking.isEmpty else {
return
}
self.remoteParticipantsMocking.removeLast()
self.participantsInfoListSubject.send(self.remoteParticipantsMocking)
}
}
func unmuteParticipant() {
Task { @MainActor [weak self] in
guard let self,
!self.remoteParticipantsMocking.isEmpty else {
return
}
let last = self.remoteParticipantsMocking.removeLast()
let lastUnmuted = ParticipantInfoModel(displayName: last.displayName,
isSpeaking: last.isSpeaking,
isTypingRtt: last.isTypingRtt,
isMuted: !last.isMuted,
isRemoteUser: last.isRemoteUser,
userIdentifier: last.userIdentifier,
status: last.status,
screenShareVideoStreamModel: last.screenShareVideoStreamModel,
cameraVideoStreamModel: last.cameraVideoStreamModel)
self.remoteParticipantsMocking.append(lastUnmuted)
self.participantsInfoListSubject.send(self.remoteParticipantsMocking)
}
}
func holdParticipant() {
Task { @MainActor [weak self] in
guard let self,
!self.remoteParticipantsMocking.isEmpty else {
return
}
let last = self.remoteParticipantsMocking.removeLast()
let lastUnmuted = ParticipantInfoModel(displayName: last.displayName,
isSpeaking: last.isSpeaking,
isTypingRtt: last.isTypingRtt,
isMuted: !last.isMuted,
isRemoteUser: last.isRemoteUser,
userIdentifier: last.userIdentifier,
status: .hold,
screenShareVideoStreamModel: last.screenShareVideoStreamModel,
cameraVideoStreamModel: last.cameraVideoStreamModel)
self.remoteParticipantsMocking.append(lastUnmuted)
self.participantsInfoListSubject.send(self.remoteParticipantsMocking)
}
}
func admitAllLobbyParticipants() {
Task { @MainActor [weak self] in
guard let self,
!self.remoteParticipantsMocking.isEmpty else {
return
}
let inLobbyParticipants = self.remoteParticipantsMocking.filter { participantInfoModel in
participantInfoModel.status == .inLobby
}
self.remoteParticipantsMocking.removeAll { participantInfoModel in
participantInfoModel.status == .inLobby
}
let connectedParticipants = inLobbyParticipants.map { participantInfoModel in
ParticipantInfoModel(displayName: participantInfoModel.displayName,
isSpeaking: participantInfoModel.isSpeaking,
isTypingRtt: participantInfoModel.isTypingRtt,
isMuted: participantInfoModel.isMuted,
isRemoteUser: participantInfoModel.isRemoteUser,
userIdentifier: participantInfoModel.userIdentifier,
status: .connected,
screenShareVideoStreamModel: participantInfoModel.screenShareVideoStreamModel,
cameraVideoStreamModel: participantInfoModel.cameraVideoStreamModel)
}
self.remoteParticipantsMocking.append(contentsOf: connectedParticipants)
self.participantsInfoListSubject.send(self.remoteParticipantsMocking)
}
}
func admitLobbyParticipant(_ participantId: String) {
Task { @MainActor [weak self] in
guard let self,
!self.remoteParticipantsMocking.isEmpty else {
return
}
let participantInfoModel = self.remoteParticipantsMocking.first { participantInfoModel in
participantInfoModel.userIdentifier == participantId
}
guard let participantInfoModel = participantInfoModel else {
return
}
self.remoteParticipantsMocking.removeAll { participantInfoModel in
participantInfoModel.userIdentifier == participantId
}
let connectedParticipant =
ParticipantInfoModel(displayName: participantInfoModel.displayName,
isSpeaking: participantInfoModel.isSpeaking,
isTypingRtt: participantInfoModel.isTypingRtt,
isMuted: participantInfoModel.isMuted,
isRemoteUser: participantInfoModel.isRemoteUser,
userIdentifier: participantInfoModel.userIdentifier,
status: .connected,
screenShareVideoStreamModel: participantInfoModel.screenShareVideoStreamModel,
cameraVideoStreamModel: participantInfoModel.cameraVideoStreamModel)
self.remoteParticipantsMocking.append(connectedParticipant)
self.participantsInfoListSubject.send(self.remoteParticipantsMocking)
}
}
func declineLobbyParticipant(_ participantId: String) {
Task { @MainActor [weak self] in
guard let self,
!self.remoteParticipantsMocking.isEmpty else {
return
}
self.remoteParticipantsMocking.removeAll { participantInfoModel in
participantInfoModel.userIdentifier == participantId
}
self.participantsInfoListSubject.send(self.remoteParticipantsMocking)
}
}
func setParticipantRole(_ role: ParticipantRoleEnum) {
Task { @MainActor [weak self] in
self?.participantRoleSubject.send(role)
}
}
func emitMediaDiagnostic(_ diagnostic: MediaCallDiagnostic, value: Bool) {
Task { @MainActor [weak self] in
guard let self else {
return
}
self.mediaDiagnosticsSubject.send(
MediaDiagnosticModel(diagnostic: diagnostic, value: value)
)
}
}
func emitNetworkQualityDiagnostic(_ diagnostic: NetworkQualityCallDiagnostic, value: CallDiagnosticQuality) {
Task { @MainActor [weak self] in
guard let self else {
return
}
self.networkQualityDiagnosticsSubject.send(
NetworkQualityDiagnosticModel(diagnostic: diagnostic, value: value)
)
}
}
func emitNetworkDiagnostic(_ diagnostic: NetworkCallDiagnostic, value: Bool) {
Task { @MainActor [weak self] in
guard let self else {
return
}
self.networkDiagnosticsSubject.send(
NetworkDiagnosticModel(diagnostic: diagnostic, value: value)
)
}
}
}
#endif