From 43f8ea08140e7cd072fbe83a139d528d75c57fd5 Mon Sep 17 00:00:00 2001 From: Peter Serwylo Date: Tue, 11 Feb 2014 07:34:01 +1100 Subject: [PATCH] Added category tests. This will be useful when somebody wants to move categories from a comma separated string in the app table, to a separate table all together. --- test/src/mock/MockCategoryResources.java | 21 +++ .../mock/MockContextSwappableComponents.java | 13 +- .../org/fdroid/fdroid/AppProviderTest.java | 160 +++++++++++++++--- .../org/fdroid/fdroid/FDroidProviderTest.java | 6 +- test/src/org/fdroid/fdroid/TestUtils.java | 30 ++++ 5 files changed, 208 insertions(+), 22 deletions(-) create mode 100644 test/src/mock/MockCategoryResources.java create mode 100644 test/src/org/fdroid/fdroid/TestUtils.java diff --git a/test/src/mock/MockCategoryResources.java b/test/src/mock/MockCategoryResources.java new file mode 100644 index 000000000..669ddd1d0 --- /dev/null +++ b/test/src/mock/MockCategoryResources.java @@ -0,0 +1,21 @@ +package mock; + +import android.test.mock.*; +import org.fdroid.fdroid.*; + +public class MockCategoryResources extends MockResources { + + @Override + public String getString(int id) { + if (id == R.string.category_all) { + return "All"; + } else if (id == R.string.category_recentlyupdated) { + return "Recently Updated"; + } else if (id == R.string.category_whatsnew) { + return "Whats New"; + } else { + return ""; + } +} + +} diff --git a/test/src/mock/MockContextSwappableComponents.java b/test/src/mock/MockContextSwappableComponents.java index 7fcbbf971..750adbed6 100644 --- a/test/src/mock/MockContextSwappableComponents.java +++ b/test/src/mock/MockContextSwappableComponents.java @@ -2,13 +2,14 @@ package mock; import android.content.pm.PackageManager; import android.content.res.Resources; -import android.test.mock.MockContext; +import android.test.mock.*; public class MockContextSwappableComponents extends MockContext { private PackageManager packageManager; private Resources resources; + private MockContentResolver contentResolver; public MockContextSwappableComponents setPackageManager(PackageManager pm) { packageManager = pm; @@ -20,6 +21,11 @@ public class MockContextSwappableComponents extends MockContext { return this; } + public MockContextSwappableComponents setContentResolver(MockContentResolver contentResolver) { + this.contentResolver = contentResolver; + return this; + } + @Override public PackageManager getPackageManager() { return packageManager; @@ -29,4 +35,9 @@ public class MockContextSwappableComponents extends MockContext { public Resources getResources() { return resources; } + + @Override + public MockContentResolver getContentResolver() { + return contentResolver; + } } diff --git a/test/src/org/fdroid/fdroid/AppProviderTest.java b/test/src/org/fdroid/fdroid/AppProviderTest.java index c1ccb7b9c..3252fd829 100644 --- a/test/src/org/fdroid/fdroid/AppProviderTest.java +++ b/test/src/org/fdroid/fdroid/AppProviderTest.java @@ -1,18 +1,18 @@ package org.fdroid.fdroid; import android.content.ContentValues; -import android.content.pm.PackageInfo; import android.database.Cursor; import android.net.Uri; -import android.provider.ContactsContract; +import junit.framework.AssertionFailedError; +import mock.MockCategoryResources; import mock.MockInstallablePackageManager; import org.fdroid.fdroid.data.ApkProvider; import org.fdroid.fdroid.data.App; import org.fdroid.fdroid.data.AppProvider; import java.util.ArrayList; +import java.util.Collections; import java.util.List; -import java.util.Map; public class AppProviderTest extends FDroidProviderTest { @@ -20,6 +20,13 @@ public class AppProviderTest extends FDroidProviderTest { super(AppProvider.class, AppProvider.getAuthority()); } + @Override + public void setUp() throws Exception { + super.setUp(); + getSwappableContext().setResources(new MockCategoryResources()); + getSwappableContext().setContentResolver(getMockContentResolver()); + } + protected String[] getMinimalProjection() { return new String[] { AppProvider.DataColumns.APP_ID, @@ -53,6 +60,12 @@ public class AppProviderTest extends FDroidProviderTest { assertNotNull(cursor); } + private void insertApps(int count) { + for (int i = 0; i < count; i ++) { + insertApp("com.example.test." + i, "Test app " + i); + } + } + public void testInstalled() { Utils.clearInstalledApksCache(); @@ -60,9 +73,7 @@ public class AppProviderTest extends FDroidProviderTest { MockInstallablePackageManager pm = new MockInstallablePackageManager(); getSwappableContext().setPackageManager(pm); - for (int i = 0; i < 100; i ++) { - insertApp("com.example.test." + i, "Test app " + i); - } + insertApps(100); assertAppCount(100, AppProvider.getContentUri()); assertAppCount(0, AppProvider.getInstalledUri()); @@ -75,7 +86,7 @@ public class AppProviderTest extends FDroidProviderTest { } private void assertAppCount(int expectedCount, Uri uri) { - Cursor cursor = getProvider().query(uri, getMinimalProjection(), null, null, null); + Cursor cursor = getMockContentResolver().query(uri, getMinimalProjection(), null, null, null); assertNotNull(cursor); assertEquals(expectedCount, cursor.getCount()); } @@ -114,25 +125,134 @@ public class AppProviderTest extends FDroidProviderTest { } private Cursor queryAllApps() { - return getProvider().query(AppProvider.getContentUri(), getMinimalProjection(), null, null, null); + return getMockContentResolver().query(AppProvider.getContentUri(), getMinimalProjection(), null, null, null); + } + + public void testCategoriesSingle() { + insertAppWithCategory("com.dog", "Dog", "Animal"); + insertAppWithCategory("com.rock", "Rock", "Mineral"); + insertAppWithCategory("com.banana", "Banana", "Vegetable"); + + List categories = AppProvider.Helper.categories(getMockContext()); + String[] expected = new String[] { + getMockContext().getResources().getString(R.string.category_whatsnew), + getMockContext().getResources().getString(R.string.category_recentlyupdated), + getMockContext().getResources().getString(R.string.category_all), + "Animal", + "Mineral", + "Vegetable" + }; + assertContainsOnly(categories, expected); + } + + public void testCategoriesMultiple() { + insertAppWithCategory("com.rock.dog", "Rock-Dog", "Mineral,Animal"); + insertAppWithCategory("com.dog.rock.apple", "Dog-Rock-Apple", "Animal,Mineral,Vegetable"); + insertAppWithCategory("com.banana.apple", "Banana", "Vegetable,Vegetable"); + + List categories = AppProvider.Helper.categories(getMockContext()); + String[] expected = new String[] { + getMockContext().getResources().getString(R.string.category_whatsnew), + getMockContext().getResources().getString(R.string.category_recentlyupdated), + getMockContext().getResources().getString(R.string.category_all), + + "Animal", + "Mineral", + "Vegetable" + }; + assertContainsOnly(categories, expected); + + insertAppWithCategory("com.example.game", "Game", + "Running,Shooting,Jumping,Bleh,Sneh,Pleh,Blah,Test category," + + "The quick brown fox jumps over the lazy dog,With apostrophe's"); + + List categoriesLonger = AppProvider.Helper.categories(getMockContext()); + String[] expectedLonger = new String[] { + getMockContext().getResources().getString(R.string.category_whatsnew), + getMockContext().getResources().getString(R.string.category_recentlyupdated), + getMockContext().getResources().getString(R.string.category_all), + + "Animal", + "Mineral", + "Vegetable", + + "Running", + "Shooting", + "Jumping", + "Bleh", + "Sneh", + "Pleh", + "Blah", + "Test category", + "The quick brown fox jumps over the lazy dog", + "With apostrophe's" + }; + + assertContainsOnly(categoriesLonger, expectedLonger); } private void insertApp(String id, String name) { - ContentValues values = new ContentValues(2); - values.put(AppProvider.DataColumns.APP_ID, id); - values.put(AppProvider.DataColumns.NAME, name); + insertApp(id, name, new ContentValues()); + } - // 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); + private void insertAppWithCategory(String id, String name, + String categories) { + ContentValues values = new ContentValues(1); + values.put(AppProvider.DataColumns.CATEGORIES, categories); + insertApp(id, name, values); + } - Uri uri = AppProvider.getContentUri(); + private void insertApp(String id, String name, + ContentValues additionalValues) { + TestUtils.insertApp(getMockContentResolver(), id, name, additionalValues); + } - getProvider().insert(uri, values); + private void assertContainsOnly(List actualList, T[] expectedContains) { + List containsList = new ArrayList(expectedContains.length); + Collections.addAll(containsList, expectedContains); + assertContainsOnly(actualList, containsList); + } + + private String listToString(List list) { + String string = "["; + for (int i = 0; i < list.size(); i ++) { + if (i > 0) { + string += ", "; + } + string += list.get(i); + } + string += "]"; + return string; + } + + private void assertContainsOnly(List actualList, List 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); + } + } } } diff --git a/test/src/org/fdroid/fdroid/FDroidProviderTest.java b/test/src/org/fdroid/fdroid/FDroidProviderTest.java index eaaa84e57..776202ba0 100644 --- a/test/src/org/fdroid/fdroid/FDroidProviderTest.java +++ b/test/src/org/fdroid/fdroid/FDroidProviderTest.java @@ -53,13 +53,17 @@ public abstract class FDroidProviderTest extends Provi protected void assertInvalidUri(Uri uri) { try { + // Use getProvdider instead of getContentResolver, because the mock + // content resolver wont result in the provider we are testing, and + // hence we don't get to see how our provider responds to invalid + // uris. getProvider().query(uri, getMinimalProjection(), null, null, null); fail(); } catch (UnsupportedOperationException e) {} } protected void assertValidUri(Uri uri) { - Cursor cursor = getProvider().query(uri, getMinimalProjection(), null, null, null); + Cursor cursor = getMockContentResolver().query(uri, getMinimalProjection(), null, null, null); assertNotNull(cursor); } diff --git a/test/src/org/fdroid/fdroid/TestUtils.java b/test/src/org/fdroid/fdroid/TestUtils.java new file mode 100644 index 000000000..a01f85460 --- /dev/null +++ b/test/src/org/fdroid/fdroid/TestUtils.java @@ -0,0 +1,30 @@ +package org.fdroid.fdroid; + +import android.content.*; +import android.net.Uri; +import org.fdroid.fdroid.data.AppProvider; + +public class TestUtils { + + public static void insertApp(ContentResolver resolver, String id, String name, ContentValues additionalValues) { + + ContentValues values = new ContentValues(); + values.put(AppProvider.DataColumns.APP_ID, 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); + } + +}