1f2dded3a2fba83dd3f0d14cce6abe467a4ab66ebMarc Blank/*
2f2dded3a2fba83dd3f0d14cce6abe467a4ab66ebMarc Blank * Copyright (C) 2009 The Android Open Source Project
3f2dded3a2fba83dd3f0d14cce6abe467a4ab66ebMarc Blank *
4f2dded3a2fba83dd3f0d14cce6abe467a4ab66ebMarc Blank * Licensed under the Apache License, Version 2.0 (the "License");
5f2dded3a2fba83dd3f0d14cce6abe467a4ab66ebMarc Blank * you may not use this file except in compliance with the License.
6f2dded3a2fba83dd3f0d14cce6abe467a4ab66ebMarc Blank * You may obtain a copy of the License at
7f2dded3a2fba83dd3f0d14cce6abe467a4ab66ebMarc Blank *
8f2dded3a2fba83dd3f0d14cce6abe467a4ab66ebMarc Blank *      http://www.apache.org/licenses/LICENSE-2.0
9f2dded3a2fba83dd3f0d14cce6abe467a4ab66ebMarc Blank *
10f2dded3a2fba83dd3f0d14cce6abe467a4ab66ebMarc Blank * Unless required by applicable law or agreed to in writing, software
11f2dded3a2fba83dd3f0d14cce6abe467a4ab66ebMarc Blank * distributed under the License is distributed on an "AS IS" BASIS,
12f2dded3a2fba83dd3f0d14cce6abe467a4ab66ebMarc Blank * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f2dded3a2fba83dd3f0d14cce6abe467a4ab66ebMarc Blank * See the License for the specific language governing permissions and
14f2dded3a2fba83dd3f0d14cce6abe467a4ab66ebMarc Blank * limitations under the License.
15f2dded3a2fba83dd3f0d14cce6abe467a4ab66ebMarc Blank */
16f2dded3a2fba83dd3f0d14cce6abe467a4ab66ebMarc Blank
1731d9acbf0623872f9d4a2b3210b5970854b654c7Marc Blankpackage com.android.emailcommon.internet;
18f2dded3a2fba83dd3f0d14cce6abe467a4ab66ebMarc Blank
197037a0bd3d8e925a9115f475f5c0d05ddae2eeeeJerry Xieimport android.content.Context;
207037a0bd3d8e925a9115f475f5c0d05ddae2eeeeJerry Xieimport android.test.ProviderTestCase2;
217037a0bd3d8e925a9115f475f5c0d05ddae2eeeeJerry Xieimport android.test.suitebuilder.annotation.Suppress;
227037a0bd3d8e925a9115f475f5c0d05ddae2eeeeJerry Xie
2380ee607a7cc784993a48741d0dfbd132cd546985Marc Blankimport com.android.email.R;
240ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blankimport com.android.email.provider.EmailProvider;
252193962ca2b3157e79f731736afa2a0c972e778aMarc Blankimport com.android.emailcommon.mail.MessagingException;
2631d9acbf0623872f9d4a2b3210b5970854b654c7Marc Blankimport com.android.emailcommon.provider.EmailContent;
27a7bc0319a75184ad706bb35c049af107ac3688e6Marc Blankimport com.android.emailcommon.provider.EmailContent.Attachment;
289cc51b72c6902b95f65857af64eb38063aa4a42bTodd Kennedyimport com.android.emailcommon.provider.EmailContent.Body;
29a7bc0319a75184ad706bb35c049af107ac3688e6Marc Blankimport com.android.emailcommon.provider.EmailContent.Message;
30f2dded3a2fba83dd3f0d14cce6abe467a4ab66ebMarc Blank
310ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blankimport org.apache.james.mime4j.field.Field;
328546e21e1e127845071c595beda16fc23eb0f58eTodd Kennedyimport org.apache.james.mime4j.message.BodyPart;
330ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blankimport org.apache.james.mime4j.message.Entity;
340ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blankimport org.apache.james.mime4j.message.Header;
350ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blankimport org.apache.james.mime4j.message.Multipart;
360ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank
370ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blankimport java.io.ByteArrayInputStream;
380ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blankimport java.io.ByteArrayOutputStream;
390ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blankimport java.io.IOException;
400ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blankimport java.util.ArrayList;
410ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blankimport java.util.List;
420ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank
43f2dded3a2fba83dd3f0d14cce6abe467a4ab66ebMarc Blank
44f2dded3a2fba83dd3f0d14cce6abe467a4ab66ebMarc Blank/**
45f2dded3a2fba83dd3f0d14cce6abe467a4ab66ebMarc Blank * Tests of the Rfc822Output (used for sending mail)
46f2dded3a2fba83dd3f0d14cce6abe467a4ab66ebMarc Blank *
47f2dded3a2fba83dd3f0d14cce6abe467a4ab66ebMarc Blank * You can run this entire test case with:
48f2dded3a2fba83dd3f0d14cce6abe467a4ab66ebMarc Blank *   runtest -c com.android.email.mail.transport.Rfc822OutputTests email
49f2dded3a2fba83dd3f0d14cce6abe467a4ab66ebMarc Blank */
507037a0bd3d8e925a9115f475f5c0d05ddae2eeeeJerry Xie@Suppress
510ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blankpublic class Rfc822OutputTests extends ProviderTestCase2<EmailProvider> {
52f2dded3a2fba83dd3f0d14cce6abe467a4ab66ebMarc Blank    private static final String SENDER = "sender@android.com";
53f2dded3a2fba83dd3f0d14cce6abe467a4ab66ebMarc Blank    private static final String RECIPIENT_TO = "recipient-to@android.com";
54f2dded3a2fba83dd3f0d14cce6abe467a4ab66ebMarc Blank    private static final String RECIPIENT_CC = "recipient-cc@android.com";
55f2dded3a2fba83dd3f0d14cce6abe467a4ab66ebMarc Blank    private static final String SUBJECT = "This is the subject";
569cc51b72c6902b95f65857af64eb38063aa4a42bTodd Kennedy    private static final String REPLY_TEXT_BODY = "This is the body.  This is also the body.";
571d98989222f2d023ddb08a70d5abb850029f95dcMarc Blank    private static final String TEXT = "Here is some new text.";
58f2dded3a2fba83dd3f0d14cce6abe467a4ab66ebMarc Blank
599cc51b72c6902b95f65857af64eb38063aa4a42bTodd Kennedy    // Full HTML document
603c73a04bec2a1d06ce0a3c861a3d88862b80c163Tony Mantler    private static final String HTML_FULL_BODY = "<html><head><title>MyTitle</title></head>"
619cc51b72c6902b95f65857af64eb38063aa4a42bTodd Kennedy            + "<body bgcolor=\"#ffffff\" text=\"#000000\">"
629cc51b72c6902b95f65857af64eb38063aa4a42bTodd Kennedy            + "<a href=\"google.com\">test1</a></body></html>";
633c73a04bec2a1d06ce0a3c861a3d88862b80c163Tony Mantler    private static final String HTML_FULL_RESULT = "<a href=\"google.com\">test1</a>";
649cc51b72c6902b95f65857af64eb38063aa4a42bTodd Kennedy    // <body/> element w/ content
653c73a04bec2a1d06ce0a3c861a3d88862b80c163Tony Mantler    private static final String HTML_BODY_BODY =
669cc51b72c6902b95f65857af64eb38063aa4a42bTodd Kennedy            "<body bgcolor=\"#ffffff\" text=\"#000000\"><a href=\"google.com\">test2</a></body>";
673c73a04bec2a1d06ce0a3c861a3d88862b80c163Tony Mantler    private static final String HTML_BODY_RESULT = "<a href=\"google.com\">test2</a>";
689cc51b72c6902b95f65857af64eb38063aa4a42bTodd Kennedy    // No <body/> tag; just content
693c73a04bec2a1d06ce0a3c861a3d88862b80c163Tony Mantler    private static final String HTML_NO_BODY_BODY =
709cc51b72c6902b95f65857af64eb38063aa4a42bTodd Kennedy            "<a href=\"google.com\">test3</a>";
713c73a04bec2a1d06ce0a3c861a3d88862b80c163Tony Mantler    private static final String HTML_NO_BODY_RESULT = "<a href=\"google.com\">test3</a>";
729cc51b72c6902b95f65857af64eb38063aa4a42bTodd Kennedy
730ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank    private Context mMockContext;
7480ee607a7cc784993a48741d0dfbd132cd546985Marc Blank    private String mForwardIntro;
750ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank
760ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank    public Rfc822OutputTests () {
7731d9acbf0623872f9d4a2b3210b5970854b654c7Marc Blank        super(EmailProvider.class, EmailContent.AUTHORITY);
780ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank    }
790ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank
800ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank    @Override
810ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank    public void setUp() throws Exception {
820ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        super.setUp();
830ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        mMockContext = getMockContext();
8480ee607a7cc784993a48741d0dfbd132cd546985Marc Blank        mForwardIntro = mMockContext.getString(R.string.message_compose_fwd_header_fmt, SUBJECT,
8580ee607a7cc784993a48741d0dfbd132cd546985Marc Blank                SENDER, RECIPIENT_TO, RECIPIENT_CC);
860ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank    }
870ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank
88f2dded3a2fba83dd3f0d14cce6abe467a4ab66ebMarc Blank    // TODO Create more tests here.  Specifically, we should test to make sure that forward works
89f2dded3a2fba83dd3f0d14cce6abe467a4ab66ebMarc Blank    // properly instead of just reply
90f2dded3a2fba83dd3f0d14cce6abe467a4ab66ebMarc Blank
912d5691cac1874eb3491353ab608a84c2a75e2b62Marc Blank    // TODO Write test that ensures that bcc is handled properly (i.e. sent/not send depending
922d5691cac1874eb3491353ab608a84c2a75e2b62Marc Blank    // on the flag passed to writeTo
932d5691cac1874eb3491353ab608a84c2a75e2b62Marc Blank
949cc51b72c6902b95f65857af64eb38063aa4a42bTodd Kennedy    private Body createTestBody(Message message) {
953c73a04bec2a1d06ce0a3c861a3d88862b80c163Tony Mantler        return Body.restoreBodyWithMessageId(mMockContext, message.mId);
9680ee607a7cc784993a48741d0dfbd132cd546985Marc Blank    }
9780ee607a7cc784993a48741d0dfbd132cd546985Marc Blank
9880ee607a7cc784993a48741d0dfbd132cd546985Marc Blank    /**
9980ee607a7cc784993a48741d0dfbd132cd546985Marc Blank     * Test for buildBodyText().
10080ee607a7cc784993a48741d0dfbd132cd546985Marc Blank     * Compare with expected values.
10180ee607a7cc784993a48741d0dfbd132cd546985Marc Blank     */
10280ee607a7cc784993a48741d0dfbd132cd546985Marc Blank    public void testBuildBodyTextWithForward() {
10380ee607a7cc784993a48741d0dfbd132cd546985Marc Blank        Message msg = new Message();
10480ee607a7cc784993a48741d0dfbd132cd546985Marc Blank        msg.mText = TEXT;
10580ee607a7cc784993a48741d0dfbd132cd546985Marc Blank        msg.mFrom = SENDER;
10680ee607a7cc784993a48741d0dfbd132cd546985Marc Blank        msg.mTo = RECIPIENT_TO;
10780ee607a7cc784993a48741d0dfbd132cd546985Marc Blank        msg.mCc = RECIPIENT_CC;
10880ee607a7cc784993a48741d0dfbd132cd546985Marc Blank        msg.mSubject = SUBJECT;
10980ee607a7cc784993a48741d0dfbd132cd546985Marc Blank        msg.mFlags = Message.FLAG_TYPE_FORWARD;
11080ee607a7cc784993a48741d0dfbd132cd546985Marc Blank        msg.save(mMockContext);
1119cc51b72c6902b95f65857af64eb38063aa4a42bTodd Kennedy        Body body = createTestBody(msg);
11217d3a29c9d8f7a27c463239f190bdcc4e0804527Jerry Xie        String[] bodyParts = Rfc822Output.buildBodyText(body, false);
1139cc51b72c6902b95f65857af64eb38063aa4a42bTodd Kennedy        assertEquals(TEXT + mForwardIntro + REPLY_TEXT_BODY, bodyParts[0]);
1141d98989222f2d023ddb08a70d5abb850029f95dcMarc Blank    }
1150ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank
1160ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank    public void testWriteToText() throws IOException, MessagingException {
1170ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        // Create a simple text message
1180ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        Message msg = new Message();
1190ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        msg.mText = TEXT;
1200ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        msg.mFrom = SENDER;
1210ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        // Save this away
1220ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        msg.save(mMockContext);
1230ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank
1240ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        // Write out an Rfc822 message
1250ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
12617d3a29c9d8f7a27c463239f190bdcc4e0804527Jerry Xie        Rfc822Output.writeTo(mMockContext, msg, byteStream, true, false, null);
1270ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank
1280ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        // Get the message and create a mime4j message from it
1290ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        // We'll take advantage of its parsing capabilities
1300ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        ByteArrayInputStream messageInputStream =
1310ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank            new ByteArrayInputStream(byteStream.toByteArray());
1320ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        org.apache.james.mime4j.message.Message mimeMessage =
1330ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank            new org.apache.james.mime4j.message.Message(messageInputStream);
1340ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank
1350ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        // Make sure its structure is correct
1366bcccf628413d40696980d0d86c7ab2b4f831952Andrew Stadler        checkMimeVersion(mimeMessage);
1370ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        assertFalse(mimeMessage.isMultipart());
1380ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        assertEquals("text/plain", mimeMessage.getMimeType());
1390ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank    }
1400ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank
1410ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank    @SuppressWarnings("unchecked")
1420ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank    public void testWriteToAlternativePart() throws IOException, MessagingException {
1430ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        // Create a message with alternative part
1440ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        Message msg = new Message();
1450ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        msg.mText = TEXT;
1460ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        msg.mFrom = SENDER;
1470ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        msg.mAttachments = new ArrayList<Attachment>();
1480ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        // Attach a meeting invitation, which needs to be sent as multipart/alternative
1490ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        Attachment att = new Attachment();
1500ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        att.mContentBytes = "__CONTENT__".getBytes("UTF-8");
1510ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        att.mFlags = Attachment.FLAG_ICS_ALTERNATIVE_PART;
1520ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        att.mMimeType = "text/calendar";
1530ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        att.mFileName = "invite.ics";
1540ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        msg.mAttachments.add(att);
1550ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        // Save this away
1560ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        msg.save(mMockContext);
1570ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank
1580ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        // Write out an Rfc822 message
1590ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
16017d3a29c9d8f7a27c463239f190bdcc4e0804527Jerry Xie        Rfc822Output.writeTo(mMockContext, msg, byteStream, true, false, null);
1610ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank
1620ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        // Get the message and create a mime4j message from it
1630ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        // We'll take advantage of its parsing capabilities
1640ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        ByteArrayInputStream messageInputStream =
1650ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank            new ByteArrayInputStream(byteStream.toByteArray());
1660ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        org.apache.james.mime4j.message.Message mimeMessage =
1670ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank            new org.apache.james.mime4j.message.Message(messageInputStream);
1680ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank
1690ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        // Make sure its structure is correct
1706bcccf628413d40696980d0d86c7ab2b4f831952Andrew Stadler        checkMimeVersion(mimeMessage);
1710ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        assertTrue(mimeMessage.isMultipart());
1720ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        Header header = mimeMessage.getHeader();
1730ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        Field contentType = header.getField("content-type");
1740ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        assertTrue(contentType.getBody().contains("multipart/alternative"));
1750ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        Multipart multipart = (Multipart)mimeMessage.getBody();
1768546e21e1e127845071c595beda16fc23eb0f58eTodd Kennedy        List<BodyPart> partList = multipart.getBodyParts();
1770ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        assertEquals(2, partList.size());
1788546e21e1e127845071c595beda16fc23eb0f58eTodd Kennedy        Entity part = partList.get(0);
1790ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        assertEquals("text/plain", part.getMimeType());
1808546e21e1e127845071c595beda16fc23eb0f58eTodd Kennedy        part = partList.get(1);
1810ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        assertEquals("text/calendar", part.getMimeType());
1820ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        header = part.getHeader();
1830ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        assertNull(header.getField("content-disposition"));
1840ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank    }
1850ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank
18680ee607a7cc784993a48741d0dfbd132cd546985Marc Blank    @SuppressWarnings("unchecked")
1870ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank    public void testWriteToMixedPart() throws IOException, MessagingException {
1880ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        // Create a message with a mixed part
1890ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        Message msg = new Message();
1900ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        msg.mText = TEXT;
1910ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        msg.mFrom = SENDER;
1920ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        msg.mAttachments = new ArrayList<Attachment>();
1930ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        // Attach a simple html "file"
1940ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        Attachment att = new Attachment();
1950ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        att.mContentBytes = "<html>Hi</html>".getBytes("UTF-8");
1960ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        att.mMimeType = "text/html";
1970ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        att.mFileName = "test.html";
1980ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        msg.mAttachments.add(att);
1990ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        // Save this away
2000ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        msg.save(mMockContext);
2010ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank
2020ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        // Write out an Rfc822 message
2030ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
20417d3a29c9d8f7a27c463239f190bdcc4e0804527Jerry Xie        Rfc822Output.writeTo(mMockContext, msg, byteStream, true, false, null);
2050ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank
2060ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        // Get the message and create a mime4j message from it
2070ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        // We'll take advantage of its parsing capabilities
2080ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        ByteArrayInputStream messageInputStream =
2090ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank            new ByteArrayInputStream(byteStream.toByteArray());
2100ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        org.apache.james.mime4j.message.Message mimeMessage =
2110ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank            new org.apache.james.mime4j.message.Message(messageInputStream);
2120ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank
2130ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        // Make sure its structure is correct
2146bcccf628413d40696980d0d86c7ab2b4f831952Andrew Stadler        checkMimeVersion(mimeMessage);
2150ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        assertTrue(mimeMessage.isMultipart());
2160ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        Header header = mimeMessage.getHeader();
2170ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        Field contentType = header.getField("content-type");
2180ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        assertTrue(contentType.getBody().contains("multipart/mixed"));
2190ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        Multipart multipart = (Multipart)mimeMessage.getBody();
2208546e21e1e127845071c595beda16fc23eb0f58eTodd Kennedy        List<BodyPart> partList = multipart.getBodyParts();
2210ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        assertEquals(2, partList.size());
2228546e21e1e127845071c595beda16fc23eb0f58eTodd Kennedy        Entity part = partList.get(0);
2230ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        assertEquals("text/plain", part.getMimeType());
2248546e21e1e127845071c595beda16fc23eb0f58eTodd Kennedy        part = partList.get(1);
2250ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        assertEquals("text/html", part.getMimeType());
2260ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        header = part.getHeader();
2270ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank        assertNotNull(header.getField("content-disposition"));
2280ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank    }
2296bcccf628413d40696980d0d86c7ab2b4f831952Andrew Stadler
2306bcccf628413d40696980d0d86c7ab2b4f831952Andrew Stadler    /**
2319cc51b72c6902b95f65857af64eb38063aa4a42bTodd Kennedy     * Tests various types of HTML reply text -- with full <html/> tags,
2329cc51b72c6902b95f65857af64eb38063aa4a42bTodd Kennedy     * with just the <body/> tags and without any surrounding tags.
2339cc51b72c6902b95f65857af64eb38063aa4a42bTodd Kennedy     */
2349cc51b72c6902b95f65857af64eb38063aa4a42bTodd Kennedy    public void testGetHtmlBody() {
2359cc51b72c6902b95f65857af64eb38063aa4a42bTodd Kennedy        String actual;
2369cc51b72c6902b95f65857af64eb38063aa4a42bTodd Kennedy        actual = Rfc822Output.getHtmlBody(HTML_FULL_BODY);
2379cc51b72c6902b95f65857af64eb38063aa4a42bTodd Kennedy        assertEquals(HTML_FULL_RESULT, actual);
2389cc51b72c6902b95f65857af64eb38063aa4a42bTodd Kennedy        actual = Rfc822Output.getHtmlBody(HTML_BODY_BODY);
2399cc51b72c6902b95f65857af64eb38063aa4a42bTodd Kennedy        assertEquals(HTML_BODY_RESULT, actual);
2409cc51b72c6902b95f65857af64eb38063aa4a42bTodd Kennedy        actual = Rfc822Output.getHtmlBody(HTML_NO_BODY_BODY);
2419cc51b72c6902b95f65857af64eb38063aa4a42bTodd Kennedy        assertEquals(HTML_NO_BODY_RESULT, actual);
2429cc51b72c6902b95f65857af64eb38063aa4a42bTodd Kennedy    }
2439cc51b72c6902b95f65857af64eb38063aa4a42bTodd Kennedy
2449cc51b72c6902b95f65857af64eb38063aa4a42bTodd Kennedy    /**
2459cc51b72c6902b95f65857af64eb38063aa4a42bTodd Kennedy     * Test the boundary digit. We modify it indirectly.
2469cc51b72c6902b95f65857af64eb38063aa4a42bTodd Kennedy     */
2479cc51b72c6902b95f65857af64eb38063aa4a42bTodd Kennedy    public void testBoundaryDigit() {
2489cc51b72c6902b95f65857af64eb38063aa4a42bTodd Kennedy        // Use getBoundary() to update the boundary digit
2499cc51b72c6902b95f65857af64eb38063aa4a42bTodd Kennedy        Rfc822Output.sBoundaryDigit = 0; // ensure it starts at a known value
2509cc51b72c6902b95f65857af64eb38063aa4a42bTodd Kennedy
2519cc51b72c6902b95f65857af64eb38063aa4a42bTodd Kennedy        Rfc822Output.getNextBoundary();
2529cc51b72c6902b95f65857af64eb38063aa4a42bTodd Kennedy        assertEquals(1, Rfc822Output.sBoundaryDigit);
2539cc51b72c6902b95f65857af64eb38063aa4a42bTodd Kennedy        Rfc822Output.getNextBoundary();
2549cc51b72c6902b95f65857af64eb38063aa4a42bTodd Kennedy        assertEquals(2, Rfc822Output.sBoundaryDigit);
2559cc51b72c6902b95f65857af64eb38063aa4a42bTodd Kennedy        Rfc822Output.getNextBoundary();
2569cc51b72c6902b95f65857af64eb38063aa4a42bTodd Kennedy        assertEquals(3, Rfc822Output.sBoundaryDigit);
2579cc51b72c6902b95f65857af64eb38063aa4a42bTodd Kennedy        Rfc822Output.getNextBoundary();
2589cc51b72c6902b95f65857af64eb38063aa4a42bTodd Kennedy        assertEquals(4, Rfc822Output.sBoundaryDigit);
2599cc51b72c6902b95f65857af64eb38063aa4a42bTodd Kennedy        Rfc822Output.getNextBoundary();
2609cc51b72c6902b95f65857af64eb38063aa4a42bTodd Kennedy        assertEquals(5, Rfc822Output.sBoundaryDigit);
2619cc51b72c6902b95f65857af64eb38063aa4a42bTodd Kennedy        Rfc822Output.getNextBoundary();
2629cc51b72c6902b95f65857af64eb38063aa4a42bTodd Kennedy        assertEquals(6, Rfc822Output.sBoundaryDigit);
2639cc51b72c6902b95f65857af64eb38063aa4a42bTodd Kennedy        Rfc822Output.getNextBoundary();
2649cc51b72c6902b95f65857af64eb38063aa4a42bTodd Kennedy        assertEquals(7, Rfc822Output.sBoundaryDigit);
2659cc51b72c6902b95f65857af64eb38063aa4a42bTodd Kennedy        Rfc822Output.getNextBoundary();
2669cc51b72c6902b95f65857af64eb38063aa4a42bTodd Kennedy        assertEquals(8, Rfc822Output.sBoundaryDigit);
2679cc51b72c6902b95f65857af64eb38063aa4a42bTodd Kennedy        Rfc822Output.getNextBoundary();
2689cc51b72c6902b95f65857af64eb38063aa4a42bTodd Kennedy        assertEquals(9, Rfc822Output.sBoundaryDigit);
2699cc51b72c6902b95f65857af64eb38063aa4a42bTodd Kennedy        Rfc822Output.getNextBoundary(); // roll over
2709cc51b72c6902b95f65857af64eb38063aa4a42bTodd Kennedy        assertEquals(0, Rfc822Output.sBoundaryDigit);
2719cc51b72c6902b95f65857af64eb38063aa4a42bTodd Kennedy    }
2729cc51b72c6902b95f65857af64eb38063aa4a42bTodd Kennedy
2733c73a04bec2a1d06ce0a3c861a3d88862b80c163Tony Mantler    private static final int BOUNDARY_COUNT = 12;
2749cc51b72c6902b95f65857af64eb38063aa4a42bTodd Kennedy    public void testGetNextBoundary() {
2759cc51b72c6902b95f65857af64eb38063aa4a42bTodd Kennedy        String[] resultArray = new String[BOUNDARY_COUNT];
2769cc51b72c6902b95f65857af64eb38063aa4a42bTodd Kennedy        for (int i = 0; i < BOUNDARY_COUNT; i++) {
2779cc51b72c6902b95f65857af64eb38063aa4a42bTodd Kennedy            resultArray[i] = Rfc822Output.getNextBoundary();
2789cc51b72c6902b95f65857af64eb38063aa4a42bTodd Kennedy        }
2799cc51b72c6902b95f65857af64eb38063aa4a42bTodd Kennedy        for (int i = 0; i < BOUNDARY_COUNT; i++) {
2809cc51b72c6902b95f65857af64eb38063aa4a42bTodd Kennedy            final String result1 = resultArray[i];
2819cc51b72c6902b95f65857af64eb38063aa4a42bTodd Kennedy            for (int j = 0; j < BOUNDARY_COUNT; j++) {
2829cc51b72c6902b95f65857af64eb38063aa4a42bTodd Kennedy                if (i == j) {
2839cc51b72c6902b95f65857af64eb38063aa4a42bTodd Kennedy                    continue; // Don't verify the same result
2849cc51b72c6902b95f65857af64eb38063aa4a42bTodd Kennedy                }
2859cc51b72c6902b95f65857af64eb38063aa4a42bTodd Kennedy                final String result2 = resultArray[j];
2869cc51b72c6902b95f65857af64eb38063aa4a42bTodd Kennedy                assertFalse(result1.equals(result2));
2879cc51b72c6902b95f65857af64eb38063aa4a42bTodd Kennedy            }
2889cc51b72c6902b95f65857af64eb38063aa4a42bTodd Kennedy        }
2899cc51b72c6902b95f65857af64eb38063aa4a42bTodd Kennedy    }
2909cc51b72c6902b95f65857af64eb38063aa4a42bTodd Kennedy
2919cc51b72c6902b95f65857af64eb38063aa4a42bTodd Kennedy    /**
2926bcccf628413d40696980d0d86c7ab2b4f831952Andrew Stadler     * Confirm that the constructed message includes "MIME-VERSION: 1.0"
2936bcccf628413d40696980d0d86c7ab2b4f831952Andrew Stadler     */
2946bcccf628413d40696980d0d86c7ab2b4f831952Andrew Stadler    private void checkMimeVersion(org.apache.james.mime4j.message.Message mimeMessage) {
2956bcccf628413d40696980d0d86c7ab2b4f831952Andrew Stadler        Header header = mimeMessage.getHeader();
2966bcccf628413d40696980d0d86c7ab2b4f831952Andrew Stadler        Field contentType = header.getField("MIME-VERSION");
2976bcccf628413d40696980d0d86c7ab2b4f831952Andrew Stadler        assertTrue(contentType.getBody().equals("1.0"));
2986bcccf628413d40696980d0d86c7ab2b4f831952Andrew Stadler    }
2990ed690bfb4fdfa86cb6f75c19e24b8ff39a1756cMarc Blank}
300