From 69c55da020a2480cf2f5a852d78ac6fefbd3376a Mon Sep 17 00:00:00 2001 From: Yevhen Kyivskyi Date: Wed, 30 Oct 2024 15:32:44 +0100 Subject: [PATCH] Use queues from QueuesMonitor to determine Secure Conversations availability --- .../SecureConversations.Availability.swift | 85 ++++-------- ...onversations.Coordinator.Environment.swift | 4 +- .../Chat/ChatCoordinator.Environment.swift | 7 +- ...gagementCoordinator.Environment.Mock.swift | 3 +- .../EngagementCoordinator.Environment.swift | 4 +- .../Sources/EntryWidget/EntryWidget.swift | 7 +- .../Glia.Environment.Mock.swift | 2 +- .../Interactor.Environment.Interface.swift | 2 + .../Interactor.Environment.Mock.swift | 1 + .../Sources/Interactor/Interactor.swift | 1 + .../QueuesMonitor/QueuesMonitor.Live.swift | 73 ++++++++--- .../QueuesMonitor/QueuesMonitor.Mock.swift | 14 +- .../RootCoordinator.Environment.Failing.swift | 3 +- .../Interactor.Environment.Failing.swift | 1 + .../Availability.Environment.Failing.swift | 3 +- .../AvailabilityTests.swift | 9 ++ .../TranscriptModelTests+GVA.swift | 6 +- .../TranscriptModelTests+MessageRetry.swift | 3 +- .../TranscriptModelTests+ResponseCard.swift | 3 +- .../TranscriptModelTests+URLs.swift | 3 +- .../ChatTranscript/TranscriptModelTests.swift | 44 +++++-- ...sations.Coordinator.Environment.Mock.swift | 3 +- ...eConversations.WelcomeViewModel.Mock.swift | 3 +- ...reConversations.WelcomeViewModelSpec.swift | 2 + .../ChatViewModel/ChatViewModelTests.swift | 11 +- .../ChatCoordinator.Environment.Mock.swift | 3 +- .../EngagementCoordinator+SurveyTests.swift | 2 +- .../Glia/GliaTests+EngagementLauncher.swift | 1 + .../Glia/GliaTests+StartEngagement.swift | 12 ++ GliaWidgetsTests/Sources/Glia/GliaTests.swift | 2 + .../Sources/InteractorTests.swift | 4 +- .../QueuesMonitor/QueuesMonitorTests.swift | 121 +++++++++++++++--- 32 files changed, 305 insertions(+), 137 deletions(-) diff --git a/GliaWidgets/SecureConversations/SecureConversations.Availability.swift b/GliaWidgets/SecureConversations/SecureConversations.Availability.swift index 251014648..35f073c44 100644 --- a/GliaWidgets/SecureConversations/SecureConversations.Availability.swift +++ b/GliaWidgets/SecureConversations/SecureConversations.Availability.swift @@ -10,23 +10,25 @@ extension SecureConversations { for queueIds: [String], completion: @escaping CompletionResult ) { - environment.listQueues { queues, error in - if let error = error { + // if provided queueIds array contains invalid ids, + // then log a warning message. + let invalidIds = queueIds.filter { UUID(uuidString: $0) == nil } + if !invalidIds.isEmpty { + environment.log.warning("Queue ID array for Secure Messaging contains invalid queue IDs: \(invalidIds).") + } + + environment.queuesMonitor.fetchAndMonitorQueues(queuesIds: queueIds) { result in + switch result { + case .success(let queues): + self.checkQueues(fetchedQueues: queues, completion: completion) + case .failure(let error): completion(.failure(error)) - return } - - self.checkQueues( - queueIds: queueIds, - fetchedQueues: queues, - completion: completion - ) } } private func checkQueues( - queueIds: [String], - fetchedQueues: [CoreSdkClient.Queue]?, + fetchedQueues: [CoreSdkClient.Queue], completion: (Result) -> Void ) { guard environment.isAuthenticated() else { @@ -35,50 +37,7 @@ extension SecureConversations { return } - guard let queues = fetchedQueues else { - // If no queue fetched from the server, - // return `.unavailable(.emptyQueue)` - completion(.success(.unavailable(.emptyQueue))) - return - } - - // if provided queueIds array contains invalid ids, - // then log a warning message. - let invalidIds = queueIds.filter { UUID(uuidString: $0) == nil } - if !invalidIds.isEmpty { - environment.log.warning("Queue ID array for Secure Messaging contains invalid queue IDs: \(invalidIds).") - } - - let matchedQueues = queues.filter { queueIds.contains($0.id) } - - guard !matchedQueues.isEmpty else { - // if provided queue ids array is not empty, but ids do not - // match with any queue, then log a warning message - if !queueIds.isEmpty { - environment.log.warning("Provided queue IDs do not match with any queue.") - } - // If no passed queueId is matched with fetched queues, - // then check default queues instead - let defaultQueues = queues.filter(\.isDefault) - // Filter queues supporting `messaging` and have status other than `closed` - let filteredQueues = defaultQueues.filter(defaultPredicate) - - if filteredQueues.isEmpty { - environment.log.warning("No default queues that have status other than closed and support messaging were found.") - // if no default queue supports `messaging` and - // have status other than `closed`, return `.unavailable(.emptyQueue)` - completion(.success(.unavailable(.emptyQueue))) - return - } - - // Otherwise, return default queue ids - let defaultQueueIds = defaultQueues.map(\.id) - environment.log.info("Secure Messaging is available using queues that are set as **Default**.") - completion(.success(.available(queueIds: defaultQueueIds))) - return - } - - let filteredQueues = matchedQueues.filter(defaultPredicate) + let filteredQueues = fetchedQueues.filter(defaultPredicate) // Check if matched queues match support `messaging` and // have status other than `closed` @@ -87,16 +46,17 @@ extension SecureConversations { completion(.success(.unavailable(.emptyQueue))) return } + let queueIds = filteredQueues.map { $0.id } environment.log.info("Secure Messaging is available in queues with IDs: \(queueIds).") completion(.success(.available(queueIds: queueIds))) } private var defaultPredicate: (CoreSdkClient.Queue) -> Bool { - return { - $0.state.status != .closed && - $0.state.media.contains(CoreSdkClient.MediaType.messaging) - } + { + $0.state.status != .closed && + $0.state.media.contains(CoreSdkClient.MediaType.messaging) + } } } } @@ -106,6 +66,7 @@ extension SecureConversations.Availability { var listQueues: CoreSdkClient.ListQueues var isAuthenticated: () -> Bool var log: CoreSdkClient.Logger + var queuesMonitor: QueuesMonitor } } @@ -139,7 +100,8 @@ extension SecureConversations.Availability.Environment { .init( listQueues: environment.listQueues, isAuthenticated: environment.isAuthenticated, - log: environment.log + log: environment.log, + queuesMonitor: environment.queuesMonitor ) } @@ -147,7 +109,8 @@ extension SecureConversations.Availability.Environment { .init( listQueues: environment.listQueues, isAuthenticated: environment.isAuthenticated, - log: environment.log + log: environment.log, + queuesMonitor: environment.queuesMonitor ) } } diff --git a/GliaWidgets/SecureConversations/SecureConversations.Coordinator.Environment.swift b/GliaWidgets/SecureConversations/SecureConversations.Coordinator.Environment.swift index c5319daca..c59686265 100644 --- a/GliaWidgets/SecureConversations/SecureConversations.Coordinator.Environment.swift +++ b/GliaWidgets/SecureConversations/SecureConversations.Coordinator.Environment.swift @@ -49,6 +49,7 @@ extension SecureConversations.Coordinator { var cameraDeviceManager: CoreSdkClient.GetCameraDeviceManageable var flipCameraButtonStyle: FlipCameraButtonStyle var alertManager: AlertManager + var queuesMonitor: QueuesMonitor } } @@ -111,7 +112,8 @@ extension SecureConversations.Coordinator.Environment { maximumUploads: environment.maximumUploads, cameraDeviceManager: environment.cameraDeviceManager, flipCameraButtonStyle: environment.flipCameraButtonStyle, - alertManager: environment.alertManager + alertManager: environment.alertManager, + queuesMonitor: environment.queuesMonitor ) } } diff --git a/GliaWidgets/Sources/Coordinators/Chat/ChatCoordinator.Environment.swift b/GliaWidgets/Sources/Coordinators/Chat/ChatCoordinator.Environment.swift index e1bd80220..a20018664 100644 --- a/GliaWidgets/Sources/Coordinators/Chat/ChatCoordinator.Environment.swift +++ b/GliaWidgets/Sources/Coordinators/Chat/ChatCoordinator.Environment.swift @@ -41,6 +41,7 @@ extension ChatCoordinator { var cameraDeviceManager: CoreSdkClient.GetCameraDeviceManageable var flipCameraButtonStyle: FlipCameraButtonStyle var alertManager: AlertManager + var queuesMonitor: QueuesMonitor } } @@ -88,7 +89,8 @@ extension ChatCoordinator.Environment { maximumUploads: environment.maximumUploads, cameraDeviceManager: environment.cameraDeviceManager, flipCameraButtonStyle: environment.flipCameraButtonStyle, - alertManager: environment.alertManager + alertManager: environment.alertManager, + queuesMonitor: environment.queuesMonitor ) } @@ -132,7 +134,8 @@ extension ChatCoordinator.Environment { maximumUploads: environment.maximumUploads, cameraDeviceManager: environment.cameraDeviceManager, flipCameraButtonStyle: environment.flipCameraButtonStyle, - alertManager: environment.alertManager + alertManager: environment.alertManager, + queuesMonitor: environment.queuesMonitor ) } } diff --git a/GliaWidgets/Sources/Coordinators/EngagementCoordinator/EngagementCoordinator.Environment.Mock.swift b/GliaWidgets/Sources/Coordinators/EngagementCoordinator/EngagementCoordinator.Environment.Mock.swift index 845f8c145..3a0878983 100644 --- a/GliaWidgets/Sources/Coordinators/EngagementCoordinator/EngagementCoordinator.Environment.Mock.swift +++ b/GliaWidgets/Sources/Coordinators/EngagementCoordinator/EngagementCoordinator.Environment.Mock.swift @@ -43,7 +43,8 @@ extension EngagementCoordinator.Environment { .mock }, flipCameraButtonStyle: .nop, - alertManager: .mock() + alertManager: .mock(), + queuesMonitor: .mock() ) } #endif diff --git a/GliaWidgets/Sources/Coordinators/EngagementCoordinator/EngagementCoordinator.Environment.swift b/GliaWidgets/Sources/Coordinators/EngagementCoordinator/EngagementCoordinator.Environment.swift index 2f5b9150b..ea7000d29 100644 --- a/GliaWidgets/Sources/Coordinators/EngagementCoordinator/EngagementCoordinator.Environment.swift +++ b/GliaWidgets/Sources/Coordinators/EngagementCoordinator/EngagementCoordinator.Environment.swift @@ -43,6 +43,7 @@ extension EngagementCoordinator { var cameraDeviceManager: CoreSdkClient.GetCameraDeviceManageable var flipCameraButtonStyle: FlipCameraButtonStyle var alertManager: AlertManager + var queuesMonitor: QueuesMonitor } } @@ -95,7 +96,8 @@ extension EngagementCoordinator.Environment { maximumUploads: maximumUploads, cameraDeviceManager: environment.cameraDeviceManager, flipCameraButtonStyle: viewFactory.theme.call.flipCameraButtonStyle, - alertManager: alertManager + alertManager: alertManager, + queuesMonitor: environment.queuesMonitor ) } } diff --git a/GliaWidgets/Sources/EntryWidget/EntryWidget.swift b/GliaWidgets/Sources/EntryWidget/EntryWidget.swift index ae2068354..e408e718f 100644 --- a/GliaWidgets/Sources/EntryWidget/EntryWidget.swift +++ b/GliaWidgets/Sources/EntryWidget/EntryWidget.swift @@ -65,7 +65,6 @@ public extension EntryWidget { func hide() { hostedViewController?.dismiss(animated: true, completion: nil) hostedViewController = nil - environment.queuesMonitor.stopMonitoring() } } @@ -133,14 +132,14 @@ private extension EntryWidget { viewModel.retryMonitoring = { [weak self] in self?.viewState = .loading - self?.environment.queuesMonitor.startMonitoring(queuesIds: self?.queueIds ?? []) + self?.environment.queuesMonitor.fetchAndMonitorQueues(queuesIds: self?.queueIds ?? []) } return viewModel } func showView(in parentView: UIView) { - self.environment.queuesMonitor.startMonitoring(queuesIds: self.queueIds) + self.environment.queuesMonitor.fetchAndMonitorQueues(queuesIds: self.queueIds) parentView.subviews.forEach { $0.removeFromSuperview() } let model = makeViewModel(showHeader: false) let view = makeView(model: model) @@ -160,7 +159,7 @@ private extension EntryWidget { } func showSheet(in parentViewController: UIViewController) { - self.environment.queuesMonitor.startMonitoring(queuesIds: self.queueIds) + self.environment.queuesMonitor.fetchAndMonitorQueues(queuesIds: self.queueIds) let model = makeViewModel(showHeader: true) let view = makeView(model: model).accessibilityAction(.escape, { self.hide() diff --git a/GliaWidgets/Sources/GliaEnvironment/Glia.Environment.Mock.swift b/GliaWidgets/Sources/GliaEnvironment/Glia.Environment.Mock.swift index c8b7fef4f..31955a5b6 100644 --- a/GliaWidgets/Sources/GliaEnvironment/Glia.Environment.Mock.swift +++ b/GliaWidgets/Sources/GliaEnvironment/Glia.Environment.Mock.swift @@ -34,7 +34,7 @@ extension Glia.Environment { snackBar: .mock, processInfo: .mock(), cameraDeviceManager: { .mock }, - queuesMonitor: .mock, + queuesMonitor: .mock(), isAuthenticated: { false } ) } diff --git a/GliaWidgets/Sources/Interactor/Interactor.Environment.Interface.swift b/GliaWidgets/Sources/Interactor/Interactor.Environment.Interface.swift index 968c261fd..2063668c4 100644 --- a/GliaWidgets/Sources/Interactor/Interactor.Environment.Interface.swift +++ b/GliaWidgets/Sources/Interactor/Interactor.Environment.Interface.swift @@ -1,6 +1,7 @@ extension Interactor { struct Environment { var coreSdk: CoreSdkClient + var queuesMonitor: QueuesMonitor var gcd: GCD var log: CoreSdkClient.Logger } @@ -13,6 +14,7 @@ extension Interactor.Environment { ) -> Self { .init( coreSdk: environment.coreSdk, + queuesMonitor: environment.queuesMonitor, gcd: environment.gcd, log: log ) diff --git a/GliaWidgets/Sources/Interactor/Interactor.Environment.Mock.swift b/GliaWidgets/Sources/Interactor/Interactor.Environment.Mock.swift index 5a7ef7a83..c6dbe7186 100644 --- a/GliaWidgets/Sources/Interactor/Interactor.Environment.Mock.swift +++ b/GliaWidgets/Sources/Interactor/Interactor.Environment.Mock.swift @@ -2,6 +2,7 @@ extension Interactor.Environment { static let mock = Self( coreSdk: .mock, + queuesMonitor: .mock(), gcd: .mock, log: .mock ) diff --git a/GliaWidgets/Sources/Interactor/Interactor.swift b/GliaWidgets/Sources/Interactor/Interactor.swift index 1d6e4dda3..27bec6858 100644 --- a/GliaWidgets/Sources/Interactor/Interactor.swift +++ b/GliaWidgets/Sources/Interactor/Interactor.swift @@ -109,6 +109,7 @@ class Interactor { extension Interactor { func setQueuesIds(_ queueIds: [String]) { self.queueIds = queueIds + environment.queuesMonitor.fetchAndMonitorQueues(queuesIds: queueIds) } func enqueueForEngagement( diff --git a/GliaWidgets/Sources/QueuesMonitor/QueuesMonitor.Live.swift b/GliaWidgets/Sources/QueuesMonitor/QueuesMonitor.Live.swift index 23f2ec7d2..cde7aad69 100644 --- a/GliaWidgets/Sources/QueuesMonitor/QueuesMonitor.Live.swift +++ b/GliaWidgets/Sources/QueuesMonitor/QueuesMonitor.Live.swift @@ -11,7 +11,7 @@ final class QueuesMonitor { @Published private(set) var state: State = .idle - /// Declared as internal var for unit tests purposes + // Declared as internal var for unit tests purposes var environment: Environment private var subscriptionId: String? { _subscriptionId.value @@ -27,40 +27,75 @@ final class QueuesMonitor { self.environment = environment } - func startMonitoring(queuesIds: [String]) { + /// Fetches all available site's queues and initiates queues monitoring for given queues IDs. + /// + /// - Parameters: + /// - queuesIds: The queues IDs that will be monitored. + /// - fetchedQueuesCompletion: Returns fetched queues result for given `queuesIds` + /// if no queues were found among site's queues returns default queues. + /// + func fetchAndMonitorQueues( + queuesIds: [String] = [], + fetchedQueuesCompletion: ((Result<[Queue], GliaCoreError>) -> Void)? = nil + ) { + stopMonitoring() + + fetchQueues(queuesIds: queuesIds) { [weak self] result in + if case let .success(queues) = result { + self?.observeQueuesUpdates(queues) + } + fetchedQueuesCompletion?(result) + } + } + + /// Stops monitoring queues. + func stopMonitoring() { + if let subscriptionId { + environment.unsubscribeFromUpdates(subscriptionId) { [weak self] error in + self?.state = .failed(error) + } + } + } +} + +private extension QueuesMonitor { + func fetchQueues(queuesIds: [String], completion: @escaping (Result<[Queue], GliaCoreError>) -> Void) { environment.listQueues { [weak self] queues, error in guard let self else { return } if let error { self.state = .failed(error) + completion(.failure(error)) return } - if let queues { - let integratorsQueues = queues.filter { queuesIds.contains($0.id) } - - let observedQueues = integratorsQueues.isEmpty ? queues.filter { $0.isDefault } : integratorsQueues + let observedQueues = evaluateQueues(queuesIds: queuesIds, fetchedQueues: queues) - self.state = .updated(observedQueues) - self.observeQueuesUpdates(observedQueues) - - self._observedQueues.setValue(observedQueues) - return - } + self.state = .updated(observedQueues) + self._observedQueues.setValue(observedQueues) + completion(.success(observedQueues)) } } - func stopMonitoring() { - if let subscriptionId { - environment.unsubscribeFromUpdates(subscriptionId) { [weak self] error in - self?.state = .failed(error) - } + func evaluateQueues(queuesIds: [String], fetchedQueues: [Queue]?) -> [Queue] { + guard let queues = fetchedQueues else { + return [] } + + let matchedQueues = queues.filter { queuesIds.contains($0.id) } + + guard !matchedQueues.isEmpty else { + // If no passed queueId is matched with fetched queues, + // then check default queues instead + let defaultQueues = queues.filter(\.isDefault) + + return defaultQueues + } + + return matchedQueues } -} -private extension QueuesMonitor { func updateQueue(_ queue: Queue) { _observedQueues.withValue { queues in guard let indexToChange = queues.firstIndex(where: { $0.id == queue.id }) else { diff --git a/GliaWidgets/Sources/QueuesMonitor/QueuesMonitor.Mock.swift b/GliaWidgets/Sources/QueuesMonitor/QueuesMonitor.Mock.swift index 9f7b937dd..01d9e94a3 100644 --- a/GliaWidgets/Sources/QueuesMonitor/QueuesMonitor.Mock.swift +++ b/GliaWidgets/Sources/QueuesMonitor/QueuesMonitor.Mock.swift @@ -1,5 +1,17 @@ #if DEBUG extension QueuesMonitor { - static let mock = QueuesMonitor(environment: .mock) + static func mock( + listQueues: CoreSdkClient.ListQueues? = nil, + subscribeForQueuesUpdates: CoreSdkClient.SubscribeForQueuesUpdates? = nil, + unsubscribeFromUpdates: CoreSdkClient.UnsubscribeFromUpdates? = nil + ) -> Self { + Self( + environment: .init( + listQueues: listQueues ?? QueuesMonitor.Environment.mock.listQueues, + subscribeForQueuesUpdates: subscribeForQueuesUpdates ?? QueuesMonitor.Environment.mock.subscribeForQueuesUpdates, + unsubscribeFromUpdates: unsubscribeFromUpdates ?? QueuesMonitor.Environment.mock.unsubscribeFromUpdates + ) + ) + } } #endif diff --git a/GliaWidgetsTests/Coordinator/RootCoordinator.Environment.Failing.swift b/GliaWidgetsTests/Coordinator/RootCoordinator.Environment.Failing.swift index 23867173f..c38b7eaf4 100644 --- a/GliaWidgetsTests/Coordinator/RootCoordinator.Environment.Failing.swift +++ b/GliaWidgetsTests/Coordinator/RootCoordinator.Environment.Failing.swift @@ -95,6 +95,7 @@ extension EngagementCoordinator.Environment { }, cameraDeviceManager: { .failing }, flipCameraButtonStyle: .nop, - alertManager: .failing(viewFactory: .mock()) + alertManager: .failing(viewFactory: .mock()), + queuesMonitor: .failing ) } diff --git a/GliaWidgetsTests/Interactor/Interactor.Environment.Failing.swift b/GliaWidgetsTests/Interactor/Interactor.Environment.Failing.swift index f102652a8..8da9e9b38 100644 --- a/GliaWidgetsTests/Interactor/Interactor.Environment.Failing.swift +++ b/GliaWidgetsTests/Interactor/Interactor.Environment.Failing.swift @@ -4,6 +4,7 @@ import Foundation extension Interactor.Environment { static let failing = Self( coreSdk: .failing, + queuesMonitor: .failing, gcd: .failing, log: .failing ) diff --git a/GliaWidgetsTests/SecureConversations/Availability.Environment.Failing.swift b/GliaWidgetsTests/SecureConversations/Availability.Environment.Failing.swift index 5167633b6..d94a9806f 100644 --- a/GliaWidgetsTests/SecureConversations/Availability.Environment.Failing.swift +++ b/GliaWidgetsTests/SecureConversations/Availability.Environment.Failing.swift @@ -9,6 +9,7 @@ extension SecureConversations.Availability.Environment { fail("\(Self.self).isAuthenticated") return false }, - log: .failing + log: .failing, + queuesMonitor: .failing ) } diff --git a/GliaWidgetsTests/SecureConversations/AvailabilityTests.swift b/GliaWidgetsTests/SecureConversations/AvailabilityTests.swift index 7c9223f9b..94f056daf 100644 --- a/GliaWidgetsTests/SecureConversations/AvailabilityTests.swift +++ b/GliaWidgetsTests/SecureConversations/AvailabilityTests.swift @@ -11,6 +11,7 @@ final class AvailabilityTests: XCTestCase { callback(nil, error) } env.isAuthenticated = { true } + env.queuesMonitor = .mock(listQueues: env.listQueues) let queueIds = [UUID.mock.uuidString] let availability = Availability(environment: env) var receivedResult: Result? @@ -30,6 +31,7 @@ final class AvailabilityTests: XCTestCase { logger.warningClosure = { _, _, _, _ in } env.log = logger env.isAuthenticated = { true } + env.queuesMonitor = .mock(listQueues: env.listQueues) let queueIds = [UUID.mock.uuidString] let availability = Availability(environment: env) var receivedResult: Result? @@ -49,6 +51,7 @@ final class AvailabilityTests: XCTestCase { logger.warningClosure = { _, _, _, _ in } env.log = logger env.isAuthenticated = { false } + env.queuesMonitor = .mock(listQueues: env.listQueues) let queueIds = [UUID.mock.uuidString] let availability = Availability(environment: env) var receivedResult: Result? @@ -69,6 +72,7 @@ final class AvailabilityTests: XCTestCase { logger.infoClosure = { _, _, _, _ in } env.log = logger env.isAuthenticated = { true } + env.queuesMonitor = .mock(listQueues: env.listQueues) let availability = Availability(environment: env) var receivedResult: Result? availability.checkSecureConversationsAvailability(for: [queueId]) { result in @@ -95,6 +99,7 @@ final class AvailabilityTests: XCTestCase { logger.warningClosure = { _, _, _, _ in } env.log = logger env.isAuthenticated = { true } + env.queuesMonitor = .mock(listQueues: env.listQueues) let availability = Availability(environment: env) var receivedResult: Result? availability.checkSecureConversationsAvailability(for: queueIds) { result in @@ -115,6 +120,7 @@ final class AvailabilityTests: XCTestCase { logger.warningClosure = { _, _, _, _ in } env.log = logger env.isAuthenticated = { true } + env.queuesMonitor = .mock(listQueues: env.listQueues) let availability = Availability(environment: env) var receivedResult: Result? availability.checkSecureConversationsAvailability(for: [queueId]) { result in @@ -135,6 +141,7 @@ final class AvailabilityTests: XCTestCase { logger.warningClosure = { _, _, _, _ in } env.log = logger env.isAuthenticated = { true } + env.queuesMonitor = .mock(listQueues: env.listQueues) let availability = Availability(environment: env) var receivedResult: Result? availability.checkSecureConversationsAvailability(for: [queueId]) { result in @@ -155,6 +162,7 @@ final class AvailabilityTests: XCTestCase { logger.warningClosure = { _, _, _, _ in } env.log = logger env.isAuthenticated = { true } + env.queuesMonitor = .mock(listQueues: env.listQueues) let availability = Availability(environment: env) var receivedResult: Result? availability.checkSecureConversationsAvailability(for: []) { result in @@ -180,6 +188,7 @@ final class AvailabilityTests: XCTestCase { logger.warningClosure = { _, _, _, _ in } env.log = logger env.isAuthenticated = { true } + env.queuesMonitor = .mock(listQueues: env.listQueues) let availability = Availability(environment: env) var receivedResult: Result? availability.checkSecureConversationsAvailability(for: []) { result in diff --git a/GliaWidgetsTests/SecureConversations/ChatTranscript/TranscriptModelTests+GVA.swift b/GliaWidgetsTests/SecureConversations/ChatTranscript/TranscriptModelTests+GVA.swift index c181711f0..919030070 100644 --- a/GliaWidgetsTests/SecureConversations/ChatTranscript/TranscriptModelTests+GVA.swift +++ b/GliaWidgetsTests/SecureConversations/ChatTranscript/TranscriptModelTests+GVA.swift @@ -151,7 +151,8 @@ extension SecureConversationsTranscriptModelTests { let availabilityEnv = SecureConversations.Availability.Environment( listQueues: modelEnv.listQueues, isAuthenticated: { true }, - log: logger + log: logger, + queuesMonitor: .mock() ) let viewModel = TranscriptModel( @@ -196,7 +197,8 @@ private extension SecureConversationsTranscriptModelTests { let availabilityEnv = SecureConversations.Availability.Environment( listQueues: modelEnv.listQueues, isAuthenticated: { true }, - log: logger + log: logger, + queuesMonitor: .mock() ) return TranscriptModel( diff --git a/GliaWidgetsTests/SecureConversations/ChatTranscript/TranscriptModelTests+MessageRetry.swift b/GliaWidgetsTests/SecureConversations/ChatTranscript/TranscriptModelTests+MessageRetry.swift index d4d8fd140..b9cd0840a 100644 --- a/GliaWidgetsTests/SecureConversations/ChatTranscript/TranscriptModelTests+MessageRetry.swift +++ b/GliaWidgetsTests/SecureConversations/ChatTranscript/TranscriptModelTests+MessageRetry.swift @@ -138,7 +138,8 @@ private extension SecureConversationsTranscriptModelTests { let availabilityEnv = SecureConversations.Availability.Environment( listQueues: modelEnv.listQueues, isAuthenticated: { true }, - log: logger + log: logger, + queuesMonitor: .mock() ) return TranscriptModel( diff --git a/GliaWidgetsTests/SecureConversations/ChatTranscript/TranscriptModelTests+ResponseCard.swift b/GliaWidgetsTests/SecureConversations/ChatTranscript/TranscriptModelTests+ResponseCard.swift index 8bfb14da7..a9938949b 100644 --- a/GliaWidgetsTests/SecureConversations/ChatTranscript/TranscriptModelTests+ResponseCard.swift +++ b/GliaWidgetsTests/SecureConversations/ChatTranscript/TranscriptModelTests+ResponseCard.swift @@ -46,7 +46,8 @@ private extension SecureConversationsTranscriptModelTests { let availabilityEnv = SecureConversations.Availability.Environment( listQueues: modelEnv.listQueues, isAuthenticated: { true }, - log: logger + log: logger, + queuesMonitor: .mock() ) return TranscriptModel( diff --git a/GliaWidgetsTests/SecureConversations/ChatTranscript/TranscriptModelTests+URLs.swift b/GliaWidgetsTests/SecureConversations/ChatTranscript/TranscriptModelTests+URLs.swift index 1667c6809..8e164e046 100644 --- a/GliaWidgetsTests/SecureConversations/ChatTranscript/TranscriptModelTests+URLs.swift +++ b/GliaWidgetsTests/SecureConversations/ChatTranscript/TranscriptModelTests+URLs.swift @@ -90,7 +90,8 @@ private extension SecureConversationsTranscriptModelTests { let availabilityEnv = SecureConversations.Availability.Environment( listQueues: modelEnv.listQueues, isAuthenticated: { true }, - log: logger + log: logger, + queuesMonitor: .mock() ) return TranscriptModel( diff --git a/GliaWidgetsTests/SecureConversations/ChatTranscript/TranscriptModelTests.swift b/GliaWidgetsTests/SecureConversations/ChatTranscript/TranscriptModelTests.swift index 3b1718c06..b4b4998a9 100644 --- a/GliaWidgetsTests/SecureConversations/ChatTranscript/TranscriptModelTests.swift +++ b/GliaWidgetsTests/SecureConversations/ChatTranscript/TranscriptModelTests.swift @@ -19,7 +19,8 @@ final class SecureConversationsTranscriptModelTests: XCTestCase { let availabilityEnv = SecureConversations.Availability.Environment( listQueues: modelEnv.listQueues, isAuthenticated: { true }, - log: logger + log: logger, + queuesMonitor: .mock(listQueues: modelEnv.listQueues) ) let viewModel = TranscriptModel( isCustomCardSupported: false, @@ -48,7 +49,8 @@ final class SecureConversationsTranscriptModelTests: XCTestCase { let availabilityEnv = SecureConversations.Availability.Environment( listQueues: modelEnv.listQueues, isAuthenticated: { false }, - log: logger + log: logger, + queuesMonitor: .mock(listQueues: modelEnv.listQueues) ) let viewModel = TranscriptModel( isCustomCardSupported: false, @@ -81,7 +83,8 @@ final class SecureConversationsTranscriptModelTests: XCTestCase { let availabilityEnv = SecureConversations.Availability.Environment( listQueues: modelEnv.listQueues, isAuthenticated: { true }, - log: .failing + log: .failing, + queuesMonitor: .mock(listQueues: modelEnv.listQueues) ) let viewModel = TranscriptModel( @@ -126,7 +129,8 @@ final class SecureConversationsTranscriptModelTests: XCTestCase { let availabilityEnv = SecureConversations.Availability.Environment( listQueues: modelEnv.listQueues, isAuthenticated: { true }, - log: .failing + log: .failing, + queuesMonitor: .mock(listQueues: modelEnv.listQueues) ) let viewModel = TranscriptModel( isCustomCardSupported: false, @@ -158,7 +162,8 @@ final class SecureConversationsTranscriptModelTests: XCTestCase { let availabilityEnv = SecureConversations.Availability.Environment( listQueues: modelEnv.listQueues, isAuthenticated: { true }, - log: .failing + log: .failing, + queuesMonitor: .mock(listQueues: modelEnv.listQueues) ) let viewModel = TranscriptModel( isCustomCardSupported: false, @@ -204,7 +209,8 @@ final class SecureConversationsTranscriptModelTests: XCTestCase { let availabilityEnv = SecureConversations.Availability.Environment( listQueues: modelEnv.listQueues, isAuthenticated: { true }, - log: .failing + log: .failing, + queuesMonitor: .mock(listQueues: modelEnv.listQueues) ) let viewModel = TranscriptModel( @@ -245,7 +251,8 @@ final class SecureConversationsTranscriptModelTests: XCTestCase { let availabilityEnv = SecureConversations.Availability.Environment( listQueues: modelEnv.listQueues, isAuthenticated: { true }, - log: .failing + log: .failing, + queuesMonitor: .mock(listQueues: modelEnv.listQueues) ) let viewModel = TranscriptModel( @@ -282,7 +289,8 @@ final class SecureConversationsTranscriptModelTests: XCTestCase { let availabilityEnv = SecureConversations.Availability.Environment( listQueues: modelEnv.listQueues, isAuthenticated: { true }, - log: .failing + log: .failing, + queuesMonitor: .mock(listQueues: modelEnv.listQueues) ) let viewModel = TranscriptModel( @@ -325,7 +333,8 @@ final class SecureConversationsTranscriptModelTests: XCTestCase { let availabilityEnv = SecureConversations.Availability.Environment( listQueues: modelEnv.listQueues, isAuthenticated: { true }, - log: .failing + log: .failing, + queuesMonitor: .mock(listQueues: modelEnv.listQueues) ) let viewModel = TranscriptModel( @@ -364,7 +373,8 @@ final class SecureConversationsTranscriptModelTests: XCTestCase { let availabilityEnv = SecureConversations.Availability.Environment( listQueues: modelEnv.listQueues, isAuthenticated: { true }, - log: .failing + log: .failing, + queuesMonitor: .mock(listQueues: modelEnv.listQueues) ) let viewModel = TranscriptModel( @@ -406,7 +416,8 @@ final class SecureConversationsTranscriptModelTests: XCTestCase { let availabilityEnv = SecureConversations.Availability.Environment( listQueues: modelEnv.listQueues, isAuthenticated: { true }, - log: .failing + log: .failing, + queuesMonitor: .mock(listQueues: modelEnv.listQueues) ) let viewModel = TranscriptModel( @@ -455,7 +466,8 @@ final class SecureConversationsTranscriptModelTests: XCTestCase { let availabilityEnv = SecureConversations.Availability.Environment( listQueues: modelEnv.listQueues, isAuthenticated: { true }, - log: .failing + log: .failing, + queuesMonitor: .mock(listQueues: modelEnv.listQueues) ) let interactor: Interactor = .failing @@ -520,7 +532,8 @@ final class SecureConversationsTranscriptModelTests: XCTestCase { let availabilityEnv = SecureConversations.Availability.Environment( listQueues: modelEnv.listQueues, isAuthenticated: { true }, - log: .failing + log: .failing, + queuesMonitor: .mock(listQueues: modelEnv.listQueues) ) let interactor: Interactor = .failing @@ -581,6 +594,7 @@ final class SecureConversationsTranscriptModelTests: XCTestCase { callback([], nil) } availabilityEnv.isAuthenticated = { true } + availabilityEnv.queuesMonitor = .mock(listQueues: availabilityEnv.listQueues) let model = TranscriptModel( isCustomCardSupported: false, environment: modelEnvironment, @@ -610,6 +624,7 @@ final class SecureConversationsTranscriptModelTests: XCTestCase { callback([.mock()], nil) } availabilityEnv.isAuthenticated = { false } + availabilityEnv.queuesMonitor = .mock(listQueues: availabilityEnv.listQueues) let model = TranscriptModel( isCustomCardSupported: false, environment: modelEnvironment, @@ -637,6 +652,7 @@ final class SecureConversationsTranscriptModelTests: XCTestCase { callback(nil, .mock()) } availabilityEnv.isAuthenticated = { false } + availabilityEnv.queuesMonitor = .mock(listQueues: availabilityEnv.listQueues) let model = TranscriptModel( isCustomCardSupported: false, environment: modelEnvironment, @@ -666,6 +682,7 @@ final class SecureConversationsTranscriptModelTests: XCTestCase { callback([.mock()], nil) } availabilityEnv.isAuthenticated = { true } + availabilityEnv.queuesMonitor = .mock(listQueues: availabilityEnv.listQueues) let model = TranscriptModel( isCustomCardSupported: false, environment: modelEnvironment, @@ -695,6 +712,7 @@ final class SecureConversationsTranscriptModelTests: XCTestCase { callback([.mock()], nil) } availabilityEnv.isAuthenticated = { true } + availabilityEnv.queuesMonitor = .mock(listQueues: availabilityEnv.listQueues) let model = TranscriptModel( isCustomCardSupported: false, environment: modelEnvironment, diff --git a/GliaWidgetsTests/SecureConversations/Coordinator/SecureConversations.Coordinator.Environment.Mock.swift b/GliaWidgetsTests/SecureConversations/Coordinator/SecureConversations.Coordinator.Environment.Mock.swift index e1d21e042..80b6c0d31 100644 --- a/GliaWidgetsTests/SecureConversations/Coordinator/SecureConversations.Coordinator.Environment.Mock.swift +++ b/GliaWidgetsTests/SecureConversations/Coordinator/SecureConversations.Coordinator.Environment.Mock.swift @@ -52,6 +52,7 @@ extension SecureConversations.Coordinator.Environment { maximumUploads: { 2 }, cameraDeviceManager: { .mock }, flipCameraButtonStyle: .nop, - alertManager: .mock() + alertManager: .mock(), + queuesMonitor: .mock() ) } diff --git a/GliaWidgetsTests/SecureConversations/Welcome/SecureConversations.WelcomeViewModel.Mock.swift b/GliaWidgetsTests/SecureConversations/Welcome/SecureConversations.WelcomeViewModel.Mock.swift index 493c20087..086e3ce7d 100644 --- a/GliaWidgetsTests/SecureConversations/Welcome/SecureConversations.WelcomeViewModel.Mock.swift +++ b/GliaWidgetsTests/SecureConversations/Welcome/SecureConversations.WelcomeViewModel.Mock.swift @@ -52,7 +52,8 @@ extension SecureConversations.Availability { environment: .init( listQueues: { _ in }, isAuthenticated: { true }, - log: .mock + log: .mock, + queuesMonitor: .mock() ) ) } diff --git a/GliaWidgetsTests/SecureConversations/Welcome/SecureConversations.WelcomeViewModelSpec.swift b/GliaWidgetsTests/SecureConversations/Welcome/SecureConversations.WelcomeViewModelSpec.swift index 24c6d5d04..dc4d5e7da 100644 --- a/GliaWidgetsTests/SecureConversations/Welcome/SecureConversations.WelcomeViewModelSpec.swift +++ b/GliaWidgetsTests/SecureConversations/Welcome/SecureConversations.WelcomeViewModelSpec.swift @@ -643,6 +643,7 @@ extension SecureConversationsWelcomeViewModelTests { } availability.environment.isAuthenticated = { true } + availability.environment.queuesMonitor = .mock(listQueues: availability.environment.listQueues) let delegate: (WelcomeViewModel.DelegateEvent) -> Void = { event in switch event { @@ -686,6 +687,7 @@ extension SecureConversationsWelcomeViewModelTests { } availability.environment.isAuthenticated = { false } + availability.environment.queuesMonitor = .mock(listQueues: availability.environment.listQueues) let delegate: (WelcomeViewModel.DelegateEvent) -> Void = { event in switch event { diff --git a/GliaWidgetsTests/Sources/ChatViewModel/ChatViewModelTests.swift b/GliaWidgetsTests/Sources/ChatViewModel/ChatViewModelTests.swift index efa293623..28280f8ba 100644 --- a/GliaWidgetsTests/Sources/ChatViewModel/ChatViewModelTests.swift +++ b/GliaWidgetsTests/Sources/ChatViewModel/ChatViewModelTests.swift @@ -239,7 +239,7 @@ class ChatViewModelTests: XCTestCase { // Given enum Calls { case fetchSiteConfigurations } var calls: [Calls] = [] - let interactorEnv = Interactor.Environment(coreSdk: .failing, gcd: .mock, log: .mock) + let interactorEnv = Interactor.Environment(coreSdk: .failing, queuesMonitor: .mock(), gcd: .mock, log: .mock) let interactor = Interactor.mock(environment: interactorEnv) var viewModelEnv = ChatViewModel.Environment.failing() viewModelEnv.fileManager.urlsForDirectoryInDomainMask = { _, _ in [.mock] } @@ -261,7 +261,7 @@ class ChatViewModelTests: XCTestCase { // Given enum Calls { case fetchSiteConfigurations } var calls: [Calls] = [] - var interactorEnv = Interactor.Environment.init(coreSdk: .failing, gcd: .mock, log: .mock) + var interactorEnv = Interactor.Environment.init(coreSdk: .failing, queuesMonitor: .mock(), gcd: .mock, log: .mock) var interactorLog = CoreSdkClient.Logger.failing interactorLog.infoClosure = { _, _, _, _ in } interactorLog.prefixedClosure = { _ in interactorLog } @@ -456,7 +456,8 @@ class ChatViewModelTests: XCTestCase { let availabilityEnv = SecureConversations.Availability.Environment( listQueues: transcriptModelEnv.listQueues, isAuthenticated: { true }, - log: logger + log: logger, + queuesMonitor: .mock() ) let transcriptModel = TranscriptModel( isCustomCardSupported: false, @@ -895,7 +896,7 @@ class ChatViewModelTests: XCTestCase { func test_quickReplyWillBeHiddenAfterMessageIsSent() throws { enum Calls { case quickReplyHidden } var calls: [Calls] = [] - let interactorEnv = Interactor.Environment(coreSdk: .failing, gcd: .mock, log: .mock) + let interactorEnv = Interactor.Environment(coreSdk: .failing, queuesMonitor: .failing, gcd: .mock, log: .mock) let interactor = Interactor.mock(environment: interactorEnv) var viewModelEnv = ChatViewModel.Environment.failing() viewModelEnv.fileManager.urlsForDirectoryInDomainMask = { _, _ in [.mock] } @@ -920,7 +921,7 @@ class ChatViewModelTests: XCTestCase { } func test_pendingMessageGetsRemovedFromListWhenMessageIsSentSuccesfully() { - var interactorEnv = Interactor.Environment(coreSdk: .failing, gcd: .mock, log: .mock) + var interactorEnv = Interactor.Environment(coreSdk: .failing, queuesMonitor: .failing, gcd: .mock, log: .mock) interactorEnv.coreSdk.sendMessageWithMessagePayload = { payload, callback in callback(.success(.mock(id: payload.messageId.rawValue))) } diff --git a/GliaWidgetsTests/Sources/Coordinators/Chat/ChatCoordinator.Environment.Mock.swift b/GliaWidgetsTests/Sources/Coordinators/Chat/ChatCoordinator.Environment.Mock.swift index 155c3f910..8360a6cd7 100644 --- a/GliaWidgetsTests/Sources/Coordinators/Chat/ChatCoordinator.Environment.Mock.swift +++ b/GliaWidgetsTests/Sources/Coordinators/Chat/ChatCoordinator.Environment.Mock.swift @@ -41,6 +41,7 @@ extension ChatCoordinator.Environment { maximumUploads: { 2 }, cameraDeviceManager: { .mock }, flipCameraButtonStyle: .nop, - alertManager: .mock() + alertManager: .mock(), + queuesMonitor: .mock() ) } diff --git a/GliaWidgetsTests/Sources/Coordinators/EngagementCoordinator/EngagementCoordinator+SurveyTests.swift b/GliaWidgetsTests/Sources/Coordinators/EngagementCoordinator/EngagementCoordinator+SurveyTests.swift index 2f3af962d..1656927c6 100644 --- a/GliaWidgetsTests/Sources/Coordinators/EngagementCoordinator/EngagementCoordinator+SurveyTests.swift +++ b/GliaWidgetsTests/Sources/Coordinators/EngagementCoordinator/EngagementCoordinator+SurveyTests.swift @@ -13,7 +13,7 @@ class EngagementCoordinatorSurveyTests: XCTestCase { }, mediaStreams: .init(audio: .none, video: .oneWay) ) - let interactor = Interactor.mock(environment: .init(coreSdk: coreSdkClient, gcd: .failing, log: .failing)) + let interactor = Interactor.mock(environment: .init(coreSdk: coreSdkClient, queuesMonitor: .mock(), gcd: .failing, log: .failing)) interactor.currentEngagement = engagement var alertManagerEnv = AlertManager.Environment.failing() var log = CoreSdkClient.Logger.failing diff --git a/GliaWidgetsTests/Sources/Glia/GliaTests+EngagementLauncher.swift b/GliaWidgetsTests/Sources/Glia/GliaTests+EngagementLauncher.swift index 45f855685..d40cbf50d 100644 --- a/GliaWidgetsTests/Sources/Glia/GliaTests+EngagementLauncher.swift +++ b/GliaWidgetsTests/Sources/Glia/GliaTests+EngagementLauncher.swift @@ -96,6 +96,7 @@ private extension GliaTests { completion(.success(())) } sdkEnv.coreSdk.getCurrentEngagement = { nil } + sdkEnv.queuesMonitor = .mock() let window = UIWindow(frame: .zero) window.makeKeyAndVisible() sdkEnv.uiApplication.windows = { [window] } diff --git a/GliaWidgetsTests/Sources/Glia/GliaTests+StartEngagement.swift b/GliaWidgetsTests/Sources/Glia/GliaTests+StartEngagement.swift index f7bf3335e..57e8c98b6 100644 --- a/GliaWidgetsTests/Sources/Glia/GliaTests+StartEngagement.swift +++ b/GliaWidgetsTests/Sources/Glia/GliaTests+StartEngagement.swift @@ -27,6 +27,7 @@ extension GliaTests { sdkEnv.coreSDKConfigurator.configureWithConfiguration = { _, completion in completion(.success(())) } + sdkEnv.queuesMonitor = .mock() let window = UIWindow(frame: .zero) window.makeKeyAndVisible() sdkEnv.uiApplication.windows = { [window] } @@ -60,6 +61,7 @@ extension GliaTests { } environment.coreSdk.localeProvider.getRemoteString = { _ in nil } environment.coreSDKConfigurator.configureWithInteractor = { _ in } + environment.queuesMonitor = .mock() let rootCoordinator = EngagementCoordinator.mock( engagementKind: .chat, @@ -102,6 +104,7 @@ extension GliaTests { sdk.environment.coreSDKConfigurator.configureWithConfiguration = { _, completion in completion(.success(())) } + sdk.environment.queuesMonitor = .mock() try sdk.configure( with: .mock(), theme: .mock() @@ -135,6 +138,7 @@ extension GliaTests { } environment.coreSdk.localeProvider.getRemoteString = { _ in nil } environment.coreSdk.getCurrentEngagement = { nil } + environment.queuesMonitor = .mock() let sdk = Glia(environment: environment) try sdk.configure( with: .mock(), @@ -175,6 +179,7 @@ extension GliaTests { environment.createRootCoordinator = { _, _, _, _, _, _, _ in .mock(environment: .engagementCoordEnvironmentWithKeyWindow) } + environment.queuesMonitor = .mock() let sdk = Glia(environment: environment) try sdk.start(.chat, configuration: .mock(), queueID: "queueId", theme: .mock()) @@ -214,6 +219,7 @@ extension GliaTests { } environment.coreSDKConfigurator.configureWithInteractor = { _ in } environment.coreSdk.localeProvider.getRemoteString = { _ in nil } + environment.queuesMonitor = .mock() let sdk = Glia(environment: environment) @@ -261,6 +267,7 @@ extension GliaTests { } environment.coreSDKConfigurator.configureWithInteractor = { _ in } environment.coreSdk.getCurrentEngagement = { nil } + environment.queuesMonitor = .mock() var logger = CoreSdkClient.Logger.failing logger.configureLocalLogLevelClosure = { _ in } logger.configureRemoteLogLevelClosure = { _ in } @@ -301,6 +308,7 @@ extension GliaTests { logger.infoClosure = { _, _, _, _ in } logger.prefixedClosure = { _ in logger } environment.coreSdk.createLogger = { _ in logger } + environment.queuesMonitor = .mock() var resultingViewFactory: ViewFactory? @@ -352,6 +360,7 @@ extension GliaTests { logger.prefixedClosure = { _ in logger } environment.coreSdk.createLogger = { _ in logger } environment.print = .mock + environment.queuesMonitor = .mock() var resultingViewFactory: ViewFactory? environment.createRootCoordinator = { _, viewFactory, _, _, _, _, _ in @@ -401,6 +410,7 @@ extension GliaTests { environment.coreSdk.createLogger = { _ in logger } environment.print = .mock environment.conditionalCompilation.isDebug = { true } + environment.queuesMonitor = .mock() var resultingViewFactory: ViewFactory? @@ -424,6 +434,7 @@ extension GliaTests { } environment.coreSDKConfigurator.configureWithInteractor = { _ in } environment.coreSdk.getCurrentEngagement = { nil } + environment.queuesMonitor = .mock() let sdk = Glia(environment: environment) @@ -457,6 +468,7 @@ extension GliaTests { environment.coreSdk.createLogger = { _ in logger } environment.print = .mock environment.conditionalCompilation.isDebug = { true } + environment.queuesMonitor = .mock() var resultingViewFactory: ViewFactory? diff --git a/GliaWidgetsTests/Sources/Glia/GliaTests.swift b/GliaWidgetsTests/Sources/Glia/GliaTests.swift index 77624ee76..f42204502 100644 --- a/GliaWidgetsTests/Sources/Glia/GliaTests.swift +++ b/GliaWidgetsTests/Sources/Glia/GliaTests.swift @@ -92,6 +92,7 @@ final class GliaTests: XCTestCase { gliaEnv.coreSdk.fetchSiteConfigurations = { _ in } gliaEnv.uuid = { .mock } gliaEnv.gcd.mainQueue.async = { callback in callback() } + gliaEnv.queuesMonitor = .mock() let expectedTheme = Theme.mock( colorStyle: .custom(.init()), @@ -603,6 +604,7 @@ final class GliaTests: XCTestCase { var engCoordEnvironment = EngagementCoordinator.Environment.engagementCoordEnvironmentWithKeyWindow engCoordEnvironment.fileManager = .mock environment.createRootCoordinator = { _, _, _, _, _, _, _ in EngagementCoordinator.mock(environment: engCoordEnvironment) } + environment.queuesMonitor = .mock() let sdk = Glia(environment: environment) enum Call { diff --git a/GliaWidgetsTests/Sources/InteractorTests.swift b/GliaWidgetsTests/Sources/InteractorTests.swift index 3b39e2b03..0bd8a29b4 100644 --- a/GliaWidgetsTests/Sources/InteractorTests.swift +++ b/GliaWidgetsTests/Sources/InteractorTests.swift @@ -28,7 +28,7 @@ class InteractorTests: XCTestCase { coreSdkCalls.append(.queueForEngagement) } - var interactorEnv = Interactor.Environment(coreSdk: coreSdk, gcd: .failing, log: .failing) + var interactorEnv = Interactor.Environment(coreSdk: coreSdk, queuesMonitor: .mock(), gcd: .failing, log: .failing) interactorEnv.log.infoClosure = { _, _, _, _ in } interactorEnv.log.prefixedClosure = { _ in interactorEnv.log } @@ -55,7 +55,7 @@ class InteractorTests: XCTestCase { interactor = .init( visitorContext: nil, - environment: .init(coreSdk: .failing, gcd: .mock, log: .failing) + environment: .init(coreSdk: .failing, queuesMonitor: .mock(), gcd: .mock, log: .failing) ) interactor.addObserver(self, handler: { event in diff --git a/GliaWidgetsTests/Sources/QueuesMonitor/QueuesMonitorTests.swift b/GliaWidgetsTests/Sources/QueuesMonitor/QueuesMonitorTests.swift index c08b63379..868201cf5 100644 --- a/GliaWidgetsTests/Sources/QueuesMonitor/QueuesMonitorTests.swift +++ b/GliaWidgetsTests/Sources/QueuesMonitor/QueuesMonitorTests.swift @@ -26,8 +26,8 @@ class QueuesMonitorTests: XCTestCase { super.tearDown() } - // MARK: Start monitoring - func test_startMonitoringWithQueuesUpdatesWithQueuesList() { + // MARK: Fetch and Motitor queues + func test_fetchAndMonitorQueuesWithQueuesUpdatesWithQueuesList() { var envCalls: [Call] = [] let mockQueueId = UUID().uuidString @@ -53,13 +53,13 @@ class QueuesMonitorTests: XCTestCase { } .store(in: &cancellables) - monitor.startMonitoring(queuesIds: [mockQueueId]) + monitor.fetchAndMonitorQueues(queuesIds: [mockQueueId]) XCTAssertEqual(receivedQueues, expectedObservedQueues) XCTAssertEqual(envCalls, [.listQueues, .subscribeForQueuesUpdates]) } - func test_startMonitoringWithWrongQueueIdsReturnsUpdatesWithDefaultQueue() { + func test_fetchAndMonitorQueuesWithWrongQueueIdsReturnsUpdatesWithDefaultQueue() { var envCalls: [Call] = [] let expectedObservedQueues = [Queue.mock(isDefault: true)] @@ -83,13 +83,13 @@ class QueuesMonitorTests: XCTestCase { } .store(in: &cancellables) - monitor.startMonitoring(queuesIds: ["1"]) + monitor.fetchAndMonitorQueues(queuesIds: ["1"]) XCTAssertEqual(receivedQueues, expectedObservedQueues) XCTAssertEqual(envCalls, [.listQueues, .subscribeForQueuesUpdates]) } - func test_startMonitoringListQueuesReturnsError() { + func test_fetchAndMonitorQueuesListQueuesReturnsError() { var envCalls: [Call] = [] let expectedError = CoreSdkClient.SalemoveError.mock() @@ -112,13 +112,13 @@ class QueuesMonitorTests: XCTestCase { } .store(in: &cancellables) - monitor.startMonitoring(queuesIds: ["1"]) + monitor.fetchAndMonitorQueues(queuesIds: ["1"]) XCTAssertEqual(receivedError, expectedError) XCTAssertEqual(envCalls, [.listQueues]) } - func test_startMonitoringWithQueuesAndReceiveUpdatedQueueSuccess() { + func test_fetchAndMonitorQueuesWithQueuesAndReceiveUpdatedQueueSuccess() { var envCalls: [Call] = [] let mockQueueId = UUID().uuidString @@ -142,7 +142,6 @@ class QueuesMonitorTests: XCTestCase { // Drop initial .idle and .updated with listed queues state update .dropFirst(2) .sink { state in - print(state) if case let .updated(queues) = state { receivedQueues = queues receivedUpdatedQueue = queues[0] @@ -150,14 +149,107 @@ class QueuesMonitorTests: XCTestCase { } .store(in: &cancellables) - monitor.startMonitoring(queuesIds: [mockQueueId]) + monitor.fetchAndMonitorQueues(queuesIds: [mockQueueId]) XCTAssertEqual(receivedQueues, [expectedUpdatedQueue]) XCTAssertEqual(receivedUpdatedQueue?.state.status, .open) XCTAssertEqual(envCalls, [.listQueues, .subscribeForQueuesUpdates]) } - func test_startMonitoringWithQueuesAndReceiveUpdatedQueueError() { + func test_fetchAndMonitorQueuesWithQueuesStopsPreviousMonitoring() { + var envCalls: [Call] = [] + + let mockQueueId = UUID().uuidString + let expectedObservedQueue = Queue.mock(id: mockQueueId, status: .closed) + let expectedUpdatedQueue = Queue.mock(id: mockQueueId, status: .open) + let mockQueues = [expectedObservedQueue, Queue.mock(id: UUID().uuidString)] + + monitor.environment.listQueues = { completion in + envCalls.append(.listQueues) + completion(mockQueues, nil) + } + monitor.environment.subscribeForQueuesUpdates = { _, completion in + envCalls.append(.subscribeForQueuesUpdates) + completion(.success(expectedUpdatedQueue)) + return UUID().uuidString + } + + monitor.environment.unsubscribeFromUpdates = { queueCallbackId, error in + envCalls.append(.unsubscribeFromUpdates) + } + + var receivedQueues: [Queue]? + var receivedUpdatedQueue: Queue? + monitor.$state + // Drop initial .idle and .updated with listed queues state update + .dropFirst(2) + .sink { state in + if case let .updated(queues) = state { + receivedQueues = queues + receivedUpdatedQueue = queues[0] + } + } + .store(in: &cancellables) + + monitor.fetchAndMonitorQueues(queuesIds: [mockQueueId]) + monitor.fetchAndMonitorQueues(queuesIds: [mockQueueId]) + + XCTAssertEqual(receivedQueues, [expectedUpdatedQueue]) + XCTAssertEqual(receivedUpdatedQueue?.state.status, .open) + XCTAssertEqual( + envCalls, + [.listQueues, .subscribeForQueuesUpdates, .unsubscribeFromUpdates, .listQueues, .subscribeForQueuesUpdates] + ) + } + + func test_fetchAndMonitorQueuesWithQueuesStopsPreviousMonitoringFailed() { + var envCalls: [Call] = [] + + let mockQueueId = UUID().uuidString + let expectedObservedQueue = Queue.mock(id: mockQueueId, status: .closed) + let expectedUpdatedQueue = Queue.mock(id: mockQueueId, status: .open) + let mockQueues = [expectedObservedQueue, Queue.mock(id: UUID().uuidString)] + + monitor.environment.listQueues = { completion in + envCalls.append(.listQueues) + completion(mockQueues, nil) + } + monitor.environment.subscribeForQueuesUpdates = { _, completion in + envCalls.append(.subscribeForQueuesUpdates) + completion(.success(expectedUpdatedQueue)) + return UUID().uuidString + } + + monitor.environment.unsubscribeFromUpdates = { queueCallbackId, error in + envCalls.append(.unsubscribeFromUpdates) + error(CoreSdkClient.SalemoveError.mock()) + } + + var receivedQueues: [Queue]? + var receivedUpdatedQueue: Queue? + monitor.$state + // Drop initial .idle and .updated with listed queues state update + .dropFirst(2) + .sink { state in + if case let .updated(queues) = state { + receivedQueues = queues + receivedUpdatedQueue = queues[0] + } + } + .store(in: &cancellables) + + monitor.fetchAndMonitorQueues(queuesIds: [mockQueueId]) + monitor.fetchAndMonitorQueues(queuesIds: [mockQueueId]) + + XCTAssertEqual(receivedQueues, [expectedUpdatedQueue]) + XCTAssertEqual(receivedUpdatedQueue?.state.status, .open) + XCTAssertEqual( + envCalls, + [.listQueues, .subscribeForQueuesUpdates, .unsubscribeFromUpdates, .listQueues, .subscribeForQueuesUpdates] + ) + } + + func test_fetchAndMonitorQueuesWithQueuesAndReceiveUpdatedQueueError() { var envCalls: [Call] = [] let expectedError = CoreSdkClient.SalemoveError.mock() @@ -178,14 +270,13 @@ class QueuesMonitorTests: XCTestCase { // Drop initial .idle and .updated with listed queues state update .dropFirst(2) .sink { state in - print(state) if case let .failed(error as CoreSdkClient.SalemoveError) = state { receivedError = error } } .store(in: &cancellables) - monitor.startMonitoring(queuesIds: [UUID().uuidString]) + monitor.fetchAndMonitorQueues(queuesIds: [UUID().uuidString]) XCTAssertEqual(receivedError, expectedError) XCTAssertEqual(envCalls, [.listQueues, .subscribeForQueuesUpdates]) @@ -211,7 +302,7 @@ class QueuesMonitorTests: XCTestCase { completion(expectedError) } - monitor.startMonitoring(queuesIds: ["1"]) + monitor.fetchAndMonitorQueues(queuesIds: ["1"]) var receivedError: CoreSdkClient.SalemoveError? monitor.$state @@ -246,7 +337,7 @@ class QueuesMonitorTests: XCTestCase { completion(.mock()) } - monitor.startMonitoring(queuesIds: ["1"]) + monitor.fetchAndMonitorQueues(queuesIds: ["1"]) monitor.stopMonitoring()