Skip to content

test(settings): fix flaky installProfile snackbar test - #6675

Merged
jamesarich merged 1 commit into
mainfrom
claude/eloquent-rhodes-6fdea8
Aug 13, 2026
Merged

test(settings): fix flaky installProfile snackbar test#6675
jamesarich merged 1 commit into
mainfrom
claude/eloquent-rhodes-6fdea8

Conversation

@jamesarich

@jamesarich jamesarich commented Aug 13, 2026

Copy link
Copy Markdown
Collaborator

Why

installProfile surfaces malformed channel URL in snackbar in RadioConfigViewModelTest is flaky — it failed 2 of 3 attempts in a local allTests run 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 calls UiText.Resource(Res.string.channel_invalid).resolve(), which goes through CMP getString(). Since CMP 1.12 the resource async cache loads on real Dispatchers.Default — outside the runTest scheduler. The coroutine suspends there, so runCurrent() (and even advanceUntilIdle()) returns with nothing to drain, and the verify races the real Default thread. Passing runs were just the real thread winning.

🧹 Changes

  • Stub snackbarManager.showSnackbar to complete a CompletableDeferred, and replace runCurrent() with awaiting that deferred, so the test deterministically waits for the effect. The exact-message assertion is unchanged.
  • Deliberately no inner withTimeout — inside runTest it runs on virtual time and would fire spuriously while waiting on the real dispatcher; a genuine hang is still caught by runTest'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 of runCurrent()/advanceUntilIdle().

Testing Performed

  • :feature:settings:allTests run 3× (twice with --rerun-tasks to 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

  • Tests
    • Improved reliability of malformed-profile URL validation tests by properly waiting for asynchronous snackbar notifications.

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>
@github-actions github-actions Bot added the testing Test additions or modifications label Aug 13, 2026
@coderabbitai

coderabbitai Bot commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 49ee41ee-0ebf-4050-a239-338545993c28

📥 Commits

Reviewing files that changed from the base of the PR and between 2f38736 and dd3aa3a.

📒 Files selected for processing (1)
  • feature/settings/src/commonTest/kotlin/org/meshtastic/feature/settings/radio/RadioConfigViewModelTest.kt

📝 Walkthrough

Walkthrough

The malformed channel URL test now uses CompletableDeferred to await asynchronous snackbar delivery instead of calling runCurrent().

Changes

Settings test synchronization

Layer / File(s) Summary
Await malformed URL snackbar
feature/settings/src/commonTest/kotlin/org/meshtastic/feature/settings/radio/RadioConfigViewModelTest.kt
The test completes a deferred when the snackbar appears and awaits it after installProfile. The file imports CompletableDeferred.

Estimated code review effort: 1 (Trivial) | ~3 minutes

Mergeability Score: ⚪ Minimal · up to dd3aa

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: jeremiah-k, simulationstation

🚥 Pre-merge checks | ✅ 5 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Tests Prove The Path, Not The End State ❓ Inconclusive Investigation is still in progress; no verdict submitted yet. Inspect the changed test and its production path before deciding.
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the flaky snackbar test fix implemented in the pull request.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Sibling Call Sites And Presence Semantics ✅ Passed The diff only changes snackbar-test synchronization and adds an import; it changes no field presence semantics, zero-guard, nullable value, or physical measurement default.

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@jamesarich
jamesarich enabled auto-merge August 13, 2026 15:44
@jamesarich
jamesarich added this pull request to the merge queue Aug 13, 2026
Merged via the queue into main with commit 80d2ad2 Aug 13, 2026
15 checks passed
@jamesarich
jamesarich deleted the claude/eloquent-rhodes-6fdea8 branch August 13, 2026 15:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

testing Test additions or modifications

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant