Started implementing ApkProvider tests.
Refactored a couple of common things from AppProviderTest to either FDroidProviderTest (baseclass) or TestUtils (static methods) where relevant.
This commit is contained in:
parent
43f8ea0814
commit
85f3232de0
@ -366,6 +366,11 @@ public class ApkProvider extends FDroidProvider {
|
||||
String[] apkDetails = apkKeys.split(",");
|
||||
String[] args = new String[apkDetails.length * 2];
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (apkDetails.length > MAX_APKS_TO_QUERY) {
|
||||
throw new IllegalArgumentException(
|
||||
"Cannot query more than " + MAX_APKS_TO_QUERY + ". " +
|
||||
"You tried to query " + apkDetails.length);
|
||||
}
|
||||
for (int i = 0; i < apkDetails.length; i ++) {
|
||||
String[] parts = apkDetails[i].split(":");
|
||||
String id = parts[0];
|
||||
|
131
test/src/org/fdroid/fdroid/ApkProviderTest.java
Normal file
131
test/src/org/fdroid/fdroid/ApkProviderTest.java
Normal file
@ -0,0 +1,131 @@
|
||||
package org.fdroid.fdroid;
|
||||
|
||||
import android.content.ContentValues;
|
||||
import android.database.Cursor;
|
||||
import org.fdroid.fdroid.data.Apk;
|
||||
import org.fdroid.fdroid.data.ApkProvider;
|
||||
import org.fdroid.fdroid.data.AppProvider;
|
||||
import org.fdroid.fdroid.mock.MockApk;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ApkProviderTest extends FDroidProviderTest<ApkProvider> {
|
||||
|
||||
public ApkProviderTest() {
|
||||
super(ApkProvider.class, ApkProvider.getAuthority());
|
||||
}
|
||||
|
||||
protected String[] getMinimalProjection() {
|
||||
return new String[] {
|
||||
ApkProvider.DataColumns.APK_ID,
|
||||
ApkProvider.DataColumns.VERSION_CODE,
|
||||
ApkProvider.DataColumns.NAME
|
||||
};
|
||||
}
|
||||
|
||||
public void testUris() {
|
||||
assertInvalidUri(ApkProvider.getAuthority());
|
||||
assertInvalidUri(AppProvider.getContentUri());
|
||||
|
||||
List<Apk> apks = new ArrayList<Apk>(3);
|
||||
for (int i = 0; i < 10; i ++) {
|
||||
apks.add(new MockApk("com.example." + i, i));
|
||||
}
|
||||
|
||||
assertValidUri(ApkProvider.getContentUri());
|
||||
assertValidUri(ApkProvider.getAppUri("org.fdroid.fdroid"));
|
||||
assertValidUri(ApkProvider.getContentUri(new MockApk("org.fdroid.fdroid", 100)));
|
||||
assertValidUri(ApkProvider.getContentUri());
|
||||
assertValidUri(ApkProvider.getContentUri(apks));
|
||||
assertValidUri(ApkProvider.getContentUri("org.fdroid.fdroid", 100));
|
||||
assertValidUri(ApkProvider.getRepoUri(1000));
|
||||
|
||||
List<Apk> manyApks = new ArrayList<Apk>(ApkProvider.MAX_APKS_TO_QUERY - 5);
|
||||
for (int i = 0; i < ApkProvider.MAX_APKS_TO_QUERY - 1; i ++) {
|
||||
manyApks.add(new MockApk("com.example." + i, i));
|
||||
}
|
||||
assertValidUri(ApkProvider.getContentUri(manyApks));
|
||||
|
||||
manyApks.add(new MockApk("org.fdroid.fdroid.1", 1));
|
||||
manyApks.add(new MockApk("org.fdroid.fdroid.2", 2));
|
||||
try {
|
||||
// Technically, it is a valid URI, because it doesn't
|
||||
// throw an UnsupportedOperationException. However it
|
||||
// is still not okay (we run out of bindable parameters
|
||||
// in the sqlite query.
|
||||
assertValidUri(ApkProvider.getContentUri(manyApks));
|
||||
fail();
|
||||
} catch (IllegalArgumentException e) {
|
||||
// This is the expected error behaviour.
|
||||
} catch (Exception e) {
|
||||
fail();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void testQuery() {
|
||||
Cursor cursor = queryAllApks();
|
||||
assertNotNull(cursor);
|
||||
}
|
||||
|
||||
private void insertApks(int count) {
|
||||
for (int i = 0; i < count; i ++) {
|
||||
insertApk("com.example.test." + i, i);
|
||||
}
|
||||
}
|
||||
|
||||
public void testInsert() {
|
||||
|
||||
// Start with an empty database...
|
||||
Cursor cursor = queryAllApks();
|
||||
assertNotNull(cursor);
|
||||
assertEquals(0, cursor.getCount());
|
||||
|
||||
// Insert a new record...
|
||||
insertApk("org.fdroid.fdroid", 13);
|
||||
cursor = queryAllApks();
|
||||
assertNotNull(cursor);
|
||||
assertEquals(1, cursor.getCount());
|
||||
|
||||
// We intentionally throw an IllegalArgumentException if you haven't
|
||||
// yet called cursor.move*()...
|
||||
try {
|
||||
new Apk(cursor);
|
||||
fail();
|
||||
} catch (IllegalArgumentException e) {
|
||||
// Success!
|
||||
} catch (Exception e) {
|
||||
fail();
|
||||
}
|
||||
|
||||
// And now we should be able to recover these values from the apk
|
||||
// value object (because the queryAllApks() helper asks for VERSION_CODE and
|
||||
// APK_ID.
|
||||
cursor.moveToFirst();
|
||||
Apk apk = new Apk(cursor);
|
||||
assertEquals("org.fdroid.fdroid", apk.id);
|
||||
assertEquals(13, apk.vercode);
|
||||
}
|
||||
|
||||
public void testIgnore() {
|
||||
for (int i = 0; i < 10; i ++) {
|
||||
insertApk("org.fdroid.fdroid", i);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private Cursor queryAllApks() {
|
||||
return getMockContentResolver().query(ApkProvider.getContentUri(), getMinimalProjection(), null, null, null);
|
||||
}
|
||||
|
||||
private void insertApk(String id, int versionCode) {
|
||||
insertApk(id, versionCode, new ContentValues());
|
||||
}
|
||||
|
||||
private void insertApk(String id, int versionCode,
|
||||
ContentValues additionalValues) {
|
||||
TestUtils.insertApk(getMockContentResolver(), id, versionCode, additionalValues);
|
||||
}
|
||||
|
||||
}
|
@ -3,7 +3,6 @@ package org.fdroid.fdroid;
|
||||
import android.content.ContentValues;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import junit.framework.AssertionFailedError;
|
||||
import mock.MockCategoryResources;
|
||||
import mock.MockInstallablePackageManager;
|
||||
import org.fdroid.fdroid.data.ApkProvider;
|
||||
@ -11,7 +10,6 @@ import org.fdroid.fdroid.data.App;
|
||||
import org.fdroid.fdroid.data.AppProvider;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class AppProviderTest extends FDroidProviderTest<AppProvider> {
|
||||
@ -24,7 +22,6 @@ public class AppProviderTest extends FDroidProviderTest<AppProvider> {
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
getSwappableContext().setResources(new MockCategoryResources());
|
||||
getSwappableContext().setContentResolver(getMockContentResolver());
|
||||
}
|
||||
|
||||
protected String[] getMinimalProjection() {
|
||||
@ -75,20 +72,14 @@ public class AppProviderTest extends FDroidProviderTest<AppProvider> {
|
||||
|
||||
insertApps(100);
|
||||
|
||||
assertAppCount(100, AppProvider.getContentUri());
|
||||
assertAppCount(0, AppProvider.getInstalledUri());
|
||||
assertResultCount(100, AppProvider.getContentUri());
|
||||
assertResultCount(0, AppProvider.getInstalledUri());
|
||||
|
||||
for (int i = 10; i < 20; i ++) {
|
||||
pm.install("com.example.test." + i, i, "v1");
|
||||
}
|
||||
|
||||
assertAppCount(10, AppProvider.getInstalledUri());
|
||||
}
|
||||
|
||||
private void assertAppCount(int expectedCount, Uri uri) {
|
||||
Cursor cursor = getMockContentResolver().query(uri, getMinimalProjection(), null, null, null);
|
||||
assertNotNull(cursor);
|
||||
assertEquals(expectedCount, cursor.getCount());
|
||||
assertResultCount(10, AppProvider.getInstalledUri());
|
||||
}
|
||||
|
||||
public void testInsert() {
|
||||
@ -142,7 +133,7 @@ public class AppProviderTest extends FDroidProviderTest<AppProvider> {
|
||||
"Mineral",
|
||||
"Vegetable"
|
||||
};
|
||||
assertContainsOnly(categories, expected);
|
||||
TestUtils.assertContainsOnly(categories, expected);
|
||||
}
|
||||
|
||||
public void testCategoriesMultiple() {
|
||||
@ -160,7 +151,7 @@ public class AppProviderTest extends FDroidProviderTest<AppProvider> {
|
||||
"Mineral",
|
||||
"Vegetable"
|
||||
};
|
||||
assertContainsOnly(categories, expected);
|
||||
TestUtils.assertContainsOnly(categories, expected);
|
||||
|
||||
insertAppWithCategory("com.example.game", "Game",
|
||||
"Running,Shooting,Jumping,Bleh,Sneh,Pleh,Blah,Test category," +
|
||||
@ -188,7 +179,7 @@ public class AppProviderTest extends FDroidProviderTest<AppProvider> {
|
||||
"With apostrophe's"
|
||||
};
|
||||
|
||||
assertContainsOnly(categoriesLonger, expectedLonger);
|
||||
TestUtils.assertContainsOnly(categoriesLonger, expectedLonger);
|
||||
}
|
||||
|
||||
private void insertApp(String id, String name) {
|
||||
@ -207,52 +198,4 @@ public class AppProviderTest extends FDroidProviderTest<AppProvider> {
|
||||
TestUtils.insertApp(getMockContentResolver(), id, name, additionalValues);
|
||||
}
|
||||
|
||||
private <T extends Comparable> void assertContainsOnly(List<T> actualList, T[] expectedContains) {
|
||||
List<T> containsList = new ArrayList<T>(expectedContains.length);
|
||||
Collections.addAll(containsList, expectedContains);
|
||||
assertContainsOnly(actualList, containsList);
|
||||
}
|
||||
|
||||
private <T> String listToString(List<T> list) {
|
||||
String string = "[";
|
||||
for (int i = 0; i < list.size(); i ++) {
|
||||
if (i > 0) {
|
||||
string += ", ";
|
||||
}
|
||||
string += list.get(i);
|
||||
}
|
||||
string += "]";
|
||||
return string;
|
||||
}
|
||||
|
||||
private <T extends Comparable> void assertContainsOnly(List<T> actualList, List<T> expectedContains) {
|
||||
if (actualList.size() != expectedContains.size()) {
|
||||
String message =
|
||||
"List sizes don't match.\n" +
|
||||
"Expected: " +
|
||||
listToString(expectedContains) + "\n" +
|
||||
"Actual: " +
|
||||
listToString(actualList);
|
||||
throw new AssertionFailedError(message);
|
||||
}
|
||||
for (T required : expectedContains) {
|
||||
boolean containsRequired = false;
|
||||
for (T itemInList : actualList) {
|
||||
if (required.equals(itemInList)) {
|
||||
containsRequired = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!containsRequired) {
|
||||
String message =
|
||||
"List doesn't contain \"" + required + "\".\n" +
|
||||
"Expected: " +
|
||||
listToString(expectedContains) + "\n" +
|
||||
"Actual: " +
|
||||
listToString(actualList);
|
||||
throw new AssertionFailedError(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -24,6 +24,13 @@ public abstract class FDroidProviderTest<T extends FDroidProvider> extends Provi
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
Utils.setupInstalledApkCache(new MockInstalledApkCache());
|
||||
|
||||
// The *Provider.Helper.* functions tend to take a Context as their
|
||||
// first parameter. This context is used to connect to the relevant
|
||||
// content provider. Thus, we need a context that is able to connect
|
||||
// to the mock content resolver, in order to reach the provider
|
||||
// under test.
|
||||
getSwappableContext().setContentResolver(getMockContentResolver());
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.ECLAIR)
|
||||
@ -74,4 +81,9 @@ public abstract class FDroidProviderTest<T extends FDroidProvider> extends Provi
|
||||
*/
|
||||
protected abstract String[] getMinimalProjection();
|
||||
|
||||
protected void assertResultCount(int expectedCount, Uri uri) {
|
||||
Cursor cursor = getMockContentResolver().query(uri, getMinimalProjection(), null, null, null);
|
||||
assertNotNull(cursor);
|
||||
assertEquals(expectedCount, cursor.getCount());
|
||||
}
|
||||
}
|
||||
|
@ -2,10 +2,65 @@ package org.fdroid.fdroid;
|
||||
|
||||
import android.content.*;
|
||||
import android.net.Uri;
|
||||
import android.test.mock.MockContentResolver;
|
||||
import junit.framework.AssertionFailedError;
|
||||
import org.fdroid.fdroid.data.ApkProvider;
|
||||
import org.fdroid.fdroid.data.AppProvider;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class TestUtils {
|
||||
|
||||
public static <T extends Comparable> void assertContainsOnly(List<T> actualList, T[] expectedContains) {
|
||||
List<T> containsList = new ArrayList<T>(expectedContains.length);
|
||||
Collections.addAll(containsList, expectedContains);
|
||||
assertContainsOnly(actualList, containsList);
|
||||
}
|
||||
|
||||
public static <T> String listToString(List<T> list) {
|
||||
String string = "[";
|
||||
for (int i = 0; i < list.size(); i ++) {
|
||||
if (i > 0) {
|
||||
string += ", ";
|
||||
}
|
||||
string += list.get(i);
|
||||
}
|
||||
string += "]";
|
||||
return string;
|
||||
}
|
||||
|
||||
public static <T extends Comparable> void assertContainsOnly(List<T> actualList, List<T> expectedContains) {
|
||||
if (actualList.size() != expectedContains.size()) {
|
||||
String message =
|
||||
"List sizes don't match.\n" +
|
||||
"Expected: " +
|
||||
listToString(expectedContains) + "\n" +
|
||||
"Actual: " +
|
||||
listToString(actualList);
|
||||
throw new AssertionFailedError(message);
|
||||
}
|
||||
for (T required : expectedContains) {
|
||||
boolean containsRequired = false;
|
||||
for (T itemInList : actualList) {
|
||||
if (required.equals(itemInList)) {
|
||||
containsRequired = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!containsRequired) {
|
||||
String message =
|
||||
"List doesn't contain \"" + required + "\".\n" +
|
||||
"Expected: " +
|
||||
listToString(expectedContains) + "\n" +
|
||||
"Actual: " +
|
||||
listToString(actualList);
|
||||
throw new AssertionFailedError(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void insertApp(ContentResolver resolver, String id, String name, ContentValues additionalValues) {
|
||||
|
||||
ContentValues values = new ContentValues();
|
||||
@ -27,4 +82,25 @@ public class TestUtils {
|
||||
resolver.insert(uri, values);
|
||||
}
|
||||
|
||||
public static void insertApk(ContentResolver resolver, String id, int versionCode, ContentValues additionalValues) {
|
||||
|
||||
ContentValues values = new ContentValues();
|
||||
|
||||
values.put(ApkProvider.DataColumns.APK_ID, id);
|
||||
values.put(ApkProvider.DataColumns.VERSION_CODE, versionCode);
|
||||
|
||||
// Required fields (NOT NULL in the database).
|
||||
values.put(ApkProvider.DataColumns.REPO_ID, 1);
|
||||
values.put(ApkProvider.DataColumns.VERSION, "The good one");
|
||||
values.put(ApkProvider.DataColumns.HASH, "11111111aaaaaaaa");
|
||||
values.put(ApkProvider.DataColumns.NAME, "Test Apk");
|
||||
values.put(ApkProvider.DataColumns.SIZE, 10000);
|
||||
values.put(ApkProvider.DataColumns.IS_COMPATIBLE, 1);
|
||||
|
||||
values.putAll(additionalValues);
|
||||
|
||||
Uri uri = ApkProvider.getContentUri();
|
||||
|
||||
resolver.insert(uri, values);
|
||||
}
|
||||
}
|
||||
|
12
test/src/org/fdroid/fdroid/mock/MockApk.java
Normal file
12
test/src/org/fdroid/fdroid/mock/MockApk.java
Normal file
@ -0,0 +1,12 @@
|
||||
package org.fdroid.fdroid.mock;
|
||||
|
||||
import org.fdroid.fdroid.data.Apk;
|
||||
|
||||
public class MockApk extends Apk {
|
||||
|
||||
public MockApk(String id, int versionCode) {
|
||||
this.id = id;
|
||||
this.vercode = versionCode;
|
||||
}
|
||||
|
||||
}
|
16
test/src/org/fdroid/fdroid/mock/MockApp.java
Normal file
16
test/src/org/fdroid/fdroid/mock/MockApp.java
Normal file
@ -0,0 +1,16 @@
|
||||
package org.fdroid.fdroid.mock;
|
||||
|
||||
import org.fdroid.fdroid.data.App;
|
||||
|
||||
public class MockApp extends App {
|
||||
|
||||
public MockApp(String id) {
|
||||
this(id, "App " + id);
|
||||
}
|
||||
|
||||
public MockApp(String id, String name) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user