fix(onboarding): request notification permission after welcome screen renders (#168)

* fix(onboarding): request notification permission after welcome screen renders

The POST_NOTIFICATIONS request fired from a MainActivity-root
NotificationPermissionEffect whose LaunchedEffect(Unit) ran on the very
first composition, so the system dialog could pop the instant the icon
was tapped — overlapping cold start/splash before any onboarding context
was on screen.

Move the effect into OnboardingWelcomeScreen so it fires once that screen
(the onboarding start destination) is composed and visible, with the
welcome content behind the dialog. Already-onboarded users launch
straight into the mailbox and never compose the welcome screen, so they
are unaffected; the API 33+ gate and the already-granted no-op are
preserved unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test(onboarding): grant POST_NOTIFICATIONS in onboarding E2E to fix API 33+ flow

Moving the notification-permission request into OnboardingWelcomeScreen
(#151) means the system POST_NOTIFICATIONS dialog now pops when that
screen composes. On API 33+ (where it became a runtime permission) the
dialog backgrounded the activity mid-flow, so OnboardingFlowTest failed
with "No compose hierarchies found" on API 33/34/35/36/37 while API
29–32 stayed green.

Pre-grant the permission via a GrantPermissionRule so the dialog never
appears during the flow, guarded for API 33+ (the permission does not
exist below TIRAMISU, so grant nothing there to avoid erroring on older
devices). Adds the androidx.test:rules dependency that provides the rule.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
This commit was merged in pull request #168.
This commit is contained in:
Jason Ross
2026-07-02 23:23:30 +00:00
committed by GitHub
co-authored by Claude Opus 4.8 github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
parent f353bdc5ec
commit 99f6ef19e4
6 changed files with 53 additions and 29 deletions
@@ -1,6 +1,8 @@
// SPDX-License-Identifier: GPL-3.0-or-later
package org.libremail.ui.onboarding
import android.Manifest
import android.os.Build
import androidx.activity.ComponentActivity
import androidx.compose.runtime.remember
import androidx.compose.ui.platform.LocalContext
@@ -18,6 +20,7 @@ import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import androidx.navigation.navArgument
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.rule.GrantPermissionRule
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
@@ -54,6 +57,19 @@ class OnboardingFlowTest {
@get:Rule
val composeTestRule = createAndroidComposeRule<ComponentActivity>()
// OnboardingWelcomeScreen requests POST_NOTIFICATIONS when it first composes (#151). On API 33+
// that runtime dialog would pop over the test, backgrounding the activity and leaving the compose
// rule with "No compose hierarchies found". Pre-grant it so the flow runs uninterrupted; the
// permission only exists on API 33+, so below TIRAMISU grant nothing (granting a nonexistent
// permission errors on older devices).
@get:Rule
val notificationPermission: GrantPermissionRule =
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
GrantPermissionRule.grant(Manifest.permission.POST_NOTIFICATIONS)
} else {
GrantPermissionRule.grant()
}
private fun string(resId: Int, vararg args: Any) = composeTestRule.activity.getString(resId, *args)
// Generous cap for the slow, animation-disabled CI matrix emulators; waitUntil returns as soon