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