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 
ComposeActivityTest()63     public ComposeActivityTest() {
64         super(ComposeActivity.class);
65     }
66 
getRefMessage(ContentResolver resolver, Uri folderListUri)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 
getRefMessage(ContentResolver resolver)97     private Message getRefMessage(ContentResolver resolver) {
98         final Account account = getActivity().getFromAccount();
99         return getRefMessage(resolver, account.folderListUri);
100     }
101 
setAccount(ComposeActivity activity, String accountName)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 
getAccounts(Context context)111     private Account[] getAccounts(Context context) {
112         return AccountUtils.getSyncingAccounts(context);
113     }
114 
getAccountForName(Context context, String accountName)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      */
testRecipientsRefReplyAllCustomFromReplyTo()130     public void testRecipientsRefReplyAllCustomFromReplyTo() throws Throwable {
131         final ComposeActivity activity = getActivity();
132         setAccount(activity, "account3@mockuiprovider.com");
133         final Message refMessage = getRefMessage(activity.getContentResolver());
134         final String customFrom = "CUSTOMaccount3@mockuiprovider.com";
135         refMessage.setFrom("account3@mockuiprovider.com");
136         refMessage.setTo("someotheraccount1@mockuiprovider.com, "
137                 + "someotheraccount2@mockuiprovider.com, someotheraccount3@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      */
testRecipientsRefReplyAllOnlyAccount()173     public void testRecipientsRefReplyAllOnlyAccount() throws Throwable {
174         final ComposeActivity activity = getActivity();
175         setAccount(activity, "account3@mockuiprovider.com");
176         final Message refMessage = getRefMessage(activity.getContentResolver());
177         refMessage.setFrom("account3@mockuiprovider.com");
178         refMessage.setTo("account3@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      */
testRecipientsRefReplyAllOnlyCustomFrom()210     public void testRecipientsRefReplyAllOnlyCustomFrom() throws Throwable {
211         final ComposeActivity activity = getActivity();
212         setAccount(activity, "account3@mockuiprovider.com");
213         final Message refMessage = getRefMessage(activity.getContentResolver());
214         final String customFrom = "CUSTOMaccount3@mockuiprovider.com";
215         refMessage.setFrom("account3@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 
testReply()247     public void testReply() throws Throwable {
248         final ComposeActivity activity = getActivity();
249         setAccount(activity, "account0@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 
testReplyWithReplyTo()269     public void testReplyWithReplyTo() throws Throwable {
270         final ComposeActivity activity = getActivity();
271         setAccount(activity, "account1@mockuiprovider.com");
272         final Message refMessage = getRefMessage(activity.getContentResolver());
273         refMessage.setReplyTo("replytofromaccount1@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      */
testReplyToSelf()295     public void testReplyToSelf() throws Throwable {
296         final ComposeActivity activity = getActivity();
297         setAccount(activity, "account1@mockuiprovider.com");
298         final Message refMessage = getRefMessage(activity.getContentResolver());
299         refMessage.setFrom("Account Test <account1@mockuiprovider.com>");
300         refMessage.setTo("test1@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@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      */
testReplyAllToSelf()320     public void testReplyAllToSelf() throws Throwable {
321         final ComposeActivity activity = getActivity();
322         setAccount(activity, "account1@mockuiprovider.com");
323         final Message refMessage = getRefMessage(activity.getContentResolver());
324         refMessage.setFrom("Account Test <account1@mockuiprovider.com>");
325         refMessage.setTo("test1@gmail.com, test2@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@gmail.com"));
336                 assertTrue(toAsString.contains("test2@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      */
testReplyAllToSelfWithCc()346     public void testReplyAllToSelfWithCc() throws Throwable {
347         final ComposeActivity activity = getActivity();
348         setAccount(activity, "account1@mockuiprovider.com");
349         final Message refMessage = getRefMessage(activity.getContentResolver());
350         refMessage.setFrom("Account Test <account1@mockuiprovider.com>");
351         refMessage.setTo("test1@gmail.com, test2@gmail.com");
352         refMessage.setCc("testcc@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@gmail.com"));
363                 assertTrue(toAsString.contains("test2@gmail.com"));
364                 String ccAsString = TextUtils.join(",", cc);
365                 assertTrue(ccAsString.contains("testcc@gmail.com"));
366                 assertTrue(cc.length == 1);
367                 assertTrue(bcc.length == 0);
368             }
369         });
370     }
371 
testReplyAll()372     public void testReplyAll() throws Throwable {
373         final ComposeActivity activity = getActivity();
374         setAccount(activity, "account0@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 
testReplyAllWithReplyTo()395     public void testReplyAllWithReplyTo() throws Throwable {
396         final ComposeActivity activity = getActivity();
397         setAccount(activity, "account1@mockuiprovider.com");
398         final Message refMessage = getRefMessage(activity.getContentResolver());
399         refMessage.setReplyTo("replytofromaccount1@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 
getRefMessageWithCc(long messageId, boolean hasAttachments)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@mock.com, account2@mock.com";
434         messageValues[UIProvider.MESSAGE_FROM_COLUMN] = "fromaccount1@mock.com";
435         messageValues[UIProvider.MESSAGE_CC_COLUMN] = "accountcc1@mock.com, accountcc2@mock.com";
436         cursor.addRow(messageValues);
437         cursor.moveToFirst();
438         return new Message(cursor);
439     }
440 
testReplyAllWithCc()441     public void testReplyAllWithCc() throws Throwable {
442         final ComposeActivity activity = getActivity();
443         setAccount(activity, "account1@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 
testForward()475     public void testForward() throws Throwable {
476         final ComposeActivity activity = getActivity();
477         setAccount(activity, "account0@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 
testCompose()494     public void testCompose() throws Throwable {
495         final ComposeActivity activity = getActivity();
496         setAccount(activity, "account0@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      */
testRecipientsRefMessageReplyToSelf()516     public void testRecipientsRefMessageReplyToSelf() throws Throwable {
517         final ComposeActivity activity = getActivity();
518         setAccount(activity, "account0@mockuiprovider.com");
519         final Message refMessage = getRefMessage(activity.getContentResolver());
520         refMessage.setFrom("account0@mockuiprovider.com");
521         refMessage.setTo("someotheraccount@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      */
brokentestRecipientsRefMessageReplyToCustomFrom()542     public void brokentestRecipientsRefMessageReplyToCustomFrom() throws Throwable {
543         final ComposeActivity activity = getActivity();
544         setAccount(activity, "account1@mockuiprovider.com");
545         final Message refMessage = getRefMessage(activity.getContentResolver());
546         refMessage.setFrom("CUSTOMaccount1@mockuiprovider.com");
547         refMessage.setTo("someotheraccount@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      */
brokentestRecipientsRefMessageReplyAllCustomFrom()582     public void brokentestRecipientsRefMessageReplyAllCustomFrom() throws Throwable {
583         final ComposeActivity activity = getActivity();
584         setAccount(activity, "account1@mockuiprovider.com");
585         final Message refMessage = getRefMessage(activity.getContentResolver());
586         final String customFrom = "CUSTOMaccount1@mockuiprovider.com";
587         refMessage.setFrom("senderaccount@mockuiprovider.com");
588         refMessage.setTo("someotheraccount@mockuiprovider.com, "
589                 + "someotheraccount2@mockuiprovider.com, someotheraccount4@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      */
brokentestRecipientsRefMessageReplyAllCustomFromThisAccount()628     public void brokentestRecipientsRefMessageReplyAllCustomFromThisAccount() throws Throwable {
629         final ComposeActivity activity = getActivity();
630         setAccount(activity, "account1@mockuiprovider.com");
631         final Message refMessage = getRefMessage(activity.getContentResolver());
632         final String customFrom = "CUSTOMaccount1@mockuiprovider.com";
633         refMessage.setFrom("account1@mockuiprovider.com");
634         refMessage.setTo("someotheraccount@mockuiprovider.com, "
635                 + "someotheraccount2@mockuiprovider.com, someotheraccount4@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
testReplySendingAccount0()673     public void testReplySendingAccount0() throws Throwable {
674         final Context context = getInstrumentation().getContext();
675         // Get the test account
676         final Account currentAccount = getAccountForName(context, "account0@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@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
testReplySendingAccount1()711     public void testReplySendingAccount1() throws Throwable {
712         final Context context = getInstrumentation().getContext();
713         // Get the test account
714         final Account currentAccount = getAccountForName(context, "account2@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@mockuiprovider.com", fromAccount.getEmailAddress());
745             }
746         });
747     }
748 
encodeMailtoParam(String s)749     private static String encodeMailtoParam(String s) throws UnsupportedEncodingException {
750         return URLEncoder.encode(s, "UTF-8").replace("+", "%20");
751     }
752 
testMailto()753     public void testMailto() throws Throwable {
754         final String to = "foo@bar.com";
755         final String cc = "baz@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
testMailToAccountJSON()788     public void testMailToAccountJSON() throws Throwable {
789         final Context context = getInstrumentation().getContext();
790         // Get the test account
791         final Account currentAccount = getAccountForName(context, "account2@mockuiprovider.com");
792 
793         // Create the mailto intent
794         final Intent mailtoIntent =
795                 new Intent(Intent.ACTION_VIEW, Uri.parse("mailto:test@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@localhost.com",
812                         Rfc822Tokenizer.tokenize(to[0])[0].getAddress());
813                 assertEquals(0, cc.length);
814                 assertEquals(0, bcc.length);
815                 assertEquals("account2@mockuiprovider.com", fromAccount.getEmailAddress());
816             }
817         });
818     }
819 
820     // Test a COMPOSE Intent, with an account specified in parcel format
testMailToAccount()821     public void testMailToAccount() throws Throwable {
822         final Context context = getInstrumentation().getContext();
823         // Get the test account
824         final Account currentAccount = getAccountForName(context, "account2@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@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@localhost.com",
847                         Rfc822Tokenizer.tokenize(to[0])[0].getAddress());
848                 assertEquals(0, cc.length);
849                 assertEquals(0, bcc.length);
850                 assertEquals("account2@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.
testMailToAccountWithLastSentAccount()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@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@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@localhost.com",
883                         Rfc822Tokenizer.tokenize(to[0])[0].getAddress());
884                 assertEquals(0, cc.length);
885                 assertEquals(0, bcc.length);
886                 assertEquals("account1@mockuiprovider.com", fromAccount.getEmailAddress());
887             }
888         });
889     }
890 
createAttachmentsJson()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.
testChangeModes0()911     public void testChangeModes0() throws Throwable {
912         final ComposeActivity activity = getActivity();
913         setAccount(activity, "account0@mockuiprovider.com");
914         final Message refMessage = getRefMessage(activity.getContentResolver());
915         refMessage.setFrom("fromaccount@mockuiprovider.com");
916         refMessage.setTo("account0@mockuiprovider.com");
917         refMessage.setCc("ccaccount@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.
testChangeModes1()945     public void testChangeModes1() throws Throwable {
946         final ComposeActivity activity = getActivity();
947         setAccount(activity, "account0@mockuiprovider.com");
948         final Message refMessage = getRefMessage(activity.getContentResolver());
949         refMessage.setFrom("fromaccount@mockuiprovider.com");
950         refMessage.setTo("account0@mockuiprovider.com, toaccount0@mockuiprovider.com");
951         refMessage.setCc("ccaccount@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@mockuiprovider.com")
971                         || activity.getCcAddresses()[1]
972                         .contains("toaccount0@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.
testChangeModes2()983     public void testChangeModes2() throws Throwable {
984         final ComposeActivity activity = getActivity();
985         setAccount(activity, "account0@mockuiprovider.com");
986         final Message refMessage = getRefMessage(activity.getContentResolver());
987         refMessage.setFrom("fromaccount@mockuiprovider.com");
988         refMessage.setTo("account0@mockuiprovider.com, toaccount0@mockuiprovider.com");
989         refMessage.setCc("ccaccount@mockuiprovider.com, ccaccount2@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@mockuiprovider.com")
1007                         || activity.getCcAddresses()[1].contains("ccaccount@mockuiprovider.com")
1008                         || activity.getCcAddresses()[2].contains("ccaccount@mockuiprovider.com"));
1009                 assertTrue(activity.getCcAddresses()[0].contains("ccaccount2@mockuiprovider.com")
1010                         || activity.getCcAddresses()[1].contains("ccaccount2@mockuiprovider.com")
1011                         || activity.getCcAddresses()[2].contains("ccaccount2@mockuiprovider.com"));
1012                 assertTrue(activity.getCcAddresses()[0].contains("toaccount0@mockuiprovider.com")
1013                         || activity.getCcAddresses()[1].contains("toaccount0@mockuiprovider.com")
1014                         || activity.getCcAddresses()[2].contains("toaccount0@mockuiprovider.com"));
1015                 assertTrue(activity.getCcAddresses()[0].contains("toaccount0@mockuiprovider.com")
1016                         || activity.getCcAddresses()[1]
1017                         .contains("toaccount0@mockuiprovider.com")
1018                         || activity.getCcAddresses()[2]
1019                         .contains("toaccount0@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.
testChangeModes3()1030     public void testChangeModes3() throws Throwable {
1031         final ComposeActivity activity = getActivity();
1032         setAccount(activity, "account0@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)
testInitFromMailTo0()1053     public void testInitFromMailTo0() throws Throwable {
1054         final ComposeActivity activity = getActivity();
1055         final String input = "mailto:Test1@Test1.com?cc=Test2@Test2.com" +
1056                 "&bcc=Test3@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@Test1.com"));
1064                 assertEquals(1, activity.getCcAddresses().length);
1065                 assertTrue(activity.getCcAddresses()[0].contains("Test2@Test2.com"));
1066                 assertEquals(1, activity.getBccAddresses().length);
1067                 assertTrue(activity.getBccAddresses()[0].contains("Test3@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 %
testInitFromMailTo1()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@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
testInitFromMailTo2()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@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