Batch 2/9 of the Robolectric JVM Compose test epic (#373). Converts the stateless onboarding + lock screens to Robolectric JVM Compose tests (v2 createComposeRule() under RobolectricTestRunner, test source set — no emulator) and drops each from jacocoNonJvmTestableSurface so its render/interaction code now counts as JVM-testable surface.
WelcomeContent + OnboardingWelcomeScreen — render + add-account. The wrapper's NotificationPermissionEffect launcher is wired to a no-op ActivityResultRegistry so no system permission dialog is surfaced on the JVM (WelcomeContent is also driven directly, as its instrumented test does).
LicenseScreen — the real bundled GPL-3.0 text (res/raw/license.txt) renders, Agree gated on scroll-to-end, Decline.
ContactsAccessContent + ContactsAccessScreen — the stateless content's skip / grant (done) / request / re-ask-rationale paths, plus the VM wrapper (allow → mark-requested → launch, skip/continue, ON_RESUME re-read) driven by a mocked OnboardingViewModel.
BatteryOptimizationScreen (whole file is the VM wrapper) — offered vs. "already unrestricted" done states; Take me there marks the prompt handled and resolves the settings intent; Not now finishes. Mocked OnboardingViewModel.
Notes
Removed from jacocoNonJvmTestableSurface: **/LockScreen*, **/OnboardingWelcomeScreen*, **/LicenseScreen*, **/ContactsAccessScreen*, **/BatteryOptimizationScreen*.
JaCoCo floor unchanged at 0.79 (the re-ratchet is the final epic step, #386). Scoped line coverage now 0.8288 (5557/6705), up from the 0.8021 baseline.
Contacts/Battery use a tall @Config display qualifier so their centered, non-scrolling columns fit without the lower controls clipping under Robolectric's small default viewport.
The instrumented androidTest tests are kept. They remain the coverage for LicenseScreen's system back press, which the v2 Robolectric compose rule does not surface a reliable dispatch hook for; the BackHandler registration line is still covered by rendering and onDecline by the Decline-button test.
Batch 2/9 of the Robolectric JVM Compose test epic (#373). Converts the stateless onboarding + lock screens to Robolectric JVM Compose tests (v2 `createComposeRule()` under `RobolectricTestRunner`, `test` source set — no emulator) and drops each from `jacocoNonJvmTestableSurface` so its render/interaction code now counts as JVM-testable surface.
### Screens covered (21 tests across 5 new files)
- **`LockScreen`** — locked title/body, optional error text, unlock callback.
- **`WelcomeContent` + `OnboardingWelcomeScreen`** — render + add-account. The wrapper's `NotificationPermissionEffect` launcher is wired to a no-op `ActivityResultRegistry` so no system permission dialog is surfaced on the JVM (`WelcomeContent` is also driven directly, as its instrumented test does).
- **`LicenseScreen`** — the real bundled GPL-3.0 text (`res/raw/license.txt`) renders, Agree gated on scroll-to-end, Decline.
- **`ContactsAccessContent` + `ContactsAccessScreen`** — the stateless content's skip / grant (done) / request / re-ask-rationale paths, plus the VM wrapper (allow → mark-requested → launch, skip/continue, ON_RESUME re-read) driven by a mocked `OnboardingViewModel`.
- **`BatteryOptimizationScreen`** (whole file is the VM wrapper) — offered vs. "already unrestricted" done states; Take me there marks the prompt handled and resolves the settings intent; Not now finishes. Mocked `OnboardingViewModel`.
### Notes
- Removed from `jacocoNonJvmTestableSurface`: `**/LockScreen*`, `**/OnboardingWelcomeScreen*`, `**/LicenseScreen*`, `**/ContactsAccessScreen*`, `**/BatteryOptimizationScreen*`.
- **JaCoCo floor unchanged at 0.79** (the re-ratchet is the final epic step, #386). Scoped line coverage now **0.8288** (5557/6705), up from the 0.8021 baseline.
- Contacts/Battery use a tall `@Config` display qualifier so their centered, non-scrolling columns fit without the lower controls clipping under Robolectric's small default viewport.
- The instrumented `androidTest` tests are kept. They remain the coverage for `LicenseScreen`'s system back press, which the v2 Robolectric compose rule does not surface a reliable dispatch hook for; the `BackHandler` registration line is still covered by rendering and `onDecline` by the Decline-button test.
Fast gate green: `assembleDebug` + `testDebugUnitTest` + `jacocoTestCoverageVerification` + `compileDebugAndroidTestKotlin` + `lintDebug` + `ktlintCheck` + `detekt`.
Closes #377.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Batch 2/9 of the Robolectric JVM Compose test epic (#373). Converts the stateless onboarding + lock screens to Robolectric JVM Compose tests (v2
createComposeRule()underRobolectricTestRunner,testsource set — no emulator) and drops each fromjacocoNonJvmTestableSurfaceso its render/interaction code now counts as JVM-testable surface.Screens covered (21 tests across 5 new files)
LockScreen— locked title/body, optional error text, unlock callback.WelcomeContent+OnboardingWelcomeScreen— render + add-account. The wrapper'sNotificationPermissionEffectlauncher is wired to a no-opActivityResultRegistryso no system permission dialog is surfaced on the JVM (WelcomeContentis also driven directly, as its instrumented test does).LicenseScreen— the real bundled GPL-3.0 text (res/raw/license.txt) renders, Agree gated on scroll-to-end, Decline.ContactsAccessContent+ContactsAccessScreen— the stateless content's skip / grant (done) / request / re-ask-rationale paths, plus the VM wrapper (allow → mark-requested → launch, skip/continue, ON_RESUME re-read) driven by a mockedOnboardingViewModel.BatteryOptimizationScreen(whole file is the VM wrapper) — offered vs. "already unrestricted" done states; Take me there marks the prompt handled and resolves the settings intent; Not now finishes. MockedOnboardingViewModel.Notes
jacocoNonJvmTestableSurface:**/LockScreen*,**/OnboardingWelcomeScreen*,**/LicenseScreen*,**/ContactsAccessScreen*,**/BatteryOptimizationScreen*.@Configdisplay qualifier so their centered, non-scrolling columns fit without the lower controls clipping under Robolectric's small default viewport.androidTesttests are kept. They remain the coverage forLicenseScreen's system back press, which the v2 Robolectric compose rule does not surface a reliable dispatch hook for; theBackHandlerregistration line is still covered by rendering andonDeclineby the Decline-button test.Fast gate green:
assembleDebug+testDebugUnitTest+jacocoTestCoverageVerification+compileDebugAndroidTestKotlin+lintDebug+ktlintCheck+detekt.Closes #377.
🤖 Generated with Claude Code