mobile/android/base/tests/ContentProviderTest.java

Wed, 31 Dec 2014 07:22:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:22:50 +0100
branch
TOR_BUG_3246
changeset 4
fc2d59ddac77
permissions
-rw-r--r--

Correct previous dual key logic pending first delivery installment.

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4
michael@0 5 package org.mozilla.gecko.tests;
michael@0 6
michael@0 7 import java.io.File;
michael@0 8 import java.util.ArrayList;
michael@0 9 import java.util.LinkedList;
michael@0 10 import java.util.concurrent.Callable;
michael@0 11
michael@0 12 import org.mozilla.gecko.db.BrowserContract;
michael@0 13 import org.mozilla.gecko.db.BrowserProvider;
michael@0 14
michael@0 15 import android.content.ContentProvider;
michael@0 16 import android.content.ContentProviderOperation;
michael@0 17 import android.content.ContentProviderResult;
michael@0 18 import android.content.ContentValues;
michael@0 19 import android.content.Context;
michael@0 20 import android.content.OperationApplicationException;
michael@0 21 import android.content.SharedPreferences;
michael@0 22 import android.content.pm.ApplicationInfo;
michael@0 23 import android.content.res.AssetManager;
michael@0 24 import android.content.res.Resources;
michael@0 25 import android.database.ContentObserver;
michael@0 26 import android.database.Cursor;
michael@0 27 import android.net.Uri;
michael@0 28 import android.os.Build;
michael@0 29 import android.test.IsolatedContext;
michael@0 30 import android.test.RenamingDelegatingContext;
michael@0 31 import android.test.mock.MockContentResolver;
michael@0 32 import android.test.mock.MockContext;
michael@0 33
michael@0 34 /*
michael@0 35 * ContentProviderTest provides the infrastructure to run content provider
michael@0 36 * tests in an controlled/isolated environment, guaranteeing that your tests
michael@0 37 * will not affect or be affected by any UI-related code. This is basically
michael@0 38 * a heavily adapted port of Android's ProviderTestCase2 to work on Mozilla's
michael@0 39 * infrastructure.
michael@0 40 *
michael@0 41 * For some tests, we need to have access to UI parts, or at least launch
michael@0 42 * the activity so the assets with test data become available, which requires
michael@0 43 * that we derive this test from BaseTest and consequently pull in some more
michael@0 44 * UI code than we'd ideally want. Furthermore, we need to pass the
michael@0 45 * Activity and not the instrumentation Context for the UI part to find some
michael@0 46 * of its required resources.
michael@0 47 * Similarly, we need to pass the Activity instead of the Instrumentation
michael@0 48 * Context down to some of our users (still wrapped in the Delegating Provider)
michael@0 49 * because they will stop working correctly if we do not. A typical problem
michael@0 50 * is that databases used in the ContentProvider will be attempted to be
michael@0 51 * opened twice.
michael@0 52 */
michael@0 53 abstract class ContentProviderTest extends BaseTest {
michael@0 54 protected ContentProvider mProvider;
michael@0 55 protected ChangeRecordingMockContentResolver mResolver;
michael@0 56 protected ArrayList<Runnable> mTests;
michael@0 57 protected String mDatabaseName;
michael@0 58 protected String mProviderAuthority;
michael@0 59 protected IsolatedContext mProviderContext;
michael@0 60
michael@0 61 private class ContentProviderMockContext extends MockContext {
michael@0 62 @Override
michael@0 63 public Resources getResources() {
michael@0 64 // We will fail to find some resources if we don't point
michael@0 65 // at the original activity.
michael@0 66 return ((Context)getActivity()).getResources();
michael@0 67 }
michael@0 68
michael@0 69 @Override
michael@0 70 public String getPackageName() {
michael@0 71 return getInstrumentation().getContext().getPackageName();
michael@0 72 }
michael@0 73
michael@0 74 @Override
michael@0 75 public String getPackageResourcePath() {
michael@0 76 return getInstrumentation().getContext().getPackageResourcePath();
michael@0 77 }
michael@0 78
michael@0 79 @Override
michael@0 80 public File getDir(String name, int mode) {
michael@0 81 return getInstrumentation().getContext().getDir(this.getClass().getSimpleName() + "_" + name, mode);
michael@0 82 }
michael@0 83
michael@0 84 @Override
michael@0 85 public Context getApplicationContext() {
michael@0 86 return this;
michael@0 87 }
michael@0 88
michael@0 89 @Override
michael@0 90 public SharedPreferences getSharedPreferences(String name, int mode) {
michael@0 91 return getInstrumentation().getContext().getSharedPreferences(name, mode);
michael@0 92 }
michael@0 93
michael@0 94 @Override
michael@0 95 public ApplicationInfo getApplicationInfo() {
michael@0 96 return getInstrumentation().getContext().getApplicationInfo();
michael@0 97 }
michael@0 98 }
michael@0 99
michael@0 100 protected class DelegatingTestContentProvider extends ContentProvider {
michael@0 101 ContentProvider mTargetProvider;
michael@0 102
michael@0 103 public DelegatingTestContentProvider(ContentProvider targetProvider) {
michael@0 104 super();
michael@0 105 mTargetProvider = targetProvider;
michael@0 106 }
michael@0 107
michael@0 108 private Uri appendTestParam(Uri uri) {
michael@0 109 try {
michael@0 110 return appendUriParam(uri, BrowserContract.PARAM_IS_TEST, "1");
michael@0 111 } catch (Exception e) {}
michael@0 112
michael@0 113 return null;
michael@0 114 }
michael@0 115
michael@0 116 @Override
michael@0 117 public boolean onCreate() {
michael@0 118 return mTargetProvider.onCreate();
michael@0 119 }
michael@0 120
michael@0 121 @Override
michael@0 122 public String getType(Uri uri) {
michael@0 123 return mTargetProvider.getType(uri);
michael@0 124 }
michael@0 125
michael@0 126 @Override
michael@0 127 public int delete(Uri uri, String selection, String[] selectionArgs) {
michael@0 128 return mTargetProvider.delete(appendTestParam(uri), selection, selectionArgs);
michael@0 129 }
michael@0 130
michael@0 131 @Override
michael@0 132 public Uri insert(Uri uri, ContentValues values) {
michael@0 133 return mTargetProvider.insert(appendTestParam(uri), values);
michael@0 134 }
michael@0 135
michael@0 136 @Override
michael@0 137 public int update(Uri uri, ContentValues values, String selection,
michael@0 138 String[] selectionArgs) {
michael@0 139 return mTargetProvider.update(appendTestParam(uri), values,
michael@0 140 selection, selectionArgs);
michael@0 141 }
michael@0 142
michael@0 143 @Override
michael@0 144 public Cursor query(Uri uri, String[] projection, String selection,
michael@0 145 String[] selectionArgs, String sortOrder) {
michael@0 146 return mTargetProvider.query(appendTestParam(uri), projection, selection,
michael@0 147 selectionArgs, sortOrder);
michael@0 148 }
michael@0 149
michael@0 150 @Override
michael@0 151 public ContentProviderResult[] applyBatch (ArrayList<ContentProviderOperation> operations)
michael@0 152 throws OperationApplicationException {
michael@0 153 return mTargetProvider.applyBatch(operations);
michael@0 154 }
michael@0 155
michael@0 156 @Override
michael@0 157 public int bulkInsert(Uri uri, ContentValues[] values) {
michael@0 158 return mTargetProvider.bulkInsert(appendTestParam(uri), values);
michael@0 159 }
michael@0 160
michael@0 161 public ContentProvider getTargetProvider() {
michael@0 162 return mTargetProvider;
michael@0 163 }
michael@0 164 }
michael@0 165
michael@0 166 /*
michael@0 167 * A MockContentResolver that records each URI that is supplied to
michael@0 168 * notifyChange. Warning: the list of changed URIs is not
michael@0 169 * synchronized.
michael@0 170 */
michael@0 171 protected class ChangeRecordingMockContentResolver extends MockContentResolver {
michael@0 172 public final LinkedList<Uri> notifyChangeList = new LinkedList<Uri>();
michael@0 173
michael@0 174 @Override
michael@0 175 public void notifyChange(Uri uri, ContentObserver observer, boolean syncToNetwork) {
michael@0 176 notifyChangeList.addLast(uri);
michael@0 177
michael@0 178 super.notifyChange(uri, observer, syncToNetwork);
michael@0 179 }
michael@0 180 }
michael@0 181
michael@0 182 /**
michael@0 183 * Factory function that makes new ContentProvider instances.
michael@0 184 * <p>
michael@0 185 * We want a fresh provider each test, so this should be invoked in
michael@0 186 * <code>setUp</code> before each individual test.
michael@0 187 */
michael@0 188 protected static Callable<ContentProvider> sBrowserProviderCallable = new Callable<ContentProvider>() {
michael@0 189 @Override
michael@0 190 public ContentProvider call() {
michael@0 191 return new BrowserProvider();
michael@0 192 }
michael@0 193 };
michael@0 194
michael@0 195 private void setUpContentProvider(ContentProvider targetProvider) throws Exception {
michael@0 196 mResolver = new ChangeRecordingMockContentResolver();
michael@0 197
michael@0 198 final String filenamePrefix = this.getClass().getSimpleName() + ".";
michael@0 199 RenamingDelegatingContext targetContextWrapper =
michael@0 200 new RenamingDelegatingContext(
michael@0 201 new ContentProviderMockContext(),
michael@0 202 (Context)getActivity(),
michael@0 203 filenamePrefix);
michael@0 204
michael@0 205 mProviderContext = new IsolatedContext(mResolver, targetContextWrapper);
michael@0 206
michael@0 207 targetProvider.attachInfo(mProviderContext, null);
michael@0 208
michael@0 209 mProvider = new DelegatingTestContentProvider(targetProvider);
michael@0 210 mProvider.attachInfo(mProviderContext, null);
michael@0 211
michael@0 212 mResolver.addProvider(mProviderAuthority, mProvider);
michael@0 213 }
michael@0 214
michael@0 215 public static Uri appendUriParam(Uri uri, String param, String value) {
michael@0 216 return uri.buildUpon().appendQueryParameter(param, value).build();
michael@0 217 }
michael@0 218
michael@0 219 public void setTestName(String testName) {
michael@0 220 mAsserter.setTestName(this.getClass().getName() + " - " + testName);
michael@0 221 }
michael@0 222
michael@0 223 @Override
michael@0 224 public void setUp() throws Exception {
michael@0 225 throw new UnsupportedOperationException("You should call setUp(authority, databaseName) instead");
michael@0 226 }
michael@0 227
michael@0 228 public void setUp(Callable<ContentProvider> contentProviderFactory, String authority, String databaseName) throws Exception {
michael@0 229 super.setUp();
michael@0 230
michael@0 231 mTests = new ArrayList<Runnable>();
michael@0 232 mDatabaseName = databaseName;
michael@0 233
michael@0 234 mProviderAuthority = authority;
michael@0 235
michael@0 236 setUpContentProvider(contentProviderFactory.call());
michael@0 237 }
michael@0 238
michael@0 239 @Override
michael@0 240 public void tearDown() throws Exception {
michael@0 241 if (Build.VERSION.SDK_INT >= 11) {
michael@0 242 mProvider.shutdown();
michael@0 243 }
michael@0 244
michael@0 245 if (mDatabaseName != null) {
michael@0 246 mProviderContext.deleteDatabase(mDatabaseName);
michael@0 247 }
michael@0 248
michael@0 249 super.tearDown();
michael@0 250 }
michael@0 251
michael@0 252 public AssetManager getAssetManager() {
michael@0 253 return getInstrumentation().getContext().getAssets();
michael@0 254 }
michael@0 255 }

mercurial