1 /* 2 * Copyright (C) 2008 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.activity; 18 19 import com.android.email.Email; 20 import com.android.email.MessagingController; 21 import com.android.email.R; 22 23 import android.app.Application; 24 import android.content.Context; 25 import android.content.Intent; 26 import android.os.Environment; 27 import android.test.ActivityInstrumentationTestCase2; 28 import android.test.UiThreadTest; 29 import android.test.suitebuilder.annotation.LargeTest; 30 import android.test.suitebuilder.annotation.Suppress; 31 import android.view.View; 32 import android.webkit.WebView; 33 import android.widget.TextView; 34 35 import java.io.File; 36 import java.io.FileNotFoundException; 37 import java.io.FileOutputStream; 38 import java.io.IOException; 39 import java.io.OutputStream; 40 41 /** 42 * Various instrumentation tests for MessageCompose. 43 * 44 * It might be possible to convert these to ActivityUnitTest, which would be faster. 45 */ 46 @LargeTest 47 public class MessageViewTests 48 extends ActivityInstrumentationTestCase2<MessageView> { 49 50 // copied from MessageView (could be package class) 51 private static final String EXTRA_MESSAGE_ID = "com.android.email.MessageView_message_id"; 52 private static final String EXTRA_MAILBOX_ID = "com.android.email.MessageView_mailbox_id"; 53 54 private TextView mToView; 55 private TextView mSubjectView; 56 private WebView mMessageContentView; 57 private Context mContext; 58 MessageViewTests()59 public MessageViewTests() { 60 super(MessageView.class); 61 } 62 63 @Override setUp()64 protected void setUp() throws Exception { 65 super.setUp(); 66 67 mContext = getInstrumentation().getTargetContext(); 68 Email.setTempDirectory(mContext); 69 Email.setServicesEnabled(mContext); 70 71 // setup an intent to spin up this activity with something useful 72 // Long.MIN_VALUE are sentinels to command MessageView to skip loading 73 Intent i = new Intent() 74 .putExtra(EXTRA_MESSAGE_ID, Long.MIN_VALUE) 75 .putExtra(EXTRA_MAILBOX_ID, Long.MIN_VALUE); 76 this.setActivityIntent(i); 77 78 // configure a mock controller 79 MessagingController mockController = 80 new MockMessagingController(getActivity().getApplication()); 81 MessagingController.injectMockController(mockController); 82 83 final MessageView a = getActivity(); 84 mToView = (TextView) a.findViewById(R.id.to); 85 mSubjectView = (TextView) a.findViewById(R.id.subject); 86 mMessageContentView = (WebView) a.findViewById(R.id.message_content); 87 } 88 89 /** 90 * The name 'test preconditions' is a convention to signal that if this 91 * test doesn't pass, the test case was not set up properly and it might 92 * explain any and all failures in other tests. This is not guaranteed 93 * to run before other tests, as junit uses reflection to find the tests. 94 */ testPreconditions()95 public void testPreconditions() { 96 assertNotNull(mToView); 97 assertEquals(0, mToView.length()); 98 assertNotNull(mSubjectView); 99 assertEquals(0, mSubjectView.length()); 100 assertNotNull(mMessageContentView); 101 } 102 103 /** 104 * Test that we have the necessary permissions to write to external storage. 105 */ testAttachmentWritePermissions()106 public void testAttachmentWritePermissions() throws FileNotFoundException, IOException { 107 File file = null; 108 try { 109 // If there's no storage available, this test is moot 110 if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { 111 return; 112 } 113 file = MessageView.createUniqueFile(Environment.getExternalStorageDirectory(), 114 "write-test"); 115 OutputStream out = new FileOutputStream(file); 116 out.write(1); 117 out.close(); 118 } finally { 119 try { 120 if (file != null) { 121 if (file.exists()) { 122 file.delete(); 123 } 124 } 125 } catch (Exception e) { 126 // ignore cleanup error - it still throws the original 127 } 128 } 129 } 130 131 /** 132 * Tests that various UI calls can be made safely even before the messaging controller 133 * has completed loading the message. This catches various race conditions. 134 */ 135 @Suppress testUiRaceConditions()136 public void testUiRaceConditions() { 137 138 MessageView a = getActivity(); 139 140 // on-streen controls 141 a.onClick(a.findViewById(R.id.reply)); 142 a.onClick(a.findViewById(R.id.reply_all)); 143 a.onClick(a.findViewById(R.id.delete)); 144 a.onClick(a.findViewById(R.id.moveToOlder)); 145 a.onClick(a.findViewById(R.id.moveToNewer)); 146 // a.onClick(a.findViewById(R.id.download)); // not revealed yet, so unfair test 147 // a.onClick(a.findViewById(R.id.view)); // not revealed yet, so unfair test 148 a.onClick(a.findViewById(R.id.show_pictures)); 149 150 // menus 151 a.handleMenuItem(R.id.delete); 152 a.handleMenuItem(R.id.reply); 153 a.handleMenuItem(R.id.reply_all); 154 a.handleMenuItem(R.id.forward); 155 a.handleMenuItem(R.id.mark_as_unread); 156 } 157 158 /** 159 * Sets EXTRA_DISABLE_REPLY on the intent to true/false, and 160 * checks change in replyButton.isEnabled(). 161 */ 162 @UiThreadTest testDisableReply()163 public void testDisableReply() { 164 MessageView a = getActivity(); 165 View replyButton = a.findViewById(R.id.reply); 166 167 Intent i = new Intent(); 168 a.setIntent(i); 169 a.initFromIntent(); 170 assertTrue(replyButton.isEnabled()); 171 172 i.putExtra(MessageView.EXTRA_DISABLE_REPLY, true); 173 a.setIntent(i); 174 a.initFromIntent(); 175 assertFalse(replyButton.isEnabled()); 176 } 177 178 /** 179 * Mock Messaging controller, so we can drive its callbacks. This probably should be 180 * generalized since we're likely to use for other tests eventually. 181 */ 182 private static class MockMessagingController extends MessagingController { 183 MockMessagingController(Application application)184 private MockMessagingController(Application application) { 185 super(application); 186 } 187 } 188 } 189