test(compose): Robolectric JVM tests for the reader screen (#381) #400

Merged
JMR-dev merged 1 commits from test-381-robolectric-reader into main 2026-07-07 04:51:45 +00:00
JMR-dev commented 2026-07-07 01:46:01 +00:00 (Migrated from github.com)

Converts the reader screen to a Robolectric JVM Compose test (umbrella #373, dispatch 6/9) and drops **/ReaderScreen* from jacocoNonJvmTestableSurface.

What

ReaderScreenJvmTest drives the real ReaderViewModel over a mocked MailRepository / SettingsRepository via the v2 createComposeRule() — no emulator — in the test (JVM) source set. 15 tests covering:

  • Chrome: top bar title + back, Reply, overflow Reply all / Forward, Star, Delete.
  • Body branches: loading spinner, plain-text body + header (subject/sender/email), blank-body placeholder, load-error text.
  • Attachments: single row (no accordion), multi-attachment accordion collapse/expand, downloaded indicator, and the download-failure snackbar. Fixtures exercise formatSize (B/KB/MB/empty) and fileExtension (normal + FILE fallback).
  • Remote-images banner: shown for an HTML message, hidden after "Show images", and suppressed by the load-remote-images preference.

WebView caveat

ReaderScreen embeds HtmlBody — a hardened WebView via AndroidView. Under Robolectric the WebView is a non-rendering shadow, so no WebView-rendered HTML is asserted. The remote-images banner (which only appears for an HTML message) is driven with an HTML message whose body is blank, hitting the isHtml && !loadRemoteImages banner branch and the blank-body placeholder branch without invoking HtmlBody at all.

HtmlBody.kt is not part of this batch and stays in scope — its logic (cidKey/resolveInlineImage/wrapHtml/toCssHex) is already JVM-covered by HtmlBodyTest / InlineImageResolverTest, and its WebView render is not meaningfully JVM-testable.

Coverage

  • ReaderScreenKt: 94.3% line (265/281). The 16 missed lines are the intentionally-skipped HtmlBody(...) WebView call and the openAttachment FileProvider intent path.
  • Bundle line coverage rises to 82.7%, above the unchanged 0.79 floor (the re-ratchet stays the final #373 step).

Tests

  • New: app/src/test/kotlin/org/libremail/ui/reader/ReaderScreenJvmTest.kt (15 tests, all green).
  • The instrumented ReaderScreenTest stays as the on-device E2E.

Fast gate green locally: assembleDebug + testDebugUnitTest + jacocoTestCoverageVerification + compileDebugAndroidTestKotlin + lintDebug + ktlintCheck + detekt.

Part of #373.

🤖 Generated with Claude Code

Converts the reader screen to a Robolectric JVM Compose test (umbrella #373, dispatch 6/9) and drops `**/ReaderScreen*` from `jacocoNonJvmTestableSurface`. ## What `ReaderScreenJvmTest` drives the **real** `ReaderViewModel` over a mocked `MailRepository` / `SettingsRepository` via the v2 `createComposeRule()` — no emulator — in the `test` (JVM) source set. 15 tests covering: - **Chrome:** top bar title + back, `Reply`, overflow `Reply all` / `Forward`, `Star`, `Delete`. - **Body branches:** loading spinner, plain-text body + header (subject/sender/email), blank-body placeholder, load-error text. - **Attachments:** single row (no accordion), multi-attachment accordion collapse/expand, downloaded indicator, and the download-failure snackbar. Fixtures exercise `formatSize` (B/KB/MB/empty) and `fileExtension` (normal + `FILE` fallback). - **Remote-images banner:** shown for an HTML message, hidden after "Show images", and suppressed by the load-remote-images preference. ## WebView caveat `ReaderScreen` embeds `HtmlBody` — a hardened `WebView` via `AndroidView`. Under Robolectric the `WebView` is a **non-rendering shadow**, so no WebView-rendered HTML is asserted. The remote-images banner (which only appears for an HTML message) is driven with an HTML message whose body is **blank**, hitting the `isHtml && !loadRemoteImages` banner branch and the blank-body placeholder branch **without invoking `HtmlBody`** at all. `HtmlBody.kt` is **not** part of this batch and stays in scope — its logic (`cidKey`/`resolveInlineImage`/`wrapHtml`/`toCssHex`) is already JVM-covered by `HtmlBodyTest` / `InlineImageResolverTest`, and its `WebView` render is not meaningfully JVM-testable. ## Coverage - `ReaderScreenKt`: **94.3%** line (265/281). The 16 missed lines are the intentionally-skipped `HtmlBody(...)` WebView call and the `openAttachment` FileProvider intent path. - Bundle line coverage rises to **82.7%**, above the **unchanged** 0.79 floor (the re-ratchet stays the final #373 step). ## Tests - New: `app/src/test/kotlin/org/libremail/ui/reader/ReaderScreenJvmTest.kt` (15 tests, all green). - The instrumented `ReaderScreenTest` stays as the on-device E2E. Fast gate green locally: `assembleDebug` + `testDebugUnitTest` + `jacocoTestCoverageVerification` + `compileDebugAndroidTestKotlin` + `lintDebug` + `ktlintCheck` + `detekt`. Part of #373. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Sign in to join this conversation.