Home | History | Annotate | Download | only in compose
      1 /**
      2  * Copyright (c) 2012, Google Inc.
      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.mail.compose;
     18 
     19 import android.content.ContentResolver;
     20 import android.content.Context;
     21 import android.content.Intent;
     22 import android.database.Cursor;
     23 import android.database.MatrixCursor;
     24 import android.net.Uri;
     25 import android.test.ActivityInstrumentationTestCase2;
     26 import android.test.suitebuilder.annotation.SmallTest;
     27 import android.text.Html;
     28 import android.text.TextUtils;
     29 import android.text.util.Rfc822Tokenizer;
     30 
     31 import com.android.mail.providers.Account;
     32 import com.android.mail.providers.Attachment;
     33 import com.android.mail.providers.MailAppProvider;
     34 import com.android.mail.providers.Message;
     35 import com.android.mail.providers.ReplyFromAccount;
     36 import com.android.mail.providers.UIProvider;
     37 import com.android.mail.utils.AccountUtils;
     38 import com.android.mail.utils.MatrixCursorWithCachedColumns;
     39 import com.android.mail.utils.Utils;
     40 
     41 import org.json.JSONArray;
     42 import org.json.JSONException;
     43 
     44 import java.io.UnsupportedEncodingException;
     45 import java.net.URLEncoder;
     46 import java.util.Date;
     47 import java.util.HashSet;
     48 
     49 @SmallTest
     50 public class ComposeActivityTest extends ActivityInstrumentationTestCase2<ComposeActivity> {
     51     // TODO: Remove usages of FromAddressSpinner#initialize and ComposeActivity#initReplyRecipients.
     52     // The internal state of the activity instance may have the wrong mReplyFromAccount as
     53     // this is set when handling the initial intent.  Theses tests should
     54     // instantiate the ComposeActivity with the correct reply all intent
     55 
     56     // This varible shouldn't be used, as it may not match the state of the ComposeActivity
     57     // TODO: remove usage of this variable
     58     @Deprecated
     59     private Account mAccount;
     60 
     61     private static final Account[] EMPTY_ACCOUNT_LIST = new Account[0];
     62 
     63     public ComposeActivityTest() {
     64         super(ComposeActivity.class);
     65     }
     66 
     67     private Message getRefMessage(ContentResolver resolver, Uri folderListUri) {
     68         Cursor foldersCursor = resolver.query(folderListUri,
     69                 UIProvider.FOLDERS_PROJECTION, null, null, null);
     70         Uri convUri = null;
     71         if (foldersCursor != null) {
     72             foldersCursor.moveToFirst();
     73             convUri = Uri.parse(foldersCursor
     74                     .getString(UIProvider.FOLDER_CONVERSATION_LIST_URI_COLUMN));
     75             foldersCursor.close();
     76         }
     77 
     78         Cursor convCursor = resolver.query(convUri,
     79                 UIProvider.CONVERSATION_PROJECTION, null, null, null);
     80         Uri messagesUri = null;
     81         if (convCursor != null) {
     82             convCursor.moveToFirst();
     83             messagesUri = Uri.parse(convCursor
     84                     .getString(UIProvider.CONVERSATION_MESSAGE_LIST_URI_COLUMN));
     85             convCursor.close();
     86         }
     87 
     88         Cursor msgCursor = resolver.query(messagesUri,
     89                 UIProvider.MESSAGE_PROJECTION, null, null, null);
     90         if (msgCursor != null) {
     91             msgCursor.moveToFirst();
     92         }
     93         return new Message(msgCursor);
     94     }
     95 
     96 
     97     private Message getRefMessage(ContentResolver resolver) {
     98         final Account account = getActivity().getFromAccount();
     99         return getRefMessage(resolver, account.folderListUri);
    100     }
    101 
    102     public void setAccount(ComposeActivity activity, String accountName) {
    103         // Get a mock account.
    104         final Account account = getAccountForName(activity, accountName);
    105         if (account != null) {
    106             mAccount = account;
    107             activity.setAccount(mAccount);
    108         }
    109     }
    110 
    111     private Account[] getAccounts(Context context) {
    112         return AccountUtils.getSyncingAccounts(context);
    113     }
    114 
    115     private Account getAccountForName(Context context, String accountName) {
    116         Account[] results = getAccounts(context);
    117         for (Account account : results) {
    118             if (account.getEmailAddress().equals(accountName)) {
    119                 return account;
    120             }
    121         }
    122         return null;
    123     }
    124 
    125     /**
    126      * Test the cases where: The user's reply-to is one of their custom from's
    127      * and they are replying all to a message where their custom from was a
    128      * recipient. TODO: verify web behavior
    129      */
    130     public void testRecipientsRefReplyAllCustomFromReplyTo() throws Throwable {
    131         final ComposeActivity activity = getActivity();
    132         setAccount(activity, "account3 (at) mockuiprovider.com");
    133         final Message refMessage = getRefMessage(activity.getContentResolver());
    134         final String customFrom = "CUSTOMaccount3 (at) mockuiprovider.com";
    135         refMessage.setFrom("account3 (at) mockuiprovider.com");
    136         refMessage.setTo("someotheraccount1 (at) mockuiprovider.com, "
    137                 + "someotheraccount2 (at) mockuiprovider.com, someotheraccount3 (at) mockuiprovider.com, "
    138                 + customFrom);
    139         refMessage.setReplyTo(customFrom);
    140 
    141         ReplyFromAccount a = new ReplyFromAccount(mAccount, mAccount.uri, customFrom,
    142                 customFrom, customFrom, true, true);
    143         JSONArray array = new JSONArray();
    144         array.put(a.serialize());
    145         mAccount.accountFromAddresses = array.toString();
    146         final ReplyFromAccount currentAccount = new ReplyFromAccount(mAccount, mAccount.uri,
    147                 mAccount.getEmailAddress(), mAccount.getEmailAddress(), customFrom, true, false);
    148         runTestOnUiThread(new Runnable() {
    149             @Override
    150             public void run() {
    151                 activity.mFromSpinner = new FromAddressSpinner(activity);
    152                 activity.mFromSpinner.setCurrentAccount(currentAccount);
    153                 activity.mFromSpinner.initialize(ComposeActivity.REPLY_ALL,
    154                         currentAccount.account, EMPTY_ACCOUNT_LIST, null);
    155 
    156                 activity.initReplyRecipients(refMessage, ComposeActivity.REPLY_ALL);
    157                 String[] to = activity.getToAddresses();
    158                 String[] cc = activity.getCcAddresses();
    159                 String[] bcc = activity.getBccAddresses();
    160                 String toAsString = TextUtils.join(",", to);
    161                 assertEquals(3, to.length);
    162                 assertFalse(toAsString.contains(customFrom));
    163                 assertEquals(0, cc.length);
    164                 assertEquals(0, bcc.length);
    165             }
    166         });
    167     }
    168 
    169     /**
    170      * Test the cases where: The user sent a message to one of
    171      * their custom froms and just replied to that message
    172      */
    173     public void testRecipientsRefReplyAllOnlyAccount() throws Throwable {
    174         final ComposeActivity activity = getActivity();
    175         setAccount(activity, "account3 (at) mockuiprovider.com");
    176         final Message refMessage = getRefMessage(activity.getContentResolver());
    177         refMessage.setFrom("account3 (at) mockuiprovider.com");
    178         refMessage.setTo("account3 (at) mockuiprovider.com");
    179         final Account account = mAccount;
    180 
    181         final ReplyFromAccount currentAccount = new ReplyFromAccount(mAccount, mAccount.uri,
    182                 mAccount.getEmailAddress(), mAccount.getEmailAddress(), mAccount.getEmailAddress(),
    183                 true, false);
    184 
    185         runTestOnUiThread(new Runnable() {
    186             @Override
    187             public void run() {
    188                 activity.mFromSpinner = new FromAddressSpinner(activity);
    189                 activity.mFromSpinner.setCurrentAccount(currentAccount);
    190                 activity.mFromSpinner.initialize(ComposeActivity.REPLY_ALL,
    191                         currentAccount.account, EMPTY_ACCOUNT_LIST, null);
    192 
    193                 activity.initReplyRecipients(refMessage, ComposeActivity.REPLY_ALL);
    194                 String[] to = activity.getToAddresses();
    195                 String[] cc = activity.getCcAddresses();
    196                 String[] bcc = activity.getBccAddresses();
    197                 String toAsString = TextUtils.join(",", to);
    198                 assertEquals(1, to.length);
    199                 assertTrue(toAsString.contains(account.getEmailAddress()));
    200                 assertEquals(0, cc.length);
    201                 assertEquals(0, bcc.length);
    202             }
    203         });
    204     }
    205 
    206     /**
    207      * Test the cases where: The user sent a message to one of
    208      * their custom froms and just replied to that message
    209      */
    210     public void testRecipientsRefReplyAllOnlyCustomFrom() throws Throwable {
    211         final ComposeActivity activity = getActivity();
    212         setAccount(activity, "account3 (at) mockuiprovider.com");
    213         final Message refMessage = getRefMessage(activity.getContentResolver());
    214         final String customFrom = "CUSTOMaccount3 (at) mockuiprovider.com";
    215         refMessage.setFrom("account3 (at) mockuiprovider.com");
    216         refMessage.setTo(customFrom);
    217 
    218         ReplyFromAccount a = new ReplyFromAccount(mAccount, mAccount.uri, customFrom,
    219                 customFrom, customFrom, true, true);
    220         JSONArray array = new JSONArray();
    221         array.put(a.serialize());
    222         mAccount.accountFromAddresses = array.toString();
    223         final ReplyFromAccount currentAccount = new ReplyFromAccount(mAccount, mAccount.uri,
    224                 mAccount.getEmailAddress(), mAccount.getEmailAddress(), customFrom, true, false);
    225 
    226         runTestOnUiThread(new Runnable() {
    227             @Override
    228             public void run() {
    229                 activity.mFromSpinner = new FromAddressSpinner(activity);
    230                 activity.mFromSpinner.setCurrentAccount(currentAccount);
    231                 activity.mFromSpinner.initialize(ComposeActivity.REPLY_ALL,
    232                         currentAccount.account, EMPTY_ACCOUNT_LIST, null);
    233 
    234                 activity.initReplyRecipients(refMessage, ComposeActivity.REPLY_ALL);
    235                 String[] to = activity.getToAddresses();
    236                 String[] cc = activity.getCcAddresses();
    237                 String[] bcc = activity.getBccAddresses();
    238                 String toAsString = TextUtils.join(",", to);
    239                 assertEquals(1, to.length);
    240                 assertTrue(toAsString.contains(customFrom));
    241                 assertEquals(0, cc.length);
    242                 assertEquals(0, bcc.length);
    243             }
    244         });
    245     }
    246 
    247     public void testReply() throws Throwable {
    248         final ComposeActivity activity = getActivity();
    249         setAccount(activity, "account0 (at) mockuiprovider.com");
    250         final Message refMessage = getRefMessage(activity.getContentResolver());
    251         final String refMessageFromAccount = refMessage.getFrom();
    252 
    253         runTestOnUiThread(new Runnable() {
    254             @Override
    255             public void run() {
    256                 activity.initReplyRecipients(refMessage, ComposeActivity.REPLY);
    257                 String[] to = activity.getToAddresses();
    258                 String[] cc = activity.getCcAddresses();
    259                 String[] bcc = activity.getBccAddresses();
    260                 assertTrue(to.length == 1);
    261                 assertEquals(refMessageFromAccount,
    262                         Rfc822Tokenizer.tokenize(to[0])[0].getAddress());
    263                 assertTrue(cc.length == 0);
    264                 assertTrue(bcc.length == 0);
    265             }
    266         });
    267     }
    268 
    269     public void testReplyWithReplyTo() throws Throwable {
    270         final ComposeActivity activity = getActivity();
    271         setAccount(activity, "account1 (at) mockuiprovider.com");
    272         final Message refMessage = getRefMessage(activity.getContentResolver());
    273         refMessage.setReplyTo("replytofromaccount1 (at) mock.com");
    274         final String refReplyToAccount = refMessage.getReplyTo();
    275 
    276         runTestOnUiThread(new Runnable() {
    277             @Override
    278             public void run() {
    279                 activity.initReplyRecipients(refMessage, ComposeActivity.REPLY);
    280                 String[] to = activity.getToAddresses();
    281                 String[] cc = activity.getCcAddresses();
    282                 String[] bcc = activity.getBccAddresses();
    283                 assertTrue(to.length == 1);
    284                 assertEquals(refReplyToAccount,
    285                         Rfc822Tokenizer.tokenize(to[0])[0].getAddress());
    286                 assertTrue(cc.length == 0);
    287                 assertTrue(bcc.length == 0);
    288             }
    289         });
    290     }
    291 
    292     /**
    293      * Reply to a message you sent yourself to some recipients in the to field.
    294      */
    295     public void testReplyToSelf() throws Throwable {
    296         final ComposeActivity activity = getActivity();
    297         setAccount(activity, "account1 (at) mockuiprovider.com");
    298         final Message refMessage = getRefMessage(activity.getContentResolver());
    299         refMessage.setFrom("Account Test <account1 (at) mockuiprovider.com>");
    300         refMessage.setTo("test1 (at) gmail.com");
    301         runTestOnUiThread(new Runnable() {
    302             @Override
    303             public void run() {
    304                 activity.initReplyRecipients(refMessage, ComposeActivity.REPLY);
    305                 String[] to = activity.getToAddresses();
    306                 String[] cc = activity.getCcAddresses();
    307                 String[] bcc = activity.getBccAddresses();
    308                 assertTrue(to.length == 1);
    309                 String toAsString = TextUtils.join(",", to);
    310                 assertTrue(toAsString.contains("test1 (at) gmail.com"));
    311                 assertTrue(cc.length == 0);
    312                 assertTrue(bcc.length == 0);
    313             }
    314         });
    315     }
    316 
    317     /**
    318      * Reply-all to a message you sent.
    319      */
    320     public void testReplyAllToSelf() throws Throwable {
    321         final ComposeActivity activity = getActivity();
    322         setAccount(activity, "account1 (at) mockuiprovider.com");
    323         final Message refMessage = getRefMessage(activity.getContentResolver());
    324         refMessage.setFrom("Account Test <account1 (at) mockuiprovider.com>");
    325         refMessage.setTo("test1 (at) gmail.com, test2 (at) gmail.com");
    326         runTestOnUiThread(new Runnable() {
    327             @Override
    328             public void run() {
    329                 activity.initReplyRecipients(refMessage, ComposeActivity.REPLY_ALL);
    330                 String[] to = activity.getToAddresses();
    331                 String[] cc = activity.getCcAddresses();
    332                 String[] bcc = activity.getBccAddresses();
    333                 assertEquals(to.length, 2);
    334                 String toAsString = TextUtils.join(",", to);
    335                 assertTrue(toAsString.contains("test1 (at) gmail.com"));
    336                 assertTrue(toAsString.contains("test2 (at) gmail.com"));
    337                 assertTrue(cc.length == 0);
    338                 assertTrue(bcc.length == 0);
    339             }
    340         });
    341     }
    342 
    343     /**
    344      * Reply-all to a message you sent with some to and some CC recips.
    345      */
    346     public void testReplyAllToSelfWithCc() throws Throwable {
    347         final ComposeActivity activity = getActivity();
    348         setAccount(activity, "account1 (at) mockuiprovider.com");
    349         final Message refMessage = getRefMessage(activity.getContentResolver());
    350         refMessage.setFrom("Account Test <account1 (at) mockuiprovider.com>");
    351         refMessage.setTo("test1 (at) gmail.com, test2 (at) gmail.com");
    352         refMessage.setCc("testcc (at) gmail.com");
    353         runTestOnUiThread(new Runnable() {
    354             @Override
    355             public void run() {
    356                 activity.initReplyRecipients(refMessage, ComposeActivity.REPLY_ALL);
    357                 String[] to = activity.getToAddresses();
    358                 String[] cc = activity.getCcAddresses();
    359                 String[] bcc = activity.getBccAddresses();
    360                 assertEquals(to.length, 2);
    361                 String toAsString = TextUtils.join(",", to);
    362                 assertTrue(toAsString.contains("test1 (at) gmail.com"));
    363                 assertTrue(toAsString.contains("test2 (at) gmail.com"));
    364                 String ccAsString = TextUtils.join(",", cc);
    365                 assertTrue(ccAsString.contains("testcc (at) gmail.com"));
    366                 assertTrue(cc.length == 1);
    367                 assertTrue(bcc.length == 0);
    368             }
    369         });
    370     }
    371 
    372     public void testReplyAll() throws Throwable {
    373         final ComposeActivity activity = getActivity();
    374         setAccount(activity, "account0 (at) mockuiprovider.com");
    375         final Message refMessage = getRefMessage(activity.getContentResolver());
    376         final String[] refMessageTo = TextUtils.split(refMessage.getTo(), ",");
    377         final String refMessageFromAccount = refMessage.getFrom();
    378 
    379         runTestOnUiThread(new Runnable() {
    380             @Override
    381             public void run() {
    382                 activity.initReplyRecipients(refMessage, ComposeActivity.REPLY_ALL);
    383                 String[] to = activity.getToAddresses();
    384                 String[] cc = activity.getCcAddresses();
    385                 String[] bcc = activity.getBccAddresses();
    386                 assertTrue(to.length == 1);
    387                 assertEquals(refMessageFromAccount,
    388                         Rfc822Tokenizer.tokenize(to[0])[0].getAddress());
    389                 assertEquals(cc.length, refMessageTo.length);
    390                 assertTrue(bcc.length == 0);
    391             }
    392         });
    393     }
    394 
    395     public void testReplyAllWithReplyTo() throws Throwable {
    396         final ComposeActivity activity = getActivity();
    397         setAccount(activity, "account1 (at) mockuiprovider.com");
    398         final Message refMessage = getRefMessage(activity.getContentResolver());
    399         refMessage.setReplyTo("replytofromaccount1 (at) mock.com");
    400         final String[] refMessageTo = TextUtils.split(refMessage.getTo(), ",");
    401         final String refReplyToAccount = refMessage.getReplyTo();
    402 
    403         runTestOnUiThread(new Runnable() {
    404             @Override
    405             public void run() {
    406                 activity.initReplyRecipients(refMessage, ComposeActivity.REPLY_ALL);
    407                 String[] to = activity.getToAddresses();
    408                 String[] cc = activity.getCcAddresses();
    409                 String[] bcc = activity.getBccAddresses();
    410                 assertTrue(to.length == 1);
    411                 assertEquals(refReplyToAccount, Rfc822Tokenizer.tokenize(to[0])[0].getAddress());
    412                 assertEquals(cc.length, refMessageTo.length);
    413                 assertTrue(bcc.length == 0);
    414             }
    415         });
    416     }
    417 
    418     private static Message getRefMessageWithCc(long messageId, boolean hasAttachments) {
    419         MatrixCursor cursor = new MatrixCursorWithCachedColumns(UIProvider.MESSAGE_PROJECTION);
    420         final String messageUri = "content://xxx/message/" + messageId;
    421         Object[] messageValues = new Object[UIProvider.MESSAGE_PROJECTION.length];
    422         messageValues[UIProvider.MESSAGE_ID_COLUMN] = Long.valueOf(messageId);
    423         messageValues[UIProvider.MESSAGE_URI_COLUMN] = messageUri;
    424         messageValues[UIProvider.MESSAGE_SUBJECT_COLUMN] = "Message subject";
    425         messageValues[UIProvider.MESSAGE_SNIPPET_COLUMN] = "SNIPPET";
    426         String html = "<html><body><b><i>This is some html!!!</i></b></body></html>";
    427         messageValues[UIProvider.MESSAGE_BODY_HTML_COLUMN] = html;
    428         messageValues[UIProvider.MESSAGE_BODY_TEXT_COLUMN] = Html.fromHtml(html);
    429         messageValues[UIProvider.MESSAGE_HAS_ATTACHMENTS_COLUMN] = hasAttachments ? 1 : 0;
    430         messageValues[UIProvider.MESSAGE_DATE_RECEIVED_MS_COLUMN] = new Date().getTime();
    431         messageValues[UIProvider.MESSAGE_ATTACHMENT_LIST_URI_COLUMN] = messageUri
    432                 + "/getAttachments";
    433         messageValues[UIProvider.MESSAGE_TO_COLUMN] = "account1 (at) mock.com, account2 (at) mock.com";
    434         messageValues[UIProvider.MESSAGE_FROM_COLUMN] = "fromaccount1 (at) mock.com";
    435         messageValues[UIProvider.MESSAGE_CC_COLUMN] = "accountcc1 (at) mock.com, accountcc2 (at) mock.com";
    436         cursor.addRow(messageValues);
    437         cursor.moveToFirst();
    438         return new Message(cursor);
    439     }
    440 
    441     public void testReplyAllWithCc() throws Throwable {
    442         final ComposeActivity activity = getActivity();
    443         setAccount(activity, "account1 (at) mockuiprovider.com");
    444         final Message refMessage = getRefMessageWithCc(0, false);
    445         final String[] refMessageTo = TextUtils.split(refMessage.getTo(), ",");
    446         final String[] refMessageCc = TextUtils.split(refMessage.getCc(), ",");
    447         final String refMessageFromAccount = refMessage.getFrom();
    448 
    449         runTestOnUiThread(new Runnable() {
    450             @Override
    451             public void run() {
    452                 activity.initReplyRecipients(refMessage, ComposeActivity.REPLY_ALL);
    453                 String[] to = activity.getToAddresses();
    454                 String[] cc = activity.getCcAddresses();
    455                 String[] bcc = activity.getBccAddresses();
    456                 assertTrue(to.length == 1);
    457                 assertEquals(refMessageFromAccount,
    458                         Rfc822Tokenizer.tokenize(to[0])[0].getAddress());
    459                 assertEquals(cc.length, refMessageTo.length + refMessageCc.length);
    460                 HashSet<String> ccMap = new HashSet<String>();
    461                 for (String recip : cc) {
    462                     ccMap.add(Rfc822Tokenizer.tokenize(recip.trim())[0].getAddress());
    463                 }
    464                 for (String toRecip : refMessageTo) {
    465                     assertTrue(ccMap.contains(toRecip.trim()));
    466                 }
    467                 for (String ccRecip : refMessageCc) {
    468                     assertTrue(ccMap.contains(ccRecip.trim()));
    469                 }
    470                 assertTrue(bcc.length == 0);
    471             }
    472         });
    473     }
    474 
    475     public void testForward() throws Throwable {
    476         final ComposeActivity activity = getActivity();
    477         setAccount(activity, "account0 (at) mockuiprovider.com");
    478         final Message refMessage = getRefMessage(activity.getContentResolver());
    479 
    480         runTestOnUiThread(new Runnable() {
    481             @Override
    482             public void run() {
    483                 activity.initReplyRecipients(refMessage, ComposeActivity.FORWARD);
    484                 String[] to = activity.getToAddresses();
    485                 String[] cc = activity.getCcAddresses();
    486                 String[] bcc = activity.getBccAddresses();
    487                 assertEquals(to.length, 0);
    488                 assertEquals(cc.length, 0);
    489                 assertEquals(bcc.length, 0);
    490             }
    491         });
    492     }
    493 
    494     public void testCompose() throws Throwable {
    495         final ComposeActivity activity = getActivity();
    496         setAccount(activity, "account0 (at) mockuiprovider.com");
    497         final Message refMessage = getRefMessage(activity.getContentResolver());
    498 
    499         runTestOnUiThread(new Runnable() {
    500             @Override
    501             public void run() {
    502                 activity.initReplyRecipients(refMessage, ComposeActivity.COMPOSE);
    503                 String[] to = activity.getToAddresses();
    504                 String[] cc = activity.getCcAddresses();
    505                 String[] bcc = activity.getBccAddresses();
    506                 assertEquals(to.length, 0);
    507                 assertEquals(cc.length, 0);
    508                 assertEquals(bcc.length, 0);
    509             }
    510         });
    511     }
    512 
    513     /**
    514      * Test the cases where: The user is replying to a message they sent
    515      */
    516     public void testRecipientsRefMessageReplyToSelf() throws Throwable {
    517         final ComposeActivity activity = getActivity();
    518         setAccount(activity, "account0 (at) mockuiprovider.com");
    519         final Message refMessage = getRefMessage(activity.getContentResolver());
    520         refMessage.setFrom("account0 (at) mockuiprovider.com");
    521         refMessage.setTo("someotheraccount (at) mockuiprovider.com");
    522 
    523         runTestOnUiThread(new Runnable() {
    524             @Override
    525             public void run() {
    526                 activity.initReplyRecipients(refMessage, ComposeActivity.REPLY);
    527                 String[] to = activity.getToAddresses();
    528                 String[] cc = activity.getCcAddresses();
    529                 String[] bcc = activity.getBccAddresses();
    530                 assertEquals(to.length, 1);
    531                 assertTrue(to[0].contains(refMessage.getTo()));
    532                 assertEquals(cc.length, 0);
    533                 assertEquals(bcc.length, 0);
    534             }
    535         });
    536     }
    537 
    538     /**
    539      * Test the cases where:
    540      * The user is replying to a message sent from one of their custom froms
    541      */
    542     public void brokentestRecipientsRefMessageReplyToCustomFrom() throws Throwable {
    543         final ComposeActivity activity = getActivity();
    544         setAccount(activity, "account1 (at) mockuiprovider.com");
    545         final Message refMessage = getRefMessage(activity.getContentResolver());
    546         refMessage.setFrom("CUSTOMaccount1 (at) mockuiprovider.com");
    547         refMessage.setTo("someotheraccount (at) mockuiprovider.com");
    548 
    549         ReplyFromAccount a = new ReplyFromAccount(mAccount, mAccount.uri, refMessage.getFrom(),
    550                 refMessage.getFrom(), refMessage.getFrom(), true, true);
    551         JSONArray array = new JSONArray();
    552         array.put(a.serialize());
    553         mAccount.accountFromAddresses = array.toString();
    554         final ReplyFromAccount currentAccount = new ReplyFromAccount(mAccount, mAccount.uri,
    555                 mAccount.getEmailAddress(), mAccount.getEmailAddress(), mAccount.getEmailAddress(),
    556                 true, false);
    557 
    558         runTestOnUiThread(new Runnable() {
    559             @Override
    560             public void run() {
    561                 activity.mFromSpinner = new FromAddressSpinner(activity);
    562                 activity.mFromSpinner.setCurrentAccount(currentAccount);
    563                 activity.mFromSpinner.initialize(ComposeActivity.REPLY, currentAccount.account,
    564                         EMPTY_ACCOUNT_LIST, null);
    565 
    566                 activity.initReplyRecipients(refMessage, ComposeActivity.REPLY);
    567                 String[] to = activity.getToAddresses();
    568                 String[] cc = activity.getCcAddresses();
    569                 String[] bcc = activity.getBccAddresses();
    570                 assertEquals(to.length, 1);
    571                 assertTrue(to[0].contains(refMessage.getTo()));
    572                 assertEquals(cc.length, 0);
    573                 assertEquals(bcc.length, 0);
    574             }
    575         });
    576     }
    577 
    578     /**
    579      * Test the cases where:
    580      * The user is replying to a message sent from one of their custom froms
    581      */
    582     public void brokentestRecipientsRefMessageReplyAllCustomFrom() throws Throwable {
    583         final ComposeActivity activity = getActivity();
    584         setAccount(activity, "account1 (at) mockuiprovider.com");
    585         final Message refMessage = getRefMessage(activity.getContentResolver());
    586         final String customFrom = "CUSTOMaccount1 (at) mockuiprovider.com";
    587         refMessage.setFrom("senderaccount (at) mockuiprovider.com");
    588         refMessage.setTo("someotheraccount (at) mockuiprovider.com, "
    589                 + "someotheraccount2 (at) mockuiprovider.com, someotheraccount4 (at) mockuiprovider.com, "
    590                 + customFrom);
    591 
    592         ReplyFromAccount a = new ReplyFromAccount(mAccount, mAccount.uri, customFrom,
    593                 customFrom, customFrom, true, true);
    594         JSONArray array = new JSONArray();
    595         array.put(a.serialize());
    596         mAccount.accountFromAddresses = array.toString();
    597         final ReplyFromAccount currentAccount = new ReplyFromAccount(mAccount, mAccount.uri,
    598                 mAccount.getEmailAddress(), mAccount.getEmailAddress(), mAccount.getEmailAddress(),
    599                 true, false);
    600 
    601         runTestOnUiThread(new Runnable() {
    602             @Override
    603             public void run() {
    604                 activity.mFromSpinner = new FromAddressSpinner(activity);
    605                 activity.mFromSpinner.setCurrentAccount(currentAccount);
    606                 activity.mFromSpinner.initialize(ComposeActivity.REPLY_ALL,
    607                         currentAccount.account, EMPTY_ACCOUNT_LIST, null);
    608 
    609                 activity.initReplyRecipients(refMessage, ComposeActivity.REPLY_ALL);
    610                 String[] to = activity.getToAddresses();
    611                 String[] cc = activity.getCcAddresses();
    612                 String[] bcc = activity.getBccAddresses();
    613                 String toAsString = TextUtils.join(",", to);
    614                 String ccAsString = TextUtils.join(",", cc);
    615                 String bccAsString = TextUtils.join(",", bcc);
    616                 assertEquals(to.length, 1);
    617                 assertFalse(toAsString.contains(customFrom));
    618                 assertFalse(ccAsString.contains(customFrom));
    619                 assertFalse(bccAsString.contains(customFrom));
    620             }
    621         });
    622     }
    623 
    624     /**
    625      * Test the cases where:
    626      * The user is replying to a message sent from one of their custom froms
    627      */
    628     public void brokentestRecipientsRefMessageReplyAllCustomFromThisAccount() throws Throwable {
    629         final ComposeActivity activity = getActivity();
    630         setAccount(activity, "account1 (at) mockuiprovider.com");
    631         final Message refMessage = getRefMessage(activity.getContentResolver());
    632         final String customFrom = "CUSTOMaccount1 (at) mockuiprovider.com";
    633         refMessage.setFrom("account1 (at) mockuiprovider.com");
    634         refMessage.setTo("someotheraccount (at) mockuiprovider.com, "
    635                 + "someotheraccount2 (at) mockuiprovider.com, someotheraccount4 (at) mockuiprovider.com, "
    636                 + customFrom);
    637 
    638         ReplyFromAccount a = new ReplyFromAccount(mAccount, mAccount.uri, customFrom,
    639                 customFrom, customFrom, true, true);
    640         JSONArray array = new JSONArray();
    641         array.put(a.serialize());
    642         mAccount.accountFromAddresses = array.toString();
    643         final ReplyFromAccount currentAccount = new ReplyFromAccount(mAccount, mAccount.uri,
    644                 mAccount.getEmailAddress(), mAccount.getEmailAddress(), mAccount.getEmailAddress(),
    645                 true, false);
    646 
    647         runTestOnUiThread(new Runnable() {
    648             @Override
    649             public void run() {
    650                 activity.mFromSpinner = new FromAddressSpinner(activity);
    651                 activity.mFromSpinner.setCurrentAccount(currentAccount);
    652                 activity.mFromSpinner.initialize(ComposeActivity.REPLY_ALL,
    653                         currentAccount.account, EMPTY_ACCOUNT_LIST, null);
    654 
    655                 activity.initReplyRecipients(refMessage, ComposeActivity.REPLY_ALL);
    656                 String[] to = activity.getToAddresses();
    657                 String[] cc = activity.getCcAddresses();
    658                 String[] bcc = activity.getBccAddresses();
    659                 String toAsString = TextUtils.join(",", to);
    660                 String ccAsString = TextUtils.join(",", cc);
    661                 String bccAsString = TextUtils.join(",", bcc);
    662                 // Should have the same count as the original message.
    663                 assertEquals(to.length, 3);
    664                 assertFalse(toAsString.contains(customFrom));
    665                 assertFalse(ccAsString.contains(customFrom));
    666                 assertFalse(bccAsString.contains(customFrom));
    667             }
    668         });
    669     }
    670 
    671     // Test replying to a message in the first account in the list, and verify that
    672     // the Compose Activity's from account for the reply is correct
    673     public void testReplySendingAccount0() throws Throwable {
    674         final Context context = getInstrumentation().getContext();
    675         // Get the test account
    676         final Account currentAccount = getAccountForName(context, "account0 (at) mockuiprovider.com");
    677 
    678         // Get the message to be replied to
    679         final Message refMessage =
    680                 getRefMessage(context.getContentResolver(), currentAccount.folderListUri);
    681 
    682         // Create the reply intent
    683         final Intent replyIntent =
    684                 ComposeActivity.updateActionIntent(currentAccount, refMessage.uri,
    685                         ComposeActivity.REPLY, new Intent());
    686 
    687         setActivityIntent(replyIntent);
    688 
    689         final ComposeActivity activity = getActivity();
    690         final String refMessageFromAccount = refMessage.getFrom();
    691 
    692         runTestOnUiThread(new Runnable() {
    693             @Override
    694             public void run() {
    695                 String[] to = activity.getToAddresses();
    696                 String[] cc = activity.getCcAddresses();
    697                 String[] bcc = activity.getBccAddresses();
    698                 Account fromAccount = activity.getFromAccount();
    699                 assertEquals(1, to.length);
    700                 assertEquals(refMessageFromAccount,
    701                         Rfc822Tokenizer.tokenize(to[0])[0].getAddress());
    702                 assertEquals(0, cc.length);
    703                 assertEquals(0, bcc.length);
    704                 assertEquals("account0 (at) mockuiprovider.com", fromAccount.getEmailAddress());
    705             }
    706         });
    707     }
    708 
    709     // Test replying to a message in the third account in the list, and verify that
    710     // the Compose Activity's from account for the reply is correct
    711     public void testReplySendingAccount1() throws Throwable {
    712         final Context context = getInstrumentation().getContext();
    713         // Get the test account
    714         final Account currentAccount = getAccountForName(context, "account2 (at) mockuiprovider.com");
    715 
    716         // Get the message to be replied to
    717         final Message refMessage =
    718                 getRefMessage(context.getContentResolver(), currentAccount.folderListUri);
    719 
    720         // Create the reply intent
    721         final Intent replyIntent =
    722                 ComposeActivity.updateActionIntent(currentAccount, refMessage.uri,
    723                         ComposeActivity.REPLY, new Intent());
    724 
    725         setActivityIntent(replyIntent);
    726 
    727         final ComposeActivity activity = getActivity();
    728         Account fromAccount = activity.getFromAccount();
    729 
    730         final String refMessageFromAccount = refMessage.getFrom();
    731 
    732         runTestOnUiThread(new Runnable() {
    733             @Override
    734             public void run() {
    735                 String[] to = activity.getToAddresses();
    736                 String[] cc = activity.getCcAddresses();
    737                 String[] bcc = activity.getBccAddresses();
    738                 Account fromAccount = activity.getFromAccount();
    739                 assertEquals(1, to.length);
    740                 assertEquals(refMessageFromAccount,
    741                         Rfc822Tokenizer.tokenize(to[0])[0].getAddress());
    742                 assertEquals(0, cc.length);
    743                 assertEquals(0, bcc.length);
    744                 assertEquals("account2 (at) mockuiprovider.com", fromAccount.getEmailAddress());
    745             }
    746         });
    747     }
    748 
    749     private static String encodeMailtoParam(String s) throws UnsupportedEncodingException {
    750         return URLEncoder.encode(s, "UTF-8").replace("+", "%20");
    751     }
    752 
    753     public void testMailto() throws Throwable {
    754         final String to = "foo (at) bar.com";
    755         final String cc = "baz (at) baf.com";
    756         final String subject = "hello world";
    757         final String body = "Dear foo,\nGoodbye.\n--me";
    758 
    759         final String mailto = String.format("mailto:%s?cc=%s&subject=%s&body=%s",
    760                 encodeMailtoParam(to), encodeMailtoParam(cc), encodeMailtoParam(subject),
    761                 encodeMailtoParam(body));
    762 
    763         final Intent mailtoIntent = new Intent(Intent.ACTION_VIEW,
    764                 Uri.parse(mailto));
    765         setActivityIntent(mailtoIntent);
    766 
    767         final ComposeActivity activity = getActivity();
    768 
    769         runTestOnUiThread(new Runnable() {
    770             @Override
    771             public void run() {
    772                 final String resultTo[] = activity.getToAddresses();
    773                 assertEquals(1, resultTo.length);
    774                 assertEquals(to, Rfc822Tokenizer.tokenize(resultTo[0])[0].getAddress());
    775 
    776                 final String resultCc[] = activity.getCcAddresses();
    777                 assertEquals(1, resultCc.length);
    778                 assertEquals(cc, Rfc822Tokenizer.tokenize(resultCc[0])[0].getAddress());
    779 
    780                 assertEquals(subject, activity.getSubject());
    781 // the result is HTML-wrapped in a way that's not trivial to test, so disabled for now
    782 //                assertEquals(body, activity.getBodyHtml());
    783             }
    784         });
    785     }
    786 
    787     // Test a mailto VIEW Intent, with an account specified in JSON format
    788     public void testMailToAccountJSON() throws Throwable {
    789         final Context context = getInstrumentation().getContext();
    790         // Get the test account
    791         final Account currentAccount = getAccountForName(context, "account2 (at) mockuiprovider.com");
    792 
    793         // Create the mailto intent
    794         final Intent mailtoIntent =
    795                 new Intent(Intent.ACTION_VIEW, Uri.parse("mailto:test (at) localhost.com"));
    796         mailtoIntent.putExtra(Utils.EXTRA_ACCOUNT, currentAccount.serialize());
    797 
    798         setActivityIntent(mailtoIntent);
    799 
    800         final ComposeActivity activity = getActivity();
    801         Account fromAccount = activity.getFromAccount();
    802 
    803         runTestOnUiThread(new Runnable() {
    804             @Override
    805             public void run() {
    806                 String[] to = activity.getToAddresses();
    807                 String[] cc = activity.getCcAddresses();
    808                 String[] bcc = activity.getBccAddresses();
    809                 Account fromAccount = activity.getFromAccount();
    810                 assertEquals( 1, to.length);
    811                 assertEquals("test (at) localhost.com",
    812                         Rfc822Tokenizer.tokenize(to[0])[0].getAddress());
    813                 assertEquals(0, cc.length);
    814                 assertEquals(0, bcc.length);
    815                 assertEquals("account2 (at) mockuiprovider.com", fromAccount.getEmailAddress());
    816             }
    817         });
    818     }
    819 
    820     // Test a COMPOSE Intent, with an account specified in parcel format
    821     public void testMailToAccount() throws Throwable {
    822         final Context context = getInstrumentation().getContext();
    823         // Get the test account
    824         final Account currentAccount = getAccountForName(context, "account2 (at) mockuiprovider.com");
    825 
    826         // Create the mailto intent
    827         Intent intent = new Intent(context, ComposeActivity.class);
    828         intent.putExtra(ComposeActivity.EXTRA_FROM_EMAIL_TASK, true);
    829         intent.putExtra(ComposeActivity.EXTRA_ACTION, ComposeActivity.COMPOSE);
    830         intent.putExtra(Utils.EXTRA_ACCOUNT, currentAccount);
    831         intent.putExtra(ComposeActivity.EXTRA_TO, "test (at) localhost.com");
    832 
    833         setActivityIntent(intent);
    834 
    835         final ComposeActivity activity = getActivity();
    836         Account fromAccount = activity.getFromAccount();
    837 
    838         runTestOnUiThread(new Runnable() {
    839             @Override
    840             public void run() {
    841                 String[] to = activity.getToAddresses();
    842                 String[] cc = activity.getCcAddresses();
    843                 String[] bcc = activity.getBccAddresses();
    844                 Account fromAccount = activity.getFromAccount();
    845                 assertEquals( 1, to.length);
    846                 assertEquals("test (at) localhost.com",
    847                         Rfc822Tokenizer.tokenize(to[0])[0].getAddress());
    848                 assertEquals(0, cc.length);
    849                 assertEquals(0, bcc.length);
    850                 assertEquals("account2 (at) mockuiprovider.com", fromAccount.getEmailAddress());
    851             }
    852         });
    853     }
    854 
    855     // Test a mailto VIEW Intent, with no account specified.  The fromAccount should default to the
    856     // last sent account.
    857     public void testMailToAccountWithLastSentAccount() throws Throwable {
    858         final Context context = getInstrumentation().getContext();
    859 
    860         // Set the last sent account to account0
    861         final Account lastSentAccount = getAccountForName(context, "account1 (at) mockuiprovider.com");
    862         MailAppProvider appProvider = MailAppProvider.getInstance();
    863         appProvider.setLastSentFromAccount(lastSentAccount.uri.toString());
    864 
    865         // Create the mailto intent
    866         final Intent mailtoIntent =
    867                 new Intent(Intent.ACTION_VIEW, Uri.parse("mailto:test (at) localhost.com"));
    868 
    869         setActivityIntent(mailtoIntent);
    870 
    871         final ComposeActivity activity = getActivity();
    872         Account fromAccount = activity.getFromAccount();
    873 
    874         runTestOnUiThread(new Runnable() {
    875             @Override
    876             public void run() {
    877                 String[] to = activity.getToAddresses();
    878                 String[] cc = activity.getCcAddresses();
    879                 String[] bcc = activity.getBccAddresses();
    880                 Account fromAccount = activity.getFromAccount();
    881                 assertEquals( 1, to.length);
    882                 assertEquals("test (at) localhost.com",
    883                         Rfc822Tokenizer.tokenize(to[0])[0].getAddress());
    884                 assertEquals(0, cc.length);
    885                 assertEquals(0, bcc.length);
    886                 assertEquals("account1 (at) mockuiprovider.com", fromAccount.getEmailAddress());
    887             }
    888         });
    889     }
    890 
    891     private static String createAttachmentsJson() {
    892         Attachment attachment1 = new Attachment();
    893         attachment1.contentUri = Uri.parse("www.google.com");
    894         attachment1.setContentType("img/jpeg");
    895         attachment1.setName("attachment1");
    896         Attachment attachment2 = new Attachment();
    897         attachment2.contentUri = Uri.parse("www.google.com");
    898         attachment2.setContentType("img/jpeg");
    899         attachment2.setName("attachment2");
    900         JSONArray attachments = new JSONArray();
    901         try {
    902             attachments.put(attachment1.toJSON());
    903             attachments.put(attachment2.toJSON());
    904         } catch (JSONException e) {
    905             assertTrue(false);
    906         }
    907         return attachments.toString();
    908     }
    909 
    910     // First test: switch reply to reply all to fwd, 1 to recipient, 1 cc recipient.
    911     public void testChangeModes0() throws Throwable {
    912         final ComposeActivity activity = getActivity();
    913         setAccount(activity, "account0 (at) mockuiprovider.com");
    914         final Message refMessage = getRefMessage(activity.getContentResolver());
    915         refMessage.setFrom("fromaccount (at) mockuiprovider.com");
    916         refMessage.setTo("account0 (at) mockuiprovider.com");
    917         refMessage.setCc("ccaccount (at) mockuiprovider.com");
    918         runTestOnUiThread(new Runnable() {
    919             @Override
    920             public void run() {
    921                 activity.mRefMessage = refMessage;
    922                 activity.initReplyRecipients(refMessage, ComposeActivity.REPLY);
    923                 String[] to = activity.getToAddresses();
    924                 String[] cc = activity.getCcAddresses();
    925                 String[] bcc = activity.getBccAddresses();
    926                 assertEquals(1, to.length);
    927                 assertTrue(to[0].contains(refMessage.getFrom()));
    928                 assertEquals(cc.length, 0);
    929                 assertEquals(bcc.length, 0);
    930                 activity.onNavigationItemSelected(1, ComposeActivity.REPLY_ALL);
    931                 assertEquals(activity.getToAddresses().length, 1);
    932                 assertTrue(activity.getToAddresses()[0].contains(refMessage.getFrom()));
    933                 assertEquals(activity.getCcAddresses().length, 1);
    934                 assertTrue(activity.getCcAddresses()[0].contains(refMessage.getCc()));
    935                 assertEquals(activity.getBccAddresses().length, 0);
    936                 activity.onNavigationItemSelected(2, ComposeActivity.FORWARD);
    937                 assertEquals(activity.getToAddresses().length, 0);
    938                 assertEquals(activity.getCcAddresses().length, 0);
    939                 assertEquals(activity.getBccAddresses().length, 0);
    940             }
    941         });
    942     }
    943 
    944     // Switch reply to reply all to fwd, 2 to recipients, 1 cc recipient.
    945     public void testChangeModes1() throws Throwable {
    946         final ComposeActivity activity = getActivity();
    947         setAccount(activity, "account0 (at) mockuiprovider.com");
    948         final Message refMessage = getRefMessage(activity.getContentResolver());
    949         refMessage.setFrom("fromaccount (at) mockuiprovider.com");
    950         refMessage.setTo("account0 (at) mockuiprovider.com, toaccount0 (at) mockuiprovider.com");
    951         refMessage.setCc("ccaccount (at) mockuiprovider.com");
    952         runTestOnUiThread(new Runnable() {
    953             @Override
    954             public void run() {
    955                 activity.mRefMessage = refMessage;
    956                 activity.initReplyRecipients(refMessage, ComposeActivity.REPLY);
    957                 String[] to = activity.getToAddresses();
    958                 String[] cc = activity.getCcAddresses();
    959                 String[] bcc = activity.getBccAddresses();
    960                 assertEquals(to.length, 1);
    961                 assertTrue(to[0].contains(refMessage.getFrom()));
    962                 assertEquals(cc.length, 0);
    963                 assertEquals(bcc.length, 0);
    964                 activity.onNavigationItemSelected(1, ComposeActivity.REPLY_ALL);
    965                 assertEquals(activity.getToAddresses().length, 1);
    966                 assertTrue(activity.getToAddresses()[0].contains(refMessage.getFrom()));
    967                 assertEquals(activity.getCcAddresses().length, 2);
    968                 assertTrue(activity.getCcAddresses()[0].contains(refMessage.getCc())
    969                         || activity.getCcAddresses()[1].contains(refMessage.getCc()));
    970                 assertTrue(activity.getCcAddresses()[0].contains("toaccount0 (at) mockuiprovider.com")
    971                         || activity.getCcAddresses()[1]
    972                         .contains("toaccount0 (at) mockuiprovider.com"));
    973                 assertEquals(activity.getBccAddresses().length, 0);
    974                 activity.onNavigationItemSelected(2, ComposeActivity.FORWARD);
    975                 assertEquals(activity.getToAddresses().length, 0);
    976                 assertEquals(activity.getCcAddresses().length, 0);
    977                 assertEquals(activity.getBccAddresses().length, 0);
    978             }
    979         });
    980     }
    981 
    982     // Switch reply to reply all to fwd, 2 to recipients, 2 cc recipients.
    983     public void testChangeModes2() throws Throwable {
    984         final ComposeActivity activity = getActivity();
    985         setAccount(activity, "account0 (at) mockuiprovider.com");
    986         final Message refMessage = getRefMessage(activity.getContentResolver());
    987         refMessage.setFrom("fromaccount (at) mockuiprovider.com");
    988         refMessage.setTo("account0 (at) mockuiprovider.com, toaccount0 (at) mockuiprovider.com");
    989         refMessage.setCc("ccaccount (at) mockuiprovider.com, ccaccount2 (at) mockuiprovider.com");
    990         runTestOnUiThread(new Runnable() {
    991             @Override
    992             public void run() {
    993                 activity.mRefMessage = refMessage;
    994                 activity.initReplyRecipients(refMessage, ComposeActivity.REPLY);
    995                 String[] to = activity.getToAddresses();
    996                 String[] cc = activity.getCcAddresses();
    997                 String[] bcc = activity.getBccAddresses();
    998                 assertEquals(to.length, 1);
    999                 assertTrue(to[0].contains(refMessage.getFrom()));
   1000                 assertEquals(cc.length, 0);
   1001                 assertEquals(bcc.length, 0);
   1002                 activity.onNavigationItemSelected(1, ComposeActivity.REPLY_ALL);
   1003                 assertEquals(activity.getToAddresses().length, 1);
   1004                 assertTrue(activity.getToAddresses()[0].contains(refMessage.getFrom()));
   1005                 assertEquals(activity.getCcAddresses().length, 3);
   1006                 assertTrue(activity.getCcAddresses()[0].contains("ccaccount (at) mockuiprovider.com")
   1007                         || activity.getCcAddresses()[1].contains("ccaccount (at) mockuiprovider.com")
   1008                         || activity.getCcAddresses()[2].contains("ccaccount (at) mockuiprovider.com"));
   1009                 assertTrue(activity.getCcAddresses()[0].contains("ccaccount2 (at) mockuiprovider.com")
   1010                         || activity.getCcAddresses()[1].contains("ccaccount2 (at) mockuiprovider.com")
   1011                         || activity.getCcAddresses()[2].contains("ccaccount2 (at) mockuiprovider.com"));
   1012                 assertTrue(activity.getCcAddresses()[0].contains("toaccount0 (at) mockuiprovider.com")
   1013                         || activity.getCcAddresses()[1].contains("toaccount0 (at) mockuiprovider.com")
   1014                         || activity.getCcAddresses()[2].contains("toaccount0 (at) mockuiprovider.com"));
   1015                 assertTrue(activity.getCcAddresses()[0].contains("toaccount0 (at) mockuiprovider.com")
   1016                         || activity.getCcAddresses()[1]
   1017                         .contains("toaccount0 (at) mockuiprovider.com")
   1018                         || activity.getCcAddresses()[2]
   1019                         .contains("toaccount0 (at) mockuiprovider.com"));
   1020                 assertEquals(activity.getBccAddresses().length, 0);
   1021                 activity.onNavigationItemSelected(2, ComposeActivity.FORWARD);
   1022                 assertEquals(activity.getToAddresses().length, 0);
   1023                 assertEquals(activity.getCcAddresses().length, 0);
   1024                 assertEquals(activity.getBccAddresses().length, 0);
   1025             }
   1026         });
   1027     }
   1028 
   1029     // Switch reply to reply all to fwd, 2 attachments.
   1030     public void testChangeModes3() throws Throwable {
   1031         final ComposeActivity activity = getActivity();
   1032         setAccount(activity, "account0 (at) mockuiprovider.com");
   1033         final Message refMessage = getRefMessage(activity.getContentResolver());
   1034         refMessage.hasAttachments = true;
   1035         refMessage.attachmentsJson = createAttachmentsJson();
   1036         runTestOnUiThread(new Runnable() {
   1037             @Override
   1038             public void run() {
   1039                 activity.mRefMessage = refMessage;
   1040                 activity.initAttachments(refMessage);
   1041                 assertEquals(activity.getAttachments().size(), 2);
   1042                 activity.onNavigationItemSelected(1, ComposeActivity.REPLY);
   1043                 assertEquals(activity.getAttachments().size(), 0);
   1044                 activity.onNavigationItemSelected(1, ComposeActivity.REPLY_ALL);
   1045                 assertEquals(activity.getAttachments().size(), 0);
   1046                 activity.onNavigationItemSelected(2, ComposeActivity.FORWARD);
   1047                 assertEquals(activity.getAttachments().size(), 2);
   1048             }
   1049         });
   1050     }
   1051 
   1052     // Test existence of % signs and basic functionality (to, cc, bcc, subject)
   1053     public void testInitFromMailTo0() throws Throwable {
   1054         final ComposeActivity activity = getActivity();
   1055         final String input = "mailto:Test1 (at) Test1.com?cc=Test2 (at) Test2.com" +
   1056                 "&bcc=Test3 (at) Test3.com&subject=Hello&body=Bye%25Bye";
   1057 
   1058         runTestOnUiThread(new Runnable() {
   1059             @Override
   1060             public void run() {
   1061                 activity.initFromMailTo(input);
   1062                 assertEquals(1, activity.getToAddresses().length);
   1063                 assertTrue(activity.getToAddresses()[0].contains("Test1 (at) Test1.com"));
   1064                 assertEquals(1, activity.getCcAddresses().length);
   1065                 assertTrue(activity.getCcAddresses()[0].contains("Test2 (at) Test2.com"));
   1066                 assertEquals(1, activity.getBccAddresses().length);
   1067                 assertTrue(activity.getBccAddresses()[0].contains("Test3 (at) Test3.com"));
   1068                 assertEquals("Hello", activity.getSubject());
   1069                 assertEquals("%25 should be decoded into %",
   1070                         "Bye%Bye", activity.getBody().getText().toString());
   1071             }
   1072         });
   1073     }
   1074 
   1075     // Test existence of + and space in addition to %
   1076     public void testInitFromMailTo1() throws Throwable {
   1077         final ComposeActivity activity = getActivity();
   1078         final String query = "Bye+Bye %";
   1079         final Uri uri = Uri.parse("mailto:test (at) test.com?body=" + encodeMailtoParam(query));
   1080 
   1081         runTestOnUiThread(new Runnable() {
   1082             @Override
   1083             public void run() {
   1084                 activity.initFromMailTo(uri.toString());
   1085                 assertEquals(query, activity.getBody().getText().toString());
   1086             }
   1087         });
   1088     }
   1089 
   1090     // Test existence of random set of url encoded characters
   1091     public void testInitFromMailTo2() throws Throwable {
   1092         final ComposeActivity activity = getActivity();
   1093         final String query = "I'm TESTING @#$%^&*\"";
   1094         final Uri uri = Uri.parse("mailto:test (at) test.com?body=" + encodeMailtoParam(query));
   1095 
   1096         runTestOnUiThread(new Runnable() {
   1097             @Override
   1098             public void run() {
   1099                 activity.initFromMailTo(uri.toString());
   1100                 assertEquals(query, activity.getBody().getText().toString());
   1101             }
   1102         });
   1103     }
   1104 }
   1105