1 /* 2 * Copyright (C) 2017 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.settings.slices; 18 19 import static com.google.common.truth.Truth.assertThat; 20 21 import static org.mockito.Mockito.doReturn; 22 import static org.mockito.Mockito.spy; 23 24 import android.content.ContentValues; 25 import android.content.Context; 26 import android.database.Cursor; 27 import android.database.sqlite.SQLiteDatabase; 28 import android.net.Uri; 29 30 import com.android.settings.slices.SlicesDatabaseHelper.IndexColumns; 31 import com.android.settings.testutils.DatabaseTestUtils; 32 33 import org.junit.After; 34 import org.junit.Before; 35 import org.junit.Test; 36 import org.junit.runner.RunWith; 37 import org.robolectric.RobolectricTestRunner; 38 import org.robolectric.RuntimeEnvironment; 39 40 import java.util.ArrayList; 41 import java.util.List; 42 43 @RunWith(RobolectricTestRunner.class) 44 public class SlicesIndexerTest { 45 46 private final String[] KEYS = new String[]{"key1", "key2", "key3"}; 47 private final String[] TITLES = new String[]{"title1", "title2", "title3"}; 48 private final String SUMMARY = "subtitle"; 49 private final String SCREEN_TITLE = "screen title"; 50 private final String KEYWORDS = "a, b, c"; 51 private final String FRAGMENT_NAME = "fragment name"; 52 private final int ICON = 1234; // I declare a thumb war 53 private final Uri URI = Uri.parse("content://com.android.settings.slices/test"); 54 private final String PREF_CONTROLLER = "com.android.settings.slices.tester"; 55 private final int SLICE_TYPE = SliceData.SliceType.SLIDER; 56 private final String UNAVAILABLE_SLICE_SUBTITLE = "subtitleOfUnavailableSlice"; 57 58 private Context mContext; 59 60 private SlicesIndexer mManager; 61 62 63 @Before setUp()64 public void setUp() { 65 mContext = RuntimeEnvironment.application; 66 mManager = spy(new SlicesIndexer(mContext)); 67 } 68 69 @After cleanUp()70 public void cleanUp() { 71 DatabaseTestUtils.clearDb(mContext); 72 } 73 74 @Test testAlreadyIndexed_doesNotIndexAgain()75 public void testAlreadyIndexed_doesNotIndexAgain() { 76 String newKey = "newKey"; 77 String newTitle = "newTitle"; 78 SlicesDatabaseHelper.getInstance(mContext).setIndexedState(); 79 insertSpecialCase(newKey, newTitle); 80 81 // Attempt indexing - should not do anything. 82 mManager.run(); 83 84 final SQLiteDatabase db = SlicesDatabaseHelper.getInstance(mContext).getWritableDatabase(); 85 try (final Cursor cursor = db.rawQuery("SELECT * FROM slices_index", null)) { 86 cursor.moveToFirst(); 87 assertThat(cursor.getCount()).isEqualTo(1); 88 assertThat(cursor.getString(cursor.getColumnIndex(IndexColumns.KEY))).isEqualTo(newKey); 89 assertThat(cursor.getString(cursor.getColumnIndex(IndexColumns.TITLE))) 90 .isEqualTo(newTitle); 91 } finally { 92 db.close(); 93 } 94 } 95 96 @Test testInsertSliceData_indexedStateSet()97 public void testInsertSliceData_indexedStateSet() { 98 final SlicesDatabaseHelper helper = SlicesDatabaseHelper.getInstance(mContext); 99 helper.setIndexedState(); 100 doReturn(new ArrayList<SliceData>()).when(mManager).getSliceData(); 101 102 mManager.run(); 103 104 assertThat(helper.isSliceDataIndexed()).isTrue(); 105 } 106 107 @Test testInsertSliceData_nonPublicSlice_mockDataInserted()108 public void testInsertSliceData_nonPublicSlice_mockDataInserted() { 109 final List<SliceData> sliceData = getDummyIndexableData(false); 110 doReturn(sliceData).when(mManager).getSliceData(); 111 112 mManager.run(); 113 114 final SQLiteDatabase db = SlicesDatabaseHelper.getInstance(mContext).getWritableDatabase(); 115 try (final Cursor cursor = db.rawQuery("SELECT * FROM slices_index", null)) { 116 assertThat(cursor.getCount()).isEqualTo(sliceData.size()); 117 118 cursor.moveToFirst(); 119 for (int i = 0; i < sliceData.size(); i++) { 120 assertThat(cursor.getString(cursor.getColumnIndex(IndexColumns.KEY))) 121 .isEqualTo(KEYS[i]); 122 assertThat(cursor.getString(cursor.getColumnIndex(IndexColumns.TITLE))) 123 .isEqualTo(TITLES[i]); 124 assertThat( 125 cursor.getString(cursor.getColumnIndex(IndexColumns.FRAGMENT))) 126 .isEqualTo(FRAGMENT_NAME); 127 assertThat(cursor.getString( 128 cursor.getColumnIndex(IndexColumns.SCREENTITLE))).isEqualTo(SCREEN_TITLE); 129 assertThat( 130 cursor.getString(cursor.getColumnIndex(IndexColumns.KEYWORDS))) 131 .isEqualTo(KEYWORDS); 132 assertThat( 133 cursor.getInt(cursor.getColumnIndex(IndexColumns.ICON_RESOURCE))) 134 .isEqualTo(ICON); 135 assertThat( 136 cursor.getString(cursor.getColumnIndex(IndexColumns.CONTROLLER))) 137 .isEqualTo(PREF_CONTROLLER); 138 assertThat(cursor.getInt(cursor.getColumnIndex(IndexColumns.SLICE_TYPE))) 139 .isEqualTo(SLICE_TYPE); 140 assertThat(cursor.getString( 141 cursor.getColumnIndex(IndexColumns.UNAVAILABLE_SLICE_SUBTITLE))) 142 .isEqualTo(UNAVAILABLE_SLICE_SUBTITLE); 143 assertThat(cursor.getInt( 144 cursor.getColumnIndex(IndexColumns.PUBLIC_SLICE))).isEqualTo(0); 145 cursor.moveToNext(); 146 } 147 } finally { 148 db.close(); 149 } 150 } 151 152 @Test insertSliceData_publicSlice_mockDataInserted()153 public void insertSliceData_publicSlice_mockDataInserted() { 154 final List<SliceData> sliceData = getDummyIndexableData(true); 155 doReturn(sliceData).when(mManager).getSliceData(); 156 157 mManager.run(); 158 159 final SQLiteDatabase db = SlicesDatabaseHelper.getInstance(mContext).getWritableDatabase(); 160 try (Cursor cursor = db.rawQuery("SELECT * FROM slices_index", null)) { 161 assertThat(cursor.getCount()).isEqualTo(sliceData.size()); 162 163 cursor.moveToFirst(); 164 for (int i = 0; i < sliceData.size(); i++) { 165 assertThat(cursor.getString(cursor.getColumnIndex(IndexColumns.KEY))) 166 .isEqualTo(KEYS[i]); 167 assertThat(cursor.getString(cursor.getColumnIndex(IndexColumns.TITLE))) 168 .isEqualTo(TITLES[i]); 169 assertThat( 170 cursor.getString(cursor.getColumnIndex(IndexColumns.FRAGMENT))) 171 .isEqualTo(FRAGMENT_NAME); 172 assertThat(cursor.getString( 173 cursor.getColumnIndex(IndexColumns.SCREENTITLE))).isEqualTo(SCREEN_TITLE); 174 assertThat( 175 cursor.getString(cursor.getColumnIndex(IndexColumns.KEYWORDS))) 176 .isEqualTo(KEYWORDS); 177 assertThat( 178 cursor.getInt(cursor.getColumnIndex(IndexColumns.ICON_RESOURCE))) 179 .isEqualTo(ICON); 180 assertThat( 181 cursor.getString(cursor.getColumnIndex(IndexColumns.CONTROLLER))) 182 .isEqualTo(PREF_CONTROLLER); 183 assertThat(cursor.getInt(cursor.getColumnIndex(IndexColumns.SLICE_TYPE))) 184 .isEqualTo(SLICE_TYPE); 185 assertThat(cursor.getString( 186 cursor.getColumnIndex(IndexColumns.UNAVAILABLE_SLICE_SUBTITLE))) 187 .isEqualTo(UNAVAILABLE_SLICE_SUBTITLE); 188 assertThat(cursor.getInt( 189 cursor.getColumnIndex(IndexColumns.PUBLIC_SLICE))).isEqualTo(1); 190 cursor.moveToNext(); 191 } 192 } finally { 193 db.close(); 194 } 195 } 196 insertSpecialCase(String key, String title)197 private void insertSpecialCase(String key, String title) { 198 final ContentValues values = new ContentValues(); 199 values.put(IndexColumns.KEY, key); 200 values.put(IndexColumns.TITLE, title); 201 final SQLiteDatabase db = SlicesDatabaseHelper.getInstance(mContext).getWritableDatabase(); 202 db.beginTransaction(); 203 try { 204 db.replaceOrThrow(SlicesDatabaseHelper.Tables.TABLE_SLICES_INDEX, null, values); 205 db.setTransactionSuccessful(); 206 } finally { 207 db.endTransaction(); 208 } 209 db.close(); 210 } 211 getDummyIndexableData(boolean isPublicSlice)212 private List<SliceData> getDummyIndexableData(boolean isPublicSlice) { 213 final List<SliceData> sliceData = new ArrayList<>(); 214 final SliceData.Builder builder = new SliceData.Builder() 215 .setSummary(SUMMARY) 216 .setScreenTitle(SCREEN_TITLE) 217 .setKeywords(KEYWORDS) 218 .setFragmentName(FRAGMENT_NAME) 219 .setIcon(ICON) 220 .setUri(URI) 221 .setPreferenceControllerClassName(PREF_CONTROLLER) 222 .setSliceType(SLICE_TYPE) 223 .setUnavailableSliceSubtitle(UNAVAILABLE_SLICE_SUBTITLE); 224 225 if (isPublicSlice) { 226 builder.setIsPublicSlice(true); 227 } 228 229 for (int i = 0; i < KEYS.length; i++) { 230 builder.setKey(KEYS[i]).setTitle(TITLES[i]); 231 sliceData.add(builder.build()); 232 } 233 234 return sliceData; 235 } 236 }