Merge "Add Slices Data object and DB Contract"

This commit is contained in:
TreeHugger Robot
2017-12-13 23:01:36 +00:00
committed by Android (Google) Code Review
9 changed files with 701 additions and 44 deletions

View File

@@ -3312,13 +3312,13 @@
</intent-filter>
</activity>
<provider android:name=".SettingsSliceProvider"
<provider android:name=".slices.SettingsSliceProvider"
android:authorities="com.android.settings.slices"
android:exported="true">
</provider>
<receiver
android:name=".SliceBroadcastReceiver" >
android:name=".slices.SliceBroadcastReceiver" >
<intent-filter>
<action android:name="com.android.settings.slice.action.WIFI_CHANGED"/>
</intent-filter>

View File

@@ -43,7 +43,7 @@ public class DatabaseIndexingUtils {
private static final String TAG = "IndexingUtil";
private static final String FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER =
public static final String FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER =
"SEARCH_INDEX_DATA_PROVIDER";
/**

View File

@@ -14,28 +14,31 @@
* limitations under the License
*/
package com.android.settings;
package com.android.settings.slices;
import android.app.PendingIntent;
import android.app.slice.Slice;
import android.app.slice.SliceProvider;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Icon;
import android.net.Uri;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import com.android.settings.R;
import androidx.app.slice.Slice;
import androidx.app.slice.SliceProvider;
import androidx.app.slice.builders.ListBuilder;
public class SettingsSliceProvider extends SliceProvider {
public static final String SLICE_AUTHORITY = "com.android.settings.slices";
public static final String PATH_WIFI = "wifi";
public static final String ACTION_WIFI_CHANGED =
"com.android.settings.slice.action.WIFI_CHANGED";
// TODO -- Associate slice URI with search result instead of separate hardcoded thing
public static final String[] WIFI_SEARCH_TERMS = {"wi-fi", "wifi", "internet"};
// TODO -- Associate slice URI with search result instead of separate hardcoded thing
public static Uri getUri(String path) {
return new Uri.Builder()
.scheme(ContentResolver.SCHEME_CONTENT)
@@ -44,7 +47,7 @@ public class SettingsSliceProvider extends SliceProvider {
}
@Override
public boolean onCreate() {
public boolean onCreateSliceProvider() {
return true;
}
@@ -53,15 +56,15 @@ public class SettingsSliceProvider extends SliceProvider {
String path = sliceUri.getPath();
switch (path) {
case "/" + PATH_WIFI:
return createWifi(sliceUri);
return createWifiSlice(sliceUri);
}
throw new IllegalArgumentException("Unrecognized slice uri: " + sliceUri);
}
private Slice createWifi(Uri uri) {
// TODO (b/70622039) remove this when the proper wifi slice is enabled.
private Slice createWifiSlice(Uri sliceUri) {
// Get wifi state
String[] toggleHints;
WifiManager wifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE);
int wifiState = wifiManager.getWifiState();
boolean wifiEnabled = false;
@@ -74,7 +77,6 @@ public class SettingsSliceProvider extends SliceProvider {
case WifiManager.WIFI_STATE_ENABLED:
case WifiManager.WIFI_STATE_ENABLING:
state = wifiManager.getConnectionInfo().getSSID();
WifiInfo.removeDoubleQuotes(state);
wifiEnabled = true;
break;
case WifiManager.WIFI_STATE_UNKNOWN:
@@ -82,28 +84,17 @@ public class SettingsSliceProvider extends SliceProvider {
state = ""; // just don't show anything?
break;
}
if (wifiEnabled) {
toggleHints = new String[] {Slice.HINT_TOGGLE, Slice.HINT_SELECTED};
} else {
toggleHints = new String[] {Slice.HINT_TOGGLE};
}
// Construct the slice
Slice.Builder b = new Slice.Builder(uri);
b.addSubSlice(new Slice.Builder(b)
.addAction(getIntent("android.settings.WIFI_SETTINGS"),
new Slice.Builder(b)
.addText(getContext().getString(R.string.wifi_settings), null)
.addText(state, null)
.addIcon(Icon.createWithResource(getContext(),
R.drawable.ic_settings_wireless), null, Slice.HINT_HIDDEN)
.addHints(Slice.HINT_TITLE)
.build())
.addAction(getBroadcastIntent(ACTION_WIFI_CHANGED),
new Slice.Builder(b)
.addHints(toggleHints)
.build())
.build());
return b.build();
boolean finalWifiEnabled = wifiEnabled;
return new ListBuilder(sliceUri)
.setColor(R.color.material_blue_500)
.add(b -> b
.setTitle(getContext().getString(R.string.wifi_settings))
.setTitleItem(Icon.createWithResource(getContext(), R.drawable.wifi_signal))
.setSubtitle(state)
.addToggle(getBroadcastIntent(ACTION_WIFI_CHANGED), finalWifiEnabled)
.setContentIntent(getIntent(Intent.ACTION_MAIN)))
.build();
}
private PendingIntent getIntent(String action) {

View File

@@ -14,9 +14,9 @@
* limitations under the License
*/
package com.android.settings;
package com.android.settings.slices;
import static com.android.settings.SettingsSliceProvider.ACTION_WIFI_CHANGED;
import static com.android.settings.slices.SettingsSliceProvider.ACTION_WIFI_CHANGED;
import android.app.slice.Slice;
import android.content.BroadcastReceiver;
@@ -42,8 +42,8 @@ public class SliceBroadcastReceiver extends BroadcastReceiver {
// Wait a bit for wifi to update (TODO: is there a better way to do this?)
Handler h = new Handler();
h.postDelayed(() -> {
Uri uri = SettingsSliceProvider.getUri(SettingsSliceProvider.PATH_WIFI);
context.getContentResolver().notifyChange(uri, null);
Uri uri = SettingsSliceProvider.getUri(SettingsSliceProvider.PATH_WIFI);
context.getContentResolver().notifyChange(uri, null);
}, 1000);
break;
}

View File

@@ -0,0 +1,188 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License
*/
package com.android.settings.slices;
import android.net.Uri;
import android.text.TextUtils;
/**
* TODO (b/67996923) Add SlicesIndexingManager
* Data class representing a slice stored by {@link SlicesIndexingManager}.
* Note that {@link #key} is treated as a primary key for this class and determines equality.
*/
public class SliceData {
private final String key;
private final String title;
private final String summary;
private final String screenTitle;
private final int iconResource;
private final String fragmentClassName;
private final Uri uri;
private final String preferenceController;
public String getKey() {
return key;
}
public String getTitle() {
return title;
}
public String getSummary() {
return summary;
}
public String getScreenTitle() {
return screenTitle;
}
public int getIconResource() {
return iconResource;
}
public String getFragmentClassName() {
return fragmentClassName;
}
public Uri getUri() {
return uri;
}
public String getPreferenceController() {
return preferenceController;
}
private SliceData(Builder builder) {
key = builder.mKey;
title = builder.mTitle;
summary = builder.mSummary;
screenTitle = builder.mScreenTitle;
iconResource = builder.mIconResource;
fragmentClassName = builder.mFragmentClassName;
uri = builder.mUri;
preferenceController = builder.mPrefControllerClassName;
}
@Override
public int hashCode() {
return key.hashCode();
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof SliceData)) {
return false;
}
SliceData newObject = (SliceData) obj;
return TextUtils.equals(key, newObject.key);
}
static class Builder {
private String mKey;
private String mTitle;
private String mSummary;
private String mScreenTitle;
private int mIconResource;
private String mFragmentClassName;
private Uri mUri;
private String mPrefControllerClassName;
public Builder setKey(String key) {
mKey = key;
return this;
}
public Builder setTitle(String title) {
mTitle = title;
return this;
}
public Builder setSummary(String summary) {
mSummary = summary;
return this;
}
public Builder setScreenTitle(String screenTitle) {
mScreenTitle = screenTitle;
return this;
}
public Builder setIcon(int iconResource) {
mIconResource = iconResource;
return this;
}
public Builder setPreferenceControllerClassName(String controllerClassName) {
mPrefControllerClassName = controllerClassName;
return this;
}
public Builder setFragmentName(String fragmentClassName) {
mFragmentClassName = fragmentClassName;
return this;
}
public Builder setUri(Uri uri) {
mUri = uri;
return this;
}
public SliceData build() {
if (TextUtils.isEmpty(mKey)) {
throw new IllegalStateException("Key cannot be empty");
}
if (TextUtils.isEmpty(mTitle)) {
throw new IllegalStateException("Title cannot be empty");
}
if (TextUtils.isEmpty(mFragmentClassName)) {
throw new IllegalStateException("Fragment Name cannot be empty");
}
if (TextUtils.isEmpty(mPrefControllerClassName)) {
throw new IllegalStateException("Preference Controller cannot be empty");
}
if (mUri == null) {
throw new IllegalStateException("Uri cannot be null");
}
return new SliceData(this);
}
public String getKey() {
return mKey;
}
}
}

View File

@@ -0,0 +1,122 @@
package com.android.settings.slices;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
/**
* Defines the schema for the Slices database.
*/
public class SlicesDatabaseHelper extends SQLiteOpenHelper {
private static final String TAG = "SlicesDatabaseHelper";
private static final String DATABASE_NAME = "slices_index.db";
private static final String SHARED_PREFS_TAG = "slices_shared_prefs";
private static final int DATABASE_VERSION = 1;
public interface Tables {
String TABLE_SLICES_INDEX = "slices_index";
}
public interface IndexColumns {
/**
* Primary key of the DB. Preference key from preference controllers.
*/
String KEY = "key";
/**
* Title of the Setting.
*/
String TITLE = "title";
/**
* Summary / Subtitle for the setting.
*/
String SUBTITLE = "subtitle";
/**
* Title of the Setting screen on which the Setting lives.
*/
String SCREENTITLE = "screentitle";
/**
* Resource ID for the icon of the setting. Should be 0 for no icon.
*/
String ICON_RESOURCE = "icon";
/**
* Classname of the fragment name of the page that hosts the setting.
*/
String FRAGMENT = "fragment";
/**
* Class name of the controller backing the setting. Must be a
* {@link com.android.settings.core.BasePreferenceController}.
*/
String CONTROLLER = "controller";
}
private static final String CREATE_SLICES_TABLE =
"CREATE VIRTUAL TABLE " + Tables.TABLE_SLICES_INDEX + " USING fts4" +
"(" +
IndexColumns.KEY +
", " +
IndexColumns.TITLE +
", " +
IndexColumns.SUBTITLE +
", " +
IndexColumns.SCREENTITLE +
", " +
IndexColumns.ICON_RESOURCE +
", " +
IndexColumns.FRAGMENT +
", " +
IndexColumns.CONTROLLER +
");";
private final Context mContext;
public SlicesDatabaseHelper(Context context) {
super(context, DATABASE_NAME, null /* CursorFactor */, DATABASE_VERSION);
mContext = context;
}
@Override
public void onCreate(SQLiteDatabase db) {
createDatabases(db);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if (oldVersion < DATABASE_VERSION) {
Log.d(TAG, "Reconstructing DB from " + oldVersion + "to " + newVersion);
reconstruct(db);
}
}
@VisibleForTesting
void reconstruct(SQLiteDatabase db) {
mContext.getSharedPreferences(SHARED_PREFS_TAG, Context.MODE_PRIVATE)
.edit()
.clear()
.commit();
dropTables(db);
createDatabases(db);
}
private void createDatabases(SQLiteDatabase db) {
db.execSQL(CREATE_SLICES_TABLE);
Log.d(TAG, "Created databases");
}
private void dropTables(SQLiteDatabase db) {
db.execSQL("DROP TABLE IF EXISTS " + Tables.TABLE_SLICES_INDEX);
}
}

View File

@@ -43,13 +43,13 @@ public class SearchIndexProviderCodeInspector extends CodeInspector {
"SettingsPreferenceFragment should implement Indexable, but these do not:\n";
private static final String NOT_CONTAINING_PROVIDER_OBJECT_ERROR =
"Indexable should have public field "
+ DatabaseIndexingManager.FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER
+ DatabaseIndexingUtils.FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER
+ " but these are not:\n";
private static final String NOT_SHARING_PREF_CONTROLLERS_BETWEEN_FRAG_AND_PROVIDER =
"DashboardFragment should share pref controllers with its SearchIndexProvider, but "
+ " these are not: \n";
private static final String NOT_IN_INDEXABLE_PROVIDER_REGISTRY =
"Class containing " + DatabaseIndexingManager.FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER
"Class containing " + DatabaseIndexingUtils.FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER
+ " must be added to " + SearchIndexableResources.class.getName()
+ " but these are not: \n";
private static final String NOT_PROVIDING_VALID_RESOURCE_ERROR =
@@ -173,7 +173,7 @@ public class SearchIndexProviderCodeInspector extends CodeInspector {
private boolean hasSearchIndexProvider(Class clazz) {
try {
final Field f = clazz.getField(
DatabaseIndexingManager.FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER);
DatabaseIndexingUtils.FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER);
return f != null;
} catch (NoClassDefFoundError e) {
// Cannot find class def, ignore

View File

@@ -0,0 +1,269 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.slices;
import static com.google.common.truth.Truth.assertThat;
import android.net.Uri;
import com.android.settings.TestConfig;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.annotation.Config;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class SliceDataTest {
private final String KEY = "KEY";
private final String TITLE = "title";
private final String SUMMARY = "summary";
private final String SCREEN_TITLE = "screen title";
private final String FRAGMENT_NAME = "fragment name";
private final int ICON = 1234; // I declare a thumb war
private final Uri URI = Uri.parse("content://com.android.settings.slices/test");
private final String PREF_CONTROLLER = "com.android.settings.slices.tester";
@Test
public void testBuilder_buildsMatchingObject() {
SliceData.Builder builder = new SliceData.Builder()
.setKey(KEY)
.setTitle(TITLE)
.setSummary(SUMMARY)
.setScreenTitle(SCREEN_TITLE)
.setIcon(ICON)
.setFragmentName(FRAGMENT_NAME)
.setUri(URI)
.setPreferenceControllerClassName(PREF_CONTROLLER);
SliceData data = builder.build();
assertThat(data.getKey()).isEqualTo(KEY);
assertThat(data.getTitle()).isEqualTo(TITLE);
assertThat(data.getSummary()).isEqualTo(SUMMARY);
assertThat(data.getScreenTitle()).isEqualTo(SCREEN_TITLE);
assertThat(data.getIconResource()).isEqualTo(ICON);
assertThat(data.getFragmentClassName()).isEqualTo(FRAGMENT_NAME);
assertThat(data.getUri()).isEqualTo(URI);
assertThat(data.getPreferenceController()).isEqualTo(PREF_CONTROLLER);
}
@Test(expected = IllegalStateException.class)
public void testBuilder_noKey_throwsIllegalStateException() {
new SliceData.Builder()
.setTitle(TITLE)
.setSummary(SUMMARY)
.setScreenTitle(SCREEN_TITLE)
.setIcon(ICON)
.setFragmentName(FRAGMENT_NAME)
.setUri(URI)
.setPreferenceControllerClassName(PREF_CONTROLLER)
.build();
}
@Test(expected = IllegalStateException.class)
public void testBuilder_noTitle_throwsIllegalStateException() {
new SliceData.Builder()
.setKey(KEY)
.setSummary(SUMMARY)
.setScreenTitle(SCREEN_TITLE)
.setIcon(ICON)
.setFragmentName(FRAGMENT_NAME)
.setUri(URI)
.setPreferenceControllerClassName(PREF_CONTROLLER)
.build();
}
@Test(expected = IllegalStateException.class)
public void testBuilder_noFragment_throwsIllegalStateException() {
new SliceData.Builder()
.setKey(KEY)
.setFragmentName(FRAGMENT_NAME)
.setSummary(SUMMARY)
.setScreenTitle(SCREEN_TITLE)
.setIcon(ICON)
.setUri(URI)
.setPreferenceControllerClassName(PREF_CONTROLLER)
.build();
}
@Test(expected = IllegalStateException.class)
public void testBuilder_noUri_throwsIllegalStateException() {
new SliceData.Builder()
.setKey(KEY)
.setTitle(TITLE)
.setSummary(SUMMARY)
.setScreenTitle(SCREEN_TITLE)
.setIcon(ICON)
.setFragmentName(FRAGMENT_NAME)
.setPreferenceControllerClassName(PREF_CONTROLLER)
.build();
}
@Test(expected = IllegalStateException.class)
public void testBuilder_noPrefController_throwsIllegalStateException() {
new SliceData.Builder()
.setKey(KEY)
.setTitle(TITLE)
.setSummary(SUMMARY)
.setScreenTitle(SCREEN_TITLE)
.setIcon(ICON)
.setUri(URI)
.setFragmentName(FRAGMENT_NAME)
.build();
}
@Test
public void testBuilder_noSubtitle_buildsMatchingObject() {
SliceData.Builder builder = new SliceData.Builder()
.setKey(KEY)
.setTitle(TITLE)
.setScreenTitle(SCREEN_TITLE)
.setIcon(ICON)
.setFragmentName(FRAGMENT_NAME)
.setUri(URI)
.setPreferenceControllerClassName(PREF_CONTROLLER);
SliceData data = builder.build();
assertThat(data.getKey()).isEqualTo(KEY);
assertThat(data.getTitle()).isEqualTo(TITLE);
assertThat(data.getSummary()).isNull();
assertThat(data.getScreenTitle()).isEqualTo(SCREEN_TITLE);
assertThat(data.getIconResource()).isEqualTo(ICON);
assertThat(data.getFragmentClassName()).isEqualTo(FRAGMENT_NAME);
assertThat(data.getUri()).isEqualTo(URI);
assertThat(data.getPreferenceController()).isEqualTo(PREF_CONTROLLER);
}
@Test
public void testBuilder_noScreenTitle_buildsMatchingObject() {
SliceData.Builder builder = new SliceData.Builder()
.setKey(KEY)
.setTitle(TITLE)
.setSummary(SUMMARY)
.setIcon(ICON)
.setFragmentName(FRAGMENT_NAME)
.setUri(URI)
.setPreferenceControllerClassName(PREF_CONTROLLER);
SliceData data = builder.build();
assertThat(data.getKey()).isEqualTo(KEY);
assertThat(data.getTitle()).isEqualTo(TITLE);
assertThat(data.getSummary()).isEqualTo(SUMMARY);
assertThat(data.getScreenTitle()).isNull();
assertThat(data.getIconResource()).isEqualTo(ICON);
assertThat(data.getFragmentClassName()).isEqualTo(FRAGMENT_NAME);
assertThat(data.getUri()).isEqualTo(URI);
assertThat(data.getPreferenceController()).isEqualTo(PREF_CONTROLLER);
}
@Test
public void testBuilder_noIcon_buildsMatchingObject() {
SliceData.Builder builder = new SliceData.Builder()
.setKey(KEY)
.setTitle(TITLE)
.setSummary(SUMMARY)
.setScreenTitle(SCREEN_TITLE)
.setFragmentName(FRAGMENT_NAME)
.setUri(URI)
.setPreferenceControllerClassName(PREF_CONTROLLER);
SliceData data = builder.build();
assertThat(data.getKey()).isEqualTo(KEY);
assertThat(data.getTitle()).isEqualTo(TITLE);
assertThat(data.getSummary()).isEqualTo(SUMMARY);
assertThat(data.getScreenTitle()).isEqualTo(SCREEN_TITLE);
assertThat(data.getIconResource()).isEqualTo(0);
assertThat(data.getFragmentClassName()).isEqualTo(FRAGMENT_NAME);
assertThat(data.getUri()).isEqualTo(URI);
assertThat(data.getPreferenceController()).isEqualTo(PREF_CONTROLLER);
}
@Test
public void testEquality_identicalObjects() {
SliceData.Builder builder = new SliceData.Builder()
.setKey(KEY)
.setTitle(TITLE)
.setSummary(SUMMARY)
.setScreenTitle(SCREEN_TITLE)
.setIcon(ICON)
.setFragmentName(FRAGMENT_NAME)
.setUri(URI)
.setPreferenceControllerClassName(PREF_CONTROLLER);
SliceData dataOne = builder.build();
SliceData dataTwo = builder.build();
assertThat(dataOne.hashCode()).isEqualTo(dataTwo.hashCode());
assertThat(dataOne).isEqualTo(dataTwo);
}
@Test
public void testEquality_matchingKey_EqualObjects() {
SliceData.Builder builder = new SliceData.Builder()
.setKey(KEY)
.setTitle(TITLE)
.setSummary(SUMMARY)
.setScreenTitle(SCREEN_TITLE)
.setIcon(ICON)
.setFragmentName(FRAGMENT_NAME)
.setUri(URI)
.setPreferenceControllerClassName(PREF_CONTROLLER);
SliceData dataOne = builder.build();
builder.setTitle(TITLE + " diff")
.setSummary(SUMMARY + " diff")
.setScreenTitle(SCREEN_TITLE + " diff")
.setIcon(ICON + 1)
.setFragmentName(FRAGMENT_NAME + " diff")
.setUri(URI)
.setPreferenceControllerClassName(PREF_CONTROLLER + " diff");
SliceData dataTwo = builder.build();
assertThat(dataOne.hashCode()).isEqualTo(dataTwo.hashCode());
assertThat(dataOne).isEqualTo(dataTwo);
}
@Test
public void testEquality_differentKey_differentObjects() {
SliceData.Builder builder = new SliceData.Builder()
.setKey(KEY)
.setTitle(TITLE)
.setSummary(SUMMARY)
.setScreenTitle(SCREEN_TITLE)
.setIcon(ICON)
.setFragmentName(FRAGMENT_NAME)
.setUri(URI)
.setPreferenceControllerClassName(PREF_CONTROLLER);
SliceData dataOne = builder.build();
builder.setKey("not key");
SliceData dataTwo = builder.build();
assertThat(dataOne.hashCode()).isNotEqualTo(dataTwo.hashCode());
assertThat(dataOne).isNotEqualTo(dataTwo);
}
}

View File

@@ -0,0 +1,87 @@
package com.android.settings.slices;
import static com.google.common.truth.Truth.assertThat;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import com.android.settings.TestConfig;
import com.android.settings.slices.SlicesDatabaseHelper.IndexColumns;
import com.android.settings.testutils.DatabaseTestUtils;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class SlicesDatabaseHelperTest {
private Context mContext;
private SlicesDatabaseHelper mSlicesDatabaseHelper;
private SQLiteDatabase mDatabase;
@Before
public void setUp() {
mContext = RuntimeEnvironment.application;
mSlicesDatabaseHelper = new SlicesDatabaseHelper(mContext);
mDatabase = mSlicesDatabaseHelper.getWritableDatabase();
}
@After
public void cleanUp() {
DatabaseTestUtils.clearDb(mContext);
}
@Test
public void testDatabaseSchema() {
Cursor cursor = mDatabase.rawQuery("SELECT * FROM slices_index", null);
String[] columnNames = cursor.getColumnNames();
String[] expectedNames = new String[]{
IndexColumns.KEY,
IndexColumns.TITLE,
IndexColumns.SUBTITLE,
IndexColumns.SCREENTITLE,
IndexColumns.ICON_RESOURCE,
IndexColumns.FRAGMENT,
IndexColumns.CONTROLLER
};
assertThat(columnNames).isEqualTo(expectedNames);
}
@Test
public void testUpgrade_dropsOldData() {
ContentValues dummyValues = getDummyRow();
mDatabase.replaceOrThrow(SlicesDatabaseHelper.Tables.TABLE_SLICES_INDEX, null, dummyValues);
Cursor baseline = mDatabase.rawQuery("SELECT * FROM slices_index", null);
assertThat(baseline.getCount()).isEqualTo(1);
mSlicesDatabaseHelper.onUpgrade(mDatabase, 0, 1);
Cursor newCursor = mDatabase.rawQuery("SELECT * FROM slices_index", null);
assertThat(newCursor.getCount()).isEqualTo(0);
}
private ContentValues getDummyRow() {
ContentValues values;
values = new ContentValues();
values.put(IndexColumns.KEY, "key");
values.put(IndexColumns.TITLE, "title");
values.put(IndexColumns.SUBTITLE, "subtitle");
values.put(IndexColumns.ICON_RESOURCE, 99);
values.put(IndexColumns.FRAGMENT, "fragmentClassName");
values.put(IndexColumns.CONTROLLER, "preferenceController");
return values;
}
}