Home | History | Annotate | Download | only in internet
      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.emailcommon.internet;
     18 
     19 import com.android.emailcommon.TempDirectory;
     20 import com.android.emailcommon.mail.Address;
     21 import com.android.emailcommon.mail.Flag;
     22 import com.android.emailcommon.mail.Message.RecipientType;
     23 import com.android.emailcommon.mail.MessagingException;
     24 
     25 import android.test.AndroidTestCase;
     26 import android.test.suitebuilder.annotation.MediumTest;
     27 import android.test.suitebuilder.annotation.SmallTest;
     28 
     29 import java.io.ByteArrayInputStream;
     30 import java.io.ByteArrayOutputStream;
     31 import java.io.IOException;
     32 import java.text.ParseException;
     33 import java.text.SimpleDateFormat;
     34 import java.util.Date;
     35 import java.util.Locale;
     36 
     37 /**
     38  * This is a series of unit tests for the MimeMessage class.  These tests must be locally
     39  * complete - no server(s) required.
     40  */
     41 @SmallTest
     42 public class MimeMessageTest extends AndroidTestCase {
     43 
     44     /** up arrow, down arrow, left arrow, right arrow */
     45     private final String SHORT_UNICODE = "\u2191\u2193\u2190\u2192";
     46     private final String SHORT_UNICODE_ENCODED = "=?UTF-8?B?4oaR4oaT4oaQ4oaS?=";
     47 
     48     /** a string without any unicode */
     49     private final String SHORT_PLAIN = "abcd";
     50 
     51     /** longer unicode strings */
     52     private final String LONG_UNICODE_16 = SHORT_UNICODE + SHORT_UNICODE +
     53             SHORT_UNICODE + SHORT_UNICODE;
     54     private final String LONG_UNICODE_64 = LONG_UNICODE_16 + LONG_UNICODE_16 +
     55             LONG_UNICODE_16 + LONG_UNICODE_16;
     56 
     57     /** longer plain strings (with fold points) */
     58     private final String LONG_PLAIN_16 = "abcdefgh ijklmno";
     59     private final String LONG_PLAIN_64 =
     60         LONG_PLAIN_16 + LONG_PLAIN_16 + LONG_PLAIN_16 + LONG_PLAIN_16;
     61     private final String LONG_PLAIN_256 =
     62         LONG_PLAIN_64 + LONG_PLAIN_64 + LONG_PLAIN_64 + LONG_PLAIN_64;
     63 
     64     @Override
     65     protected void setUp() throws Exception {
     66         super.setUp();
     67         TempDirectory.setTempDirectory(getContext());
     68     }
     69 
     70     /**
     71      * Confirms that setSentDate() correctly set the "Date" header of a Mime message.
     72      *
     73      * We tries a same test twice using two locales, Locale.US and the other, since
     74      * MimeMessage depends on the date formatter, which may emit wrong date format
     75      * in the locale other than Locale.US.
     76      * @throws MessagingException
     77      * @throws ParseException
     78      */
     79     @MediumTest
     80     public void testSetSentDate() throws MessagingException, ParseException {
     81         Locale savedLocale = Locale.getDefault();
     82         Locale.setDefault(Locale.US);
     83         doTestSetSentDate();
     84         Locale.setDefault(Locale.JAPAN);
     85         doTestSetSentDate();
     86         Locale.setDefault(savedLocale);
     87     }
     88 
     89     private void doTestSetSentDate() throws MessagingException, ParseException {
     90         // "Thu, 01 Jan 2009 09:00:00 +0000" => 1230800400000L
     91         long expectedTime = 1230800400000L;
     92         Date date = new Date(expectedTime);
     93         MimeMessage message = new MimeMessage();
     94         message.setSentDate(date);
     95         String[] headers = message.getHeader("Date");
     96         assertEquals(1, headers.length);
     97         // Explicitly specify the locale so that the object does not depend on the default
     98         // locale.
     99         SimpleDateFormat format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss Z", Locale.US);
    100 
    101         Date result = format.parse(headers[0]);
    102         assertEquals(expectedTime, result.getTime());
    103     }
    104 
    105     /**
    106      * Simple tests of the new "Message-ID" header
    107      */
    108     public void testMessageId() throws MessagingException {
    109 
    110         // Test 1.  Every message gets a default and unique message-id
    111         MimeMessage message1 = new MimeMessage();
    112         MimeMessage message2 = new MimeMessage();
    113         String id1 = message1.getMessageId();
    114         String id2 = message2.getMessageId();
    115         assertNotNull(id1);
    116         assertNotNull(id2);
    117         assertFalse("Message-ID should be unique", id1.equals(id2));
    118 
    119         // Test 2.  Set and get using API
    120         final String testId1 = "test-message-id-one";
    121         message1.setMessageId(testId1);
    122         assertEquals("set and get Message-ID", testId1, message1.getMessageId());
    123 
    124         // Test 3.  Should only be one Message-ID per message
    125         final String testId2 = "test-message-id-two";
    126         message2.setMessageId(testId1);
    127         message2.setMessageId(testId2);
    128         assertEquals("set and get Message-ID", testId2, message2.getMessageId());
    129     }
    130 
    131     /**
    132      * Confirm getContentID() correctly works.
    133      */
    134     public void testGetContentId() throws MessagingException {
    135         MimeMessage message = new MimeMessage();
    136 
    137         // no content-id
    138         assertNull(message.getContentId());
    139 
    140         // normal case
    141         final String cid1 = "cid.1 (at) android.com";
    142         message.setHeader(MimeHeader.HEADER_CONTENT_ID, cid1);
    143         assertEquals(cid1, message.getContentId());
    144 
    145         // surrounded by optional bracket
    146         message.setHeader(MimeHeader.HEADER_CONTENT_ID, "<" + cid1 + ">");
    147         assertEquals(cid1, message.getContentId());
    148     }
    149 
    150     /**
    151      * Confirm that setSubject() works with plain strings
    152      */
    153     public void testSetSubjectPlain() throws MessagingException {
    154         MimeMessage message = new MimeMessage();
    155 
    156         message.setSubject(SHORT_PLAIN);
    157 
    158         // test 1: readback
    159         assertEquals("plain subjects", SHORT_PLAIN, message.getSubject());
    160 
    161         // test 2: raw readback is not escaped
    162         String rawHeader = message.getFirstHeader("Subject");
    163         assertEquals("plain subject not encoded", -1, rawHeader.indexOf("=?"));
    164 
    165         // test 3: long subject (shouldn't fold)
    166         message.setSubject(LONG_PLAIN_64);
    167         rawHeader = message.getFirstHeader("Subject");
    168         String[] split = rawHeader.split("\r\n");
    169         assertEquals("64 shouldn't fold", 1, split.length);
    170 
    171         // test 4: very long subject (should fold)
    172         message.setSubject(LONG_PLAIN_256);
    173         rawHeader = message.getFirstHeader("Subject");
    174         split = rawHeader.split("\r\n");
    175         assertTrue("long subject should fold", split.length > 1);
    176         for (String s : split) {
    177             assertTrue("split lines max length 78", s.length() <= 76);  // 76+\r\n = 78
    178             String trimmed = s.trim();
    179             assertFalse("split lines are not encoded", trimmed.startsWith("=?"));
    180         }
    181     }
    182 
    183     /**
    184      * Confirm that setSubject() works with unicode strings
    185      */
    186     public void testSetSubject() throws MessagingException {
    187         MimeMessage message = new MimeMessage();
    188 
    189         message.setSubject(SHORT_UNICODE);
    190 
    191         // test 1: readback in unicode
    192         assertEquals("unicode readback", SHORT_UNICODE, message.getSubject());
    193 
    194         // test 2: raw readback is escaped
    195         String rawHeader = message.getFirstHeader("Subject");
    196         assertEquals("raw readback", SHORT_UNICODE_ENCODED, rawHeader);
    197     }
    198 
    199     /**
    200      * Confirm folding operations on unicode subjects
    201      */
    202     public void testSetLongSubject() throws MessagingException {
    203         MimeMessage message = new MimeMessage();
    204 
    205         // test 1: long unicode - readback in unicode
    206         message.setSubject(LONG_UNICODE_16);
    207         assertEquals("unicode readback 16", LONG_UNICODE_16, message.getSubject());
    208 
    209         // test 2: longer unicode (will fold)
    210         message.setSubject(LONG_UNICODE_64);
    211         assertEquals("unicode readback 64", LONG_UNICODE_64, message.getSubject());
    212 
    213         // test 3: check folding & encoding
    214         String rawHeader = message.getFirstHeader("Subject");
    215         String[] split = rawHeader.split("\r\n");
    216         assertTrue("long subject should fold", split.length > 1);
    217         for (String s : split) {
    218             assertTrue("split lines max length 78", s.length() <= 76);  // 76+\r\n = 78
    219             String trimmed = s.trim();
    220             assertTrue("split lines are encoded",
    221                     trimmed.startsWith("=?") && trimmed.endsWith("?="));
    222         }
    223     }
    224 
    225     /**
    226      * Test for encoding address field.
    227      */
    228     public void testEncodingAddressField() throws MessagingException {
    229         Address noName1 = new Address("noname1 (at) dom1.com");
    230         Address noName2 = new Address("<noname2 (at) dom2.com>", "");
    231         Address simpleName = new Address("address3 (at) dom3.org", "simple long and long long name");
    232         Address dquoteName = new Address("address4 (at) dom4.org", "name,4,long long name");
    233         Address quotedName = new Address("bigG (at) dom5.net", "big \"G\"");
    234         Address utf16Name = new Address("<address6 (at) co.jp>", "\"\u65E5\u672C\u8A9E\"");
    235         Address utf32Name = new Address("<address8 (at) ne.jp>", "\uD834\uDF01\uD834\uDF46");
    236 
    237         MimeMessage message = new MimeMessage();
    238 
    239         message.setFrom(noName1);
    240         message.setRecipient(RecipientType.TO, noName2);
    241         message.setRecipients(RecipientType.CC, new Address[] { simpleName, dquoteName });
    242         message.setReplyTo(new Address[] { quotedName, utf16Name, utf32Name });
    243 
    244         String[] from = message.getHeader("From");
    245         String[] to = message.getHeader("To");
    246         String[] cc = message.getHeader("Cc");
    247         String[] replyTo = message.getHeader("Reply-to");
    248 
    249         assertEquals("from address count", 1, from.length);
    250         assertEquals("no name 1", "noname1 (at) dom1.com", from[0]);
    251 
    252         assertEquals("to address count", 1, to.length);
    253         assertEquals("no name 2", "noname2 (at) dom2.com", to[0]);
    254 
    255         // folded.
    256         assertEquals("cc address count", 1, cc.length);
    257         assertEquals("simple name & double quoted name",
    258                 "simple long and long long name <address3 (at) dom3.org>, \"name,4,long long\r\n"
    259                 + " name\" <address4 (at) dom4.org>",
    260                 cc[0]);
    261 
    262         // folded and encoded.
    263         assertEquals("reply-to address count", 1, replyTo.length);
    264         assertEquals("quoted name & encoded name",
    265                 "\"big \\\"G\\\"\" <bigG (at) dom5.net>, =?UTF-8?B?5pel5pys6Kqe?=\r\n"
    266                 + " <address6 (at) co.jp>, =?UTF-8?B?8J2MgfCdjYY=?= <address8 (at) ne.jp>",
    267                 replyTo[0]);
    268     }
    269 
    270     /**
    271      * Test for parsing address field.
    272      */
    273     public void testParsingAddressField() throws MessagingException {
    274         MimeMessage message = new MimeMessage();
    275 
    276         message.setHeader("From", "noname1 (at) dom1.com");
    277         message.setHeader("To", "<noname2 (at) dom2.com>");
    278         // folded.
    279         message.setHeader("Cc",
    280                 "simple name <address3 (at) dom3.org>,\r\n"
    281                 + " \"name,4\" <address4 (at) dom4.org>");
    282         // folded and encoded.
    283         message.setHeader("Reply-to",
    284                 "\"big \\\"G\\\"\" <bigG (at) dom5.net>,\r\n"
    285                 + " =?UTF-8?B?5pel5pys6Kqe?=\r\n"
    286                 + " <address6 (at) co.jp>,\n"
    287                 + " \"=?UTF-8?B?8J2MgfCdjYY=?=\" <address8 (at) ne.jp>");
    288 
    289         Address[] from = message.getFrom();
    290         Address[] to = message.getRecipients(RecipientType.TO);
    291         Address[] cc = message.getRecipients(RecipientType.CC);
    292         Address[] replyTo = message.getReplyTo();
    293 
    294         assertEquals("from address count", 1, from.length);
    295         assertEquals("no name 1 address", "noname1 (at) dom1.com", from[0].getAddress());
    296         assertNull("no name 1 name", from[0].getPersonal());
    297 
    298         assertEquals("to address count", 1, to.length);
    299         assertEquals("no name 2 address", "noname2 (at) dom2.com", to[0].getAddress());
    300         assertNull("no name 2 name", to[0].getPersonal());
    301 
    302         assertEquals("cc address count", 2, cc.length);
    303         assertEquals("simple name address", "address3 (at) dom3.org", cc[0].getAddress());
    304         assertEquals("simple name name", "simple name", cc[0].getPersonal());
    305         assertEquals("double quoted name address", "address4 (at) dom4.org", cc[1].getAddress());
    306         assertEquals("double quoted name name", "name,4", cc[1].getPersonal());
    307 
    308         assertEquals("reply-to address count", 3, replyTo.length);
    309         assertEquals("quoted name address", "bigG (at) dom5.net", replyTo[0].getAddress());
    310         assertEquals("quoted name name", "big \"G\"", replyTo[0].getPersonal());
    311         assertEquals("utf-16 name address", "address6 (at) co.jp", replyTo[1].getAddress());
    312         assertEquals("utf-16 name name", "\u65E5\u672C\u8A9E", replyTo[1].getPersonal());
    313         assertEquals("utf-32 name address", "address8 (at) ne.jp", replyTo[2].getAddress());
    314         assertEquals("utf-32 name name", "\uD834\uDF01\uD834\uDF46", replyTo[2].getPersonal());
    315     }
    316 
    317     /*
    318      * Test setting & getting store-specific flags
    319      */
    320     public void testStoreFlags() throws MessagingException {
    321         MimeMessage message = new MimeMessage();
    322 
    323         // Message should create with no flags
    324         Flag[] flags = message.getFlags();
    325         assertEquals(0, flags.length);
    326 
    327         // Set a store flag
    328         message.setFlag(Flag.X_STORE_1, true);
    329         assertTrue(message.isSet(Flag.X_STORE_1));
    330         assertFalse(message.isSet(Flag.X_STORE_2));
    331 
    332         // Set another
    333         message.setFlag(Flag.X_STORE_2, true);
    334         assertTrue(message.isSet(Flag.X_STORE_1));
    335         assertTrue(message.isSet(Flag.X_STORE_2));
    336 
    337         // Set some and clear some
    338         message.setFlag(Flag.X_STORE_1, false);
    339         assertFalse(message.isSet(Flag.X_STORE_1));
    340         assertTrue(message.isSet(Flag.X_STORE_2));
    341 
    342     }
    343 
    344     /*
    345      * Test for setExtendedHeader() and getExtendedHeader()
    346      */
    347     public void testExtendedHeader() throws MessagingException {
    348         MimeMessage message = new MimeMessage();
    349 
    350         assertNull("non existent header", message.getExtendedHeader("X-Non-Existent"));
    351 
    352         message.setExtendedHeader("X-Header1", "value1");
    353         message.setExtendedHeader("X-Header2", "value2\n value3\r\n value4\r\n");
    354         assertEquals("simple value", "value1",
    355                 message.getExtendedHeader("X-Header1"));
    356         assertEquals("multi line value", "value2 value3 value4",
    357                 message.getExtendedHeader("X-Header2"));
    358         assertNull("non existent header 2", message.getExtendedHeader("X-Non-Existent"));
    359 
    360         message.setExtendedHeader("X-Header1", "value4");
    361         assertEquals("over written value", "value4", message.getExtendedHeader("X-Header1"));
    362 
    363         message.setExtendedHeader("X-Header1", null);
    364         assertNull("remove header", message.getExtendedHeader("X-Header1"));
    365     }
    366 
    367     /*
    368      * Test for setExtendedHeaders() and getExtendedheaders()
    369      */
    370     public void testExtendedHeaders() throws MessagingException {
    371         MimeMessage message = new MimeMessage();
    372 
    373         assertNull("new message", message.getExtendedHeaders());
    374         message.setExtendedHeaders(null);
    375         assertNull("null headers", message.getExtendedHeaders());
    376         message.setExtendedHeaders("");
    377         assertNull("empty headers", message.getExtendedHeaders());
    378 
    379         message.setExtendedHeaders("X-Header1: value1\r\n");
    380         assertEquals("header 1 value", "value1", message.getExtendedHeader("X-Header1"));
    381         assertEquals("header 1", "X-Header1: value1\r\n", message.getExtendedHeaders());
    382 
    383         message.setExtendedHeaders(null);
    384         message.setExtendedHeader("X-Header2", "value2");
    385         message.setExtendedHeader("X-Header3",  "value3\n value4\r\n value5\r\n");
    386         assertEquals("headers 2,3",
    387                 "X-Header2: value2\r\n" +
    388                 "X-Header3: value3 value4 value5\r\n",
    389                 message.getExtendedHeaders());
    390 
    391         message.setExtendedHeaders(
    392                 "X-Header3: value3 value4 value5\r\n" +
    393                 "X-Header2: value2\r\n");
    394         assertEquals("header 2", "value2", message.getExtendedHeader("X-Header2"));
    395         assertEquals("header 3", "value3 value4 value5", message.getExtendedHeader("X-Header3"));
    396         assertEquals("headers 3,2",
    397                 "X-Header3: value3 value4 value5\r\n" +
    398                 "X-Header2: value2\r\n",
    399                 message.getExtendedHeaders());
    400     }
    401 
    402     /*
    403      * Test for writeTo(), only for header part.
    404      * NOTE:  This test is fragile because it assumes headers will be written in a specific order
    405      */
    406     public void testWriteToHeader() throws Exception {
    407         MimeMessage message = new MimeMessage();
    408 
    409         message.setHeader("Header1", "value1");
    410         message.setHeader(MimeHeader.HEADER_ANDROID_ATTACHMENT_STORE_DATA, "value2");
    411         message.setExtendedHeader("X-Header3", "value3");
    412         message.setHeader("Header4", "value4");
    413         message.setExtendedHeader("X-Header5", "value5");
    414 
    415         ByteArrayOutputStream out = new ByteArrayOutputStream();
    416         message.writeTo(out);
    417         out.close();
    418         String expectedString =
    419                 "Header1: value1\r\n" +
    420                 "Header4: value4\r\n" +
    421                 "Message-ID: " + message.getMessageId() + "\r\n" +
    422                 "\r\n";
    423         byte[] expected = expectedString.getBytes();
    424         byte[] actual = out.toByteArray();
    425         assertEquals("output length", expected.length, actual.length);
    426         for (int i = 0; i < actual.length; ++i) {
    427             assertEquals("output byte["+i+"]", expected[i], actual[i]);
    428         }
    429     }
    430 
    431     /**
    432      * Test for parsing headers with extra whitespace and commennts.
    433      *
    434      * The lines up to Content-Type were copied directly out of RFC 2822
    435      * "Section A.5. White space, comments, and other oddities"
    436      */
    437     public void testWhiteSpace() throws MessagingException, IOException {
    438         String entireMessage =
    439             "From: Pete(A wonderful \\) chap) <pete(his account)@silly.test(his host)>\r\n"+
    440             "To:A Group(Some people)\r\n"+
    441             "     :Chris Jones <c@(Chris's host.)public.example>,\r\n"+
    442             "         joe (at) example.org,\r\n"+
    443             "  John <jdoe (at) one.test> (my dear friend); (the end of the group)\r\n"+
    444             "Cc:(Empty list)(start)Undisclosed recipients  :(nobody(that I know))  ;\r\n"+
    445             "Date: Thu,\r\n"+
    446             "      13\r\n"+
    447             "        Feb\r\n"+
    448             "          1969\r\n"+
    449             "      23:32\r\n"+
    450             "               -0330 (Newfoundland Time)\r\n"+
    451             "Message-ID:              <testabcd.1234 (at) silly.test>\r\n"+
    452             "Content-Type:                \r\n"+
    453             "          TEXT/hTML \r\n"+
    454             "       ; x-blah=\"y-blah\" ; \r\n"+
    455             "       CHARSET=\"us-ascii\" ; (comment)\r\n"+
    456             "\r\n"+
    457             "<html><body>Testing.</body></html>\r\n";
    458         MimeMessage mm = null;
    459         mm = new MimeMessage(new ByteArrayInputStream(
    460             entireMessage.getBytes("us-ascii")));
    461         assertTrue(mm.getMimeType(), MimeUtility.mimeTypeMatches("text/html",mm.getMimeType()));
    462         assertEquals(new Date(-27723480000L),mm.getSentDate());
    463         assertEquals("<testabcd.1234 (at) silly.test>",mm.getMessageId());
    464         Address[] toAddresses = mm.getRecipients(MimeMessage.RecipientType.TO);
    465         assertEquals("joe (at) example.org", toAddresses[1].getAddress());
    466         assertEquals("jdoe (at) one.test", toAddresses[2].getAddress());
    467 
    468 
    469         // Note: The parentheses in the middle of email addresses are not removed.
    470         //assertEquals("c (at) public.example", toAddresses[0].getAddress());
    471         //assertEquals("pete (at) silly.test",mm.getFrom()[0].getAddress());
    472     }
    473 
    474     /**
    475      * Confirm parser doesn't crash when seeing "Undisclosed recipients:;".
    476      */
    477     public void testUndisclosedRecipients() throws MessagingException, IOException {
    478         String entireMessage =
    479             "To:Undisclosed recipients:;\r\n"+
    480             "Cc:Undisclosed recipients:;\r\n"+
    481             "Bcc:Undisclosed recipients:;\r\n"+
    482             "\r\n";
    483         MimeMessage mm = null;
    484         mm = new MimeMessage(new ByteArrayInputStream(
    485             entireMessage.getBytes("us-ascii")));
    486 
    487         assertEquals(0, mm.getRecipients(MimeMessage.RecipientType.TO).length);
    488         assertEquals(0, mm.getRecipients(MimeMessage.RecipientType.CC).length);
    489         assertEquals(0, mm.getRecipients(MimeMessage.RecipientType.BCC).length);
    490     }
    491 
    492     /**
    493      * Confirm parser doesn't crash when seeing invalid headers/addresses.
    494      */
    495     public void testInvalidHeaders() throws MessagingException, IOException {
    496         String entireMessage =
    497             "To:\r\n"+
    498             "Cc:!invalid!address!, a (at) b.com\r\n"+
    499             "Bcc:Undisclosed recipients;\r\n"+ // no colon at the end
    500             "invalid header\r\n"+
    501             "Message-ID:<testabcd.1234 (at) silly.test>\r\n"+
    502             "\r\n"+
    503             "Testing\r\n";
    504         MimeMessage mm = null;
    505         mm = new MimeMessage(new ByteArrayInputStream(
    506             entireMessage.getBytes("us-ascii")));
    507 
    508         assertEquals(0, mm.getRecipients(MimeMessage.RecipientType.TO).length);
    509         assertEquals(1, mm.getRecipients(MimeMessage.RecipientType.CC).length);
    510         assertEquals("a (at) b.com", mm.getRecipients(MimeMessage.RecipientType.CC)[0].getAddress());
    511         assertEquals(0, mm.getRecipients(MimeMessage.RecipientType.BCC).length);
    512         assertEquals("<testabcd.1234 (at) silly.test>", mm.getMessageId());
    513     }
    514 
    515     /**
    516      * Confirm parser w/o a message-id inhibits a local message-id from being generated
    517      */
    518     public void testParseNoMessageId() throws MessagingException, IOException {
    519         String entireMessage =
    520             "To: user (at) domain.com\r\n" +
    521             "\r\n" +
    522             "Testing\r\n";
    523         MimeMessage mm = null;
    524         mm = new MimeMessage(new ByteArrayInputStream(entireMessage.getBytes("us-ascii")));
    525 
    526         assertNull(mm.getMessageId());
    527     }
    528 
    529     /**
    530      * Make sure the parser accepts the "eBay style" date format.
    531      *
    532      * Messages from ebay have been seen that they use the wrong date format.
    533      * @see com.android.emailcommon.utility.Utility#cleanUpMimeDate
    534      */
    535     public void testEbayDate() throws MessagingException, IOException {
    536         String entireMessage =
    537             "To:a (at) b.com\r\n" +
    538             "Date:Thu, 10 Dec 09 15:08:08 GMT-0700" +
    539             "\r\n" +
    540             "\r\n";
    541         MimeMessage mm = null;
    542         mm = new MimeMessage(new ByteArrayInputStream(entireMessage.getBytes("us-ascii")));
    543         Date actual = mm.getSentDate();
    544         Date expected = new Date(Date.UTC(109, 11, 10, 15, 8, 8) + 7 * 60 * 60 * 1000);
    545         assertEquals(expected, actual);
    546     }
    547 
    548     // TODO more test for writeTo()
    549 }
    550