test(reporting): add testability seams for ReportUpload* + E2E cover push IdleService #257

Closed
opened 2026-07-03 19:32:37 +00:00 by JMR-dev · 0 comments
JMR-dev commented 2026-07-03 19:32:37 +00:00 (Migrated from github.com)

Context

Coverage lane 4 (#249) found several classes can't be reached by JVM unit tests, holding reporting/push coverage below the ≥95% goal. Making them testable is a small, sensible improvement that lets those packages meet the floor.

Items

  1. reporting/ReportUploadScheduler calls WorkManager.getInstance(context) — a static on an abstract class MockK can't stub (AbstractMethodError). Refactor to inject Provider<WorkManager> (or dagger.Lazy<WorkManager>), mirroring SyncScheduler (which is JVM-testable for exactly this reason). Then unit-test its enqueue logic.
  2. reporting/ReportUploadWorker HTTP submit path is unreachable in tests while BuildConfig.DEBUG_REPORT_ENDPOINT is empty (default). Add a test that overrides/injects a non-empty endpoint (e.g. a local mock HTTP server) and covers success/failure/retry.
  3. push/IdleService (foreground Service) can't be instantiated off-device. Cover its start/stop/notification behavior via an instrumented/E2E test, or extract its non-Android logic into a JVM-testable helper.
  4. CrashReporter.terminate (Process.killProcess/exitProcess) is intentionally JVM-untestable — leave it; exclude it from any instruction gate.

Priority / dependency

Low — only strictly needed if the capstone (#251) opts for instruction-level gating on reporting/push. If #251 gates on line coverage, items 1–3 are optional polish. Coordinate with #251.

Definition of done (per CLAUDE.md)

  • Unit tests for items 1–2; an instrumented/E2E test for item 3.
  • Any production seam (item 1) stays minimal and behavior-preserving.
  • Not done until unit and E2E pass.
## Context Coverage **lane 4 (#249)** found several classes can't be reached by JVM unit tests, holding `reporting`/`push` coverage below the ≥95% goal. Making them testable is a small, sensible improvement that lets those packages meet the floor. ## Items 1. **`reporting/ReportUploadScheduler`** calls `WorkManager.getInstance(context)` — a static on an abstract class MockK can't stub (`AbstractMethodError`). Refactor to inject `Provider<WorkManager>` (or `dagger.Lazy<WorkManager>`), mirroring `SyncScheduler` (which is JVM-testable for exactly this reason). Then unit-test its enqueue logic. 2. **`reporting/ReportUploadWorker`** HTTP submit path is unreachable in tests while `BuildConfig.DEBUG_REPORT_ENDPOINT` is empty (default). Add a test that overrides/injects a non-empty endpoint (e.g. a local mock HTTP server) and covers success/failure/retry. 3. **`push/IdleService`** (foreground `Service`) can't be instantiated off-device. Cover its start/stop/notification behavior via an instrumented/E2E test, or extract its non-Android logic into a JVM-testable helper. 4. `CrashReporter.terminate` (`Process.killProcess`/`exitProcess`) is intentionally JVM-untestable — leave it; exclude it from any instruction gate. ## Priority / dependency **Low** — only strictly needed if the capstone (**#251**) opts for **instruction**-level gating on `reporting`/`push`. If #251 gates on **line** coverage, items 1–3 are optional polish. Coordinate with #251. ## Definition of done (per CLAUDE.md) - Unit tests for items 1–2; an instrumented/E2E test for item 3. - Any production seam (item 1) stays minimal and behavior-preserving. - Not done until unit **and** E2E pass.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: JMR-dev/LibreMail#257