Skip to content

Commit c06747d

Browse files
authored
[Fix]Respect dashboard callSettings for outgoing calls when no local settings provided (#841)
1 parent c39e9d8 commit c06747d

File tree

5 files changed

+101
-7
lines changed

5 files changed

+101
-7
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
44

55
# Upcoming
66

7-
### 🔄 Changed
7+
### 🐞 Fixed
8+
- The CallViewModel will now respect the dashboard's `CallSettings` when starting a `Call` with `ring:true` and without provided `CallSettings`. [#841](https://github.com/GetStream/stream-video-swift/pull/841)
89

910
# [1.24.0](https://github.com/GetStream/stream-video-swift/releases/tag/1.24.0)
1011
_June 02, 2025_

Sources/StreamVideoSwiftUI/CallViewModel.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,9 @@ open class CallViewModel: ObservableObject {
363363
customData: customData
364364
)
365365
} else {
366+
/// If no CallSettings have been provided, we skip passing the default ones, in order to
367+
/// respect any dashboard changes.
368+
let callSettings = localCallSettingsChange ? callSettings : nil
366369
let call = streamVideo.call(
367370
callType: callType,
368371
callId: callId,

StreamVideoSwiftUITests/CallViewModel_Tests.swift

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,73 @@ final class CallViewModel_Tests: StreamVideoTestCase, @unchecked Sendable {
3636
super.tearDown()
3737
}
3838

39+
@MainActor
40+
func test_startCall_withoutLocalCallSettingsAndRingTrue_respectsDashboardSettings() async throws {
41+
// Given
42+
let mockCall = MockCall(.dummy(callType: .default, callId: callId))
43+
await streamVideo?.disconnect()
44+
streamVideo = nil
45+
let mockStreamVideo = MockStreamVideo()
46+
mockStreamVideo.stub(for: .call, with: mockCall)
47+
let callViewModel = CallViewModel()
48+
49+
// When
50+
callViewModel.startCall(
51+
callType: .default,
52+
callId: callId,
53+
members: participants,
54+
ring: true
55+
)
56+
57+
// Then
58+
XCTAssertEqual(mockStreamVideo.timesCalled(.call), 1)
59+
let (
60+
recordedCallType,
61+
recordedCallId,
62+
recordedCallSettings
63+
) = try XCTUnwrap(
64+
mockStreamVideo
65+
.recordedInputPayload((String, String, CallSettings?).self, for: .call)?.first
66+
)
67+
XCTAssertEqual(recordedCallType, callType)
68+
XCTAssertEqual(recordedCallId, callId)
69+
XCTAssertNil(recordedCallSettings)
70+
}
71+
72+
@MainActor
73+
func test_startCall_withLocalCallSettingsAndRingTrue_respectsLocalSettings() async throws {
74+
// Given
75+
let mockCall = MockCall(.dummy(callType: .default, callId: callId))
76+
await streamVideo?.disconnect()
77+
streamVideo = nil
78+
let mockStreamVideo = MockStreamVideo()
79+
mockStreamVideo.stub(for: .call, with: mockCall)
80+
let callViewModel = CallViewModel(callSettings: .init(audioOn: false, audioOutputOn: false))
81+
82+
// When
83+
callViewModel.startCall(
84+
callType: .default,
85+
callId: callId,
86+
members: participants,
87+
ring: true
88+
)
89+
90+
// Then
91+
XCTAssertEqual(mockStreamVideo.timesCalled(.call), 1)
92+
let (
93+
recordedCallType,
94+
recordedCallId,
95+
recordedCallSettings
96+
) = try XCTUnwrap(
97+
mockStreamVideo
98+
.recordedInputPayload((String, String, CallSettings?).self, for: .call)?.first
99+
)
100+
XCTAssertEqual(recordedCallType, callType)
101+
XCTAssertEqual(recordedCallId, callId)
102+
XCTAssertFalse(recordedCallSettings?.audioOn ?? true)
103+
XCTAssertFalse(recordedCallSettings?.audioOutputOn ?? true)
104+
}
105+
39106
@MainActor
40107
func test_startCall_joiningState() {
41108
// Given

StreamVideoTests/Mock/MockCall.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import Foundation
88
final class MockCall: Call, Mockable, @unchecked Sendable {
99

1010
typealias FunctionKey = MockCallFunctionKey
11+
typealias FunctionInputKey = MockCallFunctionInputKey
1112

1213
enum MockCallFunctionKey: Hashable, CaseIterable {
1314
case get
@@ -52,9 +53,8 @@ final class MockCall: Call, Mockable, @unchecked Sendable {
5253

5354
var stubbedProperty: [String: Any]
5455
var stubbedFunction: [FunctionKey: Any] = [:]
55-
@Atomic var stubbedFunctionInput: [FunctionKey: [MockCallFunctionInputKey]] = MockCallFunctionKey
56-
.allCases
57-
.reduce(into: [FunctionKey: [MockCallFunctionInputKey]]()) { $0[$1] = [] }
56+
@Atomic var stubbedFunctionInput: [FunctionKey: [FunctionInputKey]] = FunctionKey.allCases
57+
.reduce(into: [FunctionKey: [FunctionInputKey]]()) { $0[$1] = [] }
5858

5959
override var state: CallState {
6060
get { self[dynamicMember: \.state] }

StreamVideoTests/Mock/MockStreamVideo.swift

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,32 @@ import Foundation
77

88
final class MockStreamVideo: StreamVideo, Mockable, @unchecked Sendable {
99
typealias FunctionKey = MockStreamVideoFunctionKey
10-
typealias FunctionInputKey = EmptyPayloadable
10+
typealias FunctionInputKey = MockFunctionInputKey
1111

1212
enum MockStreamVideoFunctionKey: Hashable, CaseIterable {
1313
case call
1414
case connect
1515
}
1616

17+
enum MockFunctionInputKey: Payloadable {
18+
case call(
19+
callType: String,
20+
callId: String,
21+
callSettings: CallSettings?
22+
)
23+
24+
var payload: Any {
25+
switch self {
26+
case let .call(callType, callId, callSettings):
27+
return (callType, callId, callSettings)
28+
}
29+
}
30+
}
31+
1732
var stubbedProperty: [String: Any] = [:]
1833
var stubbedFunction: [FunctionKey: Any] = [:]
19-
var stubbedFunctionInput: [FunctionKey: [FunctionInputKey]] = [:]
34+
@Atomic var stubbedFunctionInput: [FunctionKey: [FunctionInputKey]] = FunctionKey.allCases
35+
.reduce(into: [FunctionKey: [FunctionInputKey]]()) { $0[$1] = [] }
2036

2137
override var state: StreamVideo.State {
2238
get { self[dynamicMember: \.state] }
@@ -67,7 +83,14 @@ final class MockStreamVideo: StreamVideo, Mockable, @unchecked Sendable {
6783
callId: String,
6884
callSettings: CallSettings? = nil
6985
) -> Call {
70-
stubbedFunction[.call] as! Call
86+
stubbedFunctionInput[.call]?.append(
87+
.call(
88+
callType: callType,
89+
callId: callId,
90+
callSettings: callSettings
91+
)
92+
)
93+
return stubbedFunction[.call] as! Call
7194
}
7295

7396
override func connect() async throws {

0 commit comments

Comments
 (0)