Something went wrong. Try again.
This repository has no description
Something went wrong. Try again.
3.7 kB · 102 lines
Kotlin
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103package social.grain
import android.Manifestimport android.app.NotificationChannelimport android.app.NotificationManagerimport android.app.PendingIntentimport android.content.Intentimport android.os.Buildimport android.os.SystemClockimport androidx.core.app.NotificationCompatimport androidx.core.app.NotificationManagerCompatimport androidx.test.ext.junit.runners.AndroidJUnit4import androidx.test.platform.app.InstrumentationRegistryimport org.junit.Afterimport org.junit.Assert.assertTrueimport org.junit.Beforeimport org.junit.Testimport org.junit.runner.RunWithimport social.grain.data.push.GrainMessagingService
/** * Clearing the launcher's badge. * * iOS drives the app icon badge from the unseen count directly, so reading the * notifications takes it down. Android draws that dot from whatever the app * still has posted in the shade instead, which means a push read inside the * app — rather than by tapping the notification — used to leave the dot up * with nothing behind it. */@RunWith(AndroidJUnit4::class)class NotificationBadgeTest {
private val instrumentation = InstrumentationRegistry.getInstrumentation() private val context = instrumentation.targetContext private val manager = NotificationManagerCompat.from(context)
private val socialId = 4242 private val otherId = 4343 private val otherChannel = "test_other_channel"
@Before fun grantPostingAndCreateChannels() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { instrumentation.uiAutomation.grantRuntimePermission( context.packageName, Manifest.permission.POST_NOTIFICATIONS, ) } GrainMessagingService.ensureChannel(context) context.getSystemService(NotificationManager::class.java)?.createNotificationChannel( NotificationChannel(otherChannel, "Other", NotificationManager.IMPORTANCE_LOW), ) }
@After fun tidyUp() { manager.cancel(socialId) manager.cancel(otherId) context.getSystemService(NotificationManager::class.java) ?.deleteNotificationChannel(otherChannel) }
private fun pendingIntent() = PendingIntent.getActivity( context, 0, Intent(context, MainActivity::class.java), PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE, )
private fun isPosted(id: Int) = manager.activeNotifications.any { it.id == id }
/** Posting and cancelling both settle asynchronously, so poll rather than assume. */ private fun awaitPosted(id: Int, expected: Boolean): Boolean { repeat(50) { if (isPosted(id) == expected) return true SystemClock.sleep(100) } return false }
@Test fun clearingTakesDownSocialPushesAndLeavesEverythingElseUp() { manager.notify( socialId, GrainMessagingService.notification(context, "Someone", "liked it", pendingIntent()), ) manager.notify( otherId, NotificationCompat.Builder(context, otherChannel) .setSmallIcon(R.drawable.ic_notification) .setContentTitle("Uploading") .build(), ) assertTrue("the social push never posted", awaitPosted(socialId, expected = true)) assertTrue("the other notification never posted", awaitPosted(otherId, expected = true))
GrainMessagingService.clearPosted(context)
assertTrue("the social push is still up", awaitPosted(socialId, expected = false)) assertTrue("an unrelated notification was cancelled too", isPosted(otherId)) }}