test(settings): fix flaky installProfile snackbar test - #6675
Conversation
UiText.resolve() loads string resources on real Dispatchers.Default (CMP 1.12 async resource cache), outside the runTest scheduler, so runCurrent() raced the real thread and the verify intermittently saw no showSnackbar call. Await the snackbar effect via a CompletableDeferred completed by the mock instead. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughThe malformed channel URL test now uses ChangesSettings test synchronization
Estimated code review effort: 1 (Trivial) | ~3 minutes Mergeability Score: ⚪ Minimal · up to This change makes the flaky snackbar test wait deterministically for the expected effect without changing production behavior; no actionable merge-blocking risk remains after normal checks and review. Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5 | ❌ 1❌ Failed checks (1 inconclusive)
✅ Passed checks (5 passed)
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 |
Why
installProfile surfaces malformed channel URL in snackbarinRadioConfigViewModelTestis flaky — it failed 2 of 3 attempts in a localallTestsrun with Mokkery's "Expected showSnackbar() call but received none", passing on retry.The root cause is not the ViewModel's dispatcher wiring:
installProfile's catch block callsUiText.Resource(Res.string.channel_invalid).resolve(), which goes through CMPgetString(). Since CMP 1.12 the resource async cache loads on realDispatchers.Default— outside therunTestscheduler. The coroutine suspends there, sorunCurrent()(and evenadvanceUntilIdle()) returns with nothing to drain, and theverifyraces the real Default thread. Passing runs were just the real thread winning.🧹 Changes
snackbarManager.showSnackbarto complete aCompletableDeferred, and replacerunCurrent()with awaiting that deferred, so the test deterministically waits for the effect. The exact-message assertion is unchanged.withTimeout— insiderunTestit runs on virtual time and would fire spuriously while waiting on the real dispatcher; a genuine hang is still caught byrunTest's 60s real-time timeout.Note for future tests in this file: any assertion downstream of
UiText.resolve()has the same trap; reuse this await-the-effect pattern instead ofrunCurrent()/advanceUntilIdle().Testing Performed
:feature:settings:allTestsrun 3× (twice with--rerun-tasksto defeat caching; 205 tests executed each run, verified no FROM-CACHE) — target test passed all runs.:feature:settings:detekt spotlessCheck— clean.🤖 Generated with Claude Code
Summary by CodeRabbit