1 /* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.email; 18 19 import com.android.email.provider.AttachmentProvider; 20 import com.android.email.provider.ContentCache; 21 import com.android.email.provider.EmailProvider; 22 import com.android.emailcommon.provider.EmailContent; 23 import com.android.emailcommon.utility.AttachmentUtilities; 24 25 import android.content.ContentProvider; 26 import android.content.ContentResolver; 27 import android.content.ContentValues; 28 import android.content.Context; 29 import android.content.SharedPreferences; 30 import android.content.res.Resources; 31 import android.content.res.Resources.Theme; 32 import android.database.Cursor; 33 import android.net.Uri; 34 import android.test.IsolatedContext; 35 import android.test.RenamingDelegatingContext; 36 import android.test.mock.MockContentResolver; 37 import android.test.mock.MockContext; 38 import android.test.mock.MockCursor; 39 40 import java.io.File; 41 42 /** 43 * Helper classes (and possibly methods) for database related tests. 44 */ 45 public final class DBTestHelper { 46 private DBTestHelper() { // Utility class. No instantiation. 47 } 48 49 /** 50 * A simple {@link Context} that returns {@link MyProvider} as the email content provider. 51 */ 52 public static class MyContext extends MockContext { 53 private final MockContentResolver mContentResolver; 54 private final MyProvider mProvider; 55 56 public MyContext() { 57 mProvider = new MyProvider(); 58 mContentResolver = new MockContentResolver(); 59 mContentResolver.addProvider(EmailContent.AUTHORITY, mProvider); 60 } 61 62 @Override 63 public ContentResolver getContentResolver() { 64 return mContentResolver; 65 } 66 67 public MyProvider getMyProvider() { 68 return mProvider; 69 } 70 } 71 72 /** 73 * A simply {@link ContentProvider} to mock out {@link ContentProvider#query}. 74 */ 75 public static class MyProvider extends ContentProvider { 76 public Cursor mQueryPresetResult; 77 public Uri mPassedUri; 78 public String[] mPassedProjection; 79 public String mPassedSelection; 80 public String[] mPassedSelectionArgs; 81 public String mPassedSortOrder; 82 83 public void reset() { 84 mQueryPresetResult = null; 85 mPassedUri = null; 86 mPassedProjection = null; 87 mPassedSelection = null; 88 mPassedSelectionArgs = null; 89 mPassedSortOrder = null; 90 } 91 92 @Override 93 public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, 94 String sortOrder) { 95 mPassedUri = uri; 96 mPassedProjection = projection; 97 mPassedSelection = selection; 98 mPassedSelectionArgs = selectionArgs; 99 mPassedSortOrder = sortOrder; 100 return mQueryPresetResult; 101 } 102 103 @Override 104 public int delete(Uri uri, String selection, String[] selectionArgs) { 105 throw new UnsupportedOperationException(); 106 } 107 108 @Override 109 public String getType(Uri uri) { 110 throw new UnsupportedOperationException(); 111 } 112 113 @Override 114 public Uri insert(Uri uri, ContentValues values) { 115 throw new UnsupportedOperationException(); 116 } 117 118 @Override 119 public boolean onCreate() { 120 throw new UnsupportedOperationException(); 121 } 122 123 @Override 124 public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { 125 throw new UnsupportedOperationException(); 126 } 127 } 128 129 /** 130 * Simple {@link MockCursor} subclass that implements common methods. 131 */ 132 public static class EasyMockCursor extends MockCursor { 133 public int mCount; 134 public boolean mClosed; 135 136 public EasyMockCursor(int count) { 137 mCount = count; 138 } 139 140 @Override 141 public int getCount() { 142 return mCount; 143 } 144 145 @Override 146 public void close() { 147 mClosed = true; 148 } 149 } 150 151 /** 152 * This class has only one method, that creats an isolated {@link Context} similar to what 153 * {@link android.test.ProviderTestCase2} provides. 154 * 155 * The method also creates a {@link ContentProvider} of {@code providerClass}, and add it to 156 * the context. See the javadoc on android.test.ProviderTestCase2 for the details. 157 */ 158 public static class ProviderContextSetupHelper { 159 // Based on ProviderTestCase2.MockContext2. 160 private static class MockContext2 extends MockContext { 161 private final Context mBaseContext; 162 163 public MockContext2(Context baseContext) { 164 mBaseContext = baseContext; 165 } 166 167 @Override 168 public Resources getResources() { 169 return mBaseContext.getResources(); 170 } 171 172 @Override 173 public File getDir(String name, int mode) { 174 return mBaseContext.getDir("mockcontext2_" + name, mode); 175 } 176 } 177 178 /** {@link IsolatedContext} + getApplicationContext() */ 179 private static class MyIsolatedContext extends IsolatedContext { 180 private final Context mRealContext; 181 182 public MyIsolatedContext(ContentResolver resolver, Context targetContext, 183 Context realContext) { 184 super(resolver, targetContext); 185 mRealContext = realContext; 186 } 187 188 @Override 189 public Context getApplicationContext() { 190 return this; 191 } 192 193 // Following methods are not supported by the mock context. 194 // Redirect to the actual context. 195 @Override 196 public String getPackageName() { 197 return mRealContext.getPackageName(); 198 } 199 200 @Override 201 public Theme getTheme() { 202 return mRealContext.getTheme(); 203 } 204 205 @Override 206 public SharedPreferences getSharedPreferences(String name, int mode) { 207 return new MockSharedPreferences(); 208 } 209 210 @Override 211 public Object getSystemService(String name) { 212 if (Context.LAYOUT_INFLATER_SERVICE.equals(name)) { 213 return mRealContext.getSystemService(name); 214 } 215 return super.getSystemService(name); 216 } 217 } 218 219 /** 220 * Return {@link Context} with isolated EmailProvider and AttachmentProvider. This method 221 * also invalidates the DB cache. 222 */ 223 public static Context getProviderContext(Context context) throws Exception { 224 MockContentResolver resolver = new MockContentResolver(); 225 final String filenamePrefix = "test."; 226 RenamingDelegatingContext targetContextWrapper = new RenamingDelegatingContext( 227 new MockContext2(context), // The context that most methods are delegated to 228 context, // The context that file methods are delegated to 229 filenamePrefix); 230 final Context providerContext = new MyIsolatedContext(resolver, targetContextWrapper, 231 context); 232 providerContext.getContentResolver(); 233 234 // register EmailProvider and AttachmentProvider. 235 final EmailProvider ep = new EmailProvider(); 236 ep.attachInfo(providerContext, null); 237 resolver.addProvider(EmailContent.AUTHORITY, ep); 238 239 final AttachmentProvider ap = new AttachmentProvider(); 240 ap.attachInfo(providerContext, null); 241 resolver.addProvider(AttachmentUtilities.AUTHORITY, ap); 242 243 ContentCache.invalidateAllCaches(); 244 245 return providerContext; 246 } 247 } 248 } 249