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

Commit de330e9b authored by Beth Thibodeau's avatar Beth Thibodeau
Browse files

Clean up recommendations UI code

Feature has been turned down - remove non-pipeline code

Bug: 382680767
Test: atest SystemUITests:com.android.systemui.media.controls
Flag: EXEMPT removing unused code
Change-Id: Ic53edc401702feeaa5839b62ff893d568c8d72a9
parent 865fec2d
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