From 8e9ad4ac34e1d68b70480892c44e406187b5f770 Mon Sep 17 00:00:00 2001 From: meetsu <96637888+klNuno@users.noreply.github.com> Date: Wed, 21 Oct 2026 12:44:07 +0200 Subject: [PATCH 1/2] test(egui): type the restore test's note once the refresh starts --- .../accshift-egui/src/app/tests/native_regressions.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/crates/accshift-egui/src/app/tests/native_regressions.rs b/crates/accshift-egui/src/app/tests/native_regressions.rs index b8d3b10..26fd91a 100644 --- a/crates/accshift-egui/src/app/tests/native_regressions.rs +++ b/crates/accshift-egui/src/app/tests/native_regressions.rs @@ -145,14 +145,18 @@ fn native_external_storage_on_restore_preserves_dirty_local_values() { let ctx = Context::default(); let (mut app, _) = external_app(&ctx); frame(&mut app, &ctx, true, false); + // Restoration must work even if the viewport still reports focus. + frame(&mut app, &ctx, true, true); + frame(&mut app, &ctx, true, false); + // Typed once the manifest read is under way, so the write is still owed + // (120 ms debounce) when begin_refresh sees the manifest. Typed before + // the frames above, a slow runner finished the write first, and the + // mock answers a write with no fingerprint: it read as external. app.booted .as_mut() .unwrap() .stores .set_account_card_note("external", "local draft"); - // Restoration must work even if the viewport still reports focus. - frame(&mut app, &ctx, true, true); - frame(&mut app, &ctx, true, false); pump_until(&mut app, &ctx, |a| { a.booted().unwrap().stores.view_mode() == ViewMode::List }); From 757db2ec13c6805aeb2aa2c6f273f4187a3fdea2 Mon Sep 17 00:00:00 2001 From: meetsu <96637888+klNuno@users.noreply.github.com> Date: Wed, 21 Oct 2026 13:00:18 +0200 Subject: [PATCH 2/2] test: hold the restore test's manifest read, retry the PIN after a cheap wrong code --- crates/accshift-app/tests/real_backend.rs | 6 +++- .../src/app/tests/native_regressions.rs | 31 ++++++++++++++++--- 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/crates/accshift-app/tests/real_backend.rs b/crates/accshift-app/tests/real_backend.rs index 9e0bb2f..a7c098a 100644 --- a/crates/accshift-app/tests/real_backend.rs +++ b/crates/accshift-app/tests/real_backend.rs @@ -404,7 +404,11 @@ fn the_pin_session_locks_unlocks_and_guards_the_settings_store() { .unwrap_err(); assert_eq!(error.message, PIN_LOCKED_MESSAGE); - let wrong = real.pin_unlock("0000").unwrap(); + // A code of the wrong length fails before PBKDF2, which takes up to a + // second unoptimized on a slow runner: the retry right after it then + // always lands inside the one second wait, which counts from the start of + // the failed attempt. + let wrong = real.pin_unlock("00").unwrap(); assert_eq!(wrong.status, "invalid"); assert_eq!(wrong.retry_after_ms, 1000); let too_soon = real.pin_unlock("1234").unwrap(); diff --git a/crates/accshift-egui/src/app/tests/native_regressions.rs b/crates/accshift-egui/src/app/tests/native_regressions.rs index 26fd91a..b4d179e 100644 --- a/crates/accshift-egui/src/app/tests/native_regressions.rs +++ b/crates/accshift-egui/src/app/tests/native_regressions.rs @@ -143,20 +143,41 @@ fn native_external_storage_on_focus_refreshes_stores_and_accounts() { #[test] fn native_external_storage_on_restore_preserves_dirty_local_values() { let ctx = Context::default(); - let (mut app, _) = external_app(&ctx); + let (mut app, mock) = external_app(&ctx); frame(&mut app, &ctx, true, false); + // The restore frame polls the manifest read right after starting it: the + // latency keeps that poll waiting, so begin_refresh runs after the edit. + mock.latency(30); // Restoration must work even if the viewport still reports focus. frame(&mut app, &ctx, true, true); frame(&mut app, &ctx, true, false); - // Typed once the manifest read is under way, so the write is still owed - // (120 ms debounce) when begin_refresh sees the manifest. Typed before - // the frames above, a slow runner finished the write first, and the - // mock answers a write with no fingerprint: it read as external. + // Typed once the manifest read is under way. Typed before the frames + // above, a slow runner finished the write first, and the mock answers a + // write with no fingerprint: it read as an external change. app.booted .as_mut() .unwrap() .stores .set_account_card_note("external", "local draft"); + // begin_refresh records the other targets: the boundary, as below. + pump_until(&mut app, &ctx, |a| { + a.booted() + .unwrap() + .stores + .storage() + .manifest() + .stores + .get("app.config.local") + .is_some_and(|v| v == "config-2") + }); + // A write still owed at the frame's end was owed when begin_refresh ran + // at its start: saves are polled later in the frame. + assert!(app + .booted() + .unwrap() + .stores + .storage() + .has_pending_save("client.account-card-notes")); pump_until(&mut app, &ctx, |a| { a.booted().unwrap().stores.view_mode() == ViewMode::List });