Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3b44be4a authored by Beth Thibodeau's avatar Beth Thibodeau Committed by Android (Google) Code Review
Browse files

Merge "Clean up recommendations UI code" into main

parents 7380bf0d de330e9b
Loading
Loading
Loading
Loading
+0 −137
Original line number Diff line number Diff line
@@ -16,26 +16,17 @@

package com.android.systemui.media.controls.domain.interactor

import android.R
import android.graphics.drawable.Icon
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.internal.logging.InstanceId
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.kosmos.testScope
import com.android.systemui.media.controls.MediaTestHelper
import com.android.systemui.media.controls.data.repository.MediaFilterRepository
import com.android.systemui.media.controls.data.repository.mediaFilterRepository
import com.android.systemui.media.controls.domain.pipeline.interactor.MediaCarouselInteractor
import com.android.systemui.media.controls.domain.pipeline.interactor.MediaRecommendationsInteractor
import com.android.systemui.media.controls.domain.pipeline.interactor.mediaCarouselInteractor
import com.android.systemui.media.controls.domain.pipeline.interactor.mediaRecommendationsInteractor
import com.android.systemui.media.controls.shared.model.MediaCommonModel
import com.android.systemui.media.controls.shared.model.MediaData
import com.android.systemui.media.controls.shared.model.MediaDataLoadingModel
import com.android.systemui.media.controls.shared.model.SmartspaceMediaData
import com.android.systemui.media.controls.shared.model.SmartspaceMediaLoadingModel
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.test.runTest
@@ -52,16 +43,6 @@ class MediaCarouselInteractorTest : SysuiTestCase() {

    private val mediaFilterRepository: MediaFilterRepository =
        with(kosmos) { mediaFilterRepository }
    private val mediaRecommendationsInteractor: MediaRecommendationsInteractor =
        kosmos.mediaRecommendationsInteractor
    val icon = Icon.createWithResource(context, R.drawable.ic_media_play)
    private val mediaRecommendation =
        SmartspaceMediaData(
            targetId = KEY_MEDIA_SMARTSPACE,
            isActive = true,
            packageName = PACKAGE_NAME,
            recommendations = MediaTestHelper.getValidRecommendationList(icon),
        )

    private val underTest: MediaCarouselInteractor = kosmos.mediaCarouselInteractor

@@ -118,81 +99,6 @@ class MediaCarouselInteractorTest : SysuiTestCase() {
            assertThat(underTest.hasAnyMedia()).isFalse()
        }

    @Test
    fun addActiveRecommendation_inactiveMedia() =
        testScope.runTest {
            val hasActiveMediaOrRecommendation by
                collectLastValue(underTest.hasActiveMediaOrRecommendation)
            val hasAnyMediaOrRecommendation by
                collectLastValue(underTest.hasAnyMediaOrRecommendation)
            val currentMedia by collectLastValue(underTest.currentMedia)

            val userMedia = MediaData(active = false)
            val recsLoadingModel = SmartspaceMediaLoadingModel.Loaded(KEY_MEDIA_SMARTSPACE, true)
            val mediaLoadingModel = MediaDataLoadingModel.Loaded(userMedia.instanceId)

            mediaFilterRepository.setRecommendation(mediaRecommendation)
            mediaFilterRepository.setRecommendationsLoadingState(recsLoadingModel)

            assertThat(hasActiveMediaOrRecommendation).isTrue()
            assertThat(hasAnyMediaOrRecommendation).isTrue()
            assertThat(currentMedia)
                .containsExactly(MediaCommonModel.MediaRecommendations(recsLoadingModel))

            mediaFilterRepository.addSelectedUserMediaEntry(userMedia)
            mediaFilterRepository.addMediaDataLoadingState(mediaLoadingModel)
            mediaFilterRepository.setOrderedMedia()

            assertThat(hasActiveMediaOrRecommendation).isTrue()
            assertThat(hasAnyMediaOrRecommendation).isTrue()
            assertThat(currentMedia)
                .containsExactly(
                    MediaCommonModel.MediaRecommendations(recsLoadingModel),
                    MediaCommonModel.MediaControl(mediaLoadingModel, true),
                )
                .inOrder()
        }

    @Test
    fun addActiveRecommendation_thenInactive() =
        testScope.runTest {
            val hasActiveMediaOrRecommendation by
                collectLastValue(underTest.hasActiveMediaOrRecommendation)
            val hasAnyMediaOrRecommendation by
                collectLastValue(underTest.hasAnyMediaOrRecommendation)

            mediaFilterRepository.setRecommendation(mediaRecommendation)

            assertThat(hasActiveMediaOrRecommendation).isTrue()
            assertThat(hasAnyMediaOrRecommendation).isTrue()

            mediaFilterRepository.setRecommendation(mediaRecommendation.copy(isActive = false))

            assertThat(hasActiveMediaOrRecommendation).isFalse()
            assertThat(hasAnyMediaOrRecommendation).isFalse()
        }

    @Test
    fun addActiveRecommendation_thenInvalid() =
        testScope.runTest {
            val hasActiveMediaOrRecommendation by
                collectLastValue(underTest.hasActiveMediaOrRecommendation)
            val hasAnyMediaOrRecommendation by
                collectLastValue(underTest.hasAnyMediaOrRecommendation)

            mediaFilterRepository.setRecommendation(mediaRecommendation)

            assertThat(hasActiveMediaOrRecommendation).isTrue()
            assertThat(hasAnyMediaOrRecommendation).isTrue()

            mediaFilterRepository.setRecommendation(
                mediaRecommendation.copy(recommendations = listOf())
            )

            assertThat(hasActiveMediaOrRecommendation).isFalse()
            assertThat(hasAnyMediaOrRecommendation).isFalse()
        }

    @Test
    fun hasAnyMedia_noMediaSet_returnsFalse() =
        testScope.runTest { assertThat(underTest.hasAnyMedia()).isFalse() }
@@ -208,47 +114,4 @@ class MediaCarouselInteractorTest : SysuiTestCase() {
    @Test
    fun hasActiveMediaOrRecommendation_nothingSet_returnsFalse() =
        testScope.runTest { assertThat(underTest.hasActiveMediaOrRecommendation.value).isFalse() }

    @Test
    fun loadMediaFromRec() =
        testScope.runTest {
            val currentMedia by collectLastValue(underTest.currentMedia)
            val instanceId = InstanceId.fakeInstanceId(123)
            val data =
                MediaData(
                    active = true,
                    instanceId = instanceId,
                    packageName = PACKAGE_NAME,
                    notificationKey = KEY,
                )
            val smartspaceLoadingModel = SmartspaceMediaLoadingModel.Loaded(KEY_MEDIA_SMARTSPACE)
            val mediaLoadingModel = MediaDataLoadingModel.Loaded(instanceId)

            mediaFilterRepository.setRecommendation(mediaRecommendation)
            mediaFilterRepository.setRecommendationsLoadingState(smartspaceLoadingModel)
            mediaRecommendationsInteractor.switchToMediaControl(PACKAGE_NAME)
            mediaFilterRepository.addSelectedUserMediaEntry(data)
            mediaFilterRepository.addMediaDataLoadingState(mediaLoadingModel)

            assertThat(currentMedia)
                .containsExactly(MediaCommonModel.MediaRecommendations(smartspaceLoadingModel))
                .inOrder()

            mediaFilterRepository.addSelectedUserMediaEntry(data.copy(isPlaying = true))
            mediaFilterRepository.addMediaDataLoadingState(mediaLoadingModel)

            assertThat(currentMedia)
                .containsExactly(
                    MediaCommonModel.MediaControl(mediaLoadingModel, isMediaFromRec = true),
                    MediaCommonModel.MediaRecommendations(smartspaceLoadingModel),
                )
                .inOrder()
        }

    companion object {
        private const val KEY_MEDIA_SMARTSPACE = "MEDIA_SMARTSPACE_ID"
        private const val PACKAGE_NAME = "com.android.example"
        private const val KEY = "key"
        private const val SURFACE = 4
    }
}
+0 −168
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.systemui.media.controls.domain.interactor

import android.R
import android.content.ComponentName
import android.content.Intent
import android.content.applicationContext
import android.graphics.drawable.Icon
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.animation.Expandable
import com.android.systemui.broadcast.broadcastSender
import com.android.systemui.broadcast.mockBroadcastSender
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.kosmos.testScope
import com.android.systemui.media.controls.MediaTestHelper
import com.android.systemui.media.controls.domain.pipeline.MediaDataFilterImpl
import com.android.systemui.media.controls.domain.pipeline.interactor.MediaRecommendationsInteractor
import com.android.systemui.media.controls.domain.pipeline.interactor.MediaRecommendationsInteractor.Companion.EXPORTED_SMARTSPACE_TRAMPOLINE_ACTIVITY_NAME
import com.android.systemui.media.controls.domain.pipeline.interactor.mediaRecommendationsInteractor
import com.android.systemui.media.controls.domain.pipeline.mediaDataFilter
import com.android.systemui.media.controls.shared.model.MediaRecModel
import com.android.systemui.media.controls.shared.model.MediaRecommendationsModel
import com.android.systemui.media.controls.shared.model.SmartspaceMediaData
import com.android.systemui.plugins.activityStarter
import com.android.systemui.testKosmos
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.mock
import com.android.systemui.util.mockito.whenever
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.test.runTest
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mockito.doNothing
import org.mockito.Mockito.spy
import org.mockito.Mockito.verify
import org.mockito.kotlin.eq

@SmallTest
@RunWith(AndroidJUnit4::class)
class MediaRecommendationsInteractorTest : SysuiTestCase() {

    private val spyContext = spy(context)
    private val kosmos = testKosmos().apply { applicationContext = spyContext }
    private val testScope = kosmos.testScope

    private val mediaDataFilter: MediaDataFilterImpl = with(kosmos) { mediaDataFilter }
    private val activityStarter = kosmos.activityStarter
    private val icon: Icon = Icon.createWithResource(context, R.drawable.ic_media_play)
    private val smartspaceMediaData: SmartspaceMediaData =
        SmartspaceMediaData(
            targetId = KEY_MEDIA_SMARTSPACE,
            isActive = true,
            packageName = PACKAGE_NAME,
            recommendations = MediaTestHelper.getValidRecommendationList(icon),
        )

    private val underTest: MediaRecommendationsInteractor =
        with(kosmos) {
            broadcastSender = mockBroadcastSender
            kosmos.mediaRecommendationsInteractor
        }

    @Test
    fun addRecommendation_smartspaceMediaDataUpdate() =
        testScope.runTest {
            val recommendations by collectLastValue(underTest.recommendations)

            val model =
                MediaRecommendationsModel(
                    key = KEY_MEDIA_SMARTSPACE,
                    packageName = PACKAGE_NAME,
                    areRecommendationsValid = true,
                    mediaRecs =
                        listOf(
                            MediaRecModel(icon = icon),
                            MediaRecModel(icon = icon),
                            MediaRecModel(icon = icon),
                        ),
                )

            mediaDataFilter.onSmartspaceMediaDataLoaded(KEY_MEDIA_SMARTSPACE, smartspaceMediaData)

            assertThat(recommendations).isEqualTo(model)
        }

    @Test
    fun addInvalidRecommendation() =
        testScope.runTest {
            val recommendations by collectLastValue(underTest.recommendations)
            val inValidData = smartspaceMediaData.copy(recommendations = listOf())

            mediaDataFilter.onSmartspaceMediaDataLoaded(KEY_MEDIA_SMARTSPACE, smartspaceMediaData)
            assertThat(recommendations?.areRecommendationsValid).isTrue()

            mediaDataFilter.onSmartspaceMediaDataLoaded(KEY_MEDIA_SMARTSPACE, inValidData)
            assertThat(recommendations?.areRecommendationsValid).isFalse()
            assertThat(recommendations?.mediaRecs?.isEmpty()).isTrue()
        }

    @Test
    fun removeRecommendation_noTrampolineActivity() {
        val intent = Intent()

        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)

        mediaDataFilter.onSmartspaceMediaDataLoaded(KEY_MEDIA_SMARTSPACE, smartspaceMediaData)
        underTest.removeMediaRecommendations(KEY_MEDIA_SMARTSPACE, intent, 0)

        verify(kosmos.mockBroadcastSender).sendBroadcast(eq(intent))
    }

    @Test
    fun removeRecommendation_usingTrampolineActivity() {
        doNothing().whenever(spyContext).startActivity(any())
        val intent = Intent()

        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
        intent.component = ComponentName(PACKAGE_NAME, EXPORTED_SMARTSPACE_TRAMPOLINE_ACTIVITY_NAME)

        underTest.removeMediaRecommendations(KEY_MEDIA_SMARTSPACE, intent, 0)

        verify(spyContext).startActivity(eq(intent))
    }

    @Test
    fun startSettings() {
        underTest.startSettings()

        verify(activityStarter).startActivity(any(), eq(true))
    }

    @Test
    fun startClickIntent() {
        doNothing().whenever(spyContext).startActivity(any())
        val intent = Intent()
        val expandable = mock<Expandable>()

        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)

        mediaDataFilter.onSmartspaceMediaDataLoaded(KEY_MEDIA_SMARTSPACE, smartspaceMediaData)
        underTest.startClickIntent(expandable, intent)

        verify(spyContext).startActivity(eq(intent))
    }

    companion object {
        private const val KEY_MEDIA_SMARTSPACE = "MEDIA_SMARTSPACE_ID"
        private const val PACKAGE_NAME = "com.example.app"
        private const val SURFACE = 4
    }
}
+1 −99
Original line number Diff line number Diff line
@@ -23,7 +23,6 @@ import com.android.internal.logging.InstanceId
import com.android.systemui.SysuiTestCase
import com.android.systemui.media.controls.ui.viewmodel.MediaCommonViewModel
import com.android.systemui.media.controls.ui.viewmodel.mediaControlViewModel
import com.android.systemui.media.controls.ui.viewmodel.mediaRecommendationsViewModel
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
import org.junit.Assert.fail
@@ -55,25 +54,6 @@ class MediaDiffUtilTest : SysuiTestCase() {
        DiffUtil.calculateDiff(mediaLoadedCallback).dispatchUpdatesTo(mediaLoadedListUpdateCallback)
    }

    @Test
    fun newMediaRecommendationsAdded() {
        val mediaRecs = createMediaRecommendations(KEY_MEDIA_SMARTSPACE, true)
        val oldList = listOf<MediaCommonViewModel>()
        val newList = listOf(mediaRecs)
        val mediaLoadedCallback = MediaViewModelCallback(oldList, newList)
        val mediaLoadedListUpdateCallback =
            MediaViewModelListUpdateCallback(
                oldList,
                newList,
                { commonViewModel, _ -> assertThat(commonViewModel).isEqualTo(mediaRecs) },
                { commonViewModel, _ -> fail("Unexpected to update $commonViewModel") },
                { fail("Unexpected to remove $it") },
                { commonViewModel, _, _ -> fail("Unexpected to move $commonViewModel ") },
            )

        DiffUtil.calculateDiff(mediaLoadedCallback).dispatchUpdatesTo(mediaLoadedListUpdateCallback)
    }

    @Test
    fun updateMediaControl_contentChanged() {
        val mediaControl = createMediaControl(InstanceId.fakeInstanceId(123), true)
@@ -93,25 +73,6 @@ class MediaDiffUtilTest : SysuiTestCase() {
        DiffUtil.calculateDiff(mediaLoadedCallback).dispatchUpdatesTo(mediaLoadedListUpdateCallback)
    }

    @Test
    fun updateMediaRecommendations_contentChanged() {
        val mediaRecs = createMediaRecommendations(KEY_MEDIA_SMARTSPACE, true)
        val oldList = listOf(mediaRecs)
        val newList = listOf(mediaRecs.copy(key = KEY_MEDIA_SMARTSPACE_2))
        val mediaLoadedCallback = MediaViewModelCallback(oldList, newList)
        val mediaLoadedListUpdateCallback =
            MediaViewModelListUpdateCallback(
                oldList,
                newList,
                { commonViewModel, _ -> fail("Unexpected to add $commonViewModel") },
                { commonViewModel, _ -> assertThat(commonViewModel).isNotEqualTo(mediaRecs) },
                { fail("Unexpected to remove $it") },
                { commonViewModel, _, _ -> fail("Unexpected to move $commonViewModel ") },
            )

        DiffUtil.calculateDiff(mediaLoadedCallback).dispatchUpdatesTo(mediaLoadedListUpdateCallback)
    }

    @Test
    fun mediaControlMoved() {
        val mediaControl1 = createMediaControl(InstanceId.fakeInstanceId(123), true)
@@ -132,27 +93,6 @@ class MediaDiffUtilTest : SysuiTestCase() {
        DiffUtil.calculateDiff(mediaLoadedCallback).dispatchUpdatesTo(mediaLoadedListUpdateCallback)
    }

    @Test
    fun mediaRecommendationsMoved() {
        val mediaControl1 = createMediaControl(InstanceId.fakeInstanceId(123), true)
        val mediaControl2 = createMediaControl(InstanceId.fakeInstanceId(456), false)
        val mediaRecs = createMediaRecommendations(KEY_MEDIA_SMARTSPACE, true)
        val oldList = listOf(mediaRecs, mediaControl1, mediaControl2)
        val newList = listOf(mediaControl1, mediaControl2, mediaRecs)
        val mediaLoadedCallback = MediaViewModelCallback(oldList, newList)
        val mediaLoadedListUpdateCallback =
            MediaViewModelListUpdateCallback(
                oldList,
                newList,
                { commonViewModel, _ -> fail("Unexpected to add $commonViewModel") },
                { commonViewModel, _ -> fail("Unexpected to update $commonViewModel") },
                { fail("Unexpected to remove $it") },
                { commonViewModel, _, _ -> assertThat(commonViewModel).isEqualTo(mediaRecs) },
            )

        DiffUtil.calculateDiff(mediaLoadedCallback).dispatchUpdatesTo(mediaLoadedListUpdateCallback)
    }

    @Test
    fun mediaControlRemoved() {
        val mediaControl = createMediaControl(InstanceId.fakeInstanceId(123), true)
@@ -172,25 +112,6 @@ class MediaDiffUtilTest : SysuiTestCase() {
        DiffUtil.calculateDiff(mediaLoadedCallback).dispatchUpdatesTo(mediaLoadedListUpdateCallback)
    }

    @Test
    fun mediaRecommendationsRemoved() {
        val mediaRecs = createMediaRecommendations(KEY_MEDIA_SMARTSPACE_2, false)
        val oldList = listOf(mediaRecs)
        val newList = listOf<MediaCommonViewModel>()
        val mediaLoadedCallback = MediaViewModelCallback(oldList, newList)
        val mediaLoadedListUpdateCallback =
            MediaViewModelListUpdateCallback(
                oldList,
                newList,
                { commonViewModel, _ -> fail("Unexpected to add $commonViewModel") },
                { commonViewModel, _ -> fail("Unexpected to update $commonViewModel") },
                { commonViewModel -> assertThat(commonViewModel).isEqualTo(mediaRecs) },
                { commonViewModel, _, _ -> fail("Unexpected to move $commonViewModel ") },
            )

        DiffUtil.calculateDiff(mediaLoadedCallback).dispatchUpdatesTo(mediaLoadedListUpdateCallback)
    }

    private fun createMediaControl(
        instanceId: InstanceId,
        immediatelyUpdateUi: Boolean,
@@ -201,26 +122,7 @@ class MediaDiffUtilTest : SysuiTestCase() {
            controlViewModel = kosmos.mediaControlViewModel,
            onAdded = {},
            onRemoved = {},
            onUpdated = {}
        )
    }

    private fun createMediaRecommendations(
        key: String,
        loadingEnabled: Boolean,
    ): MediaCommonViewModel.MediaRecommendations {
        return MediaCommonViewModel.MediaRecommendations(
            key = key,
            loadingEnabled = loadingEnabled,
            recsViewModel = kosmos.mediaRecommendationsViewModel,
            onAdded = {},
            onRemoved = {},
            onUpdated = {}
            onUpdated = {},
        )
    }

    companion object {
        private const val KEY_MEDIA_SMARTSPACE = "MEDIA_SMARTSPACE_ID"
        private const val KEY_MEDIA_SMARTSPACE_2 = "MEDIA_SMARTSPACE_ID_2"
    }
}
+0 −90

File changed.

Preview size limit exceeded, changes collapsed.

+0 −88
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.systemui.media.controls.ui.viewmodel

import android.R
import android.content.packageManager
import android.content.pm.ApplicationInfo
import android.graphics.drawable.Icon
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.kosmos.testScope
import com.android.systemui.media.controls.MediaTestHelper
import com.android.systemui.media.controls.domain.pipeline.MediaDataFilterImpl
import com.android.systemui.media.controls.domain.pipeline.mediaDataFilter
import com.android.systemui.media.controls.shared.model.SmartspaceMediaData
import com.android.systemui.testKosmos
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.eq
import com.android.systemui.util.mockito.whenever
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.test.runTest
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers
import org.mockito.Mockito

@SmallTest
@RunWith(AndroidJUnit4::class)
class MediaRecommendationsViewModelTest : SysuiTestCase() {

    private val kosmos = testKosmos()
    private val testScope = kosmos.testScope

    private val mediaDataFilter: MediaDataFilterImpl = kosmos.mediaDataFilter
    private val packageManager = kosmos.packageManager
    private val icon: Icon = Icon.createWithResource(context, R.drawable.ic_media_play)
    private val drawable = context.getDrawable(R.drawable.ic_media_play)
    private val smartspaceMediaData: SmartspaceMediaData =
        SmartspaceMediaData(
            targetId = KEY_MEDIA_SMARTSPACE,
            isActive = true,
            packageName = PACKAGE_NAME,
            recommendations = MediaTestHelper.getValidRecommendationList(icon),
        )

    private val underTest: MediaRecommendationsViewModel = kosmos.mediaRecommendationsViewModel

    @Test
    fun loadRecommendations_recsCardViewModelIsLoaded() =
        testScope.runTest {
            whenever(packageManager.getApplicationIcon(Mockito.anyString())).thenReturn(drawable)
            whenever(packageManager.getApplicationIcon(any(ApplicationInfo::class.java)))
                .thenReturn(drawable)
            whenever(packageManager.getApplicationInfo(eq(PACKAGE_NAME), ArgumentMatchers.anyInt()))
                .thenReturn(ApplicationInfo())
            whenever(packageManager.getApplicationLabel(any())).thenReturn(PACKAGE_NAME)
            val recsCardViewModel by collectLastValue(underTest.mediaRecsCard)

            context.setMockPackageManager(packageManager)

            mediaDataFilter.onSmartspaceMediaDataLoaded(KEY_MEDIA_SMARTSPACE, smartspaceMediaData)

            assertThat(recsCardViewModel).isNotNull()
            assertThat(recsCardViewModel?.mediaRecs?.size)
                .isEqualTo(smartspaceMediaData.recommendations.size)
        }

    companion object {
        private const val KEY_MEDIA_SMARTSPACE = "MEDIA_SMARTSPACE_ID"
        private const val PACKAGE_NAME = "com.example.app"
    }
}
Loading