fix(timers): delete on the application scope, and wait for storage in the delete tests

The timer list's delete now outlives a back press the same way the alarm list's does. The instrumented delete and Undo tests wait for the row to change in storage, because that work runs outside Compose's idling.
This commit is contained in:
makiolaj committed 2026-10-22 08:35:14 +02:00
1 parent ddec2d8ed1
commit 40c71a49f7
2 files changed
+14 -5

No files matched your search

@@ -209,11 +209,13 @@ class AlarmsInstrumentedTest {
// No confirmation: the list underneath offers the Undo instead.
composeTestRule.onNodeWithContentDescription(string(R.string.editor_delete)).performClick()
// The delete runs on the application scope, which Compose's idling
// does not track, so the test waits for storage rather than for idle.
composeTestRule.waitUntil(STORAGE_TIMEOUT_MS) { stored(id) == null }
composeTestRule.waitForIdle()
composeTestRule.onNodeWithText("Work").assertDoesNotExist()
composeTestRule.onNodeWithText(string(R.string.action_undo)).assertIsDisplayed()
assertThat(stored(id)).isNull()
}
@OptIn(ExperimentalTestApi::class)
@@ -225,13 +227,18 @@ class AlarmsInstrumentedTest {
composeTestRule.onNodeWithText("Work")
.performCustomAccessibilityActionWithLabel(string(R.string.action_delete))
composeTestRule.waitUntil(STORAGE_TIMEOUT_MS) { stored(id) == null }
composeTestRule.waitForIdle()
assertThat(stored(id)).isNull()
composeTestRule.onNodeWithText(string(R.string.action_undo)).performClick()
composeTestRule.waitUntil(STORAGE_TIMEOUT_MS) { stored(id) != null }
composeTestRule.waitForIdle()
composeTestRule.onNodeWithText("Work").assertIsDisplayed()
assertThat(stored(id)).isNotNull()
}
private companion object {
/** Delete and restore run on the application scope, outside Compose's idling. */
const val STORAGE_TIMEOUT_MS = 5_000L
}
}
@@ -100,8 +100,10 @@ class TimersViewModel @Inject internal constructor(
* Through the engine, so a *ringing* timer cannot be deleted into a stuck
* ring (D2). Still no confirmation; the snackbar's Undo now covers the slip.
*/
fun onDelete(timerId: Long) = launchOnEngine {
engine.delete(timerId)?.let(undo::offer)
fun onDelete(timerId: Long) {
// On the application scope, as the alarm list's is: a back press while
// the engine lock is busy must not drop a delete the user saw happen.
appScope.launch { engine.delete(timerId)?.let(undo::offer) }
}
/**