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