MimeUtilityTest.java revision 2193962ca2b3157e79f731736afa2a0c972e778a
196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project/* 296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * 496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * you may not use this file except in compliance with the License. 696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * You may obtain a copy of the License at 796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * 896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * 1096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 1196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 1296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * See the License for the specific language governing permissions and 1496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * limitations under the License. 1596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project */ 1696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project 172193962ca2b3157e79f731736afa2a0c972e778aMarc Blankpackage com.android.emailcommon.internet; 1896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project 192193962ca2b3157e79f731736afa2a0c972e778aMarc Blankimport com.android.emailcommon.internet.MimeBodyPart; 202193962ca2b3157e79f731736afa2a0c972e778aMarc Blankimport com.android.emailcommon.internet.MimeHeader; 212193962ca2b3157e79f731736afa2a0c972e778aMarc Blankimport com.android.emailcommon.internet.MimeUtility; 222193962ca2b3157e79f731736afa2a0c972e778aMarc Blankimport com.android.emailcommon.internet.TextBody; 232193962ca2b3157e79f731736afa2a0c972e778aMarc Blankimport com.android.emailcommon.mail.BodyPart; 242193962ca2b3157e79f731736afa2a0c972e778aMarc Blankimport com.android.emailcommon.mail.Message; 252193962ca2b3157e79f731736afa2a0c972e778aMarc Blankimport com.android.emailcommon.mail.MessageTestUtils; 262193962ca2b3157e79f731736afa2a0c972e778aMarc Blankimport com.android.emailcommon.mail.MessagingException; 272193962ca2b3157e79f731736afa2a0c972e778aMarc Blankimport com.android.emailcommon.mail.Part; 282193962ca2b3157e79f731736afa2a0c972e778aMarc Blankimport com.android.emailcommon.mail.MessageTestUtils.MessageBuilder; 292193962ca2b3157e79f731736afa2a0c972e778aMarc Blankimport com.android.emailcommon.mail.MessageTestUtils.MultipartBuilder; 3096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project 3196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Projectimport android.test.suitebuilder.annotation.SmallTest; 3296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project 3396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Projectimport junit.framework.TestCase; 3496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project 3596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project/** 3696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * This is a series of unit tests for the MimeUtility class. These tests must be locally 3796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * complete - no server(s) required. 3896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project */ 3996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project@SmallTest 4096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Projectpublic class MimeUtilityTest extends TestCase { 4196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project 428aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project /** up arrow, down arrow, left arrow, right arrow */ 438aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project private final String SHORT_UNICODE = "\u2191\u2193\u2190\u2192"; 448aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project private final String SHORT_UNICODE_ENCODED = "=?UTF-8?B?4oaR4oaT4oaQ4oaS?="; 458aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project 46d351a92869438d937b84c27b026803a92923d1dbTadashi Takaoka /** dollar and euro sign */ 47d351a92869438d937b84c27b026803a92923d1dbTadashi Takaoka private final String PADDED2_UNICODE = "$\u20AC"; 48d351a92869438d937b84c27b026803a92923d1dbTadashi Takaoka private final String PADDED2_UNICODE_ENCODED = "=?UTF-8?B?JOKCrA==?="; 49d351a92869438d937b84c27b026803a92923d1dbTadashi Takaoka private final String PADDED1_UNICODE = "$$\u20AC"; 50d351a92869438d937b84c27b026803a92923d1dbTadashi Takaoka private final String PADDED1_UNICODE_ENCODED = "=?UTF-8?B?JCTigqw=?="; 51d351a92869438d937b84c27b026803a92923d1dbTadashi Takaoka private final String PADDED0_UNICODE = "$$$\u20AC"; 52d351a92869438d937b84c27b026803a92923d1dbTadashi Takaoka private final String PADDED0_UNICODE_ENCODED = "=?UTF-8?B?JCQk4oKs?="; 53d351a92869438d937b84c27b026803a92923d1dbTadashi Takaoka 548aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project /** a string without any unicode */ 558aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project private final String SHORT_PLAIN = "abcd"; 568aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project 5744cf2e2882d9d96e6f515c36334cac5ae8e2c305Tadashi Takaoka /** long subject which will be split into two MIME/Base64 chunks */ 5844cf2e2882d9d96e6f515c36334cac5ae8e2c305Tadashi Takaoka private final String LONG_UNICODE_SPLIT = 5944cf2e2882d9d96e6f515c36334cac5ae8e2c305Tadashi Takaoka "$" + 6044cf2e2882d9d96e6f515c36334cac5ae8e2c305Tadashi Takaoka "\u20AC\u20AC\u20AC\u20AC\u20AC\u20AC\u20AC\u20AC\u20AC\u20AC" + 6144cf2e2882d9d96e6f515c36334cac5ae8e2c305Tadashi Takaoka "\u20AC\u20AC\u20AC\u20AC\u20AC\u20AC\u20AC\u20AC\u20AC\u20AC"; 6244cf2e2882d9d96e6f515c36334cac5ae8e2c305Tadashi Takaoka private final String LONG_UNICODE_SPLIT_ENCODED = 6344cf2e2882d9d96e6f515c36334cac5ae8e2c305Tadashi Takaoka "=?UTF-8?B?JOKCrOKCrOKCrOKCrOKCrOKCrOKCrOKCrA==?=" + "\r\n " + 6444cf2e2882d9d96e6f515c36334cac5ae8e2c305Tadashi Takaoka "=?UTF-8?B?4oKs4oKs4oKs4oKs4oKs4oKs4oKs4oKs4oKs4oKs4oKs4oKs?="; 6544cf2e2882d9d96e6f515c36334cac5ae8e2c305Tadashi Takaoka 6644cf2e2882d9d96e6f515c36334cac5ae8e2c305Tadashi Takaoka /** strings that use supplemental characters and really stress encode/decode */ 6744cf2e2882d9d96e6f515c36334cac5ae8e2c305Tadashi Takaoka // actually it's U+10400 6844cf2e2882d9d96e6f515c36334cac5ae8e2c305Tadashi Takaoka private final String SHORT_SUPPLEMENTAL = "\uD801\uDC00"; 6944cf2e2882d9d96e6f515c36334cac5ae8e2c305Tadashi Takaoka private final String SHORT_SUPPLEMENTAL_ENCODED = "=?UTF-8?B?8JCQgA==?="; 7044cf2e2882d9d96e6f515c36334cac5ae8e2c305Tadashi Takaoka private final String LONG_SUPPLEMENTAL = SHORT_SUPPLEMENTAL + SHORT_SUPPLEMENTAL + 7144cf2e2882d9d96e6f515c36334cac5ae8e2c305Tadashi Takaoka SHORT_SUPPLEMENTAL + SHORT_SUPPLEMENTAL + SHORT_SUPPLEMENTAL + SHORT_SUPPLEMENTAL + 7244cf2e2882d9d96e6f515c36334cac5ae8e2c305Tadashi Takaoka SHORT_SUPPLEMENTAL + SHORT_SUPPLEMENTAL + SHORT_SUPPLEMENTAL + SHORT_SUPPLEMENTAL; 7344cf2e2882d9d96e6f515c36334cac5ae8e2c305Tadashi Takaoka private final String LONG_SUPPLEMENTAL_ENCODED = 7444cf2e2882d9d96e6f515c36334cac5ae8e2c305Tadashi Takaoka "=?UTF-8?B?8JCQgPCQkIDwkJCA8JCQgA==?=" + "\r\n " + 7544cf2e2882d9d96e6f515c36334cac5ae8e2c305Tadashi Takaoka "=?UTF-8?B?8JCQgPCQkIDwkJCA8JCQgPCQkIDwkJCA?="; 7644cf2e2882d9d96e6f515c36334cac5ae8e2c305Tadashi Takaoka private final String LONG_SUPPLEMENTAL_2 = "a" + SHORT_SUPPLEMENTAL + SHORT_SUPPLEMENTAL + 7744cf2e2882d9d96e6f515c36334cac5ae8e2c305Tadashi Takaoka SHORT_SUPPLEMENTAL + SHORT_SUPPLEMENTAL + SHORT_SUPPLEMENTAL + SHORT_SUPPLEMENTAL + 7844cf2e2882d9d96e6f515c36334cac5ae8e2c305Tadashi Takaoka SHORT_SUPPLEMENTAL + SHORT_SUPPLEMENTAL + SHORT_SUPPLEMENTAL + SHORT_SUPPLEMENTAL; 7944cf2e2882d9d96e6f515c36334cac5ae8e2c305Tadashi Takaoka private final String LONG_SUPPLEMENTAL_ENCODED_2 = 8044cf2e2882d9d96e6f515c36334cac5ae8e2c305Tadashi Takaoka "=?UTF-8?B?YfCQkIDwkJCA8JCQgPCQkIA=?=" + "\r\n " + 8144cf2e2882d9d96e6f515c36334cac5ae8e2c305Tadashi Takaoka "=?UTF-8?B?8JCQgPCQkIDwkJCA8JCQgPCQkIDwkJCA?="; 8244cf2e2882d9d96e6f515c36334cac5ae8e2c305Tadashi Takaoka // Earth is U+1D300. 8344cf2e2882d9d96e6f515c36334cac5ae8e2c305Tadashi Takaoka private final String LONG_SUPPLEMENTAL_QP = 8444cf2e2882d9d96e6f515c36334cac5ae8e2c305Tadashi Takaoka "*Monogram for Earth \uD834\uDF00. Monogram for Human \u268b."; 8544cf2e2882d9d96e6f515c36334cac5ae8e2c305Tadashi Takaoka private final String LONG_SUPPLEMENTAL_QP_ENCODED = 8644cf2e2882d9d96e6f515c36334cac5ae8e2c305Tadashi Takaoka "=?UTF-8?Q?*Monogram_for_Earth_?=" + "\r\n " + 8744cf2e2882d9d96e6f515c36334cac5ae8e2c305Tadashi Takaoka "=?UTF-8?Q?=F0=9D=8C=80._Monogram_for_Human_=E2=9A=8B.?="; 8844cf2e2882d9d96e6f515c36334cac5ae8e2c305Tadashi Takaoka 898aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project /** a typical no-param header */ 9087fcd03a1b266d3f6030347143f242b1eb524cf8Andrew Stadler private final String HEADER_NO_PARAMETER = 918aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project "header"; 928aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project /** a typical multi-param header */ 9387fcd03a1b266d3f6030347143f242b1eb524cf8Andrew Stadler private final String HEADER_MULTI_PARAMETER = 948aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project "header; Param1Name=Param1Value; Param2Name=Param2Value"; 9587fcd03a1b266d3f6030347143f242b1eb524cf8Andrew Stadler /** a multi-param header with quoting */ 9687fcd03a1b266d3f6030347143f242b1eb524cf8Andrew Stadler private final String HEADER_QUOTED_MULTI_PARAMETER = 9787fcd03a1b266d3f6030347143f242b1eb524cf8Andrew Stadler "header; Param1Name=\"Param1Value\"; Param2Name=\"Param2Value\""; 9887fcd03a1b266d3f6030347143f242b1eb524cf8Andrew Stadler /** a malformed header we're seeing in production servers */ 9987fcd03a1b266d3f6030347143f242b1eb524cf8Andrew Stadler private final String HEADER_MALFORMED_PARAMETER = 10087fcd03a1b266d3f6030347143f242b1eb524cf8Andrew Stadler "header; Param1Name=Param1Value; filename"; 101f7eead207407c25b41fe622e9bd4f29a2b50ee7bAndy Stadler 102f7eead207407c25b41fe622e9bd4f29a2b50ee7bAndy Stadler /** 103f7eead207407c25b41fe622e9bd4f29a2b50ee7bAndy Stadler * a string generated by google calendar that contains two interesting gotchas: 104f7eead207407c25b41fe622e9bd4f29a2b50ee7bAndy Stadler * 1. Uses windows-1252 encoding, and en-dash recoded appropriately (\u2013 / =96) 105f7eead207407c25b41fe622e9bd4f29a2b50ee7bAndy Stadler * 2. Because the first encoded char requires '=XX' encoding, we create an "internal" 106f7eead207407c25b41fe622e9bd4f29a2b50ee7bAndy Stadler * "?=" that the decoder must correctly skip over. 107f7eead207407c25b41fe622e9bd4f29a2b50ee7bAndy Stadler **/ 108f7eead207407c25b41fe622e9bd4f29a2b50ee7bAndy Stadler private final String CALENDAR_SUBJECT_UNICODE = 109f7eead207407c25b41fe622e9bd4f29a2b50ee7bAndy Stadler "=?windows-1252?Q?=5BReminder=5D_test_=40_Fri_Mar_20_10=3A30am_=96_11am_=28andro?=" + 110f7eead207407c25b41fe622e9bd4f29a2b50ee7bAndy Stadler "\r\n\t" + 111f7eead207407c25b41fe622e9bd4f29a2b50ee7bAndy Stadler "=?windows-1252?Q?id=2Etr=40gmail=2Ecom=29?="; 112f7eead207407c25b41fe622e9bd4f29a2b50ee7bAndy Stadler private final String CALENDAR_SUBJECT_PLAIN = 113f7eead207407c25b41fe622e9bd4f29a2b50ee7bAndy Stadler "[Reminder] test @ Fri Mar 20 10:30am \u2013 11am (android.tr@gmail.com)"; 114f7eead207407c25b41fe622e9bd4f29a2b50ee7bAndy Stadler 115f7eead207407c25b41fe622e9bd4f29a2b50ee7bAndy Stadler /** 116f7eead207407c25b41fe622e9bd4f29a2b50ee7bAndy Stadler * Some basic degenerate strings designed to exercise error handling in the decoder 117f7eead207407c25b41fe622e9bd4f29a2b50ee7bAndy Stadler */ 118f7eead207407c25b41fe622e9bd4f29a2b50ee7bAndy Stadler private final String CALENDAR_DEGENERATE_UNICODE_1 = 119f7eead207407c25b41fe622e9bd4f29a2b50ee7bAndy Stadler "=?windows-1252?Q=5B?="; 120f7eead207407c25b41fe622e9bd4f29a2b50ee7bAndy Stadler private final String CALENDAR_DEGENERATE_UNICODE_2 = 121f7eead207407c25b41fe622e9bd4f29a2b50ee7bAndy Stadler "=?windows-1252Q?=5B?="; 122f7eead207407c25b41fe622e9bd4f29a2b50ee7bAndy Stadler private final String CALENDAR_DEGENERATE_UNICODE_3 = 123f7eead207407c25b41fe622e9bd4f29a2b50ee7bAndy Stadler "=?windows-1252?="; 124f7eead207407c25b41fe622e9bd4f29a2b50ee7bAndy Stadler private final String CALENDAR_DEGENERATE_UNICODE_4 = 125f7eead207407c25b41fe622e9bd4f29a2b50ee7bAndy Stadler "=?windows-1252"; 1268aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project 1278aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project /** 1288aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project * Test that decode/unfold is efficient when it can be 1298aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project */ 1308aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project public void testEfficientUnfoldAndDecode() { 1318aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project String result1 = MimeUtility.unfold(SHORT_PLAIN); 1328aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project String result2 = MimeUtility.decode(SHORT_PLAIN); 1338aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project String result3 = MimeUtility.unfoldAndDecode(SHORT_PLAIN); 1348aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project 1358aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project assertSame(SHORT_PLAIN, result1); 1368aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project assertSame(SHORT_PLAIN, result2); 1378aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project assertSame(SHORT_PLAIN, result3); 1388aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project } 1398aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project 1408aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project // TODO: more tests for unfold(String s) 1418aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project 1428aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project /** 1438aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project * Test that decode is working for simple strings 1448aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project */ 1458aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project public void testDecodeSimple() { 1468aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project String result1 = MimeUtility.decode(SHORT_UNICODE_ENCODED); 1478aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project assertEquals(SHORT_UNICODE, result1); 1488aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project } 1498aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project 15096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project // TODO: tests for decode(String s) 1518aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project 1528aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project /** 1538aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project * Test that unfoldAndDecode is working for simple strings 1548aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project */ 1558aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project public void testUnfoldAndDecodeSimple() { 1568aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project String result1 = MimeUtility.unfoldAndDecode(SHORT_UNICODE_ENCODED); 1578aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project assertEquals(SHORT_UNICODE, result1); 1588aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project } 1598aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project 160f7eead207407c25b41fe622e9bd4f29a2b50ee7bAndy Stadler /** 161f7eead207407c25b41fe622e9bd4f29a2b50ee7bAndy Stadler * test decoding complex string from google calendar that has two gotchas for the decoder. 162f7eead207407c25b41fe622e9bd4f29a2b50ee7bAndy Stadler * also tests a couple of degenerate cases that should "fail" decoding and pass through. 163f7eead207407c25b41fe622e9bd4f29a2b50ee7bAndy Stadler */ 164f7eead207407c25b41fe622e9bd4f29a2b50ee7bAndy Stadler public void testComplexDecode() { 165f7eead207407c25b41fe622e9bd4f29a2b50ee7bAndy Stadler String result1 = MimeUtility.unfoldAndDecode(CALENDAR_SUBJECT_UNICODE); 166f7eead207407c25b41fe622e9bd4f29a2b50ee7bAndy Stadler assertEquals(CALENDAR_SUBJECT_PLAIN, result1); 167f7eead207407c25b41fe622e9bd4f29a2b50ee7bAndy Stadler 168f7eead207407c25b41fe622e9bd4f29a2b50ee7bAndy Stadler // These degenerate cases should "fail" and return the same string 169f7eead207407c25b41fe622e9bd4f29a2b50ee7bAndy Stadler String degenerate1 = MimeUtility.unfoldAndDecode(CALENDAR_DEGENERATE_UNICODE_1); 170f7eead207407c25b41fe622e9bd4f29a2b50ee7bAndy Stadler assertEquals("degenerate case 1", CALENDAR_DEGENERATE_UNICODE_1, degenerate1); 171f7eead207407c25b41fe622e9bd4f29a2b50ee7bAndy Stadler String degenerate2 = MimeUtility.unfoldAndDecode(CALENDAR_DEGENERATE_UNICODE_2); 172f7eead207407c25b41fe622e9bd4f29a2b50ee7bAndy Stadler assertEquals("degenerate case 2", CALENDAR_DEGENERATE_UNICODE_2, degenerate2); 173f7eead207407c25b41fe622e9bd4f29a2b50ee7bAndy Stadler String degenerate3 = MimeUtility.unfoldAndDecode(CALENDAR_DEGENERATE_UNICODE_3); 174f7eead207407c25b41fe622e9bd4f29a2b50ee7bAndy Stadler assertEquals("degenerate case 3", CALENDAR_DEGENERATE_UNICODE_3, degenerate3); 175f7eead207407c25b41fe622e9bd4f29a2b50ee7bAndy Stadler String degenerate4 = MimeUtility.unfoldAndDecode(CALENDAR_DEGENERATE_UNICODE_4); 176f7eead207407c25b41fe622e9bd4f29a2b50ee7bAndy Stadler assertEquals("degenerate case 4", CALENDAR_DEGENERATE_UNICODE_4, degenerate4); 177f7eead207407c25b41fe622e9bd4f29a2b50ee7bAndy Stadler } 178f7eead207407c25b41fe622e9bd4f29a2b50ee7bAndy Stadler 179f7eead207407c25b41fe622e9bd4f29a2b50ee7bAndy Stadler // TODO: more tests for unfoldAndDecode(String s) 1808aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project 1818aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project /** 1828aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project * Test that fold/encode is efficient when it can be 1838aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project */ 1848aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project public void testEfficientFoldAndEncode() { 1858aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project String result1 = MimeUtility.foldAndEncode(SHORT_PLAIN); 1868aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project String result2 = MimeUtility.foldAndEncode2(SHORT_PLAIN, 10); 1878aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project String result3 = MimeUtility.fold(SHORT_PLAIN, 10); 1888aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project 1898aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project assertSame(SHORT_PLAIN, result1); 1908aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project assertSame(SHORT_PLAIN, result2); 1918aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project assertSame(SHORT_PLAIN, result3); 1928aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project } 1938aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project 194d351a92869438d937b84c27b026803a92923d1dbTadashi Takaoka /** 195d351a92869438d937b84c27b026803a92923d1dbTadashi Takaoka * Test about base64 padding variety. 196d351a92869438d937b84c27b026803a92923d1dbTadashi Takaoka */ 197d351a92869438d937b84c27b026803a92923d1dbTadashi Takaoka public void testPaddingOfFoldAndEncode2() { 198d351a92869438d937b84c27b026803a92923d1dbTadashi Takaoka String result1 = MimeUtility.foldAndEncode2(PADDED2_UNICODE, 0); 199d351a92869438d937b84c27b026803a92923d1dbTadashi Takaoka String result2 = MimeUtility.foldAndEncode2(PADDED1_UNICODE, 0); 200d351a92869438d937b84c27b026803a92923d1dbTadashi Takaoka String result3 = MimeUtility.foldAndEncode2(PADDED0_UNICODE, 0); 201d351a92869438d937b84c27b026803a92923d1dbTadashi Takaoka 202d351a92869438d937b84c27b026803a92923d1dbTadashi Takaoka assertEquals("padding 2", PADDED2_UNICODE_ENCODED, result1); 203d351a92869438d937b84c27b026803a92923d1dbTadashi Takaoka assertEquals("padding 1", PADDED1_UNICODE_ENCODED, result2); 204d351a92869438d937b84c27b026803a92923d1dbTadashi Takaoka assertEquals("padding 0", PADDED0_UNICODE_ENCODED, result3); 205d351a92869438d937b84c27b026803a92923d1dbTadashi Takaoka } 206d351a92869438d937b84c27b026803a92923d1dbTadashi Takaoka 2078aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project // TODO: more tests for foldAndEncode(String s) 2088aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project 2098aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project /** 2108aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project * Test that foldAndEncode2 is working for simple strings 2118aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project */ 2128aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project public void testFoldAndEncode2() { 2138aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project String result1 = MimeUtility.foldAndEncode2(SHORT_UNICODE, 10); 2148aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project assertEquals(SHORT_UNICODE_ENCODED, result1); 2158aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project } 2168aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project 21744cf2e2882d9d96e6f515c36334cac5ae8e2c305Tadashi Takaoka /** 21844cf2e2882d9d96e6f515c36334cac5ae8e2c305Tadashi Takaoka * Test that foldAndEncode2 is working for long strings which needs splitting. 21944cf2e2882d9d96e6f515c36334cac5ae8e2c305Tadashi Takaoka */ 22044cf2e2882d9d96e6f515c36334cac5ae8e2c305Tadashi Takaoka public void testFoldAndEncode2WithLongSplit() { 22144cf2e2882d9d96e6f515c36334cac5ae8e2c305Tadashi Takaoka String result = MimeUtility.foldAndEncode2(LONG_UNICODE_SPLIT, "Subject: ".length()); 22244cf2e2882d9d96e6f515c36334cac5ae8e2c305Tadashi Takaoka 22344cf2e2882d9d96e6f515c36334cac5ae8e2c305Tadashi Takaoka assertEquals("long string", LONG_UNICODE_SPLIT_ENCODED, result); 22444cf2e2882d9d96e6f515c36334cac5ae8e2c305Tadashi Takaoka } 22544cf2e2882d9d96e6f515c36334cac5ae8e2c305Tadashi Takaoka 22644cf2e2882d9d96e6f515c36334cac5ae8e2c305Tadashi Takaoka /** 22744cf2e2882d9d96e6f515c36334cac5ae8e2c305Tadashi Takaoka * Tests of foldAndEncode2 that involve supplemental characters (UTF-32) 22844cf2e2882d9d96e6f515c36334cac5ae8e2c305Tadashi Takaoka * 22944cf2e2882d9d96e6f515c36334cac5ae8e2c305Tadashi Takaoka * Note that the difference between LONG_SUPPLEMENTAL and LONG_SUPPLEMENTAL_2 is the 23044cf2e2882d9d96e6f515c36334cac5ae8e2c305Tadashi Takaoka * insertion of a single character at the head of the string. This is intended to disrupt 23144cf2e2882d9d96e6f515c36334cac5ae8e2c305Tadashi Takaoka * the code that splits the long string into multiple encoded words, and confirm that it 23244cf2e2882d9d96e6f515c36334cac5ae8e2c305Tadashi Takaoka * properly applies the breaks between UTF-32 code points. 23344cf2e2882d9d96e6f515c36334cac5ae8e2c305Tadashi Takaoka */ 23444cf2e2882d9d96e6f515c36334cac5ae8e2c305Tadashi Takaoka public void testFoldAndEncode2Supplemental() { 23544cf2e2882d9d96e6f515c36334cac5ae8e2c305Tadashi Takaoka String result1 = MimeUtility.foldAndEncode2(SHORT_SUPPLEMENTAL, "Subject: ".length()); 23644cf2e2882d9d96e6f515c36334cac5ae8e2c305Tadashi Takaoka String result2 = MimeUtility.foldAndEncode2(LONG_SUPPLEMENTAL, "Subject: ".length()); 23744cf2e2882d9d96e6f515c36334cac5ae8e2c305Tadashi Takaoka String result3 = MimeUtility.foldAndEncode2(LONG_SUPPLEMENTAL_2, "Subject: ".length()); 23844cf2e2882d9d96e6f515c36334cac5ae8e2c305Tadashi Takaoka assertEquals("short supplemental", SHORT_SUPPLEMENTAL_ENCODED, result1); 23944cf2e2882d9d96e6f515c36334cac5ae8e2c305Tadashi Takaoka assertEquals("long supplemental", LONG_SUPPLEMENTAL_ENCODED, result2); 24044cf2e2882d9d96e6f515c36334cac5ae8e2c305Tadashi Takaoka assertEquals("long supplemental 2", LONG_SUPPLEMENTAL_ENCODED_2, result3); 24144cf2e2882d9d96e6f515c36334cac5ae8e2c305Tadashi Takaoka } 24244cf2e2882d9d96e6f515c36334cac5ae8e2c305Tadashi Takaoka 24344cf2e2882d9d96e6f515c36334cac5ae8e2c305Tadashi Takaoka /** 24444cf2e2882d9d96e6f515c36334cac5ae8e2c305Tadashi Takaoka * Tests of foldAndEncode2 that involve supplemental characters (UTF-32) 24544cf2e2882d9d96e6f515c36334cac5ae8e2c305Tadashi Takaoka * 24644cf2e2882d9d96e6f515c36334cac5ae8e2c305Tadashi Takaoka * Note that the difference between LONG_SUPPLEMENTAL and LONG_SUPPLEMENTAL_QP is that 24744cf2e2882d9d96e6f515c36334cac5ae8e2c305Tadashi Takaoka * the former will be encoded as base64 but the latter will be encoded as quoted printable. 24844cf2e2882d9d96e6f515c36334cac5ae8e2c305Tadashi Takaoka */ 24944cf2e2882d9d96e6f515c36334cac5ae8e2c305Tadashi Takaoka public void testFoldAndEncode2SupplementalQuotedPrintable() { 25044cf2e2882d9d96e6f515c36334cac5ae8e2c305Tadashi Takaoka String result = MimeUtility.foldAndEncode2(LONG_SUPPLEMENTAL_QP, "Subject: ".length()); 25144cf2e2882d9d96e6f515c36334cac5ae8e2c305Tadashi Takaoka assertEquals("long supplement quoted printable", 25244cf2e2882d9d96e6f515c36334cac5ae8e2c305Tadashi Takaoka LONG_SUPPLEMENTAL_QP_ENCODED, result); 25344cf2e2882d9d96e6f515c36334cac5ae8e2c305Tadashi Takaoka } 25444cf2e2882d9d96e6f515c36334cac5ae8e2c305Tadashi Takaoka 2558aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project // TODO: more tests for foldAndEncode2(String s) 2568aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project // TODO: more tests for fold(String s, int usedCharacters) 2578aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project 2588aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project /** 2598aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project * Basic tests of getHeaderParameter() 2608aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project * 2618aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project * Typical header value: multipart/mixed; boundary="----E5UGTXUQQJV80DR8SJ88F79BRA4S8K" 2628aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project * 2638aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project * Function spec says: 2648aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project * if header is null: return null 2658aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project * if name is null: if params, return first param. else return full field 2668aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project * else: if param is found (case insensitive) return it 2678aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project * else return null 2688aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project */ 2698aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project public void testGetHeaderParameter() { 2708aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project // if header is null, return null 2718aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project assertNull("null header check", MimeUtility.getHeaderParameter(null, "name")); 2728aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project 2738aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project // if name is null, return first param or full header 2748aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project // NOTE: The docs are wrong - it returns the header (no params) in that case 2758aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project// assertEquals("null name first param per docs", "Param1Value", 2768aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project// MimeUtility.getHeaderParameter(HEADER_MULTI_PARAMETER, null)); 27787fcd03a1b266d3f6030347143f242b1eb524cf8Andrew Stadler assertEquals("null name first param per code", "header", 2788aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project MimeUtility.getHeaderParameter(HEADER_MULTI_PARAMETER, null)); 27987fcd03a1b266d3f6030347143f242b1eb524cf8Andrew Stadler assertEquals("null name full header", HEADER_NO_PARAMETER, 2808aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project MimeUtility.getHeaderParameter(HEADER_NO_PARAMETER, null)); 2818aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project 2828aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project // find name 28387fcd03a1b266d3f6030347143f242b1eb524cf8Andrew Stadler assertEquals("get 1st param", "Param1Value", 2848aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project MimeUtility.getHeaderParameter(HEADER_MULTI_PARAMETER, "Param1Name")); 28587fcd03a1b266d3f6030347143f242b1eb524cf8Andrew Stadler assertEquals("get 2nd param", "Param2Value", 2868aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project MimeUtility.getHeaderParameter(HEADER_MULTI_PARAMETER, "Param2Name")); 28787fcd03a1b266d3f6030347143f242b1eb524cf8Andrew Stadler assertEquals("get missing param", null, 2888aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project MimeUtility.getHeaderParameter(HEADER_MULTI_PARAMETER, "Param3Name")); 2898aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project 2908aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project // case insensitivity 29187fcd03a1b266d3f6030347143f242b1eb524cf8Andrew Stadler assertEquals("get 2nd param all LC", "Param2Value", 2928aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project MimeUtility.getHeaderParameter(HEADER_MULTI_PARAMETER, "param2name")); 29387fcd03a1b266d3f6030347143f242b1eb524cf8Andrew Stadler assertEquals("get 2nd param all UC", "Param2Value", 2948aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project MimeUtility.getHeaderParameter(HEADER_MULTI_PARAMETER, "PARAM2NAME")); 29587fcd03a1b266d3f6030347143f242b1eb524cf8Andrew Stadler 29687fcd03a1b266d3f6030347143f242b1eb524cf8Andrew Stadler // quoting 29787fcd03a1b266d3f6030347143f242b1eb524cf8Andrew Stadler assertEquals("get 1st param", "Param1Value", 29887fcd03a1b266d3f6030347143f242b1eb524cf8Andrew Stadler MimeUtility.getHeaderParameter(HEADER_QUOTED_MULTI_PARAMETER, "Param1Name")); 29987fcd03a1b266d3f6030347143f242b1eb524cf8Andrew Stadler assertEquals("get 2nd param", "Param2Value", 30087fcd03a1b266d3f6030347143f242b1eb524cf8Andrew Stadler MimeUtility.getHeaderParameter(HEADER_QUOTED_MULTI_PARAMETER, "Param2Name")); 30187fcd03a1b266d3f6030347143f242b1eb524cf8Andrew Stadler 30287fcd03a1b266d3f6030347143f242b1eb524cf8Andrew Stadler // Don't fail when malformed 30387fcd03a1b266d3f6030347143f242b1eb524cf8Andrew Stadler assertEquals("malformed filename param", null, 30487fcd03a1b266d3f6030347143f242b1eb524cf8Andrew Stadler MimeUtility.getHeaderParameter(HEADER_MALFORMED_PARAMETER, "filename")); 3058aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project } 3068aeb922462694d22f42c5890e5434e9de9dc3987The Android Open Source Project 30796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project // TODO: tests for findFirstPartByMimeType(Part part, String mimeType) 3083469902379242c723b871d1dcb09b02d0998d538The Android Open Source Project 3093469902379242c723b871d1dcb09b02d0998d538The Android Open Source Project /** Tests for findPartByContentId(Part part, String contentId) */ 3103469902379242c723b871d1dcb09b02d0998d538The Android Open Source Project public void testFindPartByContentIdTestCase() throws MessagingException, Exception { 3113469902379242c723b871d1dcb09b02d0998d538The Android Open Source Project final String cid1 = "cid.1@android.com"; 3123469902379242c723b871d1dcb09b02d0998d538The Android Open Source Project final Part cid1bp = MessageTestUtils.bodyPart("image/gif", cid1); 3133469902379242c723b871d1dcb09b02d0998d538The Android Open Source Project final String cid2 = "cid.2@android.com"; 3143469902379242c723b871d1dcb09b02d0998d538The Android Open Source Project final Part cid2bp = MessageTestUtils.bodyPart("image/gif", "<" + cid2 + ">"); 3153469902379242c723b871d1dcb09b02d0998d538The Android Open Source Project 3163469902379242c723b871d1dcb09b02d0998d538The Android Open Source Project final Message msg1 = new MessageBuilder() 3173469902379242c723b871d1dcb09b02d0998d538The Android Open Source Project .setBody(new MultipartBuilder("multipart/related") 3183469902379242c723b871d1dcb09b02d0998d538The Android Open Source Project .addBodyPart(MessageTestUtils.bodyPart("text/html", null)) 3193469902379242c723b871d1dcb09b02d0998d538The Android Open Source Project .addBodyPart((BodyPart)cid1bp) 3203469902379242c723b871d1dcb09b02d0998d538The Android Open Source Project .build()) 3213469902379242c723b871d1dcb09b02d0998d538The Android Open Source Project .build(); 3223469902379242c723b871d1dcb09b02d0998d538The Android Open Source Project // found cid1 part 3233469902379242c723b871d1dcb09b02d0998d538The Android Open Source Project final Part actual1_1 = MimeUtility.findPartByContentId(msg1, cid1); 3243469902379242c723b871d1dcb09b02d0998d538The Android Open Source Project assertEquals("could not found expected content-id part", cid1bp, actual1_1); 3253469902379242c723b871d1dcb09b02d0998d538The Android Open Source Project 3263469902379242c723b871d1dcb09b02d0998d538The Android Open Source Project final Message msg2 = new MessageBuilder() 3273469902379242c723b871d1dcb09b02d0998d538The Android Open Source Project .setBody(new MultipartBuilder("multipart/mixed") 3283469902379242c723b871d1dcb09b02d0998d538The Android Open Source Project .addBodyPart(MessageTestUtils.bodyPart("image/tiff", "cid.4@android.com")) 3293469902379242c723b871d1dcb09b02d0998d538The Android Open Source Project .addBodyPart(new MultipartBuilder("multipart/related") 3303469902379242c723b871d1dcb09b02d0998d538The Android Open Source Project .addBodyPart(new MultipartBuilder("multipart/alternative") 3313469902379242c723b871d1dcb09b02d0998d538The Android Open Source Project .addBodyPart(MessageTestUtils.bodyPart("text/plain", null)) 3323469902379242c723b871d1dcb09b02d0998d538The Android Open Source Project .addBodyPart(MessageTestUtils.bodyPart("text/html", null)) 3333469902379242c723b871d1dcb09b02d0998d538The Android Open Source Project .buildBodyPart()) 3343469902379242c723b871d1dcb09b02d0998d538The Android Open Source Project .addBodyPart((BodyPart)cid1bp) 3353469902379242c723b871d1dcb09b02d0998d538The Android Open Source Project .buildBodyPart()) 3363469902379242c723b871d1dcb09b02d0998d538The Android Open Source Project .addBodyPart(MessageTestUtils.bodyPart("image/gif", "cid.3@android.com")) 3373469902379242c723b871d1dcb09b02d0998d538The Android Open Source Project .addBodyPart((BodyPart)cid2bp) 3383469902379242c723b871d1dcb09b02d0998d538The Android Open Source Project .build()) 3393469902379242c723b871d1dcb09b02d0998d538The Android Open Source Project .build(); 3403469902379242c723b871d1dcb09b02d0998d538The Android Open Source Project // found cid1 part 3413469902379242c723b871d1dcb09b02d0998d538The Android Open Source Project final Part actual2_1 = MimeUtility.findPartByContentId(msg2, cid1); 3423469902379242c723b871d1dcb09b02d0998d538The Android Open Source Project assertEquals("found part from related multipart", cid1bp, actual2_1); 3433469902379242c723b871d1dcb09b02d0998d538The Android Open Source Project 3443469902379242c723b871d1dcb09b02d0998d538The Android Open Source Project // found cid2 part 3453469902379242c723b871d1dcb09b02d0998d538The Android Open Source Project final Part actual2_2 = MimeUtility.findPartByContentId(msg2, cid2); 3463469902379242c723b871d1dcb09b02d0998d538The Android Open Source Project assertEquals("found part from mixed multipart", cid2bp, actual2_2); 3473469902379242c723b871d1dcb09b02d0998d538The Android Open Source Project } 34896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project 34996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project /** Tests for getTextFromPart(Part part) */ 35096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project public void testGetTextFromPartContentTypeCase() throws MessagingException { 35196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project final String theText = "This is the text of the part"; 35296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project TextBody tb = new TextBody(theText); 35396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project MimeBodyPart p = new MimeBodyPart(); 35496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project 35596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project // 1. test basic text/plain mode 35696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project p.setHeader(MimeHeader.HEADER_CONTENT_TYPE, "text/plain"); 35796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project p.setBody(tb); 35896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project String gotText = MimeUtility.getTextFromPart(p); 35996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project assertEquals(theText, gotText); 36096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project 36196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project // 2. mixed case is OK 36296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project p.setHeader(MimeHeader.HEADER_CONTENT_TYPE, "TEXT/PLAIN"); 36396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project p.setBody(tb); 36496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project gotText = MimeUtility.getTextFromPart(p); 36596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project assertEquals(theText, gotText); 36696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project 36796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project // 3. wildcards OK 36896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project p.setHeader(MimeHeader.HEADER_CONTENT_TYPE, "text/other"); 36996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project p.setBody(tb); 37096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project gotText = MimeUtility.getTextFromPart(p); 37196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project assertEquals(theText, gotText); 37296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project } 3732517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn 3742517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn /** Test for usage of Content-Type in getTextFromPart(Part part). 3752517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn * 3762517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn * For example 'Content-Type: text/html; charset=utf-8' 3772517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn * 3782517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn * If the body part has no mime-type, refuses to parse content as text. 3792517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn * If the mime-type does not match text/*, it will not get parsed. 3802517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn * Then, the charset parameter is used, with a default of ASCII. 3812517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn * 3822517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn * This test works by using a string that is valid Unicode, and is also 3832517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn * valid when decoded from UTF-8 bytes into Windows-1252 (so that 3842517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn * auto-detection is not possible), and checks that the correct conversion 3852517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn * was made, based on the Content-Type header. 3862517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn * 3872517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn */ 3882517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn public void testContentTypeCharset() throws MessagingException { 3892517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn final String UNICODE_EXPECT = "This is some happy unicode text \u263a"; 3902517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn // What you get if you encode to UTF-8 (\xe2\x98\xba) and reencode with Windows-1252 3912517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn final String WINDOWS1252_EXPECT = "This is some happy unicode text \u00e2\u02dc\u00ba"; 3922517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn TextBody tb = new TextBody(UNICODE_EXPECT); 3932517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn MimeBodyPart p = new MimeBodyPart(); 3942517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn 3952517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn String gotText, mimeType, charset; 3962517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn // TEST 0: Standard Content-Type header; no extraneous spaces or fields 3972517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn p.setBody(tb); 3982517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn // We call setHeader after setBody, since setBody overwrites Content-Type 3992517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn p.setHeader(MimeHeader.HEADER_CONTENT_TYPE, "text/html; charset=utf-8"); 4002517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn gotText = MimeUtility.getTextFromPart(p); 4012517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn assertTrue(MimeUtility.mimeTypeMatches(p.getMimeType(), "text/html")); 4022517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn assertEquals(UNICODE_EXPECT, gotText); 4032517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn 4042517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn p.setBody(tb); 4052517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn p.setHeader(MimeHeader.HEADER_CONTENT_TYPE, "text/html; charset=windows-1252"); 4062517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn gotText = MimeUtility.getTextFromPart(p); 4072517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn assertTrue(MimeUtility.mimeTypeMatches(p.getMimeType(), "text/html")); 4082517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn assertEquals(WINDOWS1252_EXPECT, gotText); 4092517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn 4102517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn // TEST 1: Extra fields and quotes in Content-Type (from RFC 2045) 4112517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn p.setBody(tb); 4122517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn p.setHeader(MimeHeader.HEADER_CONTENT_TYPE, 4132517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn "text/html; prop1 = \"test\"; charset = \"utf-8\"; prop2 = \"test\""); 4142517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn gotText = MimeUtility.getTextFromPart(p); 4152517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn assertTrue(MimeUtility.mimeTypeMatches(p.getMimeType(), "text/html")); 4162517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn assertEquals(UNICODE_EXPECT, gotText); 4172517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn 4182517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn p.setBody(tb); 4192517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn p.setHeader(MimeHeader.HEADER_CONTENT_TYPE, 4202517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn "text/html; prop1 = \"test\"; charset = \"windows-1252\"; prop2 = \"test\""); 4212517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn gotText = MimeUtility.getTextFromPart(p); 4222517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn assertTrue(MimeUtility.mimeTypeMatches(p.getMimeType(), "text/html")); 4232517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn assertEquals(WINDOWS1252_EXPECT, gotText); 4242517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn 4252517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn // TEST 2: Mixed case in Content-Type header: 4262517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn // RFC 2045 says that content types, subtypes and parameter names 4272517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn // are case-insensitive. 4282517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn 4292517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn p.setBody(tb); 4302517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn p.setHeader(MimeHeader.HEADER_CONTENT_TYPE, "TEXT/HtmL ; CHARseT=utf-8"); 4312517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn gotText = MimeUtility.getTextFromPart(p); 4322517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn assertTrue(MimeUtility.mimeTypeMatches(p.getMimeType(), "text/html")); 4332517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn assertEquals(UNICODE_EXPECT, gotText); 4342517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn 4352517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn p.setBody(tb); 4362517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn p.setHeader(MimeHeader.HEADER_CONTENT_TYPE, "TEXT/HtmL ; CHARseT=windows-1252"); 4372517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn gotText = MimeUtility.getTextFromPart(p); 4382517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn assertTrue(MimeUtility.mimeTypeMatches(p.getMimeType(), "text/html")); 4392517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn assertEquals(WINDOWS1252_EXPECT, gotText); 4402517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn 4412517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn // TEST 3: Comments in Content-Type header field (from RFC 2045) 4422517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn // Thunderbird permits comments after the end of a parameter, as in this example. 4432517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn // Not something that I have seen in the real world outside RFC 2045. 4442517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn 4452517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn p.setBody(tb); 4462517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn p.setHeader(MimeHeader.HEADER_CONTENT_TYPE, 4472517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn "text/html; charset=utf-8 (Plain text)"); 4482517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn gotText = MimeUtility.getTextFromPart(p); 4492517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn assertTrue(MimeUtility.mimeTypeMatches(p.getMimeType(), "text/html")); 4502517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn // Note: This test does not pass. 4512517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn //assertEquals(UNICODE_EXPECT, gotText); 4522517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn 4532517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn p.setBody(tb); 4542517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn p.setHeader(MimeHeader.HEADER_CONTENT_TYPE, 4552517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn "text/html; charset=windows-1252 (Plain text)"); 4562517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn gotText = MimeUtility.getTextFromPart(p); 4572517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn assertTrue(MimeUtility.mimeTypeMatches(p.getMimeType(), "text/html")); 4582517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn // Note: These tests does not pass. 4592517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn //assertEquals(WINDOWS1252_EXPECT, gotText); 4602517a3dfd15a4bdb01677fd1ed6a63645eaad3f7Patrick Horn } 46196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project 46296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project /** Tests for various aspects of mimeTypeMatches(String mimeType, String matchAgainst) */ 46396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project public void testMimeTypeMatches() { 46496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project // 1. No match 46596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project assertFalse(MimeUtility.mimeTypeMatches("foo/bar", "TEXT/PLAIN")); 46696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project 46796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project // 2. Match 46896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project assertTrue(MimeUtility.mimeTypeMatches("text/plain", "text/plain")); 46996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project 47096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project // 3. Match (mixed case) 47196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project assertTrue(MimeUtility.mimeTypeMatches("text/plain", "TEXT/PLAIN")); 47296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project assertTrue(MimeUtility.mimeTypeMatches("TEXT/PLAIN", "text/plain")); 47396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project 47496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project // 4. Match (wildcards) 47596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project assertTrue(MimeUtility.mimeTypeMatches("text/plain", "*/plain")); 47696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project assertTrue(MimeUtility.mimeTypeMatches("text/plain", "text/*")); 47796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project assertTrue(MimeUtility.mimeTypeMatches("text/plain", "*/*")); 47896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project 47996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project // 5. No Match (wildcards) 48096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project assertFalse(MimeUtility.mimeTypeMatches("foo/bar", "*/plain")); 48196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project assertFalse(MimeUtility.mimeTypeMatches("foo/bar", "text/*")); 48296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project } 48396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project 48496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project /** Tests for various aspects of mimeTypeMatches(String mimeType, String[] matchAgainst) */ 48596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project public void testMimeTypeMatchesArray() { 48696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project // 1. Zero-length array 48796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project String[] arrayZero = new String[0]; 48896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project assertFalse(MimeUtility.mimeTypeMatches("text/plain", arrayZero)); 48996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project 49096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project // 2. Single entry, no match 49196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project String[] arrayOne = new String[] { "text/plain" }; 49296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project assertFalse(MimeUtility.mimeTypeMatches("foo/bar", arrayOne)); 49396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project 49496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project // 3. Single entry, match 49596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project assertTrue(MimeUtility.mimeTypeMatches("text/plain", arrayOne)); 49696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project 49796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project // 4. Multi entry, no match 49896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project String[] arrayTwo = new String[] { "text/plain", "match/this" }; 49996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project assertFalse(MimeUtility.mimeTypeMatches("foo/bar", arrayTwo)); 50096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project 50196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project // 5. Multi entry, match first 50296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project assertTrue(MimeUtility.mimeTypeMatches("text/plain", arrayTwo)); 50396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project 50496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project // 6. Multi entry, match not first 50596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project assertTrue(MimeUtility.mimeTypeMatches("match/this", arrayTwo)); 50696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project } 50796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project 50896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project // TODO: tests for decodeBody(InputStream in, String contentTransferEncoding) 50996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project // TODO: tests for collectParts(Part part, ArrayList<Part> viewables, ArrayList<Part> attachments) 5103469902379242c723b871d1dcb09b02d0998d538The Android Open Source Project 51196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project} 512