1 /* 2 * Copyright (C) 2021 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 18 19 import android.content.ComponentName 20 import android.content.Context 21 import android.content.SharedPreferences 22 import android.service.quicksettings.Tile 23 import android.testing.AndroidTestingRunner 24 import androidx.test.filters.SmallTest 25 import com.android.systemui.SysuiTestCase 26 import com.android.systemui.util.mockito.capture 27 import com.android.systemui.util.mockito.eq 28 import com.google.common.truth.Truth.assertThat 29 import org.junit.Before 30 import org.junit.Test 31 import org.junit.runner.RunWith 32 import org.mockito.Answers 33 import org.mockito.ArgumentCaptor 34 import org.mockito.ArgumentMatchers.any 35 import org.mockito.ArgumentMatchers.anyInt 36 import org.mockito.ArgumentMatchers.anyString 37 import org.mockito.Captor 38 import org.mockito.Mock 39 import org.mockito.Mockito.`when` 40 import org.mockito.Mockito.verify 41 import org.mockito.MockitoAnnotations 42 43 @SmallTest 44 @RunWith(AndroidTestingRunner::class) 45 class CustomTileStatePersisterTest : SysuiTestCase() { 46 47 companion object { 48 private val TEST_COMPONENT = ComponentName("pkg", "cls") 49 private const val TEST_USER = 0 50 private val KEY = TileServiceKey(TEST_COMPONENT, TEST_USER) 51 52 private const val TEST_STATE = Tile.STATE_INACTIVE 53 private const val TEST_LABEL = "test_label" 54 private const val TEST_SUBTITLE = "test_subtitle" 55 private const val TEST_CONTENT_DESCRIPTION = "test_content_description" 56 private const val TEST_STATE_DESCRIPTION = "test_state_description" 57 58 private fun Tile.isEqualTo(other: Tile): Boolean { 59 return state == other.state && 60 label == other.label && 61 subtitle == other.subtitle && 62 contentDescription == other.contentDescription && 63 stateDescription == other.stateDescription 64 } 65 } 66 67 @Mock 68 private lateinit var mockContext: Context 69 @Mock 70 private lateinit var sharedPreferences: SharedPreferences 71 @Mock(answer = Answers.RETURNS_SELF) 72 private lateinit var editor: SharedPreferences.Editor 73 private lateinit var tile: Tile 74 private lateinit var customTileStatePersister: CustomTileStatePersister 75 76 @Captor 77 private lateinit var stringCaptor: ArgumentCaptor<String> 78 79 @Before 80 fun setUp() { 81 MockitoAnnotations.initMocks(this) 82 `when`(mockContext.getSharedPreferences(anyString(), anyInt())) 83 .thenReturn(sharedPreferences) 84 `when`(sharedPreferences.edit()).thenReturn(editor) 85 86 tile = Tile() 87 customTileStatePersister = CustomTileStatePersister(mockContext) 88 } 89 90 @Test 91 fun testWriteState() { 92 tile.apply { 93 state = TEST_STATE 94 label = TEST_LABEL 95 subtitle = TEST_SUBTITLE 96 contentDescription = TEST_CONTENT_DESCRIPTION 97 stateDescription = TEST_STATE_DESCRIPTION 98 } 99 100 customTileStatePersister.persistState(KEY, tile) 101 102 verify(editor).putString(eq(KEY.toString()), capture(stringCaptor)) 103 104 assertThat(tile.isEqualTo(readTileFromString(stringCaptor.value))).isTrue() 105 } 106 107 @Test 108 fun testReadState() { 109 tile.apply { 110 state = TEST_STATE 111 label = TEST_LABEL 112 subtitle = TEST_SUBTITLE 113 contentDescription = TEST_CONTENT_DESCRIPTION 114 stateDescription = TEST_STATE_DESCRIPTION 115 } 116 117 `when`(sharedPreferences.getString(eq(KEY.toString()), any())) 118 .thenReturn(writeToString(tile)) 119 120 assertThat(tile.isEqualTo(customTileStatePersister.readState(KEY)!!)).isTrue() 121 } 122 123 @Test 124 fun testReadStateDefault() { 125 `when`(sharedPreferences.getString(any(), any())).thenAnswer { 126 it.getArgument(1) 127 } 128 129 assertThat(customTileStatePersister.readState(KEY)).isNull() 130 } 131 132 @Test 133 fun testStoreNulls() { 134 assertThat(tile.label).isNull() 135 136 customTileStatePersister.persistState(KEY, tile) 137 138 verify(editor).putString(eq(KEY.toString()), capture(stringCaptor)) 139 140 assertThat(readTileFromString(stringCaptor.value).label).isNull() 141 } 142 143 @Test 144 fun testReadNulls() { 145 assertThat(tile.label).isNull() 146 147 `when`(sharedPreferences.getString(eq(KEY.toString()), any())) 148 .thenReturn(writeToString(tile)) 149 150 assertThat(customTileStatePersister.readState(KEY)!!.label).isNull() 151 } 152 153 @Test 154 fun testRemoveState() { 155 customTileStatePersister.removeState(KEY) 156 157 verify(editor).remove(KEY.toString()) 158 } 159 }