Add coverage for NotificationBitmapLoader

This commit is contained in:
Benoit Marty 2023-11-27 14:31:17 +01:00 committed by Benoit Marty
parent 7cb6740dd6
commit 73ebffab2e
4 changed files with 114 additions and 4 deletions

View file

@ -136,6 +136,7 @@ test_appyx_junit = { module = "com.bumble.appyx:testing-junit4", version.ref = "
coil = { module = "io.coil-kt:coil", version.ref = "coil" }
coil_compose = { module = "io.coil-kt:coil-compose", version.ref = "coil" }
coil_gif = { module = "io.coil-kt:coil-gif", version.ref = "coil" }
coil_test = { module = "io.coil-kt:coil-test", version.ref = "coil" }
compound = { module = "io.element.android:compound-android", version = "0.0.1" }
datetime = { module = "org.jetbrains.kotlinx:kotlinx-datetime", version.ref = "datetime" }
serialization_json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "serialization_json" }

View file

@ -65,6 +65,7 @@ dependencies {
testImplementation(libs.test.mockk)
testImplementation(libs.test.truth)
testImplementation(libs.test.turbine)
testImplementation(libs.coil.test)
testImplementation(libs.coroutines.test)
testImplementation(projects.libraries.matrix.test)
testImplementation(projects.services.appnavstate.test)

View file

@ -27,11 +27,13 @@ import coil.transform.CircleCropTransformation
import io.element.android.libraries.di.ApplicationContext
import io.element.android.libraries.matrix.api.media.MediaSource
import io.element.android.libraries.matrix.ui.media.MediaRequestData
import io.element.android.services.toolbox.api.sdk.BuildVersionSdkIntProvider
import timber.log.Timber
import javax.inject.Inject
class NotificationBitmapLoader @Inject constructor(
@ApplicationContext private val context: Context
@ApplicationContext private val context: Context,
private val sdkIntProvider: BuildVersionSdkIntProvider,
) {
/**
@ -65,7 +67,7 @@ class NotificationBitmapLoader @Inject constructor(
* @param path mxc url
*/
suspend fun getUserIcon(path: String?): IconCompat? {
if (path == null || Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
if (path == null || sdkIntProvider.get() < Build.VERSION_CODES.P) {
return null
}

View file

@ -17,12 +17,23 @@
package io.element.android.libraries.push.impl.notifications
import android.content.Context
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.os.Build
import coil.Coil
import coil.ImageLoader
import coil.annotation.ExperimentalCoilApi
import coil.test.FakeImageLoaderEngine
import com.google.common.truth.Truth.assertThat
import io.element.android.libraries.matrix.api.media.MediaSource
import io.element.android.libraries.matrix.test.A_ROOM_ID
import io.element.android.libraries.matrix.ui.components.aMatrixUser
import io.element.android.libraries.matrix.ui.media.MediaRequestData
import io.element.android.libraries.push.impl.notifications.factories.createNotificationCreator
import io.element.android.libraries.push.impl.notifications.fixtures.aNotifiableMessageEvent
import io.element.android.services.toolbox.api.sdk.BuildVersionSdkIntProvider
import io.element.android.services.toolbox.impl.strings.AndroidStringProvider
import io.element.android.services.toolbox.test.sdk.FakeBuildVersionSdkIntProvider
import kotlinx.coroutines.test.runTest
import org.junit.Test
import org.junit.runner.RunWith
@ -30,6 +41,9 @@ import org.robolectric.RobolectricTestRunner
import org.robolectric.RuntimeEnvironment
private const val A_TIMESTAMP = 6480L
private const val A_ROOM_AVATAR = "mxc://roomAvatar"
private const val A_USER_AVATAR_1 = "mxc://userAvatar1"
private const val A_USER_AVATAR_2 = "mxc://userAvatar2"
@RunWith(RobolectricTestRunner::class)
class RoomGroupMessageCreatorTest {
@ -85,6 +99,93 @@ class RoomGroupMessageCreatorTest {
)
}
@Test
fun `test createRoomMessage with room avatar and sender avatar android O`() {
`test createRoomMessage with room avatar and sender avatar`(
api = Build.VERSION_CODES.O,
// Only the Room avatar is loaded
expectedCoilRequests = listOf(
MediaRequestData(
source = MediaSource(url = A_ROOM_AVATAR),
kind = MediaRequestData.Kind.Thumbnail(1024)
)
)
)
}
@OptIn(ExperimentalCoilApi::class)
@Test
fun `test createRoomMessage with room avatar and sender avatar android P`() = runTest {
`test createRoomMessage with room avatar and sender avatar`(
api = Build.VERSION_CODES.P,
// Room and user avatar are loaded
expectedCoilRequests = listOf(
MediaRequestData(
source = MediaSource(url = A_USER_AVATAR_1),
kind = MediaRequestData.Kind.Thumbnail(1024)
),
MediaRequestData(
source = MediaSource(url = A_USER_AVATAR_2),
kind = MediaRequestData.Kind.Thumbnail(1024)
),
MediaRequestData(
source = MediaSource(url = A_ROOM_AVATAR),
kind = MediaRequestData.Kind.Thumbnail(1024)
),
)
)
}
@OptIn(ExperimentalCoilApi::class)
private fun `test createRoomMessage with room avatar and sender avatar`(
api: Int,
expectedCoilRequests: List<Any>,
) = runTest {
val coilRequests = mutableListOf<Any>()
val engine = FakeImageLoaderEngine.Builder()
.intercept(
predicate = {
coilRequests.add(it)
true
},
drawable = ColorDrawable(Color.BLUE)
)
.build()
val imageLoader = ImageLoader.Builder(RuntimeEnvironment.getApplication())
.components { add(engine) }
.build()
Coil.setImageLoader(imageLoader)
val sut = createRoomGroupMessageCreator(
sdkIntProvider = FakeBuildVersionSdkIntProvider(api)
)
val result = sut.createRoomMessage(
currentUser = aMatrixUser(
// Some user avatar
avatarUrl = A_USER_AVATAR_1,
),
events = listOf(
aNotifiableMessageEvent(timestamp = A_TIMESTAMP).copy(
roomAvatarPath = A_ROOM_AVATAR,
senderAvatarPath = A_USER_AVATAR_2,
)
),
roomId = A_ROOM_ID,
)
val resultMetaWithoutFormatting = result.meta.copy(
summaryLine = result.meta.summaryLine.toString()
)
assertThat(resultMetaWithoutFormatting).isEqualTo(
RoomNotification.Message.Meta(
roomId = A_ROOM_ID,
summaryLine = "room-name: sender-name message-body",
messageCount = 1,
latestTimestamp = A_TIMESTAMP,
shouldBing = false,
)
)
assertThat(coilRequests.toList()).isEqualTo(expectedCoilRequests)
}
@Test
fun `test createRoomMessage with two Events`() = runTest {
val sut = createRoomGroupMessageCreator()
@ -164,11 +265,16 @@ class RoomGroupMessageCreatorTest {
}
}
fun createRoomGroupMessageCreator(): RoomGroupMessageCreator {
fun createRoomGroupMessageCreator(
sdkIntProvider: BuildVersionSdkIntProvider = FakeBuildVersionSdkIntProvider(Build.VERSION_CODES.O),
): RoomGroupMessageCreator {
val context = RuntimeEnvironment.getApplication() as Context
return RoomGroupMessageCreator(
notificationCreator = createNotificationCreator(),
bitmapLoader = NotificationBitmapLoader(RuntimeEnvironment.getApplication()),
bitmapLoader = NotificationBitmapLoader(
context = RuntimeEnvironment.getApplication(),
sdkIntProvider = sdkIntProvider,
),
stringProvider = AndroidStringProvider(context.resources)
)
}