1 /*
2  * Copyright (C) 2019 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 package com.android.launcher3.provider;
17 
18 import static org.junit.Assert.assertArrayEquals;
19 import static org.junit.Assert.assertEquals;
20 
21 import android.content.ContentValues;
22 import android.database.Cursor;
23 import android.database.sqlite.SQLiteDatabase;
24 
25 import androidx.test.InstrumentationRegistry;
26 import androidx.test.filters.SmallTest;
27 import androidx.test.runner.AndroidJUnit4;
28 
29 import com.android.launcher3.LauncherProvider.DatabaseHelper;
30 import com.android.launcher3.LauncherSettings.Favorites;
31 
32 import org.junit.Test;
33 import org.junit.runner.RunWith;
34 
35 /**
36  * Tests for {@link RestoreDbTask}
37  */
38 @SmallTest
39 @RunWith(AndroidJUnit4.class)
40 public class RestoreDbTaskTest {
41 
42     @Test
testGetProfileId()43     public void testGetProfileId() throws Exception {
44         SQLiteDatabase db = new MyDatabaseHelper(23).getWritableDatabase();
45         assertEquals(23, new RestoreDbTask().getDefaultProfileId(db));
46     }
47 
48     @Test
testMigrateProfileId()49     public void testMigrateProfileId() throws Exception {
50         SQLiteDatabase db = new MyDatabaseHelper(42).getWritableDatabase();
51         // Add some mock data
52         for (int i = 0; i < 5; i++) {
53             ContentValues values = new ContentValues();
54             values.put(Favorites._ID, i);
55             values.put(Favorites.TITLE, "item " + i);
56             db.insert(Favorites.TABLE_NAME, null, values);
57         }
58         // Verify item add
59         assertEquals(5, getCount(db, "select * from favorites where profileId = 42"));
60 
61         new RestoreDbTask().migrateProfileId(db, 42, 33);
62 
63         // verify data migrated
64         assertEquals(0, getCount(db, "select * from favorites where profileId = 42"));
65         assertEquals(5, getCount(db, "select * from favorites where profileId = 33"));
66     }
67 
68     @Test
testChangeDefaultColumn()69     public void testChangeDefaultColumn() throws Exception {
70         SQLiteDatabase db = new MyDatabaseHelper(42).getWritableDatabase();
71         // Add some mock data
72         for (int i = 0; i < 5; i++) {
73             ContentValues values = new ContentValues();
74             values.put(Favorites._ID, i);
75             values.put(Favorites.TITLE, "item " + i);
76             db.insert(Favorites.TABLE_NAME, null, values);
77         }
78         // Verify default column is 42
79         assertEquals(5, getCount(db, "select * from favorites where profileId = 42"));
80 
81         new RestoreDbTask().changeDefaultColumn(db, 33);
82 
83         // Verify default value changed
84         ContentValues values = new ContentValues();
85         values.put(Favorites._ID, 100);
86         values.put(Favorites.TITLE, "item 100");
87         db.insert(Favorites.TABLE_NAME, null, values);
88         assertEquals(1, getCount(db, "select * from favorites where profileId = 33"));
89     }
90 
91     @Test
testRemoveScreenIdGaps_firstScreenEmpty()92     public void testRemoveScreenIdGaps_firstScreenEmpty() {
93         runRemoveScreenIdGapsTest(
94                 new int[]{1, 2, 5, 6, 6, 7, 9, 9},
95                 new int[]{1, 2, 3, 4, 4, 5, 6, 6});
96     }
97 
98     @Test
testRemoveScreenIdGaps_firstScreenOccupied()99     public void testRemoveScreenIdGaps_firstScreenOccupied() {
100         runRemoveScreenIdGapsTest(
101                 new int[]{0, 2, 5, 6, 6, 7, 9, 9},
102                 new int[]{0, 1, 2, 3, 3, 4, 5, 5});
103     }
104 
105     @Test
testRemoveScreenIdGaps_noGap()106     public void testRemoveScreenIdGaps_noGap() {
107         runRemoveScreenIdGapsTest(
108                 new int[]{0, 1, 1, 2, 3, 3, 4, 5},
109                 new int[]{0, 1, 1, 2, 3, 3, 4, 5});
110     }
111 
runRemoveScreenIdGapsTest(int[] screenIds, int[] expectedScreenIds)112     private void runRemoveScreenIdGapsTest(int[] screenIds, int[] expectedScreenIds) {
113         SQLiteDatabase db = new MyDatabaseHelper(42).getWritableDatabase();
114         // Add some mock data
115         for (int i = 0; i < screenIds.length; i++) {
116             ContentValues values = new ContentValues();
117             values.put(Favorites._ID, i);
118             values.put(Favorites.SCREEN, screenIds[i]);
119             values.put(Favorites.CONTAINER, Favorites.CONTAINER_DESKTOP);
120             db.insert(Favorites.TABLE_NAME, null, values);
121         }
122         // Verify items are added
123         assertEquals(screenIds.length,
124                 getCount(db, "select * from favorites where container = -100"));
125 
126         new RestoreDbTask().removeScreenIdGaps(db);
127 
128         // verify screenId gaps removed
129         int[] resultScreenIds = new int[screenIds.length];
130         try (Cursor c = db.rawQuery(
131                 "select screen from favorites where container = -100 order by screen", null)) {
132             int i = 0;
133             while (c.moveToNext()) {
134                 resultScreenIds[i++] = c.getInt(0);
135             }
136         }
137 
138         assertArrayEquals(expectedScreenIds, resultScreenIds);
139     }
140 
getCount(SQLiteDatabase db, String sql)141     private int getCount(SQLiteDatabase db, String sql) {
142         try (Cursor c = db.rawQuery(sql, null)) {
143             return c.getCount();
144         }
145     }
146 
147     private class MyDatabaseHelper extends DatabaseHelper {
148 
149         private final long mProfileId;
150 
MyDatabaseHelper(long profileId)151         MyDatabaseHelper(long profileId) {
152             super(InstrumentationRegistry.getInstrumentation().getTargetContext(), null, false);
153             mProfileId = profileId;
154         }
155 
156         @Override
getDefaultUserSerial()157         public long getDefaultUserSerial() {
158             return mProfileId;
159         }
160 
161         @Override
handleOneTimeDataUpgrade(SQLiteDatabase db)162         protected void handleOneTimeDataUpgrade(SQLiteDatabase db) { }
163 
onEmptyDbCreated()164         protected void onEmptyDbCreated() { }
165     }
166 }
167