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