[Fix]Show joining state after accepting an incoming call#1079
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (3)
🚧 Files skipped from review as they are similar to previous changes (2)
📝 WalkthroughWalkthroughThe incoming call acceptance flow now sets CallViewModel's calling state to Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~8 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
📝 Coding Plan for PR comments
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@StreamVideoSwiftUITests/CallViewModel_Tests.swift`:
- Around line 409-435: The test
test_incomingCall_acceptCall_updatesCallingStateToJoiningBeforeInCall currently
only verifies that .joining is emitted sometime before the final
assertCallingState(.inCall) and can miss ordering regressions; modify the test
to record the sequence of emitted callingState values from subject.$callingState
(use dropFirst() as before), collect them into an array until the final .inCall
is observed (or use an expectation that fulfills when .inCall is seen), then
assert that the observed transition sequence contains the ordered subsequence
[.joining, .inCall] (i.e., the first relevant states are [.joining, .inCall])
after calling subject.acceptCall(callType: callType, callId: callId) and before
calling assertCallingState(.inCall).
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: f176efca-1502-4c0e-8c7d-f422cdc03e40
📒 Files selected for processing (3)
CHANGELOG.mdSources/StreamVideoSwiftUI/CallViewModel.swiftStreamVideoSwiftUITests/CallViewModel_Tests.swift
| func test_incomingCall_acceptCall_updatesCallingStateToJoiningBeforeInCall() async throws { | ||
| // Given | ||
| await prepareIncomingCallScenario() | ||
| let joiningStateExpectation = expectation( | ||
| description: "CallingState becomes joining" | ||
| ) | ||
| joiningStateExpectation.assertForOverFulfill = false | ||
| var cancellable: AnyCancellable? | ||
|
|
||
| // Capture the transient state because `acceptCall` continues into the | ||
| // async `enterCall` flow immediately after the acceptance request. | ||
| cancellable = subject.$callingState | ||
| .dropFirst() | ||
| .sink { state in | ||
| if state == .joining { | ||
| joiningStateExpectation.fulfill() | ||
| } | ||
| } | ||
| defer { cancellable?.cancel() } | ||
|
|
||
| // When | ||
| subject.acceptCall(callType: callType, callId: callId) | ||
|
|
||
| // Then | ||
| await fulfillment(of: [joiningStateExpectation], timeout: defaultTimeout) | ||
| await assertCallingState(.inCall) | ||
| } |
There was a problem hiding this comment.
Assert the transition order explicitly.
This only proves that .joining is emitted at some point before the final assertion. A sequence like .inCall → .joining → .inCall would still pass, so the regression on intermediate-state ordering is not fully covered. Record the emitted states and assert the first relevant transition is [.joining, .inCall].
Suggested test tightening
- let joiningStateExpectation = expectation(
- description: "CallingState becomes joining"
- )
- joiningStateExpectation.assertForOverFulfill = false
+ let stateSequenceExpectation = expectation(
+ description: "CallingState emits joining before inCall"
+ )
var cancellable: AnyCancellable?
+ var emittedStates: [CallingState] = []
- // Capture the transient state because `acceptCall` continues into the
- // async `enterCall` flow immediately after the acceptance request.
cancellable = subject.$callingState
.dropFirst()
.sink { state in
- if state == .joining {
- joiningStateExpectation.fulfill()
+ emittedStates.append(state)
+ if Array(emittedStates.suffix(2)) == [.joining, .inCall] {
+ stateSequenceExpectation.fulfill()
}
}
defer { cancellable?.cancel() }
@@
- await fulfillment(of: [joiningStateExpectation], timeout: defaultTimeout)
+ await fulfillment(of: [stateSequenceExpectation], timeout: defaultTimeout)
+ XCTAssertEqual(Array(emittedStates.prefix(2)), [.joining, .inCall])
await assertCallingState(.inCall)🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@StreamVideoSwiftUITests/CallViewModel_Tests.swift` around lines 409 - 435,
The test test_incomingCall_acceptCall_updatesCallingStateToJoiningBeforeInCall
currently only verifies that .joining is emitted sometime before the final
assertCallingState(.inCall) and can miss ordering regressions; modify the test
to record the sequence of emitted callingState values from subject.$callingState
(use dropFirst() as before), collect them into an array until the final .inCall
is observed (or use an expectation that fulfills when .inCall is seen), then
assert that the observed transition sequence contains the ordered subsequence
[.joining, .inCall] (i.e., the first relevant states are [.joining, .inCall])
after calling subject.acceptCall(callType: callType, callId: callId) and before
calling assertCallingState(.inCall).
martinmitrevski
left a comment
There was a problem hiding this comment.
Good to check the e2e tests failing
Move CallViewModel into .joining as soon as an incoming call is accepted so the joining UI is shown while enterCall completes asynchronously. Add a regression test that verifies the transient joining state is emitted before the final in-call state, and document the fix in the changelog. # Conflicts: # CHANGELOG.md
d50af14 to
d7196ad
Compare
Public Interface🚀 No changes affecting the public interface. |
SDK Size
|
StreamVideoSwiftUI XCSize
|
|



🔗 Issue Links
Resolves https://linear.app/stream/issue/IOS-1475/joining-calling-state-its-never-reachable-while-accepting-a-ringing
🎯 Goal
Ensure accepting an incoming call moves
CallViewModelinto the joiningstate immediately so the connecting UI is visible while the async join flow
finishes.
📝 Summary
acceptCallto setcallingStateto.joiningright aftercall.accept().joiningstate ispublished before
.inCall🛠 Implementation
acceptCallalready accepted the ringing call before delegating toenterCall, but the UI stayed in the incoming state until the later joinwork completed. This change mirrors the existing
joinCallbehavior bysetting
.joiningimmediately after acceptance succeeds, then continuinginto
enterCall.The new unit test subscribes to
subject.$callingStateand asserts that.joiningis emitted before the final.inCallstate, which protects thetransition that was previously missing.
🎨 Showcase
N/A
🧪 Manual Testing Notes
to the in-call UI.
☑️ Contributor Checklist
Summary by CodeRabbit
Bug Fixes
Tests