Skip to content

Commit

Permalink
Cover QueuesMonitor with unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
ykyivskyi-gl authored and Egor Egorov committed Oct 22, 2024
1 parent f5d25d0 commit 6606af7
Show file tree
Hide file tree
Showing 5 changed files with 285 additions and 15 deletions.
22 changes: 18 additions & 4 deletions GliaWidgets.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -165,12 +165,13 @@
1AFB1E6825F7AE3C00CA460D /* ChatAttachment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AFB1E6725F7AE3C00CA460D /* ChatAttachment.swift */; };
1AFB1E7425F8B00B00CA460D /* ChatTextContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AFB1E7325F8B00B00CA460D /* ChatTextContentView.swift */; };
1AFB1E7825F8B26800CA460D /* ChatTextContentStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AFB1E7725F8B26800CA460D /* ChatTextContentStyle.swift */; };
2100B4802CB6B5A400AC7527 /* LockIsolated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2100B47F2CB6B5A400AC7527 /* LockIsolated.swift */; };
2100B47C2CB66B6500AC7527 /* EntryWidget.Environment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2100B47B2CB66B6500AC7527 /* EntryWidget.Environment.swift */; };
2100B47E2CB6A37A00AC7527 /* QueuesMonitor.Mock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2100B47D2CB6A37A00AC7527 /* QueuesMonitor.Mock.swift */; };
2100B4802CB6B5A400AC7527 /* LockIsolated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2100B47F2CB6B5A400AC7527 /* LockIsolated.swift */; };
2100B4842CB8143400AC7527 /* QueuesMonitor.Failing.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2100B4832CB8143400AC7527 /* QueuesMonitor.Failing.swift */; };
2100B4872CB91E7B00AC7527 /* CancelBag.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2100B4862CB91E7B00AC7527 /* CancelBag.swift */; };
210150742CC13E8900294BA4 /* QueuesMonitorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 210150732CC13E8900294BA4 /* QueuesMonitorTests.swift */; };
210150782CC14E8200294BA4 /* QueuesMonitor.Environment.Mock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 210150752CC140A600294BA4 /* QueuesMonitor.Environment.Mock.swift */; };
210150792CC14E8200294BA4 /* QueuesMonitor.Mock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2100B47D2CB6A37A00AC7527 /* QueuesMonitor.Mock.swift */; };
215A25902CA44D8A0013023E /* Glia+EngagementLauncher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 215A258F2CA44D8A0013023E /* Glia+EngagementLauncher.swift */; };
215A25932CA44D900013023E /* EngagementLauncher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 215A25912CA44D900013023E /* EngagementLauncher.swift */; };
215A25982CABC7DF0013023E /* EngagementLauncherTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 215A25972CABC7DF0013023E /* EngagementLauncherTests.swift */; };
Expand Down Expand Up @@ -1214,12 +1215,13 @@
1AFB1E6725F7AE3C00CA460D /* ChatAttachment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatAttachment.swift; sourceTree = "<group>"; };
1AFB1E7325F8B00B00CA460D /* ChatTextContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatTextContentView.swift; sourceTree = "<group>"; };
1AFB1E7725F8B26800CA460D /* ChatTextContentStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatTextContentStyle.swift; sourceTree = "<group>"; };
2100B47F2CB6B5A400AC7527 /* LockIsolated.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LockIsolated.swift; sourceTree = "<group>"; };
2100B47B2CB66B6500AC7527 /* EntryWidget.Environment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EntryWidget.Environment.swift; sourceTree = "<group>"; };
2100B47D2CB6A37A00AC7527 /* QueuesMonitor.Mock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QueuesMonitor.Mock.swift; sourceTree = "<group>"; };
2100B47F2CB6B5A400AC7527 /* LockIsolated.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LockIsolated.swift; sourceTree = "<group>"; };
2100B4832CB8143400AC7527 /* QueuesMonitor.Failing.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QueuesMonitor.Failing.swift; sourceTree = "<group>"; };
2100B4862CB91E7B00AC7527 /* CancelBag.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CancelBag.swift; sourceTree = "<group>"; };
210150732CC13E8900294BA4 /* QueuesMonitorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QueuesMonitorTests.swift; sourceTree = "<group>"; };
210150752CC140A600294BA4 /* QueuesMonitor.Environment.Mock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QueuesMonitor.Environment.Mock.swift; sourceTree = "<group>"; };
215A258F2CA44D8A0013023E /* Glia+EngagementLauncher.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Glia+EngagementLauncher.swift"; sourceTree = "<group>"; };
215A25912CA44D900013023E /* EngagementLauncher.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EngagementLauncher.swift; sourceTree = "<group>"; };
215A25972CABC7DF0013023E /* EngagementLauncherTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EngagementLauncherTests.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -3242,6 +3244,14 @@
path = Utilities;
sourceTree = "<group>";
};
210150722CC13E7300294BA4 /* QueuesMonitor */ = {
isa = PBXGroup;
children = (
210150732CC13E8900294BA4 /* QueuesMonitorTests.swift */,
);
path = QueuesMonitor;
sourceTree = "<group>";
};
215A25922CA44D900013023E /* EngagementLauncher */ = {
isa = PBXGroup;
children = (
Expand All @@ -3263,6 +3273,7 @@
children = (
2198B7AB2CAEB14D002C442B /* QueuesMonitor.Live.swift */,
2100B47D2CB6A37A00AC7527 /* QueuesMonitor.Mock.swift */,
210150752CC140A600294BA4 /* QueuesMonitor.Environment.Mock.swift */,
2198B7AD2CB035A6002C442B /* QueuesMonitor.Environment.swift */,
);
path = QueuesMonitor;
Expand Down Expand Up @@ -3538,6 +3549,7 @@
7512A57827BF9FB800319DF1 /* Sources */ = {
isa = PBXGroup;
children = (
210150722CC13E7300294BA4 /* QueuesMonitor */,
215A25962CABC7C50013023E /* EngagementLauncher */,
C0D6C9FE2C106A0D00D4709B /* AlertManager */,
8418AD792BFB68C9007DE207 /* OnHoldOverlayVisualEffectView */,
Expand Down Expand Up @@ -5781,10 +5793,10 @@
C0F3DE3B2C6E0DD900DE6D7B /* EntryWidgetView.swift in Sources */,
C090474C2B7E210C003C437C /* FileUploadStyle.Equatable.swift in Sources */,
C09047402B7E1FBC003C437C /* MessageCenterFileUploadStyle.swift in Sources */,
2100B47E2CB6A37A00AC7527 /* QueuesMonitor.Mock.swift in Sources */,
9A8130BB27D7A41000220BBD /* FileUpload.Environment.Interface.swift in Sources */,
C09046AB2B7D0967003C437C /* WelcomeStyle.SendButton.DisabledStyle.Accessibility.swift in Sources */,
84520BE72B1769AB00F97617 /* ChatViewController.Environment.swift in Sources */,
210150792CC14E8200294BA4 /* QueuesMonitor.Mock.swift in Sources */,
3100D92B296E946600DEC9CE /* SecureConversations.ConfirmationStyle.swift in Sources */,
C090477C2B7E27F1003C437C /* EngagementStyle.Equatable.swift in Sources */,
8491AF132A7ACC5400CC3E72 /* Theme.OperatorChatMessageStyle.swift in Sources */,
Expand Down Expand Up @@ -5849,6 +5861,7 @@
7594093F298D376B008B173A /* RemoteConfiguration+Chat.swift in Sources */,
C09047232B7E1B7F003C437C /* GvaGalleryCardStyle.TextStyle.RemoteConfig.swift in Sources */,
9A3E1D9427B6C29C005634EB /* ChatEngagementFile.Mock.swift in Sources */,
210150782CC14E8200294BA4 /* QueuesMonitor.Environment.Mock.swift in Sources */,
C09046D22B7E0843003C437C /* BadgeStyle.RemoteConfig.swift in Sources */,
1A2DA73B25EFC00500032611 /* FileUploadListStyle.swift in Sources */,
C0D6CA632C19C59100D4709B /* Glia.OpaqueAuthentication.Environment.swift in Sources */,
Expand Down Expand Up @@ -6551,6 +6564,7 @@
846A5C4529F6BEFA0049B29F /* GliaTests+StartEngagement.swift in Sources */,
7512A57A27BF9FCD00319DF1 /* ChatViewModelTests.swift in Sources */,
84602A792AEAB7CA0031E606 /* Survey.Mock.swift in Sources */,
210150742CC13E8900294BA4 /* QueuesMonitorTests.swift in Sources */,
31CCE3E42BCE8F3A00F92535 /* CallVisualizerCoordinatorTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#if DEBUG
extension QueuesMonitor.Environment {
static let mock: Self = .init(
listQueues: { _ in },
subscribeForQueuesUpdates: { _, _ in UUID().uuidString },
unsubscribeFromUpdates: { _, _ in }
)
}
#endif
4 changes: 2 additions & 2 deletions GliaWidgets/Sources/QueuesMonitor/QueuesMonitor.Live.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import Foundation
import GliaCoreSDK
import Combine

// TODO: Add unit tests in context of MOB-3669
final class QueuesMonitor {
enum State {
case idle
Expand All @@ -12,7 +11,8 @@ final class QueuesMonitor {

@Published private(set) var state: State = .idle

private let environment: Environment
/// Declared as internal var for unit tests purposes
var environment: Environment
private var subscriptionId: String? {
_subscriptionId.value
}
Expand Down
10 changes: 1 addition & 9 deletions GliaWidgets/Sources/QueuesMonitor/QueuesMonitor.Mock.swift
Original file line number Diff line number Diff line change
@@ -1,13 +1,5 @@
#if DEBUG
import Foundation

extension QueuesMonitor {
static let mock = QueuesMonitor(
environment: .init(
listQueues: { _ in },
subscribeForQueuesUpdates: { _, _ in UUID().uuidString },
unsubscribeFromUpdates: { _, _ in }
)
)
static let mock = QueuesMonitor(environment: .mock)
}
#endif
255 changes: 255 additions & 0 deletions GliaWidgetsTests/Sources/QueuesMonitor/QueuesMonitorTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,255 @@
import XCTest
import Combine
import GliaCoreSDK

@testable import GliaWidgets

class QueuesMonitorTests: XCTestCase {
private enum Call {
case listQueues
case subscribeForQueuesUpdates
case unsubscribeFromUpdates
}

private var monitor: QueuesMonitor!
private var cancellables: CancelBag!

override func setUp() {
super.setUp()
cancellables = .init()

monitor = QueuesMonitor(environment: .mock)
}

override func tearDown() {
monitor = nil
super.tearDown()
}

// MARK: Start monitoring
func test_startMonitoringWithQueuesUpdatesWithQueuesList() {
var envCalls: [Call] = []

let mockQueueId = UUID().uuidString
let expectedObservedQueues = [Queue.mock(id: mockQueueId)]
let mockQueues = [expectedObservedQueues[0], 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(expectedObservedQueues[0]))
return UUID().uuidString
}

var receivedQueues: [Queue]?
monitor.$state
.sink { state in
if case let .updated(queues) = state {
receivedQueues = queues
}
}
.store(in: &cancellables)

monitor.startMonitoring(queuesIds: [mockQueueId])

XCTAssertEqual(receivedQueues, expectedObservedQueues)
XCTAssertEqual(envCalls, [.listQueues, .subscribeForQueuesUpdates])
}

func test_startMonitoringWithWrongQueueIdsReturnsUpdatesWithDefaultQueue() {
var envCalls: [Call] = []

let expectedObservedQueues = [Queue.mock(isDefault: true)]
let mockQueues = [expectedObservedQueues[0], Queue.mock()]

monitor.environment.listQueues = { completion in
envCalls.append(.listQueues)
completion(mockQueues, nil)
}
monitor.environment.subscribeForQueuesUpdates = { _, completion in
envCalls.append(.subscribeForQueuesUpdates)
return UUID().uuidString
}

var receivedQueues: [Queue]?
monitor.$state
.sink { state in
if case let .updated(queues) = state {
receivedQueues = queues
}
}
.store(in: &cancellables)

monitor.startMonitoring(queuesIds: ["1"])

XCTAssertEqual(receivedQueues, expectedObservedQueues)
XCTAssertEqual(envCalls, [.listQueues, .subscribeForQueuesUpdates])
}

func test_startMonitoringListQueuesReturnsError() {
var envCalls: [Call] = []

let expectedError = CoreSdkClient.SalemoveError.mock()

monitor.environment.listQueues = { completion in
envCalls.append(.listQueues)
completion(nil, expectedError)
}
monitor.environment.subscribeForQueuesUpdates = { _, completion in
envCalls.append(.subscribeForQueuesUpdates)
return UUID().uuidString
}

var receivedError: CoreSdkClient.SalemoveError?
monitor.$state
.sink { state in
if case let .failed(error as CoreSdkClient.SalemoveError) = state {
receivedError = error
}
}
.store(in: &cancellables)

monitor.startMonitoring(queuesIds: ["1"])

XCTAssertEqual(receivedError, expectedError)
XCTAssertEqual(envCalls, [.listQueues])
}

func test_startMonitoringWithQueuesAndReceiveUpdatedQueueSuccess() {
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
}

var receivedQueues: [Queue]?
var receivedUpdatedQueue: Queue?
monitor.$state
// 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]
}
}
.store(in: &cancellables)

monitor.startMonitoring(queuesIds: [mockQueueId])

XCTAssertEqual(receivedQueues, [expectedUpdatedQueue])
XCTAssertEqual(receivedUpdatedQueue?.state.status, .open)
XCTAssertEqual(envCalls, [.listQueues, .subscribeForQueuesUpdates])
}

func test_startMonitoringWithQueuesAndReceiveUpdatedQueueError() {
var envCalls: [Call] = []

let expectedError = CoreSdkClient.SalemoveError.mock()
let mockQueues = [Queue.mock()]

monitor.environment.listQueues = { completion in
envCalls.append(.listQueues)
completion(mockQueues, nil)
}
monitor.environment.subscribeForQueuesUpdates = { _, completion in
envCalls.append(.subscribeForQueuesUpdates)
completion(.failure(expectedError))
return nil
}

var receivedError: CoreSdkClient.SalemoveError?
monitor.$state
// 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])

XCTAssertEqual(receivedError, expectedError)
XCTAssertEqual(envCalls, [.listQueues, .subscribeForQueuesUpdates])
}

// MARK: Stop monitoring
func test_stopMonitoringReturnError() {
var envCalls: [Call] = []

let expectedError = CoreSdkClient.SalemoveError.mock()

monitor.environment.listQueues = { completion in
envCalls.append(.listQueues)
completion([], nil)
}
monitor.environment.subscribeForQueuesUpdates = { _, completion in
envCalls.append(.subscribeForQueuesUpdates)
completion(.success(.mock()))
return UUID().uuidString
}
monitor.environment.unsubscribeFromUpdates = { subscriptionId, completion in
envCalls.append(.unsubscribeFromUpdates)
completion(expectedError)
}

monitor.startMonitoring(queuesIds: ["1"])

var receivedError: CoreSdkClient.SalemoveError?
monitor.$state
.dropFirst()
.sink { state in
if case .failed(let error as CoreSdkClient.SalemoveError) = state {
receivedError = error
}
}
.store(in: &cancellables)

monitor.stopMonitoring()

XCTAssertEqual(receivedError, expectedError)
XCTAssertEqual(envCalls, [.listQueues, .subscribeForQueuesUpdates, .unsubscribeFromUpdates])
}

func test_stopMonitoringSuccess() {
var envCalls: [Call] = []

monitor.environment.listQueues = { completion in
envCalls.append(.listQueues)
completion([], nil)
}
monitor.environment.subscribeForQueuesUpdates = { _, completion in
envCalls.append(.subscribeForQueuesUpdates)
completion(.success(.mock()))
return UUID().uuidString
}
monitor.environment.unsubscribeFromUpdates = { subscriptionId, completion in
envCalls.append(.unsubscribeFromUpdates)
completion(.mock())
}

monitor.startMonitoring(queuesIds: ["1"])

monitor.stopMonitoring()

XCTAssertEqual(envCalls, [.listQueues, .subscribeForQueuesUpdates, .unsubscribeFromUpdates])
}
}

0 comments on commit 6606af7

Please sign in to comment.