Extends #274's AccountPickerScreenTest with tappingOutlook_launchesTheAppAuthBrowserIntent, which taps the Outlook row and asserts (via Espresso-Intents) that the browser-launch intent for Microsoft OAuth fires.
Scope is deliberately narrow, per the issue: only the browser-launch intent is asserted. The OAuth redirect, token exchange, and account creation are not exercised.
Intent characteristic asserted, and why it's stable
OutlookAuthManager.createAuthIntent() calls AppAuth's AuthorizationService.getAuthorizationRequestIntent(), which (per AppAuth 0.11.1 source) never hands back a bare browser Intent — it always wraps the browser/Custom-Tab intent as a Parcelable extra inside an outer intent whose component is AppAuth's own net.openid.appauth.AuthorizationManagementActivity. That inner intent is only unwrapped and started once AuthorizationManagementActivity itself resumes. Since outlookLauncher.launch(intent) launches that outer intent, hasComponent(AuthorizationManagementActivity::class.java.name) is:
Guaranteed — every Outlook tap that successfully builds an intent goes through it (it's the literal object AppAuth returns), and
Stable — it doesn't depend on which browser (if any) is installed on the test device/emulator, unlike matching on a Custom-Tab package or the Microsoft authorize-host URI, neither of which Espresso-Intents ever observes here (that nested browser intent is never separately passed to startActivity once the test stubs the outer one).
The test stubs the result with RESULT_CANCELED so AuthorizationManagementActivity never actually resumes and a real browser never opens.
Booted a standalone google_apis API 29 AVD (same system-image tag CI's Gradle Managed Devices use; confirmed Chrome is present via adb shell pm list packages) and ran :app:connectedDebugAndroidTest -Pandroid.testInstrumentationRunnerArguments.class=org.libremail.ui.accountsetup.AccountPickerScreenTest directly (not the shared Gradle Managed Device, to avoid contending with other in-flight agents) — all 4 tests in the class passed, including the new one (3.18s). Emulator torn down afterward via adb emu kill.
Test plan
tappingOutlook_launchesTheAppAuthBrowserIntent runs and passes locally against a real emulator
Existing AccountPickerScreenTest tests still pass
CI's full matrix (unaffected areas) + Static analysis gate
Closes #276
## Summary
- Extends #274's `AccountPickerScreenTest` with `tappingOutlook_launchesTheAppAuthBrowserIntent`, which taps the Outlook row and asserts (via Espresso-Intents) that the browser-launch intent for Microsoft OAuth fires.
- Scope is deliberately narrow, per the issue: only the browser-launch intent is asserted. The OAuth redirect, token exchange, and account creation are not exercised.
## Intent characteristic asserted, and why it's stable
`OutlookAuthManager.createAuthIntent()` calls AppAuth's `AuthorizationService.getAuthorizationRequestIntent()`, which (per AppAuth 0.11.1 source) never hands back a bare browser `Intent` — it always wraps the browser/Custom-Tab intent as a Parcelable extra inside an outer intent whose component is AppAuth's own `net.openid.appauth.AuthorizationManagementActivity`. That inner intent is only unwrapped and started once `AuthorizationManagementActivity` itself resumes. Since `outlookLauncher.launch(intent)` launches that *outer* intent, `hasComponent(AuthorizationManagementActivity::class.java.name)` is:
- **Guaranteed** — every Outlook tap that successfully builds an intent goes through it (it's the literal object AppAuth returns), and
- **Stable** — it doesn't depend on which browser (if any) is installed on the test device/emulator, unlike matching on a Custom-Tab package or the Microsoft authorize-host URI, neither of which Espresso-Intents ever observes here (that nested browser intent is never separately passed to `startActivity` once the test stubs the outer one).
The test stubs the result with `RESULT_CANCELED` so `AuthorizationManagementActivity` never actually resumes and a real browser never opens.
## Validation
- `:app:compileDebugAndroidTestKotlin :app:ktlintCheck :app:detekt` — green.
- `:app:assembleDebug :app:testDebugUnitTest :app:lintDebug` — green.
- Booted a standalone `google_apis` API 29 AVD (same system-image tag CI's Gradle Managed Devices use; confirmed Chrome is present via `adb shell pm list packages`) and ran `:app:connectedDebugAndroidTest -Pandroid.testInstrumentationRunnerArguments.class=org.libremail.ui.accountsetup.AccountPickerScreenTest` directly (not the shared Gradle Managed Device, to avoid contending with other in-flight agents) — all 4 tests in the class passed, including the new one (3.18s). Emulator torn down afterward via `adb emu kill`.
## Test plan
- [x] `tappingOutlook_launchesTheAppAuthBrowserIntent` runs and passes locally against a real emulator
- [x] Existing `AccountPickerScreenTest` tests still pass
- [x] CI's full matrix (unaffected areas) + Static analysis gate
🤖 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.
Closes #276
Summary
AccountPickerScreenTestwithtappingOutlook_launchesTheAppAuthBrowserIntent, which taps the Outlook row and asserts (via Espresso-Intents) that the browser-launch intent for Microsoft OAuth fires.Intent characteristic asserted, and why it's stable
OutlookAuthManager.createAuthIntent()calls AppAuth'sAuthorizationService.getAuthorizationRequestIntent(), which (per AppAuth 0.11.1 source) never hands back a bare browserIntent— it always wraps the browser/Custom-Tab intent as a Parcelable extra inside an outer intent whose component is AppAuth's ownnet.openid.appauth.AuthorizationManagementActivity. That inner intent is only unwrapped and started onceAuthorizationManagementActivityitself resumes. SinceoutlookLauncher.launch(intent)launches that outer intent,hasComponent(AuthorizationManagementActivity::class.java.name)is:startActivityonce the test stubs the outer one).The test stubs the result with
RESULT_CANCELEDsoAuthorizationManagementActivitynever actually resumes and a real browser never opens.Validation
:app:compileDebugAndroidTestKotlin :app:ktlintCheck :app:detekt— green.:app:assembleDebug :app:testDebugUnitTest :app:lintDebug— green.google_apisAPI 29 AVD (same system-image tag CI's Gradle Managed Devices use; confirmed Chrome is present viaadb shell pm list packages) and ran:app:connectedDebugAndroidTest -Pandroid.testInstrumentationRunnerArguments.class=org.libremail.ui.accountsetup.AccountPickerScreenTestdirectly (not the shared Gradle Managed Device, to avoid contending with other in-flight agents) — all 4 tests in the class passed, including the new one (3.18s). Emulator torn down afterward viaadb emu kill.Test plan
tappingOutlook_launchesTheAppAuthBrowserIntentruns and passes locally against a real emulatorAccountPickerScreenTesttests still pass🤖 Generated with Claude Code