ReminderWorker, NotificationActionHandler and the scheduler have no tests #74

Closed
opened 2026-08-20 21:24:14 -05:00 by null · 1 comment
Owner

What is true now. The pure pieces are well covered — ReminderRulesTest (10 cases), NotificationCopyTest (10), and the instrumented NotificationPrivacyTest (6). Everything that touches state is not:

  • ReminderWorker — no test of any kind. It reads the repository, applies the rules, posts, and increments the stopping counter, and nothing exercises it.
  • NotificationActionHandler — no test. It owns the only two writes reachable from a phone's lock screen.
  • ReminderScheduler.schedule()/cancel() — untested; ReminderSchedulerTest covers only the two pure static helpers (delayUntil, nextRunDate).
  • NotificationSettingsViewModel — no test, including the permission flow.
  • There is no app/src/androidTest source set at all, so the parked-action-across-a-real-lock path cannot be tested in CI; it is an unchecked manual box at docs/security/SECURITY_CHECKLIST.md:56.

What it costs. Every defect in this batch lives in exactly the untested half. docs/qa/ClaudeQACoverage.md:230-233 also records that API 26 has never seen a notification, and :51/:203-207 that nobody has looked at a real lock screen — the instrumented tests assert the Notification object, not what the system draws.

What to do. Add androidx.work:work-testing to the version catalog and Robolectric to core/notifications; test ReminderWorker with TestListenableWorkerBuilder and a fake notifier over a real repository on a temp DataStore; test the handler per action including the stale and unknown cases; test the scheduler with WorkManagerTestInitHelper and a fixed clock; test the settings ViewModel's permission flow with a fake permission state.

Traps. core/notifications has no Robolectric or test-core dependency today and needs unitTests.isIncludeAndroidResources = true to resolve R.drawable.ic_notification. work-testing is in neither the catalog nor the Gradle cache, so the first build after adding it needs network — the other issues in this batch do not depend on it and can land first.

Verify: ./gradlew :core:notifications:test :app:testDebugUnitTest runs the named worker, handler, scheduler and settings tests, all green.

**What is true now.** The pure pieces are well covered — `ReminderRulesTest` (10 cases), `NotificationCopyTest` (10), and the instrumented `NotificationPrivacyTest` (6). Everything that touches state is not: - **`ReminderWorker`** — no test of any kind. It reads the repository, applies the rules, posts, and increments the stopping counter, and nothing exercises it. - **`NotificationActionHandler`** — no test. It owns the only two writes reachable from a phone's lock screen. - **`ReminderScheduler.schedule()`/`cancel()`** — untested; `ReminderSchedulerTest` covers only the two pure static helpers (`delayUntil`, `nextRunDate`). - **`NotificationSettingsViewModel`** — no test, including the permission flow. - There is no `app/src/androidTest` source set at all, so the parked-action-across-a-real-lock path cannot be tested in CI; it is an unchecked manual box at `docs/security/SECURITY_CHECKLIST.md:56`. **What it costs.** Every defect in this batch lives in exactly the untested half. `docs/qa/ClaudeQACoverage.md:230-233` also records that API 26 has never seen a notification, and `:51`/`:203-207` that nobody has looked at a real lock screen — the instrumented tests assert the `Notification` object, not what the system draws. **What to do.** Add `androidx.work:work-testing` to the version catalog and Robolectric to `core/notifications`; test `ReminderWorker` with `TestListenableWorkerBuilder` and a fake notifier over a real repository on a temp DataStore; test the handler per action including the stale and unknown cases; test the scheduler with `WorkManagerTestInitHelper` and a fixed clock; test the settings ViewModel's permission flow with a fake permission state. **Traps.** `core/notifications` has no Robolectric or test-core dependency today and needs `unitTests.isIncludeAndroidResources = true` to resolve `R.drawable.ic_notification`. `work-testing` is in neither the catalog nor the Gradle cache, so the first build after adding it needs network — the other issues in this batch do not depend on it and can land first. Verify: `./gradlew :core:notifications:test :app:testDebugUnitTest` runs the named worker, handler, scheduler and settings tests, all green.
null added this to the Batch 12 — Reminders that tell the truth milestone 2026-08-20 21:24:14 -05:00
null added the
P2
label 2026-08-20 21:24:14 -05:00
Author
Owner

