1/* 2 * Copyright (C) 2006 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 17package android.test; 18 19import android.content.ContentValues; 20import android.content.Context; 21import android.content.Intent; 22import android.net.Uri; 23import junit.framework.TestCase; 24 25import java.lang.reflect.Field; 26 27/** 28 * Extend this if you need to access Resources or other things that depend on Activity Context. 29 */ 30public class AndroidTestCase extends TestCase { 31 32 protected Context mContext; 33 private Context mTestContext; 34 35 @Override 36 protected void setUp() throws Exception { 37 super.setUp(); 38 } 39 40 @Override 41 protected void tearDown() throws Exception { 42 super.tearDown(); 43 } 44 45 public void testAndroidTestCaseSetupProperly() { 46 assertNotNull("Context is null. setContext should be called before tests are run", 47 mContext); 48 } 49 50 public void setContext(Context context) { 51 mContext = context; 52 } 53 54 public Context getContext() { 55 return mContext; 56 } 57 58 /** 59 * Test context can be used to access resources from the test's own package 60 * as opposed to the resources from the test target package. Access to the 61 * latter is provided by the context set with the {@link #setContext} 62 * method. 63 * 64 * @hide 65 */ 66 public void setTestContext(Context context) { 67 mTestContext = context; 68 } 69 70 /** 71 * @hide 72 */ 73 public Context getTestContext() { 74 return mTestContext; 75 } 76 77 /** 78 * Asserts that launching a given activity is protected by a particular permission by 79 * attempting to start the activity and validating that a {@link SecurityException} 80 * is thrown that mentions the permission in its error message. 81 * 82 * Note that an instrumentation isn't needed because all we are looking for is a security error 83 * and we don't need to wait for the activity to launch and get a handle to the activity. 84 * 85 * @param packageName The package name of the activity to launch. 86 * @param className The class of the activity to launch. 87 * @param permission The name of the permission. 88 */ 89 public void assertActivityRequiresPermission( 90 String packageName, String className, String permission) { 91 final Intent intent = new Intent(); 92 intent.setClassName(packageName, className); 93 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 94 95 try { 96 getContext().startActivity(intent); 97 fail("expected security exception for " + permission); 98 } catch (SecurityException expected) { 99 assertNotNull("security exception's error message.", expected.getMessage()); 100 assertTrue("error message should contain " + permission + ".", 101 expected.getMessage().contains(permission)); 102 } 103 } 104 105 106 /** 107 * Asserts that reading from the content uri requires a particular permission by querying the 108 * uri and ensuring a {@link SecurityException} is thrown mentioning the particular permission. 109 * 110 * @param uri The uri that requires a permission to query. 111 * @param permission The permission that should be required. 112 */ 113 public void assertReadingContentUriRequiresPermission(Uri uri, String permission) { 114 try { 115 getContext().getContentResolver().query(uri, null, null, null, null); 116 fail("expected SecurityException requiring " + permission); 117 } catch (SecurityException expected) { 118 assertNotNull("security exception's error message.", expected.getMessage()); 119 assertTrue("error message should contain " + permission + ".", 120 expected.getMessage().contains(permission)); 121 } 122 } 123 124 /** 125 * Asserts that writing to the content uri requires a particular permission by inserting into 126 * the uri and ensuring a {@link SecurityException} is thrown mentioning the particular 127 * permission. 128 * 129 * @param uri The uri that requires a permission to query. 130 * @param permission The permission that should be required. 131 */ 132 public void assertWritingContentUriRequiresPermission(Uri uri, String permission) { 133 try { 134 getContext().getContentResolver().insert(uri, new ContentValues()); 135 fail("expected SecurityException requiring " + permission); 136 } catch (SecurityException expected) { 137 assertNotNull("security exception's error message.", expected.getMessage()); 138 assertTrue("error message should contain " + permission + ".", 139 expected.getMessage().contains(permission)); 140 } 141 } 142 143 /** 144 * This function is called by various TestCase implementations, at tearDown() time, in order 145 * to scrub out any class variables. This protects against memory leaks in the case where a 146 * test case creates a non-static inner class (thus referencing the test case) and gives it to 147 * someone else to hold onto. 148 * 149 * @param testCaseClass The class of the derived TestCase implementation. 150 * 151 * @throws IllegalAccessException 152 */ 153 protected void scrubClass(final Class<?> testCaseClass) 154 throws IllegalAccessException { 155 final Field[] fields = getClass().getDeclaredFields(); 156 for (Field field : fields) { 157 final Class<?> fieldClass = field.getDeclaringClass(); 158 if (testCaseClass.isAssignableFrom(fieldClass) && !field.getType().isPrimitive()) { 159 try { 160 field.setAccessible(true); 161 field.set(this, null); 162 } catch (Exception e) { 163 android.util.Log.d("TestCase", "Error: Could not nullify field!"); 164 } 165 166 if (field.get(this) != null) { 167 android.util.Log.d("TestCase", "Error: Could not nullify field!"); 168 } 169 } 170 } 171 } 172 173 174} 175