Add test case for applying locus id in notification builder

This commit is contained in:
Adam Brown 2023-01-17 21:36:23 +00:00
parent 9cd9520e52
commit 69c55c05dc
6 changed files with 46 additions and 7 deletions

View File

@ -20,7 +20,7 @@ class ExpectTest(override val coroutineContext: CoroutineContext) : ExpectTestSc
override fun verifyExpects() {
expects.forEach { (times, block) -> coVerify(exactly = times) { block.invoke(this) } }
groups.forEach { coVerifyOrder { it.invoke(this) } }
groups.forEach { coVerifyAll { it.invoke(this) } }
}
override fun <T> T.expectUnit(times: Int, block: suspend MockKMatcherScope.(T) -> Unit) {

View File

@ -16,6 +16,11 @@ fun DeviceMeta.onAtLeastO(block: () -> Unit) {
whenXOrHigher(Build.VERSION_CODES.O, block, fallback = {})
}
@ChecksSdkIntAtLeast(api = Build.VERSION_CODES.Q, lambda = 0)
fun DeviceMeta.onAtLeastQ(block: () -> Unit) {
whenXOrHigher(Build.VERSION_CODES.Q, block, fallback = {})
}
@ChecksSdkIntAtLeast(api = Build.VERSION_CODES.R, lambda = 0)
fun DeviceMeta.onAtLeastR(block: () -> Unit) {
whenXOrHigher(Build.VERSION_CODES.R, block, fallback = {})

View File

@ -1,8 +1,12 @@
package fake
import android.app.Notification
import io.mockk.every
import io.mockk.mockk
import test.delegateReturn
class FakeNotificationBuilder {
val instance = mockk<Notification.Builder>(relaxed = true)
fun givenBuilds() = every { instance.build() }.delegateReturn()
}

View File

@ -9,9 +9,9 @@ import android.graphics.drawable.Icon
import app.dapk.st.core.DeviceMeta
import app.dapk.st.core.isAtLeastO
import app.dapk.st.core.onAtLeastO
import app.dapk.st.core.onAtLeastQ
@SuppressLint("NewApi")
@Suppress("ObjectPropertyName")
private val _builderFactory: (Context, String, DeviceMeta) -> Notification.Builder = { context, channel, deviceMeta ->
deviceMeta.isAtLeastO(
block = { Notification.Builder(context, channel) },
@ -23,7 +23,8 @@ class AndroidNotificationBuilder(
private val context: Context,
private val deviceMeta: DeviceMeta,
private val notificationStyleBuilder: AndroidNotificationStyleBuilder,
private val builderFactory: (Context, String, DeviceMeta) -> Notification.Builder = _builderFactory
private val builderFactory: (Context, String, DeviceMeta) -> Notification.Builder = _builderFactory,
private val notificationExtensions: NotificationExtensions = DefaultNotificationExtensions(deviceMeta),
) {
@SuppressLint("NewApi")
fun build(notification: AndroidNotification): Notification {
@ -42,7 +43,7 @@ class AndroidNotificationBuilder(
}
.ifNotNull(notification.category) { setCategory(it) }
.ifNotNull(notification.shortcutId) {
setLocusId(LocusId(it))
with(notificationExtensions) { applyLocusId(it) }
deviceMeta.onAtLeastO { setShortcutId(it) }
}
.ifNotNull(notification.smallIcon) { setSmallIcon(it) }

View File

@ -0,0 +1,16 @@
package app.dapk.st.notifications
import android.app.Notification
import android.content.LocusId
import app.dapk.st.core.DeviceMeta
import app.dapk.st.core.onAtLeastQ
interface NotificationExtensions {
fun Notification.Builder.applyLocusId(id: String)
}
internal class DefaultNotificationExtensions(private val deviceMeta: DeviceMeta) : NotificationExtensions {
override fun Notification.Builder.applyLocusId(id: String) {
deviceMeta.onAtLeastQ { setLocusId(LocusId(id)) }
}
}

View File

@ -1,12 +1,14 @@
package app.dapk.st.notifications
import android.app.Notification
import app.dapk.st.core.DeviceMeta
import fixture.NotificationDelegateFixtures.anAndroidNotification
import fake.FakeContext
import fake.FakeNotificationBuilder
import fake.aFakeMessagingStyle
import fixture.NotificationDelegateFixtures.anAndroidNotification
import io.mockk.every
import io.mockk.mockk
import org.amshove.kluent.shouldBeEqualTo
import org.junit.Test
import test.delegateReturn
import test.runExpectTest
@ -15,21 +17,30 @@ private val A_MESSAGING_STYLE = aFakeMessagingStyle()
class AndroidNotificationBuilderTest {
private val aPlatformNotification = mockk<Notification>()
private val fakeContext = FakeContext()
private val fakeNotificationBuilder = FakeNotificationBuilder()
private val fakeAndroidNotificationStyleBuilder = FakeAndroidNotificationStyleBuilder()
private val fakeNotificationExtensions = FakeNotificationExtensions()
private val builder = AndroidNotificationBuilder(
fakeContext.instance,
DeviceMeta(apiVersion = 26),
fakeAndroidNotificationStyleBuilder.instance,
builderFactory = { _, _, _ -> fakeNotificationBuilder.instance },
notificationExtensions = fakeNotificationExtensions
)
@Test
fun `applies all builder options`() = runExpectTest {
val notification = anAndroidNotification()
fakeAndroidNotificationStyleBuilder.given(notification.messageStyle!!).returns(A_MESSAGING_STYLE)
fakeNotificationBuilder.givenBuilds().returns(aPlatformNotification)
with(fakeNotificationExtensions) {
fakeNotificationExtensions.expect { fakeNotificationBuilder.instance.applyLocusId(notification.shortcutId!!) }
}
fakeNotificationBuilder.instance.captureExpects {
it.setOnlyAlertOnce(!notification.alertMoreThanOnce)
it.setAutoCancel(notification.autoCancel)
@ -45,9 +56,9 @@ class AndroidNotificationBuilderTest {
it.setLargeIcon(notification.largeIcon)
it.build()
}
val result = builder.build(notification)
val ignoredResult = builder.build(notification)
result shouldBeEqualTo aPlatformNotification
verifyExpects()
}
}
@ -57,3 +68,5 @@ class FakeAndroidNotificationStyleBuilder {
fun given(style: AndroidNotificationStyle) = every { instance.build(style) }.delegateReturn()
}
private class FakeNotificationExtensions : NotificationExtensions by mockk()