Skip to content

Commit

Permalink
Fix ending CV engagement
Browse files Browse the repository at this point in the history
Previously if WidgetsSDK is configured one time and then visitor has regular engagement, then CV engagement with screen sharing, if the operator ends CV engagement, bubble and screen sharing state is still displayed. It happened because EngagementViewModel called interator.endSession which set `isEngagementEndedByVisitor` to `true` even in case if engagement is ended by operator. Since CV engagement is started without additional `configure` call, interactor keeps  `isEngagementEndedByVisitor` as `true`, which was broking CV flow.
This commit fixes it.

MOB-2731
  • Loading branch information
Egor Egorov authored and EgorovEI committed Nov 2, 2023
1 parent fc36d18 commit fc5c6f8
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 6 deletions.
4 changes: 4 additions & 0 deletions GliaWidgets.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,7 @@
845E2F9D283FCB1400C04D56 /* Theme.Survey.Checkbox.Accessibility.swift in Sources */ = {isa = PBXBuildFile; fileRef = 845E2F9C283FCB1400C04D56 /* Theme.Survey.Checkbox.Accessibility.swift */; };
84602A742AE94DE50031E606 /* ProximityManager.Mock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84602A732AE94DE50031E606 /* ProximityManager.Mock.swift */; };
84602A772AEA5BEA0031E606 /* ProximityManager.Failing.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84602A762AEA5BEA0031E606 /* ProximityManager.Failing.swift */; };
84602A792AEAB7CA0031E606 /* Survey.Mock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84602A782AEAB7CA0031E606 /* Survey.Mock.swift */; };
8464297A2A44937600943BD6 /* AlertViewControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 846429792A44937600943BD6 /* AlertViewControllerTests.swift */; };
8464297D2A459E7D00943BD6 /* UIViewController+Replaceble.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8464297C2A459E7D00943BD6 /* UIViewController+Replaceble.swift */; };
846429802A45A1F200943BD6 /* OfferPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8464297F2A45A1F200943BD6 /* OfferPresenter.swift */; };
Expand Down Expand Up @@ -1093,6 +1094,7 @@
845E2F9C283FCB1400C04D56 /* Theme.Survey.Checkbox.Accessibility.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Theme.Survey.Checkbox.Accessibility.swift; sourceTree = "<group>"; };
84602A732AE94DE50031E606 /* ProximityManager.Mock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProximityManager.Mock.swift; sourceTree = "<group>"; };
84602A762AEA5BEA0031E606 /* ProximityManager.Failing.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProximityManager.Failing.swift; sourceTree = "<group>"; };
84602A782AEAB7CA0031E606 /* Survey.Mock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Survey.Mock.swift; sourceTree = "<group>"; };
846429792A44937600943BD6 /* AlertViewControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlertViewControllerTests.swift; sourceTree = "<group>"; };
8464297C2A459E7D00943BD6 /* UIViewController+Replaceble.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIViewController+Replaceble.swift"; sourceTree = "<group>"; };
8464297F2A45A1F200943BD6 /* OfferPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OfferPresenter.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -3180,6 +3182,7 @@
isa = PBXGroup;
children = (
84681A972A61853300DD7406 /* GvaOption.Mock.swift */,
84602A782AEAB7CA0031E606 /* Survey.Mock.swift */,
);
path = Mocks;
sourceTree = "<group>";
Expand Down Expand Up @@ -4940,6 +4943,7 @@
846429832A45DA7500943BD6 /* AlertViewController+Mock.swift in Sources */,
846A5C4529F6BEFA0049B29F /* GliaTests+StartEngagement.swift in Sources */,
7512A57A27BF9FCD00319DF1 /* ChatViewModelTests.swift in Sources */,
84602A792AEAB7CA0031E606 /* Survey.Mock.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
2 changes: 1 addition & 1 deletion GliaWidgets/Public/Glia/Glia.swift
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ extension Glia {
case let .videoStreamAdded(stream):
self?.callVisualizer.addVideoStream(stream: stream)
case let .stateChanged(state):
if state == .ended(.byOperator) {
if case .ended = state {
self?.callVisualizer.endSession()
self?.onEvent?(.ended)
} else if case .engaged = state {
Expand Down
17 changes: 12 additions & 5 deletions GliaWidgets/Sources/Interactor/Interactor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ class Interactor {
var currentEngagement: CoreSdkClient.Engagement?

private var observers = [() -> (AnyObject?, EventHandler)]()
private var isEngagementEndedByVisitor = false

var state: InteractorState = .none {
didSet {
Expand Down Expand Up @@ -159,8 +158,6 @@ extension Interactor {
success: @escaping () -> Void,
failure: @escaping (CoreSdkClient.SalemoveError) -> Void
) {
isEngagementEndedByVisitor = true

switch state {
case .none:
success()
Expand Down Expand Up @@ -203,10 +200,11 @@ extension Interactor {
success: @escaping () -> Void,
failure: @escaping (CoreSdkClient.SalemoveError) -> Void
) {
environment.coreSdk.endEngagement { _, error in
environment.coreSdk.endEngagement { [weak self] _, error in
if let error = error {
failure(error)
} else {
self?.state = .ended(.byVisitor)
success()
}
}
Expand Down Expand Up @@ -335,7 +333,16 @@ extension Interactor: CoreSdkClient.Interactable {

func end(with reason: CoreSdkClient.EngagementEndingReason) {
currentEngagement = environment.coreSdk.getCurrentEngagement()
state = isEngagementEndedByVisitor == true ? .ended(.byVisitor) : .ended(.byOperator)
switch reason {
case .visitorHungUp:
state = .ended(.byVisitor)
case .operatorHungUp:
state = .ended(.byOperator)
case .error:
state = .ended(.byError)
@unknown default:
state = .ended(.byError)
}
}

func fail(error: CoreSdkClient.SalemoveError) {
Expand Down
24 changes: 24 additions & 0 deletions GliaWidgetsTests/Sources/ChatViewModel/Mocks/Survey.Mock.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import Foundation
@testable import GliaWidgets

extension CoreSdkClient.Survey {
static func mock(
id: String = "mock",
description: String = "mock",
name: String = "mock",
title: String = "mock",
type: String = "visitor",
siteId: String = "mock"
) throws -> Self {
let data = try JSONSerialization.data(withJSONObject: [
"id": id,
"description": description,
"name": name,
"title": title,
"type": type,
"siteId": siteId,
"questions": []
])
return try JSONDecoder().decode(CoreSdkClient.Survey.self, from: data)
}
}
30 changes: 30 additions & 0 deletions GliaWidgetsTests/Sources/Glia/GliaTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -353,4 +353,34 @@ final class GliaTests: XCTestCase {
XCTAssertNil(sdk.rootCoordinator)
XCTAssertNil(rootCoordinator)
}

func test_screenSharingIsStoppedWhenCallVisualizerEngagementIsEnded() throws {
enum Call { case ended }
var calls: [Call] = []
var gliaEnv = Glia.Environment.failing
let screenShareHandler: ScreenShareHandler = .mock
screenShareHandler.status().value = .started
gliaEnv.screenShareHandler = screenShareHandler
gliaEnv.gcd.mainQueue.asyncIfNeeded = { callback in callback() }
gliaEnv.coreSDKConfigurator.configureWithConfiguration = { _, callback in
callback?()
}
gliaEnv.coreSDKConfigurator.configureWithInteractor = { _ in }
let sdk = Glia(environment: gliaEnv)
try sdk.configure(with: .mock()) {}
sdk.callVisualizer.delegate?(.visitorCodeIsRequested)
sdk.environment.coreSdk.getCurrentEngagement = { .mock(source: .callVisualizer) }
sdk.onEvent = { event in
switch event {
case .ended:
calls.append(.ended)
default:
XCTFail("There is should be no another event")
}
}
sdk.interactor?.state = .ended(.byVisitor)

XCTAssertEqual(screenShareHandler.status().value, .stopped)
XCTAssertEqual(calls, [.ended])
}
}
30 changes: 30 additions & 0 deletions GliaWidgetsTests/Sources/InteractorTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -447,4 +447,34 @@ class InteractorTests: XCTestCase {

XCTAssertEqual(callbacks, [.mediaUpgradeOffered])
}

func test_endEngagementSetsStateToEndedByVisitor() {
var interactorEnv = Interactor.Environment.failing
interactorEnv.coreSdk.endEngagement = { completion in completion(true, nil) }
let interactor = Interactor.mock(environment: interactorEnv)
interactor.state = .engaged(.mock())

interactor.endSession(success: {}, failure: { _ in })

XCTAssertEqual(interactor.state, .ended(.byVisitor))
}

func test_endWithReasonSetsProperState() {
let interactor = Interactor.failing
interactor.state = .engaged(.mock())
typealias Item = (reason: CoreSdkClient.EngagementEndingReason, state: InteractorState)

let items: [Item] = [
(.visitorHungUp, .ended(.byVisitor)),
(.operatorHungUp, .ended(.byOperator)),
(.error, .ended(.byError))
]

let test: (Item) -> Void = { item in
interactor.end(with: item.reason)
XCTAssertEqual(interactor.state, item.state)
}

items.forEach(test)
}
}

0 comments on commit fc5c6f8

Please sign in to comment.