Robolectric testing support + InstallAppProvider testing now run in JVM.

Robolectric provides testing support for Android via the JVM, including testing
of content providers. In order to get these tests to work, we need to avoid
the default behaviour of starting up FDroidApp.onCreate(). This method has a lot
of static state which fails if set multiple times. Instead of trying to ensure
we correctly zero out that state each test, it is preferable to instead never
bother with that in the first place. Expecially when that is not what is under
test (as is the case with content provider tests).
This commit is contained in:
Peter Serwylo
2016-06-05 09:36:26 +10:00
parent c7bb93f743
commit 09fd3d188c
8 changed files with 412 additions and 169 deletions

View File

@@ -131,7 +131,7 @@ public class AppProviderTest extends FDroidProviderTest<AppProvider> {
values.put(AppProvider.DataColumns.IGNORE_THISUPDATE, ignoreVercode);
insertApp(id, "App: " + id, values);
InstalledAppProviderTest.install(getSwappableContext(), packageManager, id, installedVercode, "v" + installedVercode);
InstalledAppTestUtils.install(getSwappableContext(), packageManager, id, installedVercode, "v" + installedVercode);
}
public void testCanUpdate() {
@@ -251,7 +251,7 @@ public class AppProviderTest extends FDroidProviderTest<AppProvider> {
assertResultCount(0, AppProvider.getInstalledUri());
for (int i = 10; i < 20; i++) {
InstalledAppProviderTest.install(getSwappableContext(), pm, "com.example.test." + i, i, "v1");
InstalledAppTestUtils.install(getSwappableContext(), pm, "com.example.test." + i, i, "v1");
}
assertResultCount(10, AppProvider.getInstalledUri());

View File

@@ -1,167 +0,0 @@
package org.fdroid.fdroid.data;
import android.content.ContentValues;
import android.content.pm.PackageInfo;
import android.database.Cursor;
import android.net.Uri;
import mock.MockContextSwappableComponents;
import mock.MockInstallablePackageManager;
@SuppressWarnings("PMD") // TODO port this to JUnit 4 semantics
public class InstalledAppProviderTest extends FDroidProviderTest<InstalledAppProvider> {
public InstalledAppProviderTest() {
super(InstalledAppProvider.class, InstalledAppProvider.getAuthority());
}
public void testUris() {
assertInvalidUri(InstalledAppProvider.getAuthority());
assertInvalidUri(RepoProvider.getContentUri());
assertInvalidUri(AppProvider.getContentUri());
assertInvalidUri(ApkProvider.getContentUri());
assertInvalidUri("blah");
assertValidUri(InstalledAppProvider.getContentUri());
assertValidUri(InstalledAppProvider.getAppUri("com.example.com"));
assertValidUri(InstalledAppProvider.getAppUri("blah"));
}
public void testInsert() {
assertResultCount(0, InstalledAppProvider.getContentUri());
insertInstalledApp("com.example.com1", 1, "v1");
insertInstalledApp("com.example.com2", 2, "v2");
insertInstalledApp("com.example.com3", 3, "v3");
assertResultCount(3, InstalledAppProvider.getContentUri());
assertIsInstalledVersionInDb("com.example.com1", 1, "v1");
assertIsInstalledVersionInDb("com.example.com2", 2, "v2");
assertIsInstalledVersionInDb("com.example.com3", 3, "v3");
}
public void testUpdate() {
insertInstalledApp("com.example.app1", 10, "1.0");
insertInstalledApp("com.example.app2", 10, "1.0");
assertResultCount(2, InstalledAppProvider.getContentUri());
assertIsInstalledVersionInDb("com.example.app2", 10, "1.0");
try {
getMockContentResolver().update(
InstalledAppProvider.getAppUri("com.example.app2"),
createContentValues(11, "1.1"),
null, null
);
fail();
} catch (UnsupportedOperationException e) {
// We expect this to happen, because we should be using insert() instead.
}
getMockContentResolver().insert(
InstalledAppProvider.getContentUri(),
createContentValues("com.example.app2", 11, "1.1")
);
assertResultCount(2, InstalledAppProvider.getContentUri());
assertIsInstalledVersionInDb("com.example.app2", 11, "1.1");
}
public void testLastUpdateTime() {
String packageName = "com.example.app";
insertInstalledApp(packageName, 10, "1.0");
assertResultCount(1, InstalledAppProvider.getContentUri());
assertIsInstalledVersionInDb(packageName, 10, "1.0");
Uri uri = InstalledAppProvider.getAppUri(packageName);
String[] projection = {
InstalledAppProvider.DataColumns.PACKAGE_NAME,
InstalledAppProvider.DataColumns.LAST_UPDATE_TIME,
};
Cursor cursor = getMockContentResolver().query(uri, projection, null, null, null);
assertNotNull(cursor);
assertEquals("App \"" + packageName + "\" not installed", 1, cursor.getCount());
cursor.moveToFirst();
assertEquals(packageName, cursor.getString(cursor.getColumnIndex(InstalledAppProvider.DataColumns.PACKAGE_NAME)));
long lastUpdateTime = cursor.getLong(cursor.getColumnIndex(InstalledAppProvider.DataColumns.LAST_UPDATE_TIME));
assertTrue(lastUpdateTime > 0);
assertTrue(lastUpdateTime < System.currentTimeMillis());
cursor.close();
insertInstalledApp(packageName, 11, "1.1");
cursor = getMockContentResolver().query(uri, projection, null, null, null);
assertNotNull(cursor);
assertEquals("App \"" + packageName + "\" not installed", 1, cursor.getCount());
cursor.moveToFirst();
assertTrue(lastUpdateTime < cursor.getLong(cursor.getColumnIndex(InstalledAppProvider.DataColumns.LAST_UPDATE_TIME)));
cursor.close();
}
public void testDelete() {
insertInstalledApp("com.example.app1", 10, "1.0");
insertInstalledApp("com.example.app2", 10, "1.0");
assertResultCount(2, InstalledAppProvider.getContentUri());
getMockContentResolver().delete(InstalledAppProvider.getAppUri("com.example.app1"), null, null);
assertResultCount(1, InstalledAppProvider.getContentUri());
assertIsInstalledVersionInDb("com.example.app2", 10, "1.0");
}
@Override
protected String[] getMinimalProjection() {
return new String[]{
InstalledAppProvider.DataColumns.PACKAGE_NAME,
InstalledAppProvider.DataColumns.VERSION_CODE,
InstalledAppProvider.DataColumns.VERSION_NAME,
};
}
private ContentValues createContentValues(int versionCode, String versionNumber) {
return createContentValues(null, versionCode, versionNumber);
}
private ContentValues createContentValues(String appId, int versionCode, String versionNumber) {
ContentValues values = new ContentValues(3);
if (appId != null) {
values.put(InstalledAppProvider.DataColumns.PACKAGE_NAME, appId);
}
values.put(InstalledAppProvider.DataColumns.APPLICATION_LABEL, "Mock app: " + appId);
values.put(InstalledAppProvider.DataColumns.VERSION_CODE, versionCode);
values.put(InstalledAppProvider.DataColumns.VERSION_NAME, versionNumber);
values.put(InstalledAppProvider.DataColumns.SIGNATURE, "");
values.put(InstalledAppProvider.DataColumns.LAST_UPDATE_TIME, System.currentTimeMillis());
values.put(InstalledAppProvider.DataColumns.HASH_TYPE, "sha256");
values.put(InstalledAppProvider.DataColumns.HASH, "cafecafecafecafecafecafecafecafecafecafecafecafecafecafecafecafe");
return values;
}
private void insertInstalledApp(String appId, int versionCode, String versionNumber) {
ContentValues values = createContentValues(appId, versionCode, versionNumber);
getMockContentResolver().insert(InstalledAppProvider.getContentUri(), values);
}
/**
* Will tell {@code pm} that we are installing {@code packageName}, and then update the
* "installed apps" table in the database.
*/
public static void install(MockContextSwappableComponents context,
MockInstallablePackageManager pm, String packageName,
int versionCode, String versionName) {
context.setPackageManager(pm);
pm.install(packageName, versionCode, versionName);
PackageInfo packageInfo = pm.getPackageInfo(packageName, 0);
InstalledAppProviderService.insertAppIntoDb(context, packageName, packageInfo);
}
}

View File

@@ -0,0 +1,24 @@
package org.fdroid.fdroid.data;
import android.content.pm.PackageInfo;
import mock.MockContextSwappableComponents;
import mock.MockInstallablePackageManager;
public class InstalledAppTestUtils {
/**
* Will tell {@code pm} that we are installing {@code packageName}, and then update the
* "installed apps" table in the database.
*/
public static void install(MockContextSwappableComponents context,
MockInstallablePackageManager pm, String packageName,
int versionCode, String versionName) {
context.setPackageManager(pm);
pm.install(packageName, versionCode, versionName);
PackageInfo packageInfo = pm.getPackageInfo(packageName, 0);
InstalledAppProviderService.insertAppIntoDb(context, packageName, packageInfo);
}
}