1 /* 2 * Copyright (C) 2009 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.email.mail.internet; 18 19 import com.android.email.Email; 20 import com.android.email.mail.Message; 21 import com.android.email.mail.MessageTestUtils; 22 import com.android.email.mail.MessagingException; 23 import com.android.email.mail.MessageTestUtils.MessageBuilder; 24 import com.android.email.mail.MessageTestUtils.MultipartBuilder; 25 import com.android.email.mail.MessageTestUtils.TextBuilder; 26 import com.android.email.mail.store.LocalStore; 27 import com.android.email.provider.EmailContent; 28 import com.android.email.provider.EmailContent.Account; 29 30 import android.content.ContentUris; 31 import android.content.Context; 32 import android.net.Uri; 33 import android.test.AndroidTestCase; 34 import android.test.suitebuilder.annotation.MediumTest; 35 36 import java.io.IOException; 37 38 /** 39 * Tests of the Email HTML utils. 40 * 41 * You can run this entire test case with: 42 * runtest -c com.android.email.mail.internet.EmailHtmlUtilTest email 43 */ 44 @MediumTest 45 public class EmailHtmlUtilTest extends AndroidTestCase { 46 private EmailContent.Account mAccount; 47 private long mCreatedAccountId = -1; 48 49 private static final String textTags = "<b>Plain</b> &"; 50 private static final String textSpaces = "3 spaces end."; 51 private static final String textNewlines = "ab \r\n \n \n\r\n"; 52 53 @Override 54 protected void setUp() throws Exception { 55 super.setUp(); 56 // Force assignment of a default account, and retrieve it 57 Context context = getContext(); 58 Email.setTempDirectory(context); 59 60 // Force assignment of a default account 61 long accountId = Account.getDefaultAccountId(context); 62 if (accountId == -1) { 63 Account account = new Account(); 64 account.mSenderName = "Bob Sender"; 65 account.mEmailAddress = "bob (at) sender.com"; 66 account.save(context); 67 accountId = account.mId; 68 mCreatedAccountId = accountId; 69 } 70 Account.restoreAccountWithId(context, accountId); 71 } 72 73 @Override 74 protected void tearDown() throws Exception { 75 super.tearDown(); 76 Context context = getContext(); 77 // If we created an account, delete it here 78 if (mCreatedAccountId > -1) { 79 context.getContentResolver().delete( 80 ContentUris.withAppendedId(Account.CONTENT_URI, mCreatedAccountId), null, null); 81 } 82 } 83 84 /** 85 * Tests for resolving inline image src cid: reference to content uri. 86 * 87 * TODO: These need to be completely rewritten to not use LocalStore messages. 88 */ 89 public void disable_testResolveInlineImage() throws MessagingException, IOException { 90 final LocalStore store = (LocalStore) LocalStore.newInstance( 91 mAccount.getLocalStoreUri(getContext()), mContext, null); 92 // Single cid case. 93 final String cid1 = "cid.1 (at) android.com"; 94 final long aid1 = 10; 95 final Uri uri1 = MessageTestUtils.contentUri(aid1, mAccount); 96 final String text1 = new TextBuilder("text1 > ").addCidImg(cid1).build(" <."); 97 final String expected1 = new TextBuilder("text1 > ").addUidImg(uri1).build(" <."); 98 99 // message with cid1 100 final Message msg1 = new MessageBuilder() 101 .setBody(new MultipartBuilder("multipart/related") 102 .addBodyPart(MessageTestUtils.textPart("text/html", text1)) 103 .addBodyPart(MessageTestUtils.imagePart("image/jpeg", "<"+cid1+">", aid1, store)) 104 .build()) 105 .build(); 106 // Simple case. 107 final String actual1 = EmailHtmlUtil.resolveInlineImage( 108 getContext().getContentResolver(), mAccount.mId, text1, msg1, 0); 109 assertEquals("one content id reference is not resolved", 110 expected1, actual1); 111 112 // Exceed recursive limit. 113 final String actual0 = EmailHtmlUtil.resolveInlineImage( 114 getContext().getContentResolver(), mAccount.mId, text1, msg1, 10); 115 assertEquals("recursive call limit may exceeded", 116 text1, actual0); 117 118 // Multiple cids case. 119 final String cid2 = "cid.2 (at) android.com"; 120 final long aid2 = 20; 121 final Uri uri2 = MessageTestUtils.contentUri(aid2, mAccount); 122 final String text2 = new TextBuilder("text2 ").addCidImg(cid2).build("."); 123 final String expected2 = new TextBuilder("text2 ").addUidImg(uri2).build("."); 124 125 // message with only cid2 126 final Message msg2 = new MessageBuilder() 127 .setBody(new MultipartBuilder("multipart/related") 128 .addBodyPart(MessageTestUtils.textPart("text/html", text1 + text2)) 129 .addBodyPart(MessageTestUtils.imagePart("image/gif", cid2, aid2, store)) 130 .build()) 131 .build(); 132 // cid1 is not replaced 133 final String actual2 = EmailHtmlUtil.resolveInlineImage( 134 getContext().getContentResolver(), mAccount.mId, text1 + text2, msg2, 0); 135 assertEquals("only one of two content id is resolved", 136 text1 + expected2, actual2); 137 138 // message with cid1 and cid2 139 final Message msg3 = new MessageBuilder() 140 .setBody(new MultipartBuilder("multipart/related") 141 .addBodyPart(MessageTestUtils.textPart("text/html", text2 + text1)) 142 .addBodyPart(MessageTestUtils.imagePart("image/jpeg", cid1, aid1, store)) 143 .addBodyPart(MessageTestUtils.imagePart("image/gif", cid2, aid2, store)) 144 .build()) 145 .build(); 146 // cid1 and cid2 are replaced 147 final String actual3 = EmailHtmlUtil.resolveInlineImage( 148 getContext().getContentResolver(), mAccount.mId, text2 + text1, msg3, 0); 149 assertEquals("two content ids are resolved correctly", 150 expected2 + expected1, actual3); 151 152 // message with many cids and normal attachments 153 final Message msg4 = new MessageBuilder() 154 .setBody(new MultipartBuilder("multipart/mixed") 155 .addBodyPart(MessageTestUtils.imagePart("image/jpeg", null, 30, store)) 156 .addBodyPart(MessageTestUtils.imagePart("application/pdf", cid1, aid1, store)) 157 .addBodyPart(new MultipartBuilder("multipart/related") 158 .addBodyPart(MessageTestUtils.textPart("text/html", text2 + text1)) 159 .addBodyPart(MessageTestUtils.imagePart("image/jpg", cid1, aid1, store)) 160 .addBodyPart(MessageTestUtils.imagePart("image/gif", cid2, aid2, store)) 161 .buildBodyPart()) 162 .addBodyPart(MessageTestUtils.imagePart("application/pdf", cid2, aid2, store)) 163 .build()) 164 .build(); 165 // cid1 and cid2 are replaced 166 final String actual4 = EmailHtmlUtil.resolveInlineImage( 167 getContext().getContentResolver(), mAccount.mId, text2 + text1, msg4, 0); 168 assertEquals("two content ids in deep multipart level are resolved", 169 expected2 + expected1, actual4); 170 171 // No crash on null text 172 final String actual5 = EmailHtmlUtil.resolveInlineImage(getContext().getContentResolver(), 173 mAccount.mId, null, msg4, 0); 174 assertNull(actual5); 175 } 176 177 /** 178 * Test for escapeCharacterToDisplay in plain text mode. 179 */ 180 public void testEscapeCharacterToDisplayPlainText() { 181 String plainTags = EmailHtmlUtil.escapeCharacterToDisplay(textTags); 182 assertEquals("plain tag", "<b>Plain</b> &", plainTags); 183 184 // Successive spaces will be escaped as " " 185 String plainSpaces = EmailHtmlUtil.escapeCharacterToDisplay(textSpaces); 186 assertEquals("plain spaces", "3 spaces end.", plainSpaces); 187 188 // Newlines will be escaped as "<br>" 189 String plainNewlines = EmailHtmlUtil.escapeCharacterToDisplay(textNewlines); 190 assertEquals("plain spaces", "ab <br> <br> <br><br>", plainNewlines); 191 192 // All combinations. 193 String textAll = textTags + "\n" + textSpaces + "\n" + textNewlines; 194 String plainAll = EmailHtmlUtil.escapeCharacterToDisplay(textAll); 195 assertEquals("plain all", 196 "<b>Plain</b> &<br>" + 197 "3 spaces end.<br>" + 198 "ab <br> <br> <br><br>", 199 plainAll); 200 } 201 } 202