Migrated Apk tests to robolectric.
Relatively straightforward port, nothing particularly special here.
This commit is contained in:
parent
4e66bb810f
commit
839ebebd87
@ -9,7 +9,7 @@ import android.util.Log;
|
||||
import org.fdroid.fdroid.data.Apk;
|
||||
import org.fdroid.fdroid.data.App;
|
||||
import org.fdroid.fdroid.data.Repo;
|
||||
import org.fdroid.fdroid.mock.MockRepo;
|
||||
import org.fdroid.fdroid.mock.MockRepoOld;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.xml.sax.InputSource;
|
||||
@ -678,7 +678,7 @@ public class RepoXMLHandlerTest {
|
||||
parser = SAXParserFactory.newInstance().newSAXParser();
|
||||
XMLReader reader = parser.getXMLReader();
|
||||
RepoDetails repoDetails = new RepoDetails();
|
||||
RepoXMLHandler handler = new RepoXMLHandler(new MockRepo(100), repoDetails);
|
||||
RepoXMLHandler handler = new RepoXMLHandler(new MockRepoOld(100), repoDetails);
|
||||
reader.setContentHandler(handler);
|
||||
String resName = "assets/" + indexFilename;
|
||||
Log.i(TAG, "test file: " + getClass().getClassLoader().getResource(resName));
|
||||
|
@ -1,216 +0,0 @@
|
||||
package org.fdroid.fdroid.data;
|
||||
|
||||
import android.content.ContentValues;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
|
||||
import org.fdroid.fdroid.TestUtils;
|
||||
import org.fdroid.fdroid.Utils;
|
||||
import org.fdroid.fdroid.mock.MockApk;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
@SuppressWarnings("PMD") // TODO port this to JUnit 4 semantics
|
||||
public class ApkProviderHelperTest extends BaseApkProviderTest {
|
||||
|
||||
public void testKnownApks() {
|
||||
|
||||
for (int i = 0; i < 7; i++) {
|
||||
TestUtils.insertApk(this, "org.fdroid.fdroid", i);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 9; i++) {
|
||||
TestUtils.insertApk(this, "org.example", i);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
TestUtils.insertApk(this, "com.example", i);
|
||||
}
|
||||
|
||||
TestUtils.insertApk(this, "com.apk.thingo", 1);
|
||||
|
||||
Apk[] known = {
|
||||
new MockApk("org.fdroid.fdroid", 1),
|
||||
new MockApk("org.fdroid.fdroid", 3),
|
||||
new MockApk("org.fdroid.fdroid", 5),
|
||||
|
||||
new MockApk("com.example", 1),
|
||||
new MockApk("com.example", 2),
|
||||
};
|
||||
|
||||
Apk[] unknown = {
|
||||
new MockApk("org.fdroid.fdroid", 7),
|
||||
new MockApk("org.fdroid.fdroid", 9),
|
||||
new MockApk("org.fdroid.fdroid", 11),
|
||||
new MockApk("org.fdroid.fdroid", 13),
|
||||
|
||||
new MockApk("com.example", 3),
|
||||
new MockApk("com.example", 4),
|
||||
new MockApk("com.example", 5),
|
||||
|
||||
new MockApk("info.example", 1),
|
||||
new MockApk("info.example", 2),
|
||||
};
|
||||
|
||||
List<Apk> apksToCheck = new ArrayList<>(known.length + unknown.length);
|
||||
Collections.addAll(apksToCheck, known);
|
||||
Collections.addAll(apksToCheck, unknown);
|
||||
|
||||
String[] projection = {
|
||||
ApkProvider.DataColumns.PACKAGE_NAME,
|
||||
ApkProvider.DataColumns.VERSION_CODE,
|
||||
};
|
||||
|
||||
List<Apk> knownApks = ApkProvider.Helper.knownApks(getMockContext(), apksToCheck, projection);
|
||||
|
||||
assertResultCount(known.length, knownApks);
|
||||
|
||||
for (Apk knownApk : knownApks) {
|
||||
assertContains(knownApks, knownApk);
|
||||
}
|
||||
}
|
||||
|
||||
public void testFindByApp() {
|
||||
|
||||
for (int i = 0; i < 7; i++) {
|
||||
TestUtils.insertApk(this, "org.fdroid.fdroid", i);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 9; i++) {
|
||||
TestUtils.insertApk(this, "org.example", i);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
TestUtils.insertApk(this, "com.example", i);
|
||||
}
|
||||
|
||||
TestUtils.insertApk(this, "com.apk.thingo", 1);
|
||||
|
||||
assertTotalApkCount(7 + 9 + 3 + 1);
|
||||
|
||||
List<Apk> fdroidApks = ApkProvider.Helper.findByPackageName(getMockContext(), "org.fdroid.fdroid");
|
||||
assertResultCount(7, fdroidApks);
|
||||
assertBelongsToApp(fdroidApks, "org.fdroid.fdroid");
|
||||
|
||||
List<Apk> exampleApks = ApkProvider.Helper.findByPackageName(getMockContext(), "org.example");
|
||||
assertResultCount(9, exampleApks);
|
||||
assertBelongsToApp(exampleApks, "org.example");
|
||||
|
||||
List<Apk> exampleApks2 = ApkProvider.Helper.findByPackageName(getMockContext(), "com.example");
|
||||
assertResultCount(3, exampleApks2);
|
||||
assertBelongsToApp(exampleApks2, "com.example");
|
||||
|
||||
List<Apk> thingoApks = ApkProvider.Helper.findByPackageName(getMockContext(), "com.apk.thingo");
|
||||
assertResultCount(1, thingoApks);
|
||||
assertBelongsToApp(thingoApks, "com.apk.thingo");
|
||||
}
|
||||
|
||||
public void testUpdate() {
|
||||
|
||||
Uri apkUri = TestUtils.insertApk(this, "com.example", 10);
|
||||
|
||||
String[] allFields = ApkProvider.DataColumns.ALL;
|
||||
Cursor cursor = getMockContentResolver().query(apkUri, allFields, null, null, null);
|
||||
assertResultCount(1, cursor);
|
||||
|
||||
cursor.moveToFirst();
|
||||
Apk apk = new Apk(cursor);
|
||||
cursor.close();
|
||||
|
||||
assertEquals("com.example", apk.packageName);
|
||||
assertEquals(10, apk.versionCode);
|
||||
|
||||
assertNull(apk.features);
|
||||
assertNull(apk.added);
|
||||
assertNull(apk.hashType);
|
||||
|
||||
apk.features = Utils.CommaSeparatedList.make("one,two,three");
|
||||
long dateTimestamp = System.currentTimeMillis();
|
||||
apk.added = new Date(dateTimestamp);
|
||||
apk.hashType = "i'm a hash type";
|
||||
|
||||
ApkProvider.Helper.update(getMockContext(), apk);
|
||||
|
||||
// Should not have inserted anything else, just updated the already existing apk.
|
||||
Cursor allCursor = getMockContentResolver().query(ApkProvider.getContentUri(), allFields, null, null, null);
|
||||
assertResultCount(1, allCursor);
|
||||
allCursor.close();
|
||||
|
||||
Cursor updatedCursor = getMockContentResolver().query(apkUri, allFields, null, null, null);
|
||||
assertResultCount(1, updatedCursor);
|
||||
|
||||
updatedCursor.moveToFirst();
|
||||
Apk updatedApk = new Apk(updatedCursor);
|
||||
updatedCursor.close();
|
||||
|
||||
assertEquals("com.example", updatedApk.packageName);
|
||||
assertEquals(10, updatedApk.versionCode);
|
||||
|
||||
assertNotNull(updatedApk.features);
|
||||
assertNotNull(updatedApk.added);
|
||||
assertNotNull(updatedApk.hashType);
|
||||
|
||||
assertEquals("one,two,three", updatedApk.features.toString());
|
||||
assertEquals(new Date(dateTimestamp).getYear(), updatedApk.added.getYear());
|
||||
assertEquals(new Date(dateTimestamp).getMonth(), updatedApk.added.getMonth());
|
||||
assertEquals(new Date(dateTimestamp).getDay(), updatedApk.added.getDay());
|
||||
assertEquals("i'm a hash type", updatedApk.hashType);
|
||||
}
|
||||
|
||||
public void testFind() {
|
||||
|
||||
// Insert some random apks either side of the "com.example", so that
|
||||
// the Helper.find() method doesn't stumble upon the app we are interested
|
||||
// in by shear dumb luck...
|
||||
for (int i = 0; i < 10; i++) {
|
||||
TestUtils.insertApk(this, "org.fdroid.apk." + i, i);
|
||||
}
|
||||
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(ApkProvider.DataColumns.VERSION_NAME, "v1.1");
|
||||
values.put(ApkProvider.DataColumns.HASH, "xxxxyyyy");
|
||||
values.put(ApkProvider.DataColumns.HASH_TYPE, "a hash type");
|
||||
TestUtils.insertApk(this, "com.example", 11, values);
|
||||
|
||||
// ...and a few more for good measure...
|
||||
for (int i = 15; i < 20; i++) {
|
||||
TestUtils.insertApk(this, "com.other.thing." + i, i);
|
||||
}
|
||||
|
||||
Apk apk = ApkProvider.Helper.find(getMockContext(), "com.example", 11);
|
||||
|
||||
assertNotNull(apk);
|
||||
|
||||
// The find() method populates ALL fields if you don't specify any,
|
||||
// so we expect to find each of the ones we inserted above...
|
||||
assertEquals("com.example", apk.packageName);
|
||||
assertEquals(11, apk.versionCode);
|
||||
assertEquals("v1.1", apk.versionName);
|
||||
assertEquals("xxxxyyyy", apk.hash);
|
||||
assertEquals("a hash type", apk.hashType);
|
||||
|
||||
String[] projection = {
|
||||
ApkProvider.DataColumns.PACKAGE_NAME,
|
||||
ApkProvider.DataColumns.HASH,
|
||||
};
|
||||
|
||||
Apk apkLessFields = ApkProvider.Helper.find(getMockContext(), "com.example", 11, projection);
|
||||
|
||||
assertNotNull(apkLessFields);
|
||||
|
||||
assertEquals("com.example", apkLessFields.packageName);
|
||||
assertEquals("xxxxyyyy", apkLessFields.hash);
|
||||
|
||||
// Didn't ask for these fields, so should be their default values...
|
||||
assertNull(apkLessFields.hashType);
|
||||
assertNull(apkLessFields.versionName);
|
||||
assertEquals(0, apkLessFields.versionCode);
|
||||
|
||||
Apk notFound = ApkProvider.Helper.find(getMockContext(), "com.doesnt.exist", 1000);
|
||||
assertNull(notFound);
|
||||
}
|
||||
|
||||
}
|
@ -1,334 +0,0 @@
|
||||
package org.fdroid.fdroid.data;
|
||||
|
||||
import android.content.ContentValues;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
|
||||
import org.fdroid.fdroid.TestUtils;
|
||||
import org.fdroid.fdroid.mock.MockApk;
|
||||
import org.fdroid.fdroid.mock.MockApp;
|
||||
import org.fdroid.fdroid.mock.MockRepo;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@SuppressWarnings("PMD") // TODO port this to JUnit 4 semantics
|
||||
public class ApkProviderTest extends BaseApkProviderTest {
|
||||
|
||||
/**
|
||||
* I want to test the protected {@link org.fdroid.fdroid.data.ApkProvider#getContentUri(java.util.List)}
|
||||
* method, but don't want to make it public. This exposes it.
|
||||
*/
|
||||
private static class PublicApkProvider extends ApkProvider {
|
||||
|
||||
public static final int MAX_APKS_TO_QUERY = ApkProvider.MAX_APKS_TO_QUERY;
|
||||
|
||||
public static Uri getContentUri(List<Apk> apks) {
|
||||
return ApkProvider.getContentUri(apks);
|
||||
}
|
||||
}
|
||||
|
||||
public void testUris() {
|
||||
assertInvalidUri(ApkProvider.getAuthority());
|
||||
assertInvalidUri(RepoProvider.getContentUri());
|
||||
|
||||
List<Apk> apks = new ArrayList<>(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(PublicApkProvider.getContentUri(apks));
|
||||
assertValidUri(ApkProvider.getContentUri("org.fdroid.fdroid", 100));
|
||||
assertValidUri(ApkProvider.getRepoUri(1000));
|
||||
|
||||
List<Apk> manyApks = new ArrayList<>(PublicApkProvider.MAX_APKS_TO_QUERY - 5);
|
||||
for (int i = 0; i < PublicApkProvider.MAX_APKS_TO_QUERY - 1; i++) {
|
||||
manyApks.add(new MockApk("com.example." + i, i));
|
||||
}
|
||||
assertValidUri(PublicApkProvider.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(PublicApkProvider.getContentUri(manyApks));
|
||||
fail();
|
||||
} catch (IllegalArgumentException e) {
|
||||
// This is the expected error behaviour.
|
||||
} catch (Exception e) {
|
||||
fail();
|
||||
}
|
||||
}
|
||||
|
||||
public void testAppApks() {
|
||||
for (int i = 1; i <= 10; i++) {
|
||||
TestUtils.insertApk(this, "org.fdroid.fdroid", i);
|
||||
TestUtils.insertApk(this, "com.example", i);
|
||||
}
|
||||
|
||||
assertTotalApkCount(20);
|
||||
|
||||
Cursor fdroidApks = getMockContentResolver().query(
|
||||
ApkProvider.getAppUri("org.fdroid.fdroid"),
|
||||
getMinimalProjection(),
|
||||
null, null, null);
|
||||
assertResultCount(10, fdroidApks);
|
||||
assertBelongsToApp(fdroidApks, "org.fdroid.fdroid");
|
||||
fdroidApks.close();
|
||||
|
||||
Cursor exampleApks = getMockContentResolver().query(
|
||||
ApkProvider.getAppUri("com.example"),
|
||||
getMinimalProjection(),
|
||||
null, null, null);
|
||||
assertResultCount(10, exampleApks);
|
||||
assertBelongsToApp(exampleApks, "com.example");
|
||||
exampleApks.close();
|
||||
|
||||
ApkProvider.Helper.deleteApksByApp(getMockContext(), new MockApp("com.example"));
|
||||
|
||||
Cursor all = queryAllApks();
|
||||
assertResultCount(10, all);
|
||||
assertBelongsToApp(all, "org.fdroid.fdroid");
|
||||
all.close();
|
||||
}
|
||||
|
||||
public void testInvalidUpdateUris() {
|
||||
Apk apk = new MockApk("org.fdroid.fdroid", 10);
|
||||
|
||||
List<Apk> apks = new ArrayList<>();
|
||||
apks.add(apk);
|
||||
|
||||
assertCantUpdate(ApkProvider.getContentUri());
|
||||
assertCantUpdate(ApkProvider.getAppUri("org.fdroid.fdroid"));
|
||||
assertCantUpdate(ApkProvider.getRepoUri(1));
|
||||
assertCantUpdate(PublicApkProvider.getContentUri(apks));
|
||||
assertCantUpdate(Uri.withAppendedPath(ApkProvider.getContentUri(), "some-random-path"));
|
||||
|
||||
// The only valid ones are:
|
||||
// ApkProvider.getContentUri(apk)
|
||||
// ApkProvider.getContentUri(id, version)
|
||||
// which are tested elsewhere.
|
||||
}
|
||||
|
||||
public void testDeleteArbitraryApks() {
|
||||
Apk one = insertApkForRepo("com.example.one", 1, 10);
|
||||
Apk two = insertApkForRepo("com.example.two", 1, 10);
|
||||
Apk three = insertApkForRepo("com.example.three", 1, 10);
|
||||
Apk four = insertApkForRepo("com.example.four", 1, 10);
|
||||
Apk five = insertApkForRepo("com.example.five", 1, 10);
|
||||
|
||||
assertTotalApkCount(5);
|
||||
|
||||
assertEquals("com.example.one", one.packageName);
|
||||
assertEquals("com.example.two", two.packageName);
|
||||
assertEquals("com.example.five", five.packageName);
|
||||
|
||||
String[] expectedIds = {
|
||||
"com.example.one",
|
||||
"com.example.two",
|
||||
"com.example.three",
|
||||
"com.example.four",
|
||||
"com.example.five",
|
||||
};
|
||||
|
||||
List<Apk> all = ApkProvider.Helper.findByRepo(getSwappableContext(), new MockRepo(10), ApkProvider.DataColumns.ALL);
|
||||
List<String> actualIds = new ArrayList<>();
|
||||
for (Apk apk : all) {
|
||||
actualIds.add(apk.packageName);
|
||||
}
|
||||
|
||||
TestUtils.assertContainsOnly(actualIds, expectedIds);
|
||||
|
||||
List<Apk> toDelete = new ArrayList<>(3);
|
||||
toDelete.add(two);
|
||||
toDelete.add(three);
|
||||
toDelete.add(four);
|
||||
ApkProvider.Helper.deleteApks(getSwappableContext(), toDelete);
|
||||
|
||||
assertTotalApkCount(2);
|
||||
|
||||
List<Apk> allRemaining = ApkProvider.Helper.findByRepo(getSwappableContext(), new MockRepo(10), ApkProvider.DataColumns.ALL);
|
||||
List<String> actualRemainingIds = new ArrayList<>();
|
||||
for (Apk apk : allRemaining) {
|
||||
actualRemainingIds.add(apk.packageName);
|
||||
}
|
||||
|
||||
String[] expectedRemainingIds = {
|
||||
"com.example.one",
|
||||
"com.example.five",
|
||||
};
|
||||
|
||||
TestUtils.assertContainsOnly(actualRemainingIds, expectedRemainingIds);
|
||||
}
|
||||
|
||||
public void testInvalidDeleteUris() {
|
||||
Apk apk = new MockApk("org.fdroid.fdroid", 10);
|
||||
|
||||
assertCantDelete(ApkProvider.getContentUri());
|
||||
assertCantDelete(ApkProvider.getContentUri("org.fdroid.fdroid", 10));
|
||||
assertCantDelete(ApkProvider.getContentUri(apk));
|
||||
assertCantDelete(Uri.withAppendedPath(ApkProvider.getContentUri(), "some-random-path"));
|
||||
}
|
||||
|
||||
private static final long REPO_KEEP = 1;
|
||||
private static final long REPO_DELETE = 2;
|
||||
|
||||
public void testRepoApks() {
|
||||
|
||||
// Insert apks into two repos, one of which we will later purge the
|
||||
// the apks from.
|
||||
for (int i = 1; i <= 5; i++) {
|
||||
insertApkForRepo("org.fdroid.fdroid", i, REPO_KEEP);
|
||||
insertApkForRepo("com.example." + i, 1, REPO_DELETE);
|
||||
}
|
||||
for (int i = 6; i <= 10; i++) {
|
||||
insertApkForRepo("org.fdroid.fdroid", i, REPO_DELETE);
|
||||
insertApkForRepo("com.example." + i, 1, REPO_KEEP);
|
||||
}
|
||||
|
||||
assertTotalApkCount(20);
|
||||
|
||||
Cursor cursor = getMockContentResolver().query(
|
||||
ApkProvider.getRepoUri(REPO_DELETE), getMinimalProjection(), null, null, null);
|
||||
assertResultCount(10, cursor);
|
||||
assertBelongsToRepo(cursor, REPO_DELETE);
|
||||
cursor.close();
|
||||
|
||||
int count = ApkProvider.Helper.deleteApksByRepo(getMockContext(), new MockRepo(REPO_DELETE));
|
||||
assertEquals(10, count);
|
||||
|
||||
assertTotalApkCount(10);
|
||||
cursor = getMockContentResolver().query(
|
||||
ApkProvider.getRepoUri(REPO_DELETE), getMinimalProjection(), null, null, null);
|
||||
assertResultCount(0, cursor);
|
||||
cursor.close();
|
||||
|
||||
// The only remaining apks should be those from REPO_KEEP.
|
||||
assertBelongsToRepo(queryAllApks(), REPO_KEEP);
|
||||
}
|
||||
|
||||
public void testQuery() {
|
||||
Cursor cursor = queryAllApks();
|
||||
assertNotNull(cursor);
|
||||
cursor.close();
|
||||
}
|
||||
|
||||
public void testInsert() {
|
||||
|
||||
// Start with an empty database...
|
||||
Cursor cursor = queryAllApks();
|
||||
assertNotNull(cursor);
|
||||
assertEquals(0, cursor.getCount());
|
||||
cursor.close();
|
||||
|
||||
Apk apk = new MockApk("org.fdroid.fdroid", 13);
|
||||
|
||||
// Insert a new record...
|
||||
Uri newUri = TestUtils.insertApk(this, apk.packageName, apk.versionCode);
|
||||
assertEquals(ApkProvider.getContentUri(apk).toString(), newUri.toString());
|
||||
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
|
||||
// PACKAGE_NAME.
|
||||
cursor.moveToFirst();
|
||||
Apk toCheck = new Apk(cursor);
|
||||
cursor.close();
|
||||
assertEquals("org.fdroid.fdroid", toCheck.packageName);
|
||||
assertEquals(13, toCheck.versionCode);
|
||||
}
|
||||
|
||||
public void testCount() {
|
||||
String[] projectionFields = getMinimalProjection();
|
||||
String[] projectionCount = new String[] {ApkProvider.DataColumns._COUNT};
|
||||
|
||||
for (int i = 0; i < 13; i++) {
|
||||
TestUtils.insertApk(this, "com.example", i);
|
||||
}
|
||||
|
||||
Uri all = ApkProvider.getContentUri();
|
||||
Cursor allWithFields = getMockContentResolver().query(all, projectionFields, null, null, null);
|
||||
Cursor allWithCount = getMockContentResolver().query(all, projectionCount, null, null, null);
|
||||
|
||||
assertResultCount(13, allWithFields);
|
||||
allWithFields.close();
|
||||
assertResultCount(1, allWithCount);
|
||||
|
||||
allWithCount.moveToFirst();
|
||||
int countColumn = allWithCount.getColumnIndex(ApkProvider.DataColumns._COUNT);
|
||||
assertEquals(13, allWithCount.getInt(countColumn));
|
||||
allWithCount.close();
|
||||
}
|
||||
|
||||
public void testInsertWithExtraFields() {
|
||||
|
||||
assertResultCount(0, queryAllApks());
|
||||
|
||||
String[] repoFields = new String[] {
|
||||
RepoProvider.DataColumns.DESCRIPTION,
|
||||
RepoProvider.DataColumns.ADDRESS,
|
||||
RepoProvider.DataColumns.FINGERPRINT,
|
||||
RepoProvider.DataColumns.NAME,
|
||||
RepoProvider.DataColumns.SIGNING_CERT,
|
||||
};
|
||||
|
||||
for (String field : repoFields) {
|
||||
ContentValues invalidRepo = new ContentValues();
|
||||
invalidRepo.put(field, "Test data");
|
||||
try {
|
||||
TestUtils.insertApk(this, "org.fdroid.fdroid", 10, invalidRepo);
|
||||
fail();
|
||||
} catch (IllegalArgumentException e) {
|
||||
} catch (Exception e) {
|
||||
fail();
|
||||
}
|
||||
assertResultCount(0, queryAllApks());
|
||||
}
|
||||
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(ApkProvider.DataColumns.REPO_ID, 10);
|
||||
values.put(ApkProvider.DataColumns.REPO_ADDRESS, "http://example.com");
|
||||
values.put(ApkProvider.DataColumns.REPO_VERSION, 3);
|
||||
values.put(ApkProvider.DataColumns.FEATURES, "Some features");
|
||||
Uri uri = TestUtils.insertApk(this, "com.example.com", 1, values);
|
||||
|
||||
assertResultCount(1, queryAllApks());
|
||||
|
||||
String[] projections = ApkProvider.DataColumns.ALL;
|
||||
Cursor cursor = getMockContentResolver().query(uri, projections, null, null, null);
|
||||
cursor.moveToFirst();
|
||||
Apk apk = new Apk(cursor);
|
||||
cursor.close();
|
||||
|
||||
// These should have quietly been dropped when we tried to save them,
|
||||
// because the provider only knows how to query them (not update them).
|
||||
assertEquals(null, apk.repoAddress);
|
||||
assertEquals(0, apk.repoVersion);
|
||||
|
||||
// But this should have saved correctly...
|
||||
assertEquals("Some features", apk.features.toString());
|
||||
assertEquals("com.example.com", apk.packageName);
|
||||
assertEquals(1, apk.versionCode);
|
||||
assertEquals(10, apk.repo);
|
||||
}
|
||||
}
|
@ -1,78 +0,0 @@
|
||||
package org.fdroid.fdroid.data;
|
||||
|
||||
import android.content.ContentValues;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
|
||||
import org.fdroid.fdroid.TestUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Provides helper methods that can be used by both Helper and plain old
|
||||
* Provider tests. Allows the test classes to contain only test methods,
|
||||
* hopefully making them easier to understand.
|
||||
*
|
||||
* This should not contain any test methods, or else they get executed
|
||||
* once for every concrete subclass.
|
||||
*/
|
||||
abstract class BaseApkProviderTest extends FDroidProviderTestOld<ApkProvider> {
|
||||
|
||||
BaseApkProviderTest() {
|
||||
super(ApkProvider.class, ApkProvider.getAuthority());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String[] getMinimalProjection() {
|
||||
return new String[] {
|
||||
ApkProvider.DataColumns.PACKAGE_NAME,
|
||||
ApkProvider.DataColumns.VERSION_CODE,
|
||||
ApkProvider.DataColumns.NAME,
|
||||
ApkProvider.DataColumns.REPO_ID,
|
||||
};
|
||||
}
|
||||
|
||||
protected final Cursor queryAllApks() {
|
||||
return getMockContentResolver().query(ApkProvider.getContentUri(), getMinimalProjection(), null, null, null);
|
||||
}
|
||||
|
||||
protected void assertContains(List<Apk> apks, Apk apk) {
|
||||
boolean found = false;
|
||||
for (Apk a : apks) {
|
||||
if (a.versionCode == apk.versionCode && a.packageName.equals(apk.packageName)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
fail("Apk [" + apk + "] not found in " + TestUtils.listToString(apks));
|
||||
}
|
||||
}
|
||||
|
||||
protected void assertBelongsToApp(Cursor apks, String appId) {
|
||||
assertBelongsToApp(ApkProvider.Helper.cursorToList(apks), appId);
|
||||
}
|
||||
|
||||
protected void assertBelongsToApp(List<Apk> apks, String appId) {
|
||||
for (Apk apk : apks) {
|
||||
assertEquals(appId, apk.packageName);
|
||||
}
|
||||
}
|
||||
|
||||
protected void assertTotalApkCount(int expected) {
|
||||
assertResultCount(expected, queryAllApks());
|
||||
}
|
||||
|
||||
protected void assertBelongsToRepo(Cursor apkCursor, long repoId) {
|
||||
for (Apk apk : ApkProvider.Helper.cursorToList(apkCursor)) {
|
||||
assertEquals(repoId, apk.repo);
|
||||
}
|
||||
}
|
||||
|
||||
protected Apk insertApkForRepo(String id, int versionCode, long repoId) {
|
||||
ContentValues additionalValues = new ContentValues();
|
||||
additionalValues.put(ApkProvider.DataColumns.REPO_ID, repoId);
|
||||
Uri uri = TestUtils.insertApk(this, id, versionCode, additionalValues);
|
||||
return ApkProvider.Helper.get(getSwappableContext(), uri);
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
package org.fdroid.fdroid.mock;
|
||||
|
||||
import org.fdroid.fdroid.data.Repo;
|
||||
|
||||
public class MockRepoOld extends Repo {
|
||||
|
||||
public MockRepoOld(long repoId) {
|
||||
id = repoId;
|
||||
}
|
||||
|
||||
}
|
@ -26,7 +26,7 @@ public class ApkProvider extends FDroidProvider {
|
||||
* we may want to add additional constraints, so we give our self some
|
||||
* room by saying only 450 apks can be queried at once.
|
||||
*/
|
||||
protected static final int MAX_APKS_TO_QUERY = 450;
|
||||
static final int MAX_APKS_TO_QUERY = 450;
|
||||
|
||||
public static final class Helper {
|
||||
|
||||
@ -319,7 +319,7 @@ public class ApkProvider extends FDroidProvider {
|
||||
* this directly, think about using
|
||||
* {@link org.fdroid.fdroid.data.ApkProvider.Helper#knownApks(android.content.Context, java.util.List, String[])}
|
||||
*/
|
||||
protected static Uri getContentUri(List<Apk> apks) {
|
||||
static Uri getContentUri(List<Apk> apks) {
|
||||
return getContentUri().buildUpon()
|
||||
.appendPath(PATH_APKS)
|
||||
.appendPath(buildApkString(apks))
|
||||
|
535
app/src/test/java/org/fdroid/fdroid/data/ApkProviderTest.java
Normal file
535
app/src/test/java/org/fdroid/fdroid/data/ApkProviderTest.java
Normal file
@ -0,0 +1,535 @@
|
||||
package org.fdroid.fdroid.data;
|
||||
|
||||
import android.app.Application;
|
||||
import android.content.ContentValues;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
|
||||
import org.fdroid.fdroid.BuildConfig;
|
||||
import org.fdroid.fdroid.Utils;
|
||||
import org.fdroid.fdroid.mock.MockApk;
|
||||
import org.fdroid.fdroid.mock.MockApp;
|
||||
import org.fdroid.fdroid.mock.MockRepo;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RobolectricGradleTestRunner;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import static org.fdroid.fdroid.data.ProviderTestUtils.assertCantDelete;
|
||||
import static org.fdroid.fdroid.data.ProviderTestUtils.assertContainsOnly;
|
||||
import static org.fdroid.fdroid.data.ProviderTestUtils.assertResultCount;
|
||||
import static org.fdroid.fdroid.data.ProviderTestUtils.insertApk;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
@Config(constants = BuildConfig.class, application = Application.class)
|
||||
@RunWith(RobolectricGradleTestRunner.class)
|
||||
public class ApkProviderTest extends FDroidProviderTest {
|
||||
|
||||
private static final String[] PROJ = ApkProvider.DataColumns.ALL;
|
||||
|
||||
@Test
|
||||
public void testAppApks() {
|
||||
for (int i = 1; i <= 10; i++) {
|
||||
insertApk(contentResolver, "org.fdroid.fdroid", i);
|
||||
insertApk(contentResolver, "com.example", i);
|
||||
}
|
||||
|
||||
assertTotalApkCount(20);
|
||||
|
||||
Cursor fdroidApks = contentResolver.query(
|
||||
ApkProvider.getAppUri("org.fdroid.fdroid"),
|
||||
PROJ,
|
||||
null, null, null);
|
||||
assertResultCount(10, fdroidApks);
|
||||
assertBelongsToApp(fdroidApks, "org.fdroid.fdroid");
|
||||
fdroidApks.close();
|
||||
|
||||
Cursor exampleApks = contentResolver.query(
|
||||
ApkProvider.getAppUri("com.example"),
|
||||
PROJ,
|
||||
null, null, null);
|
||||
assertResultCount(10, exampleApks);
|
||||
assertBelongsToApp(exampleApks, "com.example");
|
||||
exampleApks.close();
|
||||
|
||||
ApkProvider.Helper.deleteApksByApp(context, new MockApp("com.example"));
|
||||
|
||||
Cursor all = queryAllApks();
|
||||
assertResultCount(10, all);
|
||||
assertBelongsToApp(all, "org.fdroid.fdroid");
|
||||
all.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteArbitraryApks() {
|
||||
Apk one = insertApkForRepo("com.example.one", 1, 10);
|
||||
Apk two = insertApkForRepo("com.example.two", 1, 10);
|
||||
Apk three = insertApkForRepo("com.example.three", 1, 10);
|
||||
Apk four = insertApkForRepo("com.example.four", 1, 10);
|
||||
Apk five = insertApkForRepo("com.example.five", 1, 10);
|
||||
|
||||
assertTotalApkCount(5);
|
||||
|
||||
assertEquals("com.example.one", one.packageName);
|
||||
assertEquals("com.example.two", two.packageName);
|
||||
assertEquals("com.example.five", five.packageName);
|
||||
|
||||
String[] expectedIds = {
|
||||
"com.example.one",
|
||||
"com.example.two",
|
||||
"com.example.three",
|
||||
"com.example.four",
|
||||
"com.example.five",
|
||||
};
|
||||
|
||||
List<Apk> all = ApkProvider.Helper.findByRepo(context, new MockRepo(10), ApkProvider.DataColumns.ALL);
|
||||
List<String> actualIds = new ArrayList<>();
|
||||
for (Apk apk : all) {
|
||||
actualIds.add(apk.packageName);
|
||||
}
|
||||
|
||||
assertContainsOnly(actualIds, expectedIds);
|
||||
|
||||
List<Apk> toDelete = new ArrayList<>(3);
|
||||
toDelete.add(two);
|
||||
toDelete.add(three);
|
||||
toDelete.add(four);
|
||||
ApkProvider.Helper.deleteApks(context, toDelete);
|
||||
|
||||
assertTotalApkCount(2);
|
||||
|
||||
List<Apk> allRemaining = ApkProvider.Helper.findByRepo(context, new MockRepo(10), ApkProvider.DataColumns.ALL);
|
||||
List<String> actualRemainingIds = new ArrayList<>();
|
||||
for (Apk apk : allRemaining) {
|
||||
actualRemainingIds.add(apk.packageName);
|
||||
}
|
||||
|
||||
String[] expectedRemainingIds = {
|
||||
"com.example.one",
|
||||
"com.example.five",
|
||||
};
|
||||
|
||||
assertContainsOnly(actualRemainingIds, expectedRemainingIds);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInvalidDeleteUris() {
|
||||
Apk apk = new MockApk("org.fdroid.fdroid", 10);
|
||||
|
||||
assertCantDelete(contentResolver, ApkProvider.getContentUri());
|
||||
assertCantDelete(contentResolver, ApkProvider.getContentUri("org.fdroid.fdroid", 10));
|
||||
assertCantDelete(contentResolver, ApkProvider.getContentUri(apk));
|
||||
assertCantDelete(contentResolver, Uri.withAppendedPath(ApkProvider.getContentUri(), "some-random-path"));
|
||||
}
|
||||
|
||||
private static final long REPO_KEEP = 1;
|
||||
private static final long REPO_DELETE = 2;
|
||||
|
||||
@Test
|
||||
public void testRepoApks() {
|
||||
|
||||
// Insert apks into two repos, one of which we will later purge the
|
||||
// the apks from.
|
||||
for (int i = 1; i <= 5; i++) {
|
||||
insertApkForRepo("org.fdroid.fdroid", i, REPO_KEEP);
|
||||
insertApkForRepo("com.example." + i, 1, REPO_DELETE);
|
||||
}
|
||||
for (int i = 6; i <= 10; i++) {
|
||||
insertApkForRepo("org.fdroid.fdroid", i, REPO_DELETE);
|
||||
insertApkForRepo("com.example." + i, 1, REPO_KEEP);
|
||||
}
|
||||
|
||||
assertTotalApkCount(20);
|
||||
|
||||
Cursor cursor = contentResolver.query(
|
||||
ApkProvider.getRepoUri(REPO_DELETE), PROJ, null, null, null);
|
||||
assertResultCount(10, cursor);
|
||||
assertBelongsToRepo(cursor, REPO_DELETE);
|
||||
cursor.close();
|
||||
|
||||
int count = ApkProvider.Helper.deleteApksByRepo(context, new MockRepo(REPO_DELETE));
|
||||
assertEquals(10, count);
|
||||
|
||||
assertTotalApkCount(10);
|
||||
cursor = contentResolver.query(
|
||||
ApkProvider.getRepoUri(REPO_DELETE), PROJ, null, null, null);
|
||||
assertResultCount(0, cursor);
|
||||
cursor.close();
|
||||
|
||||
// The only remaining apks should be those from REPO_KEEP.
|
||||
assertBelongsToRepo(queryAllApks(), REPO_KEEP);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQuery() {
|
||||
Cursor cursor = queryAllApks();
|
||||
assertNotNull(cursor);
|
||||
cursor.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInsert() {
|
||||
|
||||
// Start with an empty database...
|
||||
Cursor cursor = queryAllApks();
|
||||
assertNotNull(cursor);
|
||||
assertEquals(0, cursor.getCount());
|
||||
cursor.close();
|
||||
|
||||
Apk apk = new MockApk("org.fdroid.fdroid", 13);
|
||||
|
||||
// Insert a new record...
|
||||
Uri newUri = insertApk(contentResolver, apk.packageName, apk.versionCode);
|
||||
assertEquals(ApkProvider.getContentUri(apk).toString(), newUri.toString());
|
||||
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
|
||||
// PACKAGE_NAME.
|
||||
cursor.moveToFirst();
|
||||
Apk toCheck = new Apk(cursor);
|
||||
cursor.close();
|
||||
assertEquals("org.fdroid.fdroid", toCheck.packageName);
|
||||
assertEquals(13, toCheck.versionCode);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCount() {
|
||||
String[] projectionCount = new String[] {ApkProvider.DataColumns._COUNT};
|
||||
|
||||
for (int i = 0; i < 13; i++) {
|
||||
insertApk(contentResolver, "com.example", i);
|
||||
}
|
||||
|
||||
Uri all = ApkProvider.getContentUri();
|
||||
Cursor allWithFields = contentResolver.query(all, PROJ, null, null, null);
|
||||
Cursor allWithCount = contentResolver.query(all, projectionCount, null, null, null);
|
||||
|
||||
assertResultCount(13, allWithFields);
|
||||
allWithFields.close();
|
||||
assertResultCount(1, allWithCount);
|
||||
|
||||
allWithCount.moveToFirst();
|
||||
int countColumn = allWithCount.getColumnIndex(ApkProvider.DataColumns._COUNT);
|
||||
assertEquals(13, allWithCount.getInt(countColumn));
|
||||
allWithCount.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInsertWithExtraFields() {
|
||||
|
||||
assertResultCount(0, queryAllApks());
|
||||
|
||||
String[] repoFields = new String[] {
|
||||
RepoProvider.DataColumns.DESCRIPTION,
|
||||
RepoProvider.DataColumns.ADDRESS,
|
||||
RepoProvider.DataColumns.FINGERPRINT,
|
||||
RepoProvider.DataColumns.NAME,
|
||||
RepoProvider.DataColumns.SIGNING_CERT,
|
||||
};
|
||||
|
||||
for (String field : repoFields) {
|
||||
ContentValues invalidRepo = new ContentValues();
|
||||
invalidRepo.put(field, "Test data");
|
||||
try {
|
||||
insertApk(contentResolver, "org.fdroid.fdroid", 10, invalidRepo);
|
||||
fail();
|
||||
} catch (IllegalArgumentException e) {
|
||||
} catch (Exception e) {
|
||||
fail();
|
||||
}
|
||||
assertResultCount(0, queryAllApks());
|
||||
}
|
||||
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(ApkProvider.DataColumns.REPO_ID, 10);
|
||||
values.put(ApkProvider.DataColumns.REPO_ADDRESS, "http://example.com");
|
||||
values.put(ApkProvider.DataColumns.REPO_VERSION, 3);
|
||||
values.put(ApkProvider.DataColumns.FEATURES, "Some features");
|
||||
Uri uri = insertApk(contentResolver, "com.example.com", 1, values);
|
||||
|
||||
assertResultCount(1, queryAllApks());
|
||||
|
||||
String[] projections = ApkProvider.DataColumns.ALL;
|
||||
Cursor cursor = contentResolver.query(uri, projections, null, null, null);
|
||||
cursor.moveToFirst();
|
||||
Apk apk = new Apk(cursor);
|
||||
cursor.close();
|
||||
|
||||
// These should have quietly been dropped when we tried to save them,
|
||||
// because the provider only knows how to query them (not update them).
|
||||
assertEquals(null, apk.repoAddress);
|
||||
assertEquals(0, apk.repoVersion);
|
||||
|
||||
// But this should have saved correctly...
|
||||
assertEquals("Some features", apk.features.toString());
|
||||
assertEquals("com.example.com", apk.packageName);
|
||||
assertEquals(1, apk.versionCode);
|
||||
assertEquals(10, apk.repo);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testKnownApks() {
|
||||
|
||||
for (int i = 0; i < 7; i++) {
|
||||
insertApk(contentResolver, "org.fdroid.fdroid", i);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 9; i++) {
|
||||
insertApk(contentResolver, "org.example", i);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
insertApk(contentResolver, "com.example", i);
|
||||
}
|
||||
|
||||
insertApk(contentResolver, "com.apk.thingo", 1);
|
||||
|
||||
Apk[] known = {
|
||||
new MockApk("org.fdroid.fdroid", 1),
|
||||
new MockApk("org.fdroid.fdroid", 3),
|
||||
new MockApk("org.fdroid.fdroid", 5),
|
||||
|
||||
new MockApk("com.example", 1),
|
||||
new MockApk("com.example", 2),
|
||||
};
|
||||
|
||||
Apk[] unknown = {
|
||||
new MockApk("org.fdroid.fdroid", 7),
|
||||
new MockApk("org.fdroid.fdroid", 9),
|
||||
new MockApk("org.fdroid.fdroid", 11),
|
||||
new MockApk("org.fdroid.fdroid", 13),
|
||||
|
||||
new MockApk("com.example", 3),
|
||||
new MockApk("com.example", 4),
|
||||
new MockApk("com.example", 5),
|
||||
|
||||
new MockApk("info.example", 1),
|
||||
new MockApk("info.example", 2),
|
||||
};
|
||||
|
||||
List<Apk> apksToCheck = new ArrayList<>(known.length + unknown.length);
|
||||
Collections.addAll(apksToCheck, known);
|
||||
Collections.addAll(apksToCheck, unknown);
|
||||
|
||||
String[] projection = {
|
||||
ApkProvider.DataColumns.PACKAGE_NAME,
|
||||
ApkProvider.DataColumns.VERSION_CODE,
|
||||
};
|
||||
|
||||
List<Apk> knownApks = ApkProvider.Helper.knownApks(context, apksToCheck, projection);
|
||||
|
||||
assertResultCount(known.length, knownApks);
|
||||
|
||||
for (Apk knownApk : knownApks) {
|
||||
assertContains(knownApks, knownApk);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFindByApp() {
|
||||
|
||||
for (int i = 0; i < 7; i++) {
|
||||
insertApk(contentResolver, "org.fdroid.fdroid", i);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 9; i++) {
|
||||
insertApk(contentResolver, "org.example", i);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
insertApk(contentResolver, "com.example", i);
|
||||
}
|
||||
|
||||
insertApk(contentResolver, "com.apk.thingo", 1);
|
||||
|
||||
assertTotalApkCount(7 + 9 + 3 + 1);
|
||||
|
||||
List<Apk> fdroidApks = ApkProvider.Helper.findByPackageName(context, "org.fdroid.fdroid");
|
||||
assertResultCount(7, fdroidApks);
|
||||
assertBelongsToApp(fdroidApks, "org.fdroid.fdroid");
|
||||
|
||||
List<Apk> exampleApks = ApkProvider.Helper.findByPackageName(context, "org.example");
|
||||
assertResultCount(9, exampleApks);
|
||||
assertBelongsToApp(exampleApks, "org.example");
|
||||
|
||||
List<Apk> exampleApks2 = ApkProvider.Helper.findByPackageName(context, "com.example");
|
||||
assertResultCount(3, exampleApks2);
|
||||
assertBelongsToApp(exampleApks2, "com.example");
|
||||
|
||||
List<Apk> thingoApks = ApkProvider.Helper.findByPackageName(context, "com.apk.thingo");
|
||||
assertResultCount(1, thingoApks);
|
||||
assertBelongsToApp(thingoApks, "com.apk.thingo");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdate() {
|
||||
|
||||
Uri apkUri = insertApk(contentResolver, "com.example", 10);
|
||||
|
||||
String[] allFields = ApkProvider.DataColumns.ALL;
|
||||
Cursor cursor = contentResolver.query(apkUri, allFields, null, null, null);
|
||||
assertResultCount(1, cursor);
|
||||
|
||||
cursor.moveToFirst();
|
||||
Apk apk = new Apk(cursor);
|
||||
cursor.close();
|
||||
|
||||
assertEquals("com.example", apk.packageName);
|
||||
assertEquals(10, apk.versionCode);
|
||||
|
||||
assertNull(apk.features);
|
||||
assertNull(apk.added);
|
||||
assertNull(apk.hashType);
|
||||
|
||||
apk.features = Utils.CommaSeparatedList.make("one,two,three");
|
||||
long dateTimestamp = System.currentTimeMillis();
|
||||
apk.added = new Date(dateTimestamp);
|
||||
apk.hashType = "i'm a hash type";
|
||||
|
||||
ApkProvider.Helper.update(context, apk);
|
||||
|
||||
// Should not have inserted anything else, just updated the already existing apk.
|
||||
Cursor allCursor = contentResolver.query(ApkProvider.getContentUri(), allFields, null, null, null);
|
||||
assertResultCount(1, allCursor);
|
||||
allCursor.close();
|
||||
|
||||
Cursor updatedCursor = contentResolver.query(apkUri, allFields, null, null, null);
|
||||
assertResultCount(1, updatedCursor);
|
||||
|
||||
updatedCursor.moveToFirst();
|
||||
Apk updatedApk = new Apk(updatedCursor);
|
||||
updatedCursor.close();
|
||||
|
||||
assertEquals("com.example", updatedApk.packageName);
|
||||
assertEquals(10, updatedApk.versionCode);
|
||||
|
||||
assertNotNull(updatedApk.features);
|
||||
assertNotNull(updatedApk.added);
|
||||
assertNotNull(updatedApk.hashType);
|
||||
|
||||
assertEquals("one,two,three", updatedApk.features.toString());
|
||||
assertEquals(new Date(dateTimestamp).getYear(), updatedApk.added.getYear());
|
||||
assertEquals(new Date(dateTimestamp).getMonth(), updatedApk.added.getMonth());
|
||||
assertEquals(new Date(dateTimestamp).getDay(), updatedApk.added.getDay());
|
||||
assertEquals("i'm a hash type", updatedApk.hashType);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFind() {
|
||||
// Insert some random apks either side of the "com.example", so that
|
||||
// the Helper.find() method doesn't stumble upon the app we are interested
|
||||
// in by shear dumb luck...
|
||||
for (int i = 0; i < 10; i++) {
|
||||
insertApk(contentResolver, "org.fdroid.apk." + i, i);
|
||||
}
|
||||
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(ApkProvider.DataColumns.VERSION_NAME, "v1.1");
|
||||
values.put(ApkProvider.DataColumns.HASH, "xxxxyyyy");
|
||||
values.put(ApkProvider.DataColumns.HASH_TYPE, "a hash type");
|
||||
insertApk(contentResolver, "com.example", 11, values);
|
||||
|
||||
// ...and a few more for good measure...
|
||||
for (int i = 15; i < 20; i++) {
|
||||
insertApk(contentResolver, "com.other.thing." + i, i);
|
||||
}
|
||||
|
||||
Apk apk = ApkProvider.Helper.find(context, "com.example", 11);
|
||||
|
||||
assertNotNull(apk);
|
||||
|
||||
// The find() method populates ALL fields if you don't specify any,
|
||||
// so we expect to find each of the ones we inserted above...
|
||||
assertEquals("com.example", apk.packageName);
|
||||
assertEquals(11, apk.versionCode);
|
||||
assertEquals("v1.1", apk.versionName);
|
||||
assertEquals("xxxxyyyy", apk.hash);
|
||||
assertEquals("a hash type", apk.hashType);
|
||||
|
||||
String[] projection = {
|
||||
ApkProvider.DataColumns.PACKAGE_NAME,
|
||||
ApkProvider.DataColumns.HASH,
|
||||
};
|
||||
|
||||
Apk apkLessFields = ApkProvider.Helper.find(context, "com.example", 11, projection);
|
||||
|
||||
assertNotNull(apkLessFields);
|
||||
|
||||
assertEquals("com.example", apkLessFields.packageName);
|
||||
assertEquals("xxxxyyyy", apkLessFields.hash);
|
||||
|
||||
// Didn't ask for these fields, so should be their default values...
|
||||
assertNull(apkLessFields.hashType);
|
||||
assertNull(apkLessFields.versionName);
|
||||
assertEquals(0, apkLessFields.versionCode);
|
||||
|
||||
Apk notFound = ApkProvider.Helper.find(context, "com.doesnt.exist", 1000);
|
||||
assertNull(notFound);
|
||||
}
|
||||
|
||||
protected final Cursor queryAllApks() {
|
||||
return contentResolver.query(ApkProvider.getContentUri(), PROJ, null, null, null);
|
||||
}
|
||||
|
||||
protected void assertContains(List<Apk> apks, Apk apk) {
|
||||
boolean found = false;
|
||||
for (Apk a : apks) {
|
||||
if (a.versionCode == apk.versionCode && a.packageName.equals(apk.packageName)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
fail("Apk [" + apk + "] not found in " + ProviderTestUtils.listToString(apks));
|
||||
}
|
||||
}
|
||||
|
||||
protected void assertBelongsToApp(Cursor apks, String appId) {
|
||||
assertBelongsToApp(ApkProvider.Helper.cursorToList(apks), appId);
|
||||
}
|
||||
|
||||
protected void assertBelongsToApp(List<Apk> apks, String appId) {
|
||||
for (Apk apk : apks) {
|
||||
assertEquals(appId, apk.packageName);
|
||||
}
|
||||
}
|
||||
|
||||
protected void assertTotalApkCount(int expected) {
|
||||
assertResultCount(expected, queryAllApks());
|
||||
}
|
||||
|
||||
protected void assertBelongsToRepo(Cursor apkCursor, long repoId) {
|
||||
for (Apk apk : ApkProvider.Helper.cursorToList(apkCursor)) {
|
||||
assertEquals(repoId, apk.repo);
|
||||
}
|
||||
}
|
||||
|
||||
protected Apk insertApkForRepo(String id, int versionCode, long repoId) {
|
||||
ContentValues additionalValues = new ContentValues();
|
||||
additionalValues.put(ApkProvider.DataColumns.REPO_ID, repoId);
|
||||
Uri uri = insertApk(contentResolver, id, versionCode, additionalValues);
|
||||
return ApkProvider.Helper.get(context, uri);
|
||||
}
|
||||
}
|
@ -168,4 +168,55 @@ public class ProviderTestUtils {
|
||||
cursor.close();
|
||||
}
|
||||
|
||||
public static void insertApp(ShadowContentResolver resolver, String appId, String name) {
|
||||
insertApp(resolver, appId, name, new ContentValues());
|
||||
}
|
||||
|
||||
public static void insertApp(ShadowContentResolver resolver, String id, String name, ContentValues additionalValues) {
|
||||
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(AppProvider.DataColumns.PACKAGE_NAME, id);
|
||||
values.put(AppProvider.DataColumns.NAME, name);
|
||||
|
||||
// Required fields (NOT NULL in the database).
|
||||
values.put(AppProvider.DataColumns.SUMMARY, "test summary");
|
||||
values.put(AppProvider.DataColumns.DESCRIPTION, "test description");
|
||||
values.put(AppProvider.DataColumns.LICENSE, "GPL?");
|
||||
values.put(AppProvider.DataColumns.IS_COMPATIBLE, 1);
|
||||
values.put(AppProvider.DataColumns.IGNORE_ALLUPDATES, 0);
|
||||
values.put(AppProvider.DataColumns.IGNORE_THISUPDATE, 0);
|
||||
|
||||
values.putAll(additionalValues);
|
||||
|
||||
Uri uri = AppProvider.getContentUri();
|
||||
|
||||
resolver.insert(uri, values);
|
||||
}
|
||||
|
||||
public static Uri insertApk(ShadowContentResolver resolver, String id, int versionCode) {
|
||||
return insertApk(resolver, id, versionCode, new ContentValues());
|
||||
}
|
||||
|
||||
public static Uri insertApk(ShadowContentResolver resolver, String id, int versionCode, ContentValues additionalValues) {
|
||||
|
||||
ContentValues values = new ContentValues();
|
||||
|
||||
values.put(ApkProvider.DataColumns.PACKAGE_NAME, 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_NAME, "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();
|
||||
|
||||
return resolver.insert(uri, values);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package org.fdroid.fdroid.data;
|
||||
|
||||
import org.fdroid.fdroid.BuildConfig;
|
||||
import org.fdroid.fdroid.mock.MockApk;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@ -16,6 +17,7 @@ import java.util.List;
|
||||
|
||||
import static org.fdroid.fdroid.data.ProviderTestUtils.assertInvalidUri;
|
||||
import static org.fdroid.fdroid.data.ProviderTestUtils.assertValidUri;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
@Config(constants = BuildConfig.class)
|
||||
@RunWith(RobolectricGradleTestRunner.class)
|
||||
@ -99,4 +101,50 @@ public class ProviderUriTests {
|
||||
assertValidUri(resolver, AppProvider.getContentUri("org.fdroid.fdroid"), "content://org.fdroid.fdroid.data.AppProvider/org.fdroid.fdroid", projection);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invalidApkProviderUris() {
|
||||
ShadowContentResolver.registerProvider(ApkProvider.getAuthority(), new ApkProvider());
|
||||
assertInvalidUri(resolver, ApkProvider.getAuthority());
|
||||
assertInvalidUri(resolver, "blah");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validApkProviderUris() {
|
||||
ShadowContentResolver.registerProvider(ApkProvider.getAuthority(), new ApkProvider());
|
||||
String[] projection = new String[] { ApkProvider.DataColumns._ID };
|
||||
|
||||
List<Apk> apks = new ArrayList<>(10);
|
||||
for (int i = 0; i < 10; i++) {
|
||||
apks.add(new MockApk("com.example." + i, i));
|
||||
}
|
||||
|
||||
assertValidUri(resolver, ApkProvider.getContentUri(), "content://org.fdroid.fdroid.data.ApkProvider", projection);
|
||||
assertValidUri(resolver, ApkProvider.getAppUri("org.fdroid.fdroid"), "content://org.fdroid.fdroid.data.ApkProvider/app/org.fdroid.fdroid", projection);
|
||||
assertValidUri(resolver, ApkProvider.getContentUri(new MockApk("org.fdroid.fdroid", 100)), "content://org.fdroid.fdroid.data.ApkProvider/apk/100/org.fdroid.fdroid", projection);
|
||||
assertValidUri(resolver, ApkProvider.getContentUri(apks), projection);
|
||||
assertValidUri(resolver, ApkProvider.getContentUri("org.fdroid.fdroid", 100), "content://org.fdroid.fdroid.data.ApkProvider/apk/100/org.fdroid.fdroid", projection);
|
||||
assertValidUri(resolver, ApkProvider.getRepoUri(1000), "content://org.fdroid.fdroid.data.ApkProvider/repo/1000", projection);
|
||||
|
||||
List<Apk> manyApks = new ArrayList<>(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(resolver, ApkProvider.getContentUri(manyApks), projection);
|
||||
|
||||
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(resolver, ApkProvider.getContentUri(manyApks), projection);
|
||||
fail();
|
||||
} catch (IllegalArgumentException e) {
|
||||
// This is the expected error behaviour.
|
||||
} catch (Exception e) {
|
||||
fail();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user