All five named classes now have tests, landed across the Batch 12 fixes rather than as a separate pass — each defect needed its harness before it could be proved.

ReminderWorkerTest (8, core/notifications/src/test/.../ReminderWorkerTest.kt): built with TestListenableWorkerBuilder over a real repository and preference store with only the notifier faked. Covers a check-in that could not be posted not counting as having asked, a posted one counting, the count surviving a fresh worker (which is a fresh process), the period-due reminder offering a start and a not-yet and never an end, no history saying nothing, every reminder switched off saying nothing, and the retry taxonomy in both directions.

NotificationActionHandlerTest (12, app/src/test/.../NotificationActionHandlerTest.kt): every action including ENDED closing the open period rather than opening one, STILL_GOING writing nothing, the next-morning case, the days-late case, the already-answered case, a future date, and a legacy notification with no date.

WorkManagerReminderSchedulerTest (9) and ReminderSchedulerTest (4, core/notifications/src/test/): schedule() and cancel() against WorkManager's own recorded next-run time, sharing one clock with it — including the change-the-time case that only fails once time has moved, which is the one that catches the UPDATE defect.

NotificationSettingsViewModelTest (6, app/src/test/.../feature/settings/): the permission flow, denial keeping the toggle, revocation noticed on resume.

ReminderCoordinatorTest (6): extended with the check-in tally surviving two starts and the dismissal chain's first emission not cancelling what the worker is about to post.

Verify: ./gradlew :core:notifications:testDebugUnitTest :app:testDebugUnitTest — 44 and 93 tests, all green. Also proved with scripts/prove-guard.sh: the posted-and-counts guard, the retry taxonomy, the next-run override, and the overdue-run rule each redden exactly one test.

All five named classes now have tests, landed across the Batch 12 fixes rather than as a separate pass — each defect needed its harness before it could be proved. ReminderWorkerTest (8, core/notifications/src/test/.../ReminderWorkerTest.kt): built with TestListenableWorkerBuilder over a real repository and preference store with only the notifier faked. Covers a check-in that could not be posted not counting as having asked, a posted one counting, the count surviving a fresh worker (which is a fresh process), the period-due reminder offering a start and a not-yet and never an end, no history saying nothing, every reminder switched off saying nothing, and the retry taxonomy in both directions. NotificationActionHandlerTest (12, app/src/test/.../NotificationActionHandlerTest.kt): every action including ENDED closing the open period rather than opening one, STILL_GOING writing nothing, the next-morning case, the days-late case, the already-answered case, a future date, and a legacy notification with no date. WorkManagerReminderSchedulerTest (9) and ReminderSchedulerTest (4, core/notifications/src/test/): schedule() and cancel() against WorkManager's own recorded next-run time, sharing one clock with it — including the change-the-time case that only fails once time has moved, which is the one that catches the UPDATE defect. NotificationSettingsViewModelTest (6, app/src/test/.../feature/settings/): the permission flow, denial keeping the toggle, revocation noticed on resume. ReminderCoordinatorTest (6): extended with the check-in tally surviving two starts and the dismissal chain's first emission not cancelling what the worker is about to post. Verify: ./gradlew :core:notifications:testDebugUnitTest :app:testDebugUnitTest — 44 and 93 tests, all green. Also proved with scripts/prove-guard.sh: the posted-and-counts guard, the retry taxonomy, the next-run override, and the overdue-run rule each redden exactly one test.
null closed this issue 2026-08-21 01:06:51 -05:00
Sign in to join this conversation.
No Label
P0
P1
P2
release-blocker
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: null/Privacy-Period-Tracker#74
No description provided.