diff --git a/app/build.gradle b/app/build.gradle index 8fd669d5d..bb41a86ed 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -41,6 +41,9 @@ dependencies { testCompile 'junit:junit:4.12' + // 3.1-rc1 is required because it is the first to implements API v23. + testCompile "org.robolectric:robolectric:3.1-rc1" + androidTestCompile 'com.android.support:support-annotations:23.4.0' androidTestCompile 'com.android.support.test:runner:0.5' androidTestCompile 'com.android.support.test:rules:0.5' diff --git a/app/src/androidTest/java/org/fdroid/fdroid/data/AppProviderTest.java b/app/src/androidTest/java/org/fdroid/fdroid/data/AppProviderTest.java index 454759c0e..0bce53b68 100644 --- a/app/src/androidTest/java/org/fdroid/fdroid/data/AppProviderTest.java +++ b/app/src/androidTest/java/org/fdroid/fdroid/data/AppProviderTest.java @@ -131,7 +131,7 @@ public class AppProviderTest extends FDroidProviderTest { 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 { 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()); diff --git a/app/src/androidTest/java/org/fdroid/fdroid/data/InstalledAppProviderTest.java b/app/src/androidTest/java/org/fdroid/fdroid/data/InstalledAppProviderTest.java deleted file mode 100644 index 7da03fcd0..000000000 --- a/app/src/androidTest/java/org/fdroid/fdroid/data/InstalledAppProviderTest.java +++ /dev/null @@ -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 { - - 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); - } - -} diff --git a/app/src/androidTest/java/org/fdroid/fdroid/data/InstalledAppTestUtils.java b/app/src/androidTest/java/org/fdroid/fdroid/data/InstalledAppTestUtils.java new file mode 100644 index 000000000..77959530c --- /dev/null +++ b/app/src/androidTest/java/org/fdroid/fdroid/data/InstalledAppTestUtils.java @@ -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); + } + +} diff --git a/app/src/test/java/org/fdroid/fdroid/TestFDroidApp.java b/app/src/test/java/org/fdroid/fdroid/TestFDroidApp.java new file mode 100644 index 000000000..b0fcd8319 --- /dev/null +++ b/app/src/test/java/org/fdroid/fdroid/TestFDroidApp.java @@ -0,0 +1,11 @@ +package org.fdroid.fdroid; + +import android.app.Application; + +/** + * Due to there being so much static initialization in the main FDroidApp, it becomes hard to reset + * that state between Robolectric test runs. Therefore, robolectric tests will default to this + * {@link Application} instead of {@link FDroidApp}. It intentionally doesn't extends {@link FDroidApp} + * so that the static initialization in {@link FDroidApp#onCreate()} is not executed. + */ +public class TestFDroidApp extends Application {} diff --git a/app/src/test/java/org/fdroid/fdroid/data/InstalledAppProviderTest.java b/app/src/test/java/org/fdroid/fdroid/data/InstalledAppProviderTest.java new file mode 100644 index 000000000..75a4dcded --- /dev/null +++ b/app/src/test/java/org/fdroid/fdroid/data/InstalledAppProviderTest.java @@ -0,0 +1,200 @@ +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.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricGradleTestRunner; +import org.robolectric.RuntimeEnvironment; +import org.robolectric.Shadows; +import org.robolectric.annotation.Config; +import org.robolectric.shadows.ShadowContentResolver; + +import static org.fdroid.fdroid.data.ProviderTestUtils.assertIsInstalledVersionInDb; +import static org.fdroid.fdroid.data.ProviderTestUtils.assertResultCount; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.util.Map; + +@Config(constants = BuildConfig.class, application = Application.class) +@RunWith(RobolectricGradleTestRunner.class) +public class InstalledAppProviderTest { + + private ShadowContentResolver contentResolver; + + @Before + public void setup() { + contentResolver = Shadows.shadowOf(RuntimeEnvironment.application.getContentResolver()); + ShadowContentResolver.registerProvider(InstalledAppProvider.getAuthority(), new InstalledAppProvider()); + } + + @After + public void teardown() { + FDroidProvider.clearDbHelperSingleton(); + } + + @Test + public void insertSingleApp() { + Map foundBefore = InstalledAppProvider.Helper.all(RuntimeEnvironment.application); + assertEquals(foundBefore.size(), 0); + + ContentValues values = new ContentValues(); + values.put(InstalledAppProvider.DataColumns.PACKAGE_NAME, "org.example.test-app"); + values.put(InstalledAppProvider.DataColumns.APPLICATION_LABEL, "Test App"); + values.put(InstalledAppProvider.DataColumns.VERSION_CODE, 1021); + values.put(InstalledAppProvider.DataColumns.VERSION_NAME, "Longhorn"); + values.put(InstalledAppProvider.DataColumns.HASH, "has of test app"); + values.put(InstalledAppProvider.DataColumns.HASH_TYPE, "fake hash type"); + values.put(InstalledAppProvider.DataColumns.LAST_UPDATE_TIME, 100000000L); + values.put(InstalledAppProvider.DataColumns.SIGNATURE, "000111222333444555666777888999aaabbbcccdddeeefff"); + contentResolver.insert(InstalledAppProvider.getContentUri(), values); + + Map foundAfter = InstalledAppProvider.Helper.all(RuntimeEnvironment.application); + assertEquals(1, foundAfter.size()); + assertEquals(100000000L, foundAfter.get("org.example.test-app").longValue()); + + Cursor cursor = contentResolver.query(InstalledAppProvider.getAppUri("org.example.test-app"), InstalledAppProvider.DataColumns.ALL, null, null, null); + assertEquals(cursor.getCount(), 1); + + cursor.moveToFirst(); + assertEquals("org.example.test-app", cursor.getString(cursor.getColumnIndex(InstalledAppProvider.DataColumns.PACKAGE_NAME))); + assertEquals("Test App", cursor.getString(cursor.getColumnIndex(InstalledAppProvider.DataColumns.APPLICATION_LABEL))); + assertEquals(1021, cursor.getInt(cursor.getColumnIndex(InstalledAppProvider.DataColumns.VERSION_CODE))); + assertEquals("Longhorn", cursor.getString(cursor.getColumnIndex(InstalledAppProvider.DataColumns.VERSION_NAME))); + assertEquals("has of test app", cursor.getString(cursor.getColumnIndex(InstalledAppProvider.DataColumns.HASH))); + assertEquals("fake hash type", cursor.getString(cursor.getColumnIndex(InstalledAppProvider.DataColumns.HASH_TYPE))); + assertEquals(100000000L, cursor.getLong(cursor.getColumnIndex(InstalledAppProvider.DataColumns.LAST_UPDATE_TIME))); + assertEquals("000111222333444555666777888999aaabbbcccdddeeefff", cursor.getString(cursor.getColumnIndex(InstalledAppProvider.DataColumns.SIGNATURE))); + + cursor.close(); + } + + @Test + public void testInsert() { + + assertResultCount(contentResolver, 0, InstalledAppProvider.getContentUri()); + + insertInstalledApp("com.example.com1", 1, "v1"); + insertInstalledApp("com.example.com2", 2, "v2"); + insertInstalledApp("com.example.com3", 3, "v3"); + + assertResultCount(contentResolver, 3, InstalledAppProvider.getContentUri()); + assertIsInstalledVersionInDb(contentResolver, "com.example.com1", 1, "v1"); + assertIsInstalledVersionInDb(contentResolver, "com.example.com2", 2, "v2"); + assertIsInstalledVersionInDb(contentResolver, "com.example.com3", 3, "v3"); + } + + @Test + public void testUpdate() { + + insertInstalledApp("com.example.app1", 10, "1.0"); + insertInstalledApp("com.example.app2", 10, "1.0"); + + assertResultCount(contentResolver, 2, InstalledAppProvider.getContentUri()); + assertIsInstalledVersionInDb(contentResolver, "com.example.app2", 10, "1.0"); + + try { + contentResolver.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. + } + + contentResolver.insert( + InstalledAppProvider.getContentUri(), + createContentValues("com.example.app2", 11, "1.1") + ); + + assertResultCount(contentResolver, 2, InstalledAppProvider.getContentUri()); + assertIsInstalledVersionInDb(contentResolver, "com.example.app2", 11, "1.1"); + + } + + @Test + public void testLastUpdateTime() { + String packageName = "com.example.app"; + + insertInstalledApp(packageName, 10, "1.0"); + assertResultCount(contentResolver, 1, InstalledAppProvider.getContentUri()); + assertIsInstalledVersionInDb(contentResolver, packageName, 10, "1.0"); + + Uri uri = InstalledAppProvider.getAppUri(packageName); + + String[] projection = { + InstalledAppProvider.DataColumns.PACKAGE_NAME, + InstalledAppProvider.DataColumns.LAST_UPDATE_TIME, + }; + + Cursor cursor = contentResolver.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 = contentResolver.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(); + } + + @Test + public void testDelete() { + + insertInstalledApp("com.example.app1", 10, "1.0"); + insertInstalledApp("com.example.app2", 10, "1.0"); + + assertResultCount(contentResolver, 2, InstalledAppProvider.getContentUri()); + + contentResolver.delete(InstalledAppProvider.getAppUri("com.example.app1"), null, null); + + assertResultCount(contentResolver, 1, InstalledAppProvider.getContentUri()); + assertIsInstalledVersionInDb(contentResolver, "com.example.app2", 10, "1.0"); + + } + + 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); + contentResolver.insert(InstalledAppProvider.getContentUri(), values); + } +} + +// https://github.com/robolectric/robolectric/wiki/2.4-to-3.0-Upgrade-Guide diff --git a/app/src/test/java/org/fdroid/fdroid/data/ProviderTestUtils.java b/app/src/test/java/org/fdroid/fdroid/data/ProviderTestUtils.java new file mode 100644 index 000000000..9c3b2cc4b --- /dev/null +++ b/app/src/test/java/org/fdroid/fdroid/data/ProviderTestUtils.java @@ -0,0 +1,103 @@ +package org.fdroid.fdroid.data; + +import android.content.ContentValues; +import android.database.Cursor; +import android.net.Uri; + +import org.robolectric.shadows.ShadowContentResolver; + +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.fail; + +public class ProviderTestUtils { + + public static void assertCantDelete(ShadowContentResolver resolver, Uri uri) { + try { + resolver.delete(uri, null, null); + fail(); + } catch (UnsupportedOperationException e) { + // Successful condition + } catch (Exception e) { + fail(); + } + } + + public static void assertCantUpdate(ShadowContentResolver resolver, Uri uri) { + try { + resolver.update(uri, new ContentValues(), null, null); + fail(); + } catch (UnsupportedOperationException e) { + // Successful condition + } catch (Exception e) { + fail(); + } + } + + public static void assertInvalidUri(ShadowContentResolver resolver, String uri) { + assertInvalidUri(resolver, Uri.parse(uri)); + } + + public static void assertValidUri(ShadowContentResolver resolver, String uri, String[] projection) { + assertValidUri(resolver, Uri.parse(uri), projection); + } + + public static void assertInvalidUri(ShadowContentResolver resolver, Uri uri) { + Cursor cursor = resolver.query(uri, new String[] {}, null, null, null); + assertNull(cursor); + } + + public static void assertValidUri(ShadowContentResolver resolver, Uri uri, String[] projection) { + Cursor cursor = resolver.query(uri, projection, null, null, null); + assertNotNull(cursor); + cursor.close(); + } + + public static void assertValidUri(ShadowContentResolver resolver, Uri actualUri, String expectedUri, String[] projection) { + assertValidUri(resolver, actualUri, projection); + assertEquals(expectedUri, actualUri.toString()); + } + + public static void assertResultCount(ShadowContentResolver resolver, int expectedCount, Uri uri) { + Cursor cursor = resolver.query(uri, new String[] {}, null, null, null); + assertResultCount(expectedCount, cursor); + cursor.close(); + } + + public static void assertResultCount(int expectedCount, List items) { + assertNotNull(items); + assertEquals(expectedCount, items.size()); + } + + public static void assertResultCount(int expectedCount, Cursor result) { + assertNotNull(result); + assertEquals(expectedCount, result.getCount()); + } + + public static void assertIsInstalledVersionInDb(ShadowContentResolver resolver, String appId, int versionCode, String versionName) { + Uri uri = InstalledAppProvider.getAppUri(appId); + + String[] projection = { + InstalledAppProvider.DataColumns.PACKAGE_NAME, + InstalledAppProvider.DataColumns.VERSION_CODE, + InstalledAppProvider.DataColumns.VERSION_NAME, + InstalledAppProvider.DataColumns.APPLICATION_LABEL, + }; + + Cursor cursor = resolver.query(uri, projection, null, null, null); + + assertNotNull(cursor); + assertEquals("App \"" + appId + "\" not installed", 1, cursor.getCount()); + + cursor.moveToFirst(); + + assertEquals(appId, cursor.getString(cursor.getColumnIndex(InstalledAppProvider.DataColumns.PACKAGE_NAME))); + assertEquals(versionCode, cursor.getInt(cursor.getColumnIndex(InstalledAppProvider.DataColumns.VERSION_CODE))); + assertEquals(versionName, cursor.getString(cursor.getColumnIndex(InstalledAppProvider.DataColumns.VERSION_NAME))); + cursor.close(); + } + +} diff --git a/app/src/test/java/org/fdroid/fdroid/data/ProviderUriTests.java b/app/src/test/java/org/fdroid/fdroid/data/ProviderUriTests.java new file mode 100644 index 000000000..c62aa465b --- /dev/null +++ b/app/src/test/java/org/fdroid/fdroid/data/ProviderUriTests.java @@ -0,0 +1,69 @@ +package org.fdroid.fdroid.data; + +import org.fdroid.fdroid.BuildConfig; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricGradleTestRunner; +import org.robolectric.RuntimeEnvironment; +import org.robolectric.Shadows; +import org.robolectric.annotation.Config; +import org.robolectric.shadows.ShadowContentResolver; + +import static org.fdroid.fdroid.data.ProviderTestUtils.assertInvalidUri; +import static org.fdroid.fdroid.data.ProviderTestUtils.assertValidUri; + +@Config(constants = BuildConfig.class) +@RunWith(RobolectricGradleTestRunner.class) +public class ProviderUriTests { + + private ShadowContentResolver resolver; + + @Before + public void setup() { + resolver = Shadows.shadowOf(RuntimeEnvironment.application.getContentResolver()); + } + + @After + public void teardown() { + FDroidProvider.clearDbHelperSingleton(); + } + + @Test + public void invalidInstalledAppProviderUris() { + ShadowContentResolver.registerProvider(InstalledAppProvider.getAuthority(), new InstalledAppProvider()); + assertInvalidUri(resolver, InstalledAppProvider.getAuthority()); + assertInvalidUri(resolver, "blah"); + } + + @Test + public void validInstalledAppProviderUris() { + ShadowContentResolver.registerProvider(InstalledAppProvider.getAuthority(), new InstalledAppProvider()); + String[] projection = new String[] { InstalledAppProvider.DataColumns._ID }; + assertValidUri(resolver, InstalledAppProvider.getContentUri(), projection); + assertValidUri(resolver, InstalledAppProvider.getAppUri("org.example.app"), projection); + assertValidUri(resolver, InstalledAppProvider.getSearchUri("blah"), projection); + assertValidUri(resolver, InstalledAppProvider.getSearchUri("\"blah\""), projection); + assertValidUri(resolver, InstalledAppProvider.getSearchUri("blah & sneh"), projection); + assertValidUri(resolver, InstalledAppProvider.getSearchUri("http://blah.example.com?sneh=\"sneh\""), projection); + } + + @Test + public void invalidRepoProviderUris() { + ShadowContentResolver.registerProvider(RepoProvider.getAuthority(), new RepoProvider()); + assertInvalidUri(resolver, RepoProvider.getAuthority()); + assertInvalidUri(resolver, "blah"); + } + + @Test + public void validRepoProviderUris() { + ShadowContentResolver.registerProvider(RepoProvider.getAuthority(), new RepoProvider()); + String[] projection = new String[] { RepoProvider.DataColumns._ID }; + assertValidUri(resolver, RepoProvider.getContentUri(), projection); + assertValidUri(resolver, RepoProvider.getContentUri(10000L), projection); + assertValidUri(resolver, RepoProvider.allExceptSwapUri(), projection); + } + } + +}