1 /* 2 * Copyright (C) 2024 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.systemui.qs.external.ui.viewmodel 18 19 import android.content.applicationContext 20 import android.content.res.mainResources 21 import android.graphics.drawable.Icon 22 import android.graphics.drawable.TestStubDrawable 23 import android.service.quicksettings.Tile 24 import androidx.test.ext.junit.runners.AndroidJUnit4 25 import androidx.test.filters.SmallTest 26 import com.android.app.iUriGrantsManager 27 import com.android.systemui.SysuiTestCase 28 import com.android.systemui.kosmos.Kosmos 29 import com.android.systemui.kosmos.runCurrent 30 import com.android.systemui.kosmos.runTest 31 import com.android.systemui.kosmos.testScope 32 import com.android.systemui.lifecycle.activateIn 33 import com.android.systemui.plugins.qs.QSTile 34 import com.android.systemui.qs.external.TileData 35 import com.android.systemui.qs.panels.ui.viewmodel.toUiState 36 import com.android.systemui.qs.tileimpl.QSTileImpl 37 import com.android.systemui.qs.tileimpl.QSTileImpl.ResourceIcon 38 import com.android.systemui.res.R 39 import com.android.systemui.testKosmos 40 import com.google.common.truth.Expect 41 import com.google.common.truth.Truth.assertThat 42 import org.junit.Rule 43 import org.junit.Test 44 import org.junit.runner.RunWith 45 import org.mockito.kotlin.doReturn 46 import org.mockito.kotlin.mock 47 import org.mockito.kotlin.stub 48 49 @SmallTest 50 @RunWith(AndroidJUnit4::class) 51 class TileRequestDialogViewModelTest : SysuiTestCase() { 52 53 @get:Rule val expect: Expect = Expect.create() 54 55 private val kosmos = testKosmos() 56 <lambda>null57 private val icon: Icon = mock { 58 on { 59 loadDrawableCheckingUriGrant( 60 kosmos.applicationContext, 61 kosmos.iUriGrantsManager, 62 TEST_UID, 63 TEST_PACKAGE, 64 ) 65 } doReturn (loadedDrawable) 66 } 67 68 private val tileData = TileData(TEST_UID, TEST_APP_NAME, TEST_LABEL, icon, TEST_PACKAGE) 69 70 private val Kosmos.underTest by <lambda>null71 Kosmos.Fixture { tileRequestDialogViewModelFactory.create(applicationContext, tileData) } 72 73 private val baseResultLegacyState = <lambda>null74 QSTile.State().apply { 75 label = TEST_LABEL 76 state = Tile.STATE_ACTIVE 77 handlesLongClick = false 78 } 79 80 @Test uiState_beforeActivation_hasDefaultIcon_andCorrectDatanull81 fun uiState_beforeActivation_hasDefaultIcon_andCorrectData() = 82 kosmos.runTest { 83 val expectedState = 84 baseResultLegacyState.apply { icon = defaultIcon }.toUiState(mainResources) 85 86 with(underTest.uiState) { 87 expect.that(label).isEqualTo(TEST_LABEL) 88 expect.that(secondaryLabel).isEmpty() 89 expect.that(state).isEqualTo(expectedState.state) 90 expect.that(handlesLongClick).isFalse() 91 expect.that(handlesSecondaryClick).isFalse() 92 expect.that(icon.get()).isEqualTo(defaultIcon) 93 expect.that(sideDrawable).isNull() 94 expect.that(accessibilityUiState).isEqualTo(expectedState.accessibilityUiState) 95 } 96 } 97 98 @Test uiState_afterActivation_hasCorrectIcon_andCorrectDatanull99 fun uiState_afterActivation_hasCorrectIcon_andCorrectData() = 100 kosmos.runTest { 101 val expectedState = 102 baseResultLegacyState 103 .apply { icon = QSTileImpl.DrawableIcon(loadedDrawable) } 104 .toUiState(mainResources) 105 106 underTest.activateIn(testScope) 107 runCurrent() 108 109 with(underTest.uiState) { 110 expect.that(label).isEqualTo(TEST_LABEL) 111 expect.that(secondaryLabel).isEmpty() 112 expect.that(state).isEqualTo(expectedState.state) 113 expect.that(handlesLongClick).isFalse() 114 expect.that(handlesSecondaryClick).isFalse() 115 expect.that(icon.get()).isEqualTo(QSTileImpl.DrawableIcon(loadedDrawable)) 116 expect.that(sideDrawable).isNull() 117 expect.that(accessibilityUiState).isEqualTo(expectedState.accessibilityUiState) 118 } 119 } 120 121 @Test uiState_afterActivation_iconNotLoaded_usesDefaultnull122 fun uiState_afterActivation_iconNotLoaded_usesDefault() = 123 kosmos.runTest { 124 icon.stub { 125 on { 126 loadDrawableCheckingUriGrant( 127 kosmos.applicationContext, 128 kosmos.iUriGrantsManager, 129 TEST_UID, 130 TEST_PACKAGE, 131 ) 132 } doReturn (null) 133 } 134 135 underTest.activateIn(testScope) 136 runCurrent() 137 138 assertThat(underTest.uiState.icon.get()).isEqualTo(defaultIcon) 139 } 140 141 companion object { 142 private val defaultIcon: QSTile.Icon = ResourceIcon.get(R.drawable.android) 143 private val loadedDrawable = TestStubDrawable("loaded") 144 145 private const val TEST_PACKAGE = "test_pkg" 146 private const val TEST_APP_NAME = "App" 147 private const val TEST_LABEL = "Label" 148 private const val TEST_UID = 12345 149 } 150 } 151