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 }