test(sync): unit-cover the cache-lock gate on every pre-auth DB entry point #225

Closed
opened 2026-07-03 15:42:18 +00:00 by JMR-dev · 0 comments
JMR-dev commented 2026-07-03 15:42:18 +00:00 (Migrated from github.com)

Source: "same-class crash-state" audit (Finding 2 — the gating invariant is entirely untested; this is how the PruneWorker/BackfillWorker gap slipped in).

There is zero coverage of the EncryptedCacheGuard cache-lock gate: grep finds no EncryptedCacheGuard / isCacheLocked references in src/test or src/androidTest, and no *WorkerTest exists — so even the existing guards on SyncWorker / SendWorker / IdleService are unverified and can regress silently.

Add a parameterized unit suite over every pre-auth DB entry point — SyncWorker, SendWorker, PruneWorker, BackfillWorker, IdleService — asserting: with a mock EncryptedCacheGuard.isCacheLocked() == true, doWork() returns Result.retry() (the service stopSelf()s) AND the Lazy<DB-dep> is never resolved (verify .get() isn't called); with false, the job actually runs. Construct workers via their @AssistedInject constructors with mocks (no Hilt needed).

Plus a DatabaseProvisionerTest case: appLock = true with a resolvePassphrase stub that suspends on a CompletableDeferred, asserting prepareCache() does not complete until it resolves — proving the precondition the guard exists to avoid (DatabaseProvisionerTest currently only tests appLock = false with an instant passphrase). Depends on the worker-gating fix.

**Source:** "same-class crash-state" audit (Finding 2 — the gating invariant is entirely untested; this is how the `PruneWorker`/`BackfillWorker` gap slipped in). There is **zero** coverage of the `EncryptedCacheGuard` cache-lock gate: grep finds no `EncryptedCacheGuard` / `isCacheLocked` references in `src/test` or `src/androidTest`, and no `*WorkerTest` exists — so even the existing guards on `SyncWorker` / `SendWorker` / `IdleService` are unverified and can regress silently. **Add a parameterized unit suite** over every pre-auth DB entry point — `SyncWorker`, `SendWorker`, `PruneWorker`, `BackfillWorker`, `IdleService` — asserting: with a mock `EncryptedCacheGuard.isCacheLocked() == true`, `doWork()` returns `Result.retry()` (the service `stopSelf()`s) AND the `Lazy<DB-dep>` is **never resolved** (`verify` `.get()` isn't called); with `false`, the job actually runs. Construct workers via their `@AssistedInject` constructors with mocks (no Hilt needed). Plus a `DatabaseProvisionerTest` case: `appLock = true` with a `resolvePassphrase` stub that suspends on a `CompletableDeferred`, asserting `prepareCache()` does not complete until it resolves — proving the precondition the guard exists to avoid (`DatabaseProvisionerTest` currently only tests `appLock = false` with an instant passphrase). Depends on the worker-gating fix.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: JMR-dev/LibreMail#225