Finish porting tests to Robolectric, and appease PMD.
To appease PMD, we now have a three rulesets in `config/pmd/*.xml`: * `rules.xml`: The bulk of the rules, used by both main and test code. * `rules-main.xml`: Rules specific to the andoid client code. * `rules-test.xml`: Rules specific to test code. The rationale is because checkstyle by default checks for "too many static imports", which is a fair call. However in JUnit4 code, it is common to import many `assert*` static methods.
This commit is contained in:
		
							parent
							
								
									253900e927
								
							
						
					
					
						commit
						4e73d1e5e6
					
				| @ -230,13 +230,22 @@ pmd { | ||||
|     consoleOutput = true | ||||
| } | ||||
| 
 | ||||
| task pmd(type: Pmd, dependsOn: assembleDebug) { | ||||
|     ruleSetFiles = files("${project.rootDir}/config/pmd/rules.xml") | ||||
| task pmdMain(type: Pmd, dependsOn: assembleDebug) { | ||||
|     ruleSetFiles = files("${project.rootDir}/config/pmd/rules.xml", "${project.rootDir}/config/pmd/rules-main.xml") | ||||
|     ruleSets = [] // otherwise defaults clash with the list in rules.xml | ||||
|     source 'src/main/java', 'src/test/java', 'src/androidTest/java' | ||||
|     source 'src/main/java' | ||||
|     include '**/*.java' | ||||
| } | ||||
| 
 | ||||
| task pmdTest(type: Pmd, dependsOn: assembleDebug) { | ||||
|     ruleSetFiles = files("${project.rootDir}/config/pmd/rules.xml", "${project.rootDir}/config/pmd/rules-test.xml") | ||||
|     ruleSets = [] // otherwise defaults clash with the list in rules.xml | ||||
|     source 'src/test/java', 'src/androidTest/java' | ||||
|     include '**/*.java' | ||||
| } | ||||
| 
 | ||||
| task pmd(dependsOn: [pmdMain, pmdTest]) {} | ||||
| 
 | ||||
| // This person took the example code below from another blogpost online, however | ||||
| // I lost the reference to it: | ||||
| // http://stackoverflow.com/questions/23297562/gradle-javadoc-and-android-documentation | ||||
|  | ||||
										
											Binary file not shown.
										
									
								
							| @ -1,257 +0,0 @@ | ||||
| /* | ||||
|  * Copyright (C) 2007 The Android Open Source Project | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  *      http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  */ | ||||
| 
 | ||||
| package android.test; | ||||
| 
 | ||||
| import android.annotation.TargetApi; | ||||
| import android.content.ContentProvider; | ||||
| import android.content.ContentResolver; | ||||
| import android.content.Context; | ||||
| import android.content.ContextWrapper; | ||||
| import android.content.res.Resources; | ||||
| import android.database.DatabaseUtils; | ||||
| import android.os.Build; | ||||
| import android.test.mock.MockContentResolver; | ||||
| import android.test.mock.MockContext; | ||||
| 
 | ||||
| import org.junit.After; | ||||
| import org.junit.Before; | ||||
| 
 | ||||
| import java.io.File; | ||||
| 
 | ||||
| /** | ||||
|  * This test case class provides a framework for testing a single | ||||
|  * {@link ContentProvider} and for testing your app code with an | ||||
|  * isolated content provider. Instead of using the system map of | ||||
|  * providers that is based on the manifests of other applications, the test | ||||
|  * case creates its own internal map. It then uses this map to resolve providers | ||||
|  * given an authority. This allows you to inject test providers and to null out | ||||
|  * providers that you do not want to use. | ||||
|  * <p> | ||||
|  *      This test case also sets up the following mock objects: | ||||
|  * </p> | ||||
|  * <ul> | ||||
|  *      <li> | ||||
|  *          An {@link android.test.IsolatedContext} that stubs out Context methods that might | ||||
|  *          affect the rest of the running system, while allowing tests to do real file and | ||||
|  *          database work. | ||||
|  *      </li> | ||||
|  *      <li> | ||||
|  *          A {@link android.test.mock.MockContentResolver} that provides the functionality of a | ||||
|  *          regular content resolver, but uses {@link IsolatedContext}. It stubs out | ||||
|  *          {@link ContentResolver#notifyChange(Uri, ContentObserver, boolean)} to | ||||
|  *          prevent the test from affecting the running system. | ||||
|  *      </li> | ||||
|  *      <li> | ||||
|  *          An instance of the provider under test, running in an {@link IsolatedContext}. | ||||
|  *      </li> | ||||
|  * </ul> | ||||
|  * <p> | ||||
|  *      This framework is set up automatically by the base class' {@link #setUp()} method. If you | ||||
|  *      override this method, you must call the super method as the first statement in | ||||
|  *      your override. | ||||
|  * </p> | ||||
|  * <p> | ||||
|  *     In order for their tests to be run, concrete subclasses must provide their own | ||||
|  *     constructor with no arguments. This constructor must call | ||||
|  *     {@link #ProviderTestCase2MockContext(Class, String)} as  its first operation. | ||||
|  * </p> | ||||
|  * For more information on content provider testing, please see | ||||
|  * <a href="{@docRoot}tools/testing/contentprovider_testing.html">Content Provider Testing</a>. | ||||
|  */ | ||||
| public abstract class ProviderTestCase2MockContext<T extends ContentProvider> extends AndroidTestCase { | ||||
| 
 | ||||
|     Class<T> mProviderClass; | ||||
|     String mProviderAuthority; | ||||
| 
 | ||||
|     private IsolatedContext mProviderContext; | ||||
|     private MockContentResolver mResolver; | ||||
| 
 | ||||
|     private class MockContext2 extends MockContext { | ||||
| 
 | ||||
|         @Override | ||||
|         public Resources getResources() { | ||||
|             return getContext().getResources(); | ||||
|         } | ||||
| 
 | ||||
|         @Override | ||||
|         public File getDir(String name, int mode) { | ||||
|             // name the directory so the directory will be separated from | ||||
|             // one created through the regular Context | ||||
|             return getContext().getDir("mockcontext2_" + name, mode); | ||||
|         } | ||||
| 
 | ||||
|         @Override | ||||
|         public Context getApplicationContext() { | ||||
|             return this; | ||||
|         } | ||||
| 
 | ||||
|         @Override | ||||
|         public String getPackageName() { | ||||
|             return "org.fdroid.fdroid"; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Constructor. | ||||
|      * | ||||
|      * @param providerClass The class name of the provider under test | ||||
|      * @param providerAuthority The provider's authority string | ||||
|      */ | ||||
|     public ProviderTestCase2MockContext(Class<T> providerClass, String providerAuthority) { | ||||
|         mProviderClass = providerClass; | ||||
|         mProviderAuthority = providerAuthority; | ||||
|     } | ||||
| 
 | ||||
|     private T mProvider; | ||||
| 
 | ||||
|     /** | ||||
|      * Returns the content provider created by this class in the {@link #setUp()} method. | ||||
|      * @return T An instance of the provider class given as a parameter to the test case class. | ||||
|      */ | ||||
|     public T getProvider() { | ||||
|         return mProvider; | ||||
|     } | ||||
| 
 | ||||
|     protected abstract Context createMockContext(Context delegate); | ||||
| 
 | ||||
|     /** | ||||
|      * Sets up the environment for the test fixture. | ||||
|      * <p> | ||||
|      * Creates a new | ||||
|      * {@link android.test.mock.MockContentResolver}, a new IsolatedContext | ||||
|      * that isolates the provider's file operations, and a new instance of | ||||
|      * the provider under test within the isolated environment. | ||||
|      * </p> | ||||
|      * | ||||
|      * @throws Exception | ||||
|      */ | ||||
|     @Override | ||||
|     @Before | ||||
|     protected void setUp() throws Exception { | ||||
|         super.setUp(); | ||||
| 
 | ||||
|         mResolver = new MockContentResolver(); | ||||
|         final String filenamePrefix = "test."; | ||||
|         final RenamingDelegatingContext targetContextWrapper = new | ||||
|                 RenamingDelegatingContext( | ||||
|                 createMockContext(new MockContext2()), // The context that most methods are delegated to | ||||
|                 getContext(), // The context that file methods are delegated to | ||||
|                 filenamePrefix); | ||||
| 
 | ||||
|         mProviderContext = new IsolatedContext(mResolver, new ContextWrapper(targetContextWrapper) { | ||||
|             // The FDroidProvider class needs access to an application context in order to initialize | ||||
|             // the singleton DBHelper instance. | ||||
|             @Override | ||||
|             public Context getApplicationContext() { | ||||
|                 return targetContextWrapper; | ||||
|             } | ||||
|         }); | ||||
| 
 | ||||
|         mProvider = mProviderClass.newInstance(); | ||||
|         mProvider.attachInfo(mProviderContext, null); | ||||
|         assertNotNull(mProvider); | ||||
|         mResolver.addProvider(mProviderAuthority, getProvider()); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Tears down the environment for the test fixture. | ||||
|      * <p> | ||||
|      * Calls {@link android.content.ContentProvider#shutdown()} on the | ||||
|      * {@link android.content.ContentProvider} represented by mProvider. | ||||
|      */ | ||||
|     @Override | ||||
|     @After | ||||
|     protected void tearDown() throws Exception { | ||||
|         shutdownProvider(); | ||||
|         super.tearDown(); | ||||
|     } | ||||
| 
 | ||||
|     @TargetApi(Build.VERSION_CODES.HONEYCOMB) | ||||
|     private void shutdownProvider() { | ||||
|         if (Build.VERSION.SDK_INT >= 11) { | ||||
|             mProvider.shutdown(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Gets the {@link MockContentResolver} created by this class during initialization. You | ||||
|      * must use the methods of this resolver to access the provider under test. | ||||
|      * | ||||
|      * @return A {@link MockContentResolver} instance. | ||||
|      */ | ||||
|     public MockContentResolver getMockContentResolver() { | ||||
|         return mResolver; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Gets the {@link IsolatedContext} created by this class during initialization. | ||||
|      * @return The {@link IsolatedContext} instance | ||||
|      */ | ||||
|     public IsolatedContext getMockContext() { | ||||
|         return mProviderContext; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * <p> | ||||
|      *      Creates a new content provider of the same type as that passed to the test case class, | ||||
|      *      with an authority name set to the authority parameter, and using an SQLite database as | ||||
|      *      the underlying data source. The SQL statement parameter is used to create the database. | ||||
|      *      This method also creates a new {@link MockContentResolver} and adds the provider to it. | ||||
|      * </p> | ||||
|      * <p> | ||||
|      *      Both the new provider and the new resolver are put into an {@link IsolatedContext} | ||||
|      *      that uses the targetContext parameter for file operations and a {@link MockContext} | ||||
|      *      for everything else. The IsolatedContext prepends the filenamePrefix parameter to | ||||
|      *      file, database, and directory names. | ||||
|      * </p> | ||||
|      * <p> | ||||
|      *      This is a convenience method for creating a "mock" provider that can contain test data. | ||||
|      * </p> | ||||
|      * | ||||
|      * @param targetContext The context to use as the basis of the IsolatedContext | ||||
|      * @param filenamePrefix A string that is prepended to file, database, and directory names | ||||
|      * @param providerClass The type of the provider being tested | ||||
|      * @param authority The authority string to associated with the test provider | ||||
|      * @param databaseName The name assigned to the database | ||||
|      * @param databaseVersion The version assigned to the database | ||||
|      * @param sql A string containing the SQL statements that are needed to create the desired | ||||
|      * database and its tables. The format is the same as that generated by the | ||||
|      * <a href="http://www.sqlite.org/sqlite.html">sqlite3</a> tool's <code>.dump</code> command. | ||||
|      * @return ContentResolver A new {@link MockContentResolver} linked to the provider | ||||
|      * | ||||
|      * @throws IllegalAccessException | ||||
|      * @throws InstantiationException | ||||
|      */ | ||||
|     public static <T extends ContentProvider> ContentResolver newResolverWithContentProviderFromSql( | ||||
|             Context targetContext, String filenamePrefix, Class<T> providerClass, String authority, | ||||
|             String databaseName, int databaseVersion, String sql) | ||||
|             throws IllegalAccessException, InstantiationException { | ||||
|         MockContentResolver resolver = new MockContentResolver(); | ||||
|         RenamingDelegatingContext targetContextWrapper = new RenamingDelegatingContext( | ||||
|                 new MockContext(), // The context that most methods are delegated to | ||||
|                 targetContext, // The context that file methods are delegated to | ||||
|                 filenamePrefix); | ||||
|         Context context = new IsolatedContext(resolver, targetContextWrapper); | ||||
|         DatabaseUtils.createDbFromSqlStatements(context, databaseName, databaseVersion, sql); | ||||
| 
 | ||||
|         T provider = providerClass.newInstance(); | ||||
|         provider.attachInfo(context, null); | ||||
|         resolver.addProvider(authority, provider); | ||||
| 
 | ||||
|         return resolver; | ||||
|     } | ||||
| } | ||||
| @ -1,7 +1,10 @@ | ||||
| package org.fdroid.fdroid; | ||||
| 
 | ||||
| import android.app.Instrumentation; | ||||
| import android.content.Context; | ||||
| import android.os.Build; | ||||
| import android.os.Environment; | ||||
| import android.support.annotation.Nullable; | ||||
| import android.support.test.InstrumentationRegistry; | ||||
| import android.support.test.runner.AndroidJUnit4; | ||||
| import android.util.Log; | ||||
| @ -14,10 +17,15 @@ import org.junit.Test; | ||||
| import org.junit.runner.RunWith; | ||||
| 
 | ||||
| import java.io.File; | ||||
| import java.io.FileOutputStream; | ||||
| import java.io.IOException; | ||||
| import java.io.InputStream; | ||||
| import java.io.OutputStream; | ||||
| import java.util.UUID; | ||||
| 
 | ||||
| import static org.junit.Assert.assertFalse; | ||||
| import static org.junit.Assert.assertTrue; | ||||
| import static org.junit.Assume.assumeTrue; | ||||
| 
 | ||||
| 
 | ||||
| /** | ||||
| @ -36,8 +44,8 @@ public class FileCompatTest { | ||||
|     @Before | ||||
|     public void setUp() { | ||||
|         Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation(); | ||||
|         File dir = TestUtilsOld.getWriteableDir(instrumentation); | ||||
|         sourceFile = SanitizedFile.knownSanitized(TestUtilsOld.copyAssetToDir(instrumentation.getContext(), "simpleIndex.jar", dir)); | ||||
|         File dir = getWriteableDir(instrumentation); | ||||
|         sourceFile = SanitizedFile.knownSanitized(copyAssetToDir(instrumentation.getContext(), "simpleIndex.jar", dir)); | ||||
|         destFile = new SanitizedFile(dir, "dest-" + UUID.randomUUID() + ".testproduct"); | ||||
|         assertFalse(destFile.exists()); | ||||
|         assertTrue(sourceFile.getAbsolutePath() + " should exist.", sourceFile.exists()); | ||||
| @ -62,24 +70,70 @@ public class FileCompatTest { | ||||
| 
 | ||||
|     @Test | ||||
|     public void testSymlinkLibcore() { | ||||
| 
 | ||||
|         if (Build.VERSION.SDK_INT >= 19) { | ||||
|             FileCompatForTest.symlinkLibcoreTest(sourceFile, destFile); | ||||
|             assertTrue(destFile.getAbsolutePath() + " should exist after symlinking", destFile.exists()); | ||||
|         } else { | ||||
|             Log.w(TAG, "Cannot test symlink-libcore on this device. Requires android-19, but this has android-" + Build.VERSION.SDK_INT); | ||||
|         } | ||||
|         assumeTrue(Build.VERSION.SDK_INT >= 19); | ||||
|         FileCompatForTest.symlinkLibcoreTest(sourceFile, destFile); | ||||
|         assertTrue(destFile.getAbsolutePath() + " should exist after symlinking", destFile.exists()); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void testSymlinkOs() { | ||||
| 
 | ||||
|         if (Build.VERSION.SDK_INT >= 21) { | ||||
|             FileCompatForTest.symlinkOsTest(sourceFile, destFile); | ||||
|             assertTrue(destFile.getAbsolutePath() + " should exist after symlinking", destFile.exists()); | ||||
|         } else { | ||||
|             Log.w(TAG, "Cannot test symlink-os on this device. Requires android-21, but only has android-" + Build.VERSION.SDK_INT); | ||||
|         } | ||||
|         assumeTrue(Build.VERSION.SDK_INT >= 21); | ||||
|         FileCompatForTest.symlinkOsTest(sourceFile, destFile); | ||||
|         assertTrue(destFile.getAbsolutePath() + " should exist after symlinking", destFile.exists()); | ||||
|     } | ||||
| 
 | ||||
|     @Nullable | ||||
|     private static File copyAssetToDir(Context context, String assetName, File directory) { | ||||
|         File tempFile; | ||||
|         InputStream input = null; | ||||
|         OutputStream output = null; | ||||
|         try { | ||||
|             tempFile = File.createTempFile(assetName + "-", ".testasset", directory); | ||||
|             Log.i(TAG, "Copying asset file " + assetName + " to directory " + directory); | ||||
|             input = context.getAssets().open(assetName); | ||||
|             output = new FileOutputStream(tempFile); | ||||
|             Utils.copy(input, output); | ||||
|         } catch (IOException e) { | ||||
|             e.printStackTrace(); | ||||
|             return null; | ||||
|         } finally { | ||||
|             Utils.closeQuietly(output); | ||||
|             Utils.closeQuietly(input); | ||||
|         } | ||||
|         return tempFile; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Prefer internal over external storage, because external tends to be FAT filesystems, | ||||
|      * which don't support symlinks (which we test using this method). | ||||
|      */ | ||||
|     private static File getWriteableDir(Instrumentation instrumentation) { | ||||
|         Context context = instrumentation.getContext(); | ||||
|         Context targetContext = instrumentation.getTargetContext(); | ||||
| 
 | ||||
|         File[] dirsToTry = new File[]{ | ||||
|                 context.getCacheDir(), | ||||
|                 context.getFilesDir(), | ||||
|                 targetContext.getCacheDir(), | ||||
|                 targetContext.getFilesDir(), | ||||
|                 context.getExternalCacheDir(), | ||||
|                 context.getExternalFilesDir(null), | ||||
|                 targetContext.getExternalCacheDir(), | ||||
|                 targetContext.getExternalFilesDir(null), | ||||
|                 Environment.getExternalStorageDirectory(), | ||||
|         }; | ||||
| 
 | ||||
|         return getWriteableDir(dirsToTry); | ||||
|     } | ||||
| 
 | ||||
|     private static File getWriteableDir(File[] dirsToTry) { | ||||
| 
 | ||||
|         for (File dir : dirsToTry) { | ||||
|             if (dir != null && dir.canWrite()) { | ||||
|                 return dir; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         return null; | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -1,73 +0,0 @@ | ||||
| package org.fdroid.fdroid; | ||||
| 
 | ||||
| import android.app.Instrumentation; | ||||
| import android.content.Context; | ||||
| import android.os.Environment; | ||||
| import android.support.annotation.Nullable; | ||||
| import android.util.Log; | ||||
| 
 | ||||
| import java.io.File; | ||||
| import java.io.FileOutputStream; | ||||
| import java.io.IOException; | ||||
| import java.io.InputStream; | ||||
| import java.io.OutputStream; | ||||
| 
 | ||||
| public class TestUtilsOld { | ||||
| 
 | ||||
|     private static final String TAG = "TestUtilsOld"; | ||||
| 
 | ||||
|     @Nullable | ||||
|     public static File copyAssetToDir(Context context, String assetName, File directory) { | ||||
|         File tempFile; | ||||
|         InputStream input = null; | ||||
|         OutputStream output = null; | ||||
|         try { | ||||
|             tempFile = File.createTempFile(assetName + "-", ".testasset", directory); | ||||
|             Log.i(TAG, "Copying asset file " + assetName + " to directory " + directory); | ||||
|             input = context.getAssets().open(assetName); | ||||
|             output = new FileOutputStream(tempFile); | ||||
|             Utils.copy(input, output); | ||||
|         } catch (IOException e) { | ||||
|             e.printStackTrace(); | ||||
|             return null; | ||||
|         } finally { | ||||
|             Utils.closeQuietly(output); | ||||
|             Utils.closeQuietly(input); | ||||
|         } | ||||
|         return tempFile; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Prefer internal over external storage, because external tends to be FAT filesystems, | ||||
|      * which don't support symlinks (which we test using this method). | ||||
|      */ | ||||
|     public static File getWriteableDir(Instrumentation instrumentation) { | ||||
|         Context context = instrumentation.getContext(); | ||||
|         Context targetContext = instrumentation.getTargetContext(); | ||||
| 
 | ||||
|         File[] dirsToTry = new File[]{ | ||||
|             context.getCacheDir(), | ||||
|             context.getFilesDir(), | ||||
|             targetContext.getCacheDir(), | ||||
|             targetContext.getFilesDir(), | ||||
|             context.getExternalCacheDir(), | ||||
|             context.getExternalFilesDir(null), | ||||
|             targetContext.getExternalCacheDir(), | ||||
|             targetContext.getExternalFilesDir(null), | ||||
|             Environment.getExternalStorageDirectory(), | ||||
|         }; | ||||
| 
 | ||||
|         return getWriteableDir(dirsToTry); | ||||
|     } | ||||
| 
 | ||||
|     private static File getWriteableDir(File[] dirsToTry) { | ||||
| 
 | ||||
|         for (File dir : dirsToTry) { | ||||
|             if (dir != null && dir.canWrite()) { | ||||
|                 return dir; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         return null; | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,82 @@ | ||||
| 
 | ||||
| package org.fdroid.fdroid; | ||||
| 
 | ||||
| import android.util.Log; | ||||
| 
 | ||||
| import org.fdroid.fdroid.RepoUpdater.UpdateException; | ||||
| import org.fdroid.fdroid.data.Repo; | ||||
| import org.fdroid.fdroid.data.RepoProvider; | ||||
| import org.junit.Test; | ||||
| import org.junit.runner.RunWith; | ||||
| import org.robolectric.RobolectricGradleTestRunner; | ||||
| import org.robolectric.annotation.Config; | ||||
| 
 | ||||
| import java.util.List; | ||||
| 
 | ||||
| import static org.junit.Assert.assertEquals; | ||||
| 
 | ||||
| @Config(constants = BuildConfig.class) | ||||
| @RunWith(RobolectricGradleTestRunner.class) | ||||
| public class AcceptableMultiRepoUpdaterTest extends MultiRepoUpdaterTest { | ||||
|     private static final String TAG = "AcceptableMultiRepoTest"; | ||||
| 
 | ||||
|     private void assertSomewhatAcceptable() { | ||||
|         Log.i(TAG, "Asserting at least one versions of each .apk is in index."); | ||||
|         List<Repo> repos = RepoProvider.Helper.all(context); | ||||
|         assertEquals("Repos", 3, repos.size()); | ||||
| 
 | ||||
|         assertApp2048(); | ||||
|         assertAppAdaway(); | ||||
|         assertAppAdbWireless(); | ||||
|         assertAppIcsImport(); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void testAcceptableConflictingThenMainThenArchive() throws UpdateException { | ||||
|         assertEmpty(); | ||||
|         if (updateConflicting() && updateMain() && updateArchive()) { | ||||
|             assertSomewhatAcceptable(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void testAcceptableConflictingThenArchiveThenMain() throws UpdateException { | ||||
|         assertEmpty(); | ||||
|         if (updateConflicting() && updateArchive() && updateMain()) { | ||||
|             assertSomewhatAcceptable(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void testAcceptableArchiveThenMainThenConflicting() throws UpdateException { | ||||
|         assertEmpty(); | ||||
|         if (updateArchive() && updateMain() && updateConflicting()) { | ||||
|             assertSomewhatAcceptable(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void testAcceptableArchiveThenConflictingThenMain() throws UpdateException { | ||||
|         assertEmpty(); | ||||
|         if (updateArchive() && updateConflicting() && updateMain()) { | ||||
|             assertSomewhatAcceptable(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void testAcceptableMainThenArchiveThenConflicting() throws UpdateException { | ||||
|         assertEmpty(); | ||||
|         if (updateMain() && updateArchive() && updateConflicting()) { | ||||
|             assertSomewhatAcceptable(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void testAcceptableMainThenConflictingThenArchive() throws UpdateException { | ||||
|         assertEmpty(); | ||||
|         if (updateMain() && updateConflicting() && updateArchive()) { | ||||
|             assertSomewhatAcceptable(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -5,7 +5,6 @@ import android.content.ContentValues; | ||||
| import android.content.Context; | ||||
| import android.support.annotation.NonNull; | ||||
| import android.text.TextUtils; | ||||
| import android.util.Log; | ||||
| 
 | ||||
| import org.fdroid.fdroid.RepoUpdater.UpdateException; | ||||
| import org.fdroid.fdroid.data.Apk; | ||||
| @ -16,10 +15,6 @@ import org.fdroid.fdroid.data.Repo; | ||||
| import org.fdroid.fdroid.data.RepoProvider; | ||||
| import org.junit.After; | ||||
| import org.junit.Before; | ||||
| import org.junit.Test; | ||||
| import org.junit.runner.RunWith; | ||||
| import org.robolectric.RobolectricGradleTestRunner; | ||||
| import org.robolectric.annotation.Config; | ||||
| 
 | ||||
| import java.io.File; | ||||
| import java.util.List; | ||||
| @ -30,18 +25,16 @@ import static org.junit.Assert.assertEquals; | ||||
| import static org.junit.Assert.assertNotNull; | ||||
| import static org.junit.Assert.assertTrue; | ||||
| 
 | ||||
| @Config(constants = BuildConfig.class) | ||||
| @RunWith(RobolectricGradleTestRunner.class) | ||||
| public class MultiRepoUpdaterTest extends FDroidProviderTest { | ||||
|     private static final String TAG = "MultiRepoUpdaterTest"; | ||||
| public abstract class MultiRepoUpdaterTest extends FDroidProviderTest { | ||||
|     private static final String TAG = "AcceptableMultiRepoUpdaterTest"; // NOPMD | ||||
| 
 | ||||
|     private static final String REPO_MAIN = "Test F-Droid repo"; | ||||
|     private static final String REPO_ARCHIVE = "Test F-Droid repo (Archive)"; | ||||
|     private static final String REPO_CONFLICTING = "Test F-Droid repo with different apps"; | ||||
|     protected static final String REPO_MAIN = "Test F-Droid repo"; | ||||
|     protected static final String REPO_ARCHIVE = "Test F-Droid repo (Archive)"; | ||||
|     protected static final String REPO_CONFLICTING = "Test F-Droid repo with different apps"; | ||||
| 
 | ||||
|     private RepoUpdater conflictingRepoUpdater; | ||||
|     private RepoUpdater mainRepoUpdater; | ||||
|     private RepoUpdater archiveRepoUpdater; | ||||
|     protected RepoUpdater conflictingRepoUpdater; | ||||
|     protected RepoUpdater mainRepoUpdater; | ||||
|     protected RepoUpdater archiveRepoUpdater; | ||||
| 
 | ||||
|     private static final String PUB_KEY = | ||||
|             "3082050b308202f3a003020102020420d8f212300d06092a864886f70d01010b050030363110300e0603" + | ||||
| @ -77,7 +70,7 @@ public class MultiRepoUpdaterTest extends FDroidProviderTest { | ||||
|             "e8af60597c4ae2977977cf61dc715a572e241ae717cafdb4f71781943945ac52e0f50b"; | ||||
| 
 | ||||
|     @Before | ||||
|     public void setup() throws Exception { | ||||
|     public final void setupMultiRepo() throws Exception { | ||||
|         // On a fresh database install, there will be F-Droid + GP repos, including their Archive | ||||
|         // repos that we are not interested in. | ||||
|         RepoProvider.Helper.remove(context, 1); | ||||
| @ -93,123 +86,33 @@ public class MultiRepoUpdaterTest extends FDroidProviderTest { | ||||
|     } | ||||
| 
 | ||||
|     @After | ||||
|     public void tearDown() { | ||||
|     public final void tearDownMultiRepo() { | ||||
|         Preferences.clearSingletonForTesting(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Check that all of the expected apps and apk versions are available in the database. This | ||||
|      * check will take into account the repository the apks came from, to ensure that each | ||||
|      * repository indeed contains the apks that it said it would provide. | ||||
|      */ | ||||
|     private void assertExpected() { | ||||
|         Log.i(TAG, "Asserting all versions of each .apk are in index."); | ||||
|         List<Repo> repos = RepoProvider.Helper.all(context); | ||||
|         assertEquals("Repos", 3, repos.size()); | ||||
| 
 | ||||
|         assertMainRepo(repos); | ||||
|         assertMainArchiveRepo(repos); | ||||
|         assertConflictingRepo(repos); | ||||
|     } | ||||
| 
 | ||||
|     private void assertSomewhatAcceptable() { | ||||
|         Log.i(TAG, "Asserting at least one versions of each .apk is in index."); | ||||
|         List<Repo> repos = RepoProvider.Helper.all(context); | ||||
|         assertEquals("Repos", 3, repos.size()); | ||||
| 
 | ||||
|         assertApp2048(); | ||||
|         assertAppAdaway(); | ||||
|         assertAppAdbWireless(); | ||||
|         assertAppIcsImport(); | ||||
|     } | ||||
| 
 | ||||
|     private void assertApp(String packageName, int[] versionCodes) { | ||||
|     protected void assertApp(String packageName, int[] versionCodes) { | ||||
|         List<Apk> apks = ApkProvider.Helper.findByPackageName(context, packageName, ApkProvider.DataColumns.ALL); | ||||
|         assertApksExist(apks, packageName, versionCodes); | ||||
|     } | ||||
| 
 | ||||
|     private void assertApp2048() { | ||||
|     protected void assertApp2048() { | ||||
|         assertApp("com.uberspot.a2048", new int[]{19, 18}); | ||||
|     } | ||||
| 
 | ||||
|     private void assertAppAdaway() { | ||||
|     protected void assertAppAdaway() { | ||||
|         assertApp("org.adaway", new int[]{54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 42, 40, 38, 37, 36, 35}); | ||||
|     } | ||||
| 
 | ||||
|     private void assertAppAdbWireless() { | ||||
|     protected void assertAppAdbWireless() { | ||||
|         assertApp("siir.es.adbWireless", new int[]{12}); | ||||
|     } | ||||
| 
 | ||||
|     private void assertAppIcsImport() { | ||||
|     protected void assertAppIcsImport() { | ||||
|         assertApp("org.dgtale.icsimport", new int[]{3, 2}); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * + 2048 (com.uberspot.a2048) | ||||
|      * - Version 1.96 (19) | ||||
|      * - Version 1.95 (18) | ||||
|      * + AdAway (org.adaway) | ||||
|      * - Version 3.0.2 (54) | ||||
|      * - Version 3.0.1 (53) | ||||
|      * - Version 3.0 (52) | ||||
|      * + adbWireless (siir.es.adbWireless) | ||||
|      * - Version 1.5.4 (12) | ||||
|      */ | ||||
|     private void assertMainRepo(List<Repo> allRepos) { | ||||
|         Repo repo = findRepo(REPO_MAIN, allRepos); | ||||
| 
 | ||||
|         List<Apk> apks = ApkProvider.Helper.findByRepo(context, repo, ApkProvider.DataColumns.ALL); | ||||
|         assertEquals("Apks for main repo", apks.size(), 6); | ||||
|         assertApksExist(apks, "com.uberspot.a2048", new int[]{18, 19}); | ||||
|         assertApksExist(apks, "org.adaway", new int[]{52, 53, 54}); | ||||
|         assertApksExist(apks, "siir.es.adbWireless", new int[]{12}); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * + AdAway (org.adaway) | ||||
|      * - Version 2.9.2 (51) | ||||
|      * - Version 2.9.1 (50) | ||||
|      * - Version 2.9 (49) | ||||
|      * - Version 2.8.1 (48) | ||||
|      * - Version 2.8 (47) | ||||
|      * - Version 2.7 (46) | ||||
|      * - Version 2.6 (45) | ||||
|      * - Version 2.3 (42) | ||||
|      * - Version 2.1 (40) | ||||
|      * - Version 1.37 (38) | ||||
|      * - Version 1.36 (37) | ||||
|      * - Version 1.35 (36) | ||||
|      * - Version 1.34 (35) | ||||
|      */ | ||||
|     private void assertMainArchiveRepo(List<Repo> allRepos) { | ||||
|         Repo repo = findRepo(REPO_ARCHIVE, allRepos); | ||||
| 
 | ||||
|         List<Apk> apks = ApkProvider.Helper.findByRepo(context, repo, ApkProvider.DataColumns.ALL); | ||||
|         assertEquals("Apks for main archive repo", 13, apks.size()); | ||||
|         assertApksExist(apks, "org.adaway", new int[]{35, 36, 37, 38, 40, 42, 45, 46, 47, 48, 49, 50, 51}); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * + AdAway (org.adaway) | ||||
|      * - Version 3.0.1 (53) * | ||||
|      * - Version 3.0 (52) * | ||||
|      * - Version 2.9.2 (51) * | ||||
|      * - Version 2.2.1 (50) * | ||||
|      * + Add to calendar (org.dgtale.icsimport) | ||||
|      * - Version 1.2 (3) | ||||
|      * - Version 1.1 (2) | ||||
|      */ | ||||
|     private void assertConflictingRepo(List<Repo> allRepos) { | ||||
|         Repo repo = findRepo(REPO_CONFLICTING, allRepos); | ||||
| 
 | ||||
|         List<Apk> apks = ApkProvider.Helper.findByRepo(context, repo, ApkProvider.DataColumns.ALL); | ||||
|         assertEquals("Apks for main repo", 6, apks.size()); | ||||
|         assertApksExist(apks, "org.adaway", new int[]{50, 51, 52, 53}); | ||||
|         assertApksExist(apks, "org.dgtale.icsimport", new int[]{2, 3}); | ||||
|     } | ||||
| 
 | ||||
|     @NonNull | ||||
|     private Repo findRepo(@NonNull String name, List<Repo> allRepos) { | ||||
|     protected Repo findRepo(@NonNull String name, List<Repo> allRepos) { | ||||
|         Repo repo = null; | ||||
|         for (Repo r : allRepos) { | ||||
|             if (TextUtils.equals(name, r.getName())) { | ||||
| @ -225,7 +128,7 @@ public class MultiRepoUpdaterTest extends FDroidProviderTest { | ||||
|     /** | ||||
|      * Checks that each version of appId as specified in versionCodes is present in apksToCheck. | ||||
|      */ | ||||
|     private void assertApksExist(List<Apk> apksToCheck, String appId, int[] versionCodes) { | ||||
|     protected void assertApksExist(List<Apk> apksToCheck, String appId, int[] versionCodes) { | ||||
|         for (int versionCode : versionCodes) { | ||||
|             boolean found = false; | ||||
|             for (Apk apk : apksToCheck) { | ||||
| @ -239,7 +142,7 @@ public class MultiRepoUpdaterTest extends FDroidProviderTest { | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private void assertEmpty() { | ||||
|     protected void assertEmpty() { | ||||
|         assertEquals("No apps present", 0, AppProvider.Helper.all(context.getContentResolver()).size()); | ||||
| 
 | ||||
|         String[] packages = { | ||||
| @ -253,102 +156,6 @@ public class MultiRepoUpdaterTest extends FDroidProviderTest { | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /* At time fo writing, the following tests did not pass. This is because the multi-repo support | ||||
|        in F-Droid was not sufficient. When working on proper multi repo support than this should be | ||||
|        ucommented and all these tests should pass: | ||||
| 
 | ||||
|     public void testCorrectConflictingThenMainThenArchive() throws UpdateException { | ||||
|         assertEmpty(); | ||||
|         if (updateConflicting() && updateMain() && updateArchive()) { | ||||
|             assertExpected(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public void testCorrectConflictingThenArchiveThenMain() throws UpdateException { | ||||
|         assertEmpty(); | ||||
|         if (updateConflicting() && updateArchive() && updateMain()) { | ||||
|             assertExpected(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public void testCorrectArchiveThenMainThenConflicting() throws UpdateException { | ||||
|         assertEmpty(); | ||||
|         if (updateArchive() && updateMain() && updateConflicting()) { | ||||
|             assertExpected(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public void testCorrectArchiveThenConflictingThenMain() throws UpdateException { | ||||
|         assertEmpty(); | ||||
|         if (updateArchive() && updateConflicting() && updateMain()) { | ||||
|             assertExpected(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public void testCorrectMainThenArchiveThenConflicting() throws UpdateException { | ||||
|         assertEmpty(); | ||||
|         if (updateMain() && updateArchive() && updateConflicting()) { | ||||
|             assertExpected(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public void testCorrectMainThenConflictingThenArchive() throws UpdateException { | ||||
|         assertEmpty(); | ||||
|         if (updateMain() && updateConflicting() && updateArchive()) { | ||||
|             assertExpected(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     */ | ||||
| 
 | ||||
|     @Test | ||||
|     public void testAcceptableConflictingThenMainThenArchive() throws UpdateException { | ||||
|         assertEmpty(); | ||||
|         if (updateConflicting() && updateMain() && updateArchive()) { | ||||
|             assertSomewhatAcceptable(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void testAcceptableConflictingThenArchiveThenMain() throws UpdateException { | ||||
|         assertEmpty(); | ||||
|         if (updateConflicting() && updateArchive() && updateMain()) { | ||||
|             assertSomewhatAcceptable(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void testAcceptableArchiveThenMainThenConflicting() throws UpdateException { | ||||
|         assertEmpty(); | ||||
|         if (updateArchive() && updateMain() && updateConflicting()) { | ||||
|             assertSomewhatAcceptable(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void testAcceptableArchiveThenConflictingThenMain() throws UpdateException { | ||||
|         assertEmpty(); | ||||
|         if (updateArchive() && updateConflicting() && updateMain()) { | ||||
|             assertSomewhatAcceptable(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void testAcceptableMainThenArchiveThenConflicting() throws UpdateException { | ||||
|         assertEmpty(); | ||||
|         if (updateMain() && updateArchive() && updateConflicting()) { | ||||
|             assertSomewhatAcceptable(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void testAcceptableMainThenConflictingThenArchive() throws UpdateException { | ||||
|         assertEmpty(); | ||||
|         if (updateMain() && updateConflicting() && updateArchive()) { | ||||
|             assertSomewhatAcceptable(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private RepoUpdater createUpdater(String name, Context context) { | ||||
|         Repo repo = new Repo(); | ||||
|         repo.signingCertificate = PUB_KEY; | ||||
| @ -367,15 +174,15 @@ public class MultiRepoUpdaterTest extends FDroidProviderTest { | ||||
|         return new RepoUpdater(context, RepoProvider.Helper.findByAddress(context, repo.address)); | ||||
|     } | ||||
| 
 | ||||
|     private boolean updateConflicting() throws UpdateException { | ||||
|     protected boolean updateConflicting() throws UpdateException { | ||||
|         return updateRepo(conflictingRepoUpdater, "multiRepo.conflicting.jar"); | ||||
|     } | ||||
| 
 | ||||
|     private boolean updateMain() throws UpdateException { | ||||
|     protected boolean updateMain() throws UpdateException { | ||||
|         return updateRepo(mainRepoUpdater, "multiRepo.normal.jar"); | ||||
|     } | ||||
| 
 | ||||
|     private boolean updateArchive() throws UpdateException { | ||||
|     protected boolean updateArchive() throws UpdateException { | ||||
|         return updateRepo(archiveRepoUpdater, "multiRepo.archive.jar"); | ||||
|     } | ||||
| 
 | ||||
| @ -385,7 +192,7 @@ public class MultiRepoUpdaterTest extends FDroidProviderTest { | ||||
|             updater.processDownloadedFile(indexJar); | ||||
|         } finally { | ||||
|             if (indexJar != null && indexJar.exists()) { | ||||
|                 indexJar.delete(); | ||||
|                 assertTrue(indexJar.delete()); | ||||
|             } | ||||
|         } | ||||
|         return true; | ||||
|  | ||||
| @ -0,0 +1,155 @@ | ||||
| 
 | ||||
| package org.fdroid.fdroid; | ||||
| 
 | ||||
| import android.util.Log; | ||||
| 
 | ||||
| import org.fdroid.fdroid.RepoUpdater.UpdateException; | ||||
| import org.fdroid.fdroid.data.Apk; | ||||
| import org.fdroid.fdroid.data.ApkProvider; | ||||
| import org.fdroid.fdroid.data.Repo; | ||||
| import org.fdroid.fdroid.data.RepoProvider; | ||||
| import org.junit.Test; | ||||
| 
 | ||||
| import java.util.List; | ||||
| 
 | ||||
| import static org.junit.Assert.assertEquals; | ||||
| 
 | ||||
| /* | ||||
| At time fo writing, the following tests did not pass. This is because the multi-repo support | ||||
| in F-Droid was not sufficient. When working on proper multi repo support than this should be | ||||
| uncommented and all these tests will be required to pass: | ||||
| 
 | ||||
| @Config(constants = BuildConfig.class) | ||||
| @RunWith(RobolectricGradleTestRunner.class) | ||||
| */ | ||||
| public class ProperMultiRepoUpdaterTest extends MultiRepoUpdaterTest { | ||||
|     private static final String TAG = "ProperMultiRepoSupport"; | ||||
| 
 | ||||
|     @Test | ||||
|     public void testCorrectConflictingThenMainThenArchive() throws UpdateException { | ||||
|         assertEmpty(); | ||||
|         if (updateConflicting() && updateMain() && updateArchive()) { | ||||
|             assertExpected(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void testCorrectConflictingThenArchiveThenMain() throws UpdateException { | ||||
|         assertEmpty(); | ||||
|         if (updateConflicting() && updateArchive() && updateMain()) { | ||||
|             assertExpected(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void testCorrectArchiveThenMainThenConflicting() throws UpdateException { | ||||
|         assertEmpty(); | ||||
|         if (updateArchive() && updateMain() && updateConflicting()) { | ||||
|             assertExpected(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void testCorrectArchiveThenConflictingThenMain() throws UpdateException { | ||||
|         assertEmpty(); | ||||
|         if (updateArchive() && updateConflicting() && updateMain()) { | ||||
|             assertExpected(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void testCorrectMainThenArchiveThenConflicting() throws UpdateException { | ||||
|         assertEmpty(); | ||||
|         if (updateMain() && updateArchive() && updateConflicting()) { | ||||
|             assertExpected(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void testCorrectMainThenConflictingThenArchive() throws UpdateException { | ||||
|         assertEmpty(); | ||||
|         if (updateMain() && updateConflicting() && updateArchive()) { | ||||
|             assertExpected(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Check that all of the expected apps and apk versions are available in the database. This | ||||
|      * check will take into account the repository the apks came from, to ensure that each | ||||
|      * repository indeed contains the apks that it said it would provide. | ||||
|      */ | ||||
|     private void assertExpected() { | ||||
|         Log.i(TAG, "Asserting all versions of each .apk are in index."); | ||||
|         List<Repo> repos = RepoProvider.Helper.all(context); | ||||
|         assertEquals("Repos", 3, repos.size()); | ||||
| 
 | ||||
|         assertMainRepo(repos); | ||||
|         assertMainArchiveRepo(repos); | ||||
|         assertConflictingRepo(repos); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * + 2048 (com.uberspot.a2048) | ||||
|      * - Version 1.96 (19) | ||||
|      * - Version 1.95 (18) | ||||
|      * + AdAway (org.adaway) | ||||
|      * - Version 3.0.2 (54) | ||||
|      * - Version 3.0.1 (53) | ||||
|      * - Version 3.0 (52) | ||||
|      * + adbWireless (siir.es.adbWireless) | ||||
|      * - Version 1.5.4 (12) | ||||
|      */ | ||||
|     private void assertMainRepo(List<Repo> allRepos) { | ||||
|         Repo repo = findRepo(REPO_MAIN, allRepos); | ||||
| 
 | ||||
|         List<Apk> apks = ApkProvider.Helper.findByRepo(context, repo, ApkProvider.DataColumns.ALL); | ||||
|         assertEquals("Apks for main repo", apks.size(), 6); | ||||
|         assertApksExist(apks, "com.uberspot.a2048", new int[]{18, 19}); | ||||
|         assertApksExist(apks, "org.adaway", new int[]{52, 53, 54}); | ||||
|         assertApksExist(apks, "siir.es.adbWireless", new int[]{12}); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * + AdAway (org.adaway) | ||||
|      * - Version 2.9.2 (51) | ||||
|      * - Version 2.9.1 (50) | ||||
|      * - Version 2.9 (49) | ||||
|      * - Version 2.8.1 (48) | ||||
|      * - Version 2.8 (47) | ||||
|      * - Version 2.7 (46) | ||||
|      * - Version 2.6 (45) | ||||
|      * - Version 2.3 (42) | ||||
|      * - Version 2.1 (40) | ||||
|      * - Version 1.37 (38) | ||||
|      * - Version 1.36 (37) | ||||
|      * - Version 1.35 (36) | ||||
|      * - Version 1.34 (35) | ||||
|      */ | ||||
|     private void assertMainArchiveRepo(List<Repo> allRepos) { | ||||
|         Repo repo = findRepo(REPO_ARCHIVE, allRepos); | ||||
| 
 | ||||
|         List<Apk> apks = ApkProvider.Helper.findByRepo(context, repo, ApkProvider.DataColumns.ALL); | ||||
|         assertEquals("Apks for main archive repo", 13, apks.size()); | ||||
|         assertApksExist(apks, "org.adaway", new int[]{35, 36, 37, 38, 40, 42, 45, 46, 47, 48, 49, 50, 51}); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * + AdAway (org.adaway) | ||||
|      * - Version 3.0.1 (53) * | ||||
|      * - Version 3.0 (52) * | ||||
|      * - Version 2.9.2 (51) * | ||||
|      * - Version 2.2.1 (50) * | ||||
|      * + Add to calendar (org.dgtale.icsimport) | ||||
|      * - Version 1.2 (3) | ||||
|      * - Version 1.1 (2) | ||||
|      */ | ||||
|     private void assertConflictingRepo(List<Repo> allRepos) { | ||||
|         Repo repo = findRepo(REPO_CONFLICTING, allRepos); | ||||
| 
 | ||||
|         List<Apk> apks = ApkProvider.Helper.findByRepo(context, repo, ApkProvider.DataColumns.ALL); | ||||
|         assertEquals("Apks for main repo", 6, apks.size()); | ||||
|         assertApksExist(apks, "org.adaway", new int[]{50, 51, 52, 53}); | ||||
|         assertApksExist(apks, "org.dgtale.icsimport", new int[]{2, 3}); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -6,11 +6,13 @@ import java.io.IOException; | ||||
| import java.io.InputStream; | ||||
| import java.io.OutputStream; | ||||
| 
 | ||||
| import static org.junit.Assert.assertTrue; | ||||
| import static org.junit.Assert.fail; | ||||
| 
 | ||||
| public class TestUtils { | ||||
| 
 | ||||
|     private static final String TAG = "TestUtils"; | ||||
|     @SuppressWarnings("unused") | ||||
|     private static final String TAG = "TestUtils"; // NOPMD | ||||
| 
 | ||||
|     public static File copyResourceToTempFile(String resourceName) { | ||||
|         File tempFile = null; | ||||
| @ -24,7 +26,7 @@ public class TestUtils { | ||||
|         } catch (IOException e) { | ||||
|             e.printStackTrace(); | ||||
|             if (tempFile != null && tempFile.exists()) { | ||||
|                 tempFile.delete(); | ||||
|                 assertTrue(tempFile.delete()); | ||||
|             } | ||||
|             fail(); | ||||
|             return null; | ||||
|  | ||||
| @ -1,14 +1,14 @@ | ||||
| 
 | ||||
| package org.fdroid.fdroid; | ||||
| 
 | ||||
| import android.app.Instrumentation; | ||||
| import android.content.Context; | ||||
| import android.support.test.InstrumentationRegistry; | ||||
| import android.support.test.runner.AndroidJUnit4; | ||||
| 
 | ||||
| import org.apache.commons.io.FileUtils; | ||||
| import org.junit.Test; | ||||
| import org.junit.runner.RunWith; | ||||
| import org.robolectric.RobolectricGradleTestRunner; | ||||
| import org.robolectric.RuntimeEnvironment; | ||||
| import org.robolectric.annotation.Config; | ||||
| 
 | ||||
| import java.io.File; | ||||
| import java.io.IOException; | ||||
| @ -17,7 +17,8 @@ import static org.junit.Assert.assertEquals; | ||||
| import static org.junit.Assert.assertFalse; | ||||
| import static org.junit.Assert.assertTrue; | ||||
| 
 | ||||
| @RunWith(AndroidJUnit4.class) | ||||
| @Config(constants = BuildConfig.class) | ||||
| @RunWith(RobolectricGradleTestRunner.class) | ||||
| public class UtilsTest { | ||||
| 
 | ||||
|     String fdroidFingerprint = "43238D512C1E5EB2D6569F4A3AFBF5523418B82E0A3ED1552770ABB9A9C9CCAB"; | ||||
| @ -50,7 +51,7 @@ public class UtilsTest { | ||||
| 
 | ||||
|     @Test | ||||
|     public void testFormatFingerprint() { | ||||
|         Context context = InstrumentationRegistry.getTargetContext(); | ||||
|         Context context = RuntimeEnvironment.application; | ||||
|         String badResult = Utils.formatFingerprint(context, ""); | ||||
|         // real fingerprints | ||||
|         String formatted; | ||||
| @ -145,22 +146,29 @@ public class UtilsTest { | ||||
| 
 | ||||
|     @Test | ||||
|     public void testClearOldFiles() throws IOException, InterruptedException { | ||||
|         Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation(); | ||||
|         File dir = new File(TestUtilsOld.getWriteableDir(instrumentation), "clearOldFiles"); | ||||
|         File tempDir = new File(System.getProperty("java.io.tmpdir")); | ||||
|         assertTrue(tempDir.isDirectory()); | ||||
|         assertTrue(tempDir.canWrite()); | ||||
| 
 | ||||
|         File dir = new File(tempDir, "F-Droid-test.clearOldFiles"); | ||||
|         FileUtils.deleteQuietly(dir); | ||||
|         dir.mkdirs(); | ||||
|         assertTrue(dir.mkdirs()); | ||||
|         assertTrue(dir.isDirectory()); | ||||
| 
 | ||||
|         File first = new File(dir, "first"); | ||||
|         first.deleteOnExit(); | ||||
| 
 | ||||
|         File second = new File(dir, "second"); | ||||
|         second.deleteOnExit(); | ||||
| 
 | ||||
|         assertFalse(first.exists()); | ||||
|         assertFalse(second.exists()); | ||||
| 
 | ||||
|         first.createNewFile(); | ||||
|         assertTrue(first.createNewFile()); | ||||
|         assertTrue(first.exists()); | ||||
| 
 | ||||
|         Thread.sleep(7000); | ||||
|         second.createNewFile(); | ||||
|         assertTrue(second.createNewFile()); | ||||
|         assertTrue(second.exists()); | ||||
| 
 | ||||
|         Utils.clearOldFiles(dir, 3); | ||||
| @ -23,7 +23,6 @@ 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; | ||||
| @ -38,8 +37,8 @@ public class ApkProviderTest extends FDroidProviderTest { | ||||
|     @Test | ||||
|     public void testAppApks() { | ||||
|         for (int i = 1; i <= 10; i++) { | ||||
|             insertApk(contentResolver, "org.fdroid.fdroid", i); | ||||
|             insertApk(contentResolver, "com.example", i); | ||||
|             ProviderTestUtils.insertApk(contentResolver, "org.fdroid.fdroid", i); | ||||
|             ProviderTestUtils.insertApk(contentResolver, "com.example", i); | ||||
|         } | ||||
| 
 | ||||
|         assertTotalApkCount(20); | ||||
| @ -187,23 +186,12 @@ public class ApkProviderTest extends FDroidProviderTest { | ||||
|         Apk apk = new MockApk("org.fdroid.fdroid", 13); | ||||
| 
 | ||||
|         // Insert a new record... | ||||
|         Uri newUri = insertApk(contentResolver, apk.packageName, apk.versionCode); | ||||
|         Uri newUri = ProviderTestUtils.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. | ||||
| @ -214,12 +202,19 @@ public class ApkProviderTest extends FDroidProviderTest { | ||||
|         assertEquals(13, toCheck.versionCode); | ||||
|     } | ||||
| 
 | ||||
|     @Test(expected = IllegalArgumentException.class) | ||||
|     public void testCursorMustMoveToFirst() { | ||||
|         ProviderTestUtils.insertApk(contentResolver, "org.example.test", 12); | ||||
|         Cursor cursor = queryAllApks(); | ||||
|         new Apk(cursor); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void testCount() { | ||||
|         String[] projectionCount = new String[] {ApkProvider.DataColumns._COUNT}; | ||||
| 
 | ||||
|         for (int i = 0; i < 13; i++) { | ||||
|             insertApk(contentResolver, "com.example", i); | ||||
|             ProviderTestUtils.insertApk(contentResolver, "com.example", i); | ||||
|         } | ||||
| 
 | ||||
|         Uri all = ApkProvider.getContentUri(); | ||||
| @ -236,38 +231,48 @@ public class ApkProviderTest extends FDroidProviderTest { | ||||
|         allWithCount.close(); | ||||
|     } | ||||
| 
 | ||||
|     @Test(expected = IllegalArgumentException.class) | ||||
|     public void testInsertWithInvalidExtraFieldDescription() { | ||||
|         assertInvalidExtraField(RepoProvider.DataColumns.DESCRIPTION); | ||||
|     } | ||||
| 
 | ||||
|     @Test(expected = IllegalArgumentException.class) | ||||
|     public void testInsertWithInvalidExtraFieldAddress() { | ||||
|         assertInvalidExtraField(RepoProvider.DataColumns.ADDRESS); | ||||
|     } | ||||
| 
 | ||||
|     @Test(expected = IllegalArgumentException.class) | ||||
|     public void testInsertWithInvalidExtraFieldFingerprint() { | ||||
|         assertInvalidExtraField(RepoProvider.DataColumns.FINGERPRINT); | ||||
|     } | ||||
| 
 | ||||
|     @Test(expected = IllegalArgumentException.class) | ||||
|     public void testInsertWithInvalidExtraFieldName() { | ||||
|         assertInvalidExtraField(RepoProvider.DataColumns.NAME); | ||||
|     } | ||||
| 
 | ||||
|     @Test(expected = IllegalArgumentException.class) | ||||
|     public void testInsertWithInvalidExtraFieldSigningCert() { | ||||
|         assertInvalidExtraField(RepoProvider.DataColumns.SIGNING_CERT); | ||||
|     } | ||||
| 
 | ||||
|     public void assertInvalidExtraField(String field) { | ||||
|         ContentValues invalidRepo = new ContentValues(); | ||||
|         invalidRepo.put(field, "Test data"); | ||||
|         ProviderTestUtils.insertApk(contentResolver, "org.fdroid.fdroid", 10, invalidRepo); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void testInsertWithExtraFields() { | ||||
|     public void testInsertWithValidExtraFields() { | ||||
| 
 | ||||
|         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); | ||||
|         Uri uri = ProviderTestUtils.insertApk(contentResolver, "com.example.com", 1, values); | ||||
| 
 | ||||
|         assertResultCount(1, queryAllApks()); | ||||
| 
 | ||||
| @ -293,18 +298,18 @@ public class ApkProviderTest extends FDroidProviderTest { | ||||
|     public void testKnownApks() { | ||||
| 
 | ||||
|         for (int i = 0; i < 7; i++) { | ||||
|             insertApk(contentResolver, "org.fdroid.fdroid", i); | ||||
|             ProviderTestUtils.insertApk(contentResolver, "org.fdroid.fdroid", i); | ||||
|         } | ||||
| 
 | ||||
|         for (int i = 0; i < 9; i++) { | ||||
|             insertApk(contentResolver, "org.example", i); | ||||
|             ProviderTestUtils.insertApk(contentResolver, "org.example", i); | ||||
|         } | ||||
| 
 | ||||
|         for (int i = 0; i < 3; i++) { | ||||
|             insertApk(contentResolver, "com.example", i); | ||||
|             ProviderTestUtils.insertApk(contentResolver, "com.example", i); | ||||
|         } | ||||
| 
 | ||||
|         insertApk(contentResolver, "com.apk.thingo", 1); | ||||
|         ProviderTestUtils.insertApk(contentResolver, "com.apk.thingo", 1); | ||||
| 
 | ||||
|         Apk[] known = { | ||||
|             new MockApk("org.fdroid.fdroid", 1), | ||||
| @ -351,18 +356,18 @@ public class ApkProviderTest extends FDroidProviderTest { | ||||
|     public void testFindByApp() { | ||||
| 
 | ||||
|         for (int i = 0; i < 7; i++) { | ||||
|             insertApk(contentResolver, "org.fdroid.fdroid", i); | ||||
|             ProviderTestUtils.insertApk(contentResolver, "org.fdroid.fdroid", i); | ||||
|         } | ||||
| 
 | ||||
|         for (int i = 0; i < 9; i++) { | ||||
|             insertApk(contentResolver, "org.example", i); | ||||
|             ProviderTestUtils.insertApk(contentResolver, "org.example", i); | ||||
|         } | ||||
| 
 | ||||
|         for (int i = 0; i < 3; i++) { | ||||
|             insertApk(contentResolver, "com.example", i); | ||||
|             ProviderTestUtils.insertApk(contentResolver, "com.example", i); | ||||
|         } | ||||
| 
 | ||||
|         insertApk(contentResolver, "com.apk.thingo", 1); | ||||
|         ProviderTestUtils.insertApk(contentResolver, "com.apk.thingo", 1); | ||||
| 
 | ||||
|         assertTotalApkCount(7 + 9 + 3 + 1); | ||||
| 
 | ||||
| @ -386,7 +391,7 @@ public class ApkProviderTest extends FDroidProviderTest { | ||||
|     @Test | ||||
|     public void testUpdate() { | ||||
| 
 | ||||
|         Uri apkUri = insertApk(contentResolver, "com.example", 10); | ||||
|         Uri apkUri = ProviderTestUtils.insertApk(contentResolver, "com.example", 10); | ||||
| 
 | ||||
|         String[] allFields = ApkProvider.DataColumns.ALL; | ||||
|         Cursor cursor = contentResolver.query(apkUri, allFields, null, null, null); | ||||
| @ -442,18 +447,18 @@ public class ApkProviderTest extends FDroidProviderTest { | ||||
|         // 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); | ||||
|             ProviderTestUtils.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); | ||||
|         ProviderTestUtils.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); | ||||
|             ProviderTestUtils.insertApk(contentResolver, "com.other.thing." + i, i); | ||||
|         } | ||||
| 
 | ||||
|         Apk apk = ApkProvider.Helper.find(context, "com.example", 11); | ||||
| @ -529,7 +534,7 @@ public class ApkProviderTest extends FDroidProviderTest { | ||||
|     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); | ||||
|         Uri uri = ProviderTestUtils.insertApk(contentResolver, id, versionCode, additionalValues); | ||||
|         return ApkProvider.Helper.get(context, uri); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -25,7 +25,6 @@ import static org.junit.Assert.assertFalse; | ||||
| import static org.junit.Assert.assertNotNull; | ||||
| import static org.junit.Assert.assertNull; | ||||
| import static org.junit.Assert.assertTrue; | ||||
| import static org.junit.Assert.fail; | ||||
| 
 | ||||
| @Config(constants = BuildConfig.class, application = Application.class) | ||||
| @RunWith(RobolectricGradleTestRunner.class) | ||||
| @ -224,17 +223,6 @@ public class AppProviderTest extends FDroidProviderTest { | ||||
|         assertNotNull(cursor); | ||||
|         assertEquals(1, cursor.getCount()); | ||||
| 
 | ||||
|         // We intentionally throw an IllegalArgumentException if you haven't | ||||
|         // yet called cursor.move*()... | ||||
|         try { | ||||
|             new App(cursor); | ||||
|             fail(); | ||||
|         } catch (IllegalArgumentException e) { | ||||
|             // Success! | ||||
|         } catch (Exception e) { | ||||
|             fail(); | ||||
|         } | ||||
| 
 | ||||
|         // And now we should be able to recover these values from the app | ||||
|         // value object (because the queryAllApps() helper asks for NAME and | ||||
|         // PACKAGE_NAME. | ||||
| @ -250,6 +238,17 @@ public class AppProviderTest extends FDroidProviderTest { | ||||
|         assertEquals("F-Droid", otherApp.name); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * We intentionally throw an IllegalArgumentException if you haven't | ||||
|      * yet called cursor.move*(). | ||||
|      */ | ||||
|     @Test(expected = IllegalArgumentException.class) | ||||
|     public void testCursorMustMoveToFirst() { | ||||
|         insertApp("org.fdroid.fdroid", "F-Droid"); | ||||
|         Cursor cursor = queryAllApps(); | ||||
|         new App(cursor); | ||||
|     } | ||||
| 
 | ||||
|     private Cursor queryAllApps() { | ||||
|         String[] projection = new String[] { | ||||
|                 AppProvider.DataColumns._ID, | ||||
|  | ||||
| @ -19,7 +19,6 @@ 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; | ||||
| 
 | ||||
| @ -85,24 +84,12 @@ public class InstalledAppProviderTest extends FDroidProviderTest{ | ||||
| 
 | ||||
|     @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") | ||||
| @ -110,7 +97,19 @@ public class InstalledAppProviderTest extends FDroidProviderTest{ | ||||
| 
 | ||||
|         assertResultCount(contentResolver, 2, InstalledAppProvider.getContentUri()); | ||||
|         assertIsInstalledVersionInDb(contentResolver, "com.example.app2", 11, "1.1"); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * We expect this to happen, because we should be using insert() instead as it will | ||||
|      * do an insert/replace query. | ||||
|      */ | ||||
|     @Test(expected = UnsupportedOperationException.class) | ||||
|     public void testUpdateFails() { | ||||
|         contentResolver.update( | ||||
|                 InstalledAppProvider.getAppUri("com.example.app2"), | ||||
|                 createContentValues(11, "1.1"), | ||||
|                 null, null | ||||
|         ); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|  | ||||
| @ -17,7 +17,6 @@ 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) | ||||
| @ -124,6 +123,11 @@ public class ProviderUriTests { | ||||
|         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); | ||||
|     } | ||||
| 
 | ||||
|     @Test(expected = IllegalArgumentException.class) | ||||
|     public void invalidApkUrisWithTooManyApks() { | ||||
|         String[] projection = ApkProvider.DataColumns.ALL; | ||||
| 
 | ||||
|         List<Apk> manyApks = new ArrayList<>(ApkProvider.MAX_APKS_TO_QUERY - 5); | ||||
|         for (int i = 0; i < ApkProvider.MAX_APKS_TO_QUERY - 1; i++) { | ||||
| @ -133,18 +137,12 @@ public class ProviderUriTests { | ||||
| 
 | ||||
|         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(); | ||||
|         } | ||||
| 
 | ||||
|         // 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); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
|  | ||||
							
								
								
									
										
											BIN
										
									
								
								app/src/test/resources/simpleIndex.jar
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								app/src/test/resources/simpleIndex.jar
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										9
									
								
								config/pmd/rules-main.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								config/pmd/rules-main.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,9 @@ | ||||
| <?xml version="1.0"?> | ||||
| <ruleset name="Custom ruleset (for main code)" | ||||
|         xmlns="http://pmd.sf.net/ruleset/1.0.0" | ||||
|         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||||
|         xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0 http://pmd.sf.net/ruleset_xml_schema.xsd" | ||||
|         xsi:noNamespaceSchemaLocation="http://pmd.sf.net/ruleset_xml_schema.xsd"> | ||||
| 
 | ||||
|     <rule ref="rulesets/java/imports.xml" /> | ||||
| </ruleset> | ||||
							
								
								
									
										11
									
								
								config/pmd/rules-test.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								config/pmd/rules-test.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,11 @@ | ||||
| <?xml version="1.0"?> | ||||
| <ruleset name="Custom ruleset (for tests)" | ||||
|         xmlns="http://pmd.sf.net/ruleset/1.0.0" | ||||
|         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||||
|         xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0 http://pmd.sf.net/ruleset_xml_schema.xsd" | ||||
|         xsi:noNamespaceSchemaLocation="http://pmd.sf.net/ruleset_xml_schema.xsd"> | ||||
| 
 | ||||
|     <rule ref="rulesets/java/imports.xml"> | ||||
|         <exclude name="TooManyStaticImports" /><!-- Static imports are commonly used for JUnit tests --> | ||||
|     </rule> | ||||
| </ruleset> | ||||
| @ -12,7 +12,6 @@ | ||||
|     <rule ref="rulesets/java/android.xml"/> | ||||
|     <rule ref="rulesets/java/clone.xml"/> | ||||
|     <rule ref="rulesets/java/finalizers.xml"/> | ||||
|     <rule ref="rulesets/java/imports.xml"/> | ||||
|     <rule ref="rulesets/java/migrating.xml"/> | ||||
|     <rule ref="rulesets/java/unnecessary.xml"> | ||||
|         <exclude name="UselessParentheses"/> <!--Too nitpicky--> | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Peter Serwylo
						Peter Serwylo