13f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler/*
23f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler * Copyright (C) 2009 The Android Open Source Project
33f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler *
43f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler * Licensed under the Apache License, Version 2.0 (the "License");
53f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler * you may not use this file except in compliance with the License.
63f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler * You may obtain a copy of the License at
73f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler *
83f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler *      http://www.apache.org/licenses/LICENSE-2.0
93f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler *
103f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler * Unless required by applicable law or agreed to in writing, software
113f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler * distributed under the License is distributed on an "AS IS" BASIS,
123f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler * See the License for the specific language governing permissions and
143f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler * limitations under the License.
153f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler */
163f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler
173f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadlerpackage com.android.email;
183f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler
19515d830e8755d3674e04bcc60d7f85b4fa7fb202Jerry Xieimport android.content.ContentUris;
20515d830e8755d3674e04bcc60d7f85b4fa7fb202Jerry Xieimport android.content.Context;
21515d830e8755d3674e04bcc60d7f85b4fa7fb202Jerry Xieimport android.database.Cursor;
22515d830e8755d3674e04bcc60d7f85b4fa7fb202Jerry Xieimport android.net.Uri;
23515d830e8755d3674e04bcc60d7f85b4fa7fb202Jerry Xieimport android.test.ProviderTestCase2;
2489b8fdca1841efd832e05cee877ab3eaf3780aaeJerry Xieimport android.test.suitebuilder.annotation.Suppress;
25515d830e8755d3674e04bcc60d7f85b4fa7fb202Jerry Xie
2675a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blankimport com.android.email.provider.EmailProvider;
2775a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blankimport com.android.email.provider.ProviderTestUtils;
282193962ca2b3157e79f731736afa2a0c972e778aMarc Blankimport com.android.emailcommon.internet.MimeBodyPart;
292193962ca2b3157e79f731736afa2a0c972e778aMarc Blankimport com.android.emailcommon.internet.MimeHeader;
302193962ca2b3157e79f731736afa2a0c972e778aMarc Blankimport com.android.emailcommon.internet.MimeMessage;
312193962ca2b3157e79f731736afa2a0c972e778aMarc Blankimport com.android.emailcommon.internet.MimeUtility;
322193962ca2b3157e79f731736afa2a0c972e778aMarc Blankimport com.android.emailcommon.internet.TextBody;
332193962ca2b3157e79f731736afa2a0c972e778aMarc Blankimport com.android.emailcommon.mail.Address;
342193962ca2b3157e79f731736afa2a0c972e778aMarc Blankimport com.android.emailcommon.mail.BodyPart;
352193962ca2b3157e79f731736afa2a0c972e778aMarc Blankimport com.android.emailcommon.mail.Flag;
362193962ca2b3157e79f731736afa2a0c972e778aMarc Blankimport com.android.emailcommon.mail.Message;
372193962ca2b3157e79f731736afa2a0c972e778aMarc Blankimport com.android.emailcommon.mail.Message.RecipientType;
3831d9acbf0623872f9d4a2b3210b5970854b654c7Marc Blankimport com.android.emailcommon.mail.MessageTestUtils;
392193962ca2b3157e79f731736afa2a0c972e778aMarc Blankimport com.android.emailcommon.mail.MessageTestUtils.MessageBuilder;
402193962ca2b3157e79f731736afa2a0c972e778aMarc Blankimport com.android.emailcommon.mail.MessageTestUtils.MultipartBuilder;
4131d9acbf0623872f9d4a2b3210b5970854b654c7Marc Blankimport com.android.emailcommon.mail.MessagingException;
4231d9acbf0623872f9d4a2b3210b5970854b654c7Marc Blankimport com.android.emailcommon.mail.Part;
43a7bc0319a75184ad706bb35c049af107ac3688e6Marc Blankimport com.android.emailcommon.provider.EmailContent;
44a7bc0319a75184ad706bb35c049af107ac3688e6Marc Blankimport com.android.emailcommon.provider.EmailContent.Attachment;
458a574694606f0e5d781334d0d426fc379c51f3edMarc Blankimport com.android.emailcommon.utility.ConversionUtilities;
46515d830e8755d3674e04bcc60d7f85b4fa7fb202Jerry Xieimport com.android.emailcommon.utility.ConversionUtilities.BodyFieldData;
473f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler
483f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadlerimport java.io.IOException;
493f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadlerimport java.util.ArrayList;
50eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadlerimport java.util.Date;
513f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler
523f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler/**
533f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler * Tests of the Legacy Conversions code (used by MessagingController).
540993190cafebc107bd27a26996b5d63d4a4ede10Marc Blank *
553f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler * NOTE:  It would probably make sense to rewrite this using a MockProvider, instead of the
563f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler * ProviderTestCase (which is a real provider running on a temp database).  This would be more of
573f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler * a true "unit test".
580993190cafebc107bd27a26996b5d63d4a4ede10Marc Blank *
593f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler * You can run this entire test case with:
603f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler *   runtest -c com.android.email.LegacyConversionsTests email
613f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler */
6289b8fdca1841efd832e05cee877ab3eaf3780aaeJerry Xie@Suppress
633f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadlerpublic class LegacyConversionsTests extends ProviderTestCase2<EmailProvider> {
643f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler
65eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler    private static final String UID = "UID.12345678";
66eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler    private static final String SENDER = "sender@android.com";
67eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler    private static final String RECIPIENT_TO = "recipient-to@android.com";
68eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler    private static final String RECIPIENT_CC = "recipient-cc@android.com";
69eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler    private static final String RECIPIENT_BCC = "recipient-bcc@android.com";
70eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler    private static final String REPLY_TO = "reply-to@android.com";
71eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler    private static final String SUBJECT = "This is the subject";
72eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler    private static final String MESSAGE_ID = "Test-Message-ID";
73eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler    private static final String MESSAGE_ID_2 = "Test-Message-ID-Second";
74eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler
753f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler    EmailProvider mProvider;
763f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler    Context mProviderContext;
773f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler    Context mContext;
785e91cccd4b530eb2aeace5c5bf4f3328a5b5d69dAndrew Stadler    Preferences mPreferences = null;
793f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler
803f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler    public LegacyConversionsTests() {
8131d9acbf0623872f9d4a2b3210b5970854b654c7Marc Blank        super(EmailProvider.class, EmailContent.AUTHORITY);
823f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler    }
833f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler
843f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler    @Override
853f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler    public void setUp() throws Exception {
863f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler        super.setUp();
873f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler        mProviderContext = getMockContext();
883f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler        mContext = getContext();
893f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler    }
903f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler
913f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler    /**
923f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler     * TODO: basic Legacy -> Provider Message conversions
933f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler     * TODO: basic Legacy -> Provider Body conversions
943f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler     * TODO: rainy day tests of all kinds
953f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler     */
963f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler
973f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler    /**
98eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler     * Test basic conversion from Store message to Provider message
99eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler     *
100eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler     * TODO: Not a complete test of all fields, and some fields need special tests (e.g. flags)
101eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler     * TODO: There are many special cases in the tested function, that need to be
102eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler     * tested here as well.
103eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler     */
104eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler    public void testUpdateMessageFields() throws MessagingException {
105eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler        MimeMessage message = buildTestMessage(RECIPIENT_TO, RECIPIENT_CC, RECIPIENT_BCC,
106eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler                REPLY_TO, SENDER, SUBJECT, null);
107eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler        EmailContent.Message localMessage = new EmailContent.Message();
108eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler
109eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler        boolean result = LegacyConversions.updateMessageFields(localMessage, message, 1, 1);
110eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler        assertTrue(result);
111eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler        checkProviderMessage("testUpdateMessageFields", message, localMessage);
112eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler    }
113eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler
114eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler    /**
115eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler     * Test basic conversion from Store message to Provider message, when the provider message
116eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler     * does not have a proper message-id.
117eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler     */
118eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler    public void testUpdateMessageFieldsNoMessageId() throws MessagingException {
119eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler        MimeMessage message = buildTestMessage(RECIPIENT_TO, RECIPIENT_CC, RECIPIENT_BCC,
120eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler                REPLY_TO, SENDER, SUBJECT, null);
121eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler        EmailContent.Message localMessage = new EmailContent.Message();
122eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler
123eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler        // If the source message-id is null, the target should be left as-is
124eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler        localMessage.mMessageId = MESSAGE_ID_2;
125eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler        message.removeHeader("Message-ID");
126eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler
127eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler        boolean result = LegacyConversions.updateMessageFields(localMessage, message, 1, 1);
128eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler        assertTrue(result);
129eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler        assertEquals(MESSAGE_ID_2, localMessage.mMessageId);
130eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler    }
131eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler
132eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler    /**
133eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler     * Build a lightweight Store message with simple field population
134eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler     */
135eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler    private MimeMessage buildTestMessage(String to, String cc, String bcc, String replyTo,
136eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler            String sender, String subject, String content) throws MessagingException {
137eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler        MimeMessage message = new MimeMessage();
138eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler
139eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler        if (to != null) {
140eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler            Address[] addresses = Address.parse(to);
141eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler            message.setRecipients(RecipientType.TO, addresses);
142eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler        }
143eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler        if (cc != null) {
144eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler            Address[] addresses = Address.parse(cc);
145eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler            message.setRecipients(RecipientType.CC, addresses);
146eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler        }
147eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler        if (bcc != null) {
148eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler            Address[] addresses = Address.parse(bcc);
149eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler            message.setRecipients(RecipientType.BCC, addresses);
150eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler        }
151eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler        if (replyTo != null) {
152eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler            Address[] addresses = Address.parse(replyTo);
153eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler            message.setReplyTo(addresses);
154eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler        }
155eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler        if (sender != null) {
156eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler            Address[] addresses = Address.parse(sender);
1575e91cccd4b530eb2aeace5c5bf4f3328a5b5d69dAndrew Stadler            message.setFrom(addresses[0]);
158eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler        }
159eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler        if (subject != null) {
160eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler            message.setSubject(subject);
161eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler        }
162eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler        if (content != null) {
163eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler            TextBody body = new TextBody(content);
164eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler            message.setBody(body);
165eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler        }
166eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler
167eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler        message.setUid(UID);
168eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler        message.setSentDate(new Date());
169eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler        message.setInternalDate(new Date());
170eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler        message.setMessageId(MESSAGE_ID);
171eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler        return message;
172eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler    }
173eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler
174eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler    /**
175b6756688b1bf07c50b999c9d30dd6cb224d3812bAndrew Stadler     * Basic test of body parts conversion from Store message to Provider message.
176b6756688b1bf07c50b999c9d30dd6cb224d3812bAndrew Stadler     * This tests that a null body part simply results in null text, and does not crash
177b6756688b1bf07c50b999c9d30dd6cb224d3812bAndrew Stadler     * or return "null".
178b6756688b1bf07c50b999c9d30dd6cb224d3812bAndrew Stadler     *
179b6756688b1bf07c50b999c9d30dd6cb224d3812bAndrew Stadler     * TODO very incomplete, there are many permutations to be explored
180b6756688b1bf07c50b999c9d30dd6cb224d3812bAndrew Stadler     */
181b6756688b1bf07c50b999c9d30dd6cb224d3812bAndrew Stadler    public void testUpdateBodyFieldsNullText() throws MessagingException {
182b6756688b1bf07c50b999c9d30dd6cb224d3812bAndrew Stadler        EmailContent.Body localBody = new EmailContent.Body();
183b6756688b1bf07c50b999c9d30dd6cb224d3812bAndrew Stadler        EmailContent.Message localMessage = new EmailContent.Message();
184b6756688b1bf07c50b999c9d30dd6cb224d3812bAndrew Stadler        ArrayList<Part> viewables = new ArrayList<Part>();
185b6756688b1bf07c50b999c9d30dd6cb224d3812bAndrew Stadler        Part emptyTextPart = new MimeBodyPart(null, "text/plain");
186b6756688b1bf07c50b999c9d30dd6cb224d3812bAndrew Stadler        viewables.add(emptyTextPart);
187b6756688b1bf07c50b999c9d30dd6cb224d3812bAndrew Stadler
188b6756688b1bf07c50b999c9d30dd6cb224d3812bAndrew Stadler        // a "null" body part of type text/plain should result in a null mTextContent
1896be411edd0ef5a1fb357d90c7fee22de83632be5Andrew Sapperstein        final BodyFieldData data =
1906be411edd0ef5a1fb357d90c7fee22de83632be5Andrew Sapperstein                ConversionUtilities.parseBodyFields(viewables);
1916be411edd0ef5a1fb357d90c7fee22de83632be5Andrew Sapperstein        assertNull(data.textContent);
192b6756688b1bf07c50b999c9d30dd6cb224d3812bAndrew Stadler    }
193b6756688b1bf07c50b999c9d30dd6cb224d3812bAndrew Stadler
194b6756688b1bf07c50b999c9d30dd6cb224d3812bAndrew Stadler    /**
1957d738cb7e89353c51c567e466a135b54337f310dAndrew Stadler     * Sunny day test of adding attachments from an IMAP/POP message.
1963f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler     */
1973f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler    public void testAddAttachments() throws MessagingException, IOException {
1983f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler        // Prepare a local message to add the attachments to
1993f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler        final long accountId = 1;
2003f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler        final long mailboxId = 1;
2017d738cb7e89353c51c567e466a135b54337f310dAndrew Stadler
2027d738cb7e89353c51c567e466a135b54337f310dAndrew Stadler        // test 1: legacy message using content-type:name style for name
2033f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler        final EmailContent.Message localMessage = ProviderTestUtils.setupMessage(
2043f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler                "local-message", accountId, mailboxId, false, true, mProviderContext);
2057d51b7a05ba07377e3df0b07c2aaa430a8b5bc42Andy Stadler        final Message legacyMessage = prepareLegacyMessageWithAttachments(2, false);
2067d738cb7e89353c51c567e466a135b54337f310dAndrew Stadler        convertAndCheckcheckAddedAttachments(localMessage, legacyMessage);
2073f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler
2087d738cb7e89353c51c567e466a135b54337f310dAndrew Stadler        // test 2: legacy message using content-disposition:filename style for name
2097d738cb7e89353c51c567e466a135b54337f310dAndrew Stadler        final EmailContent.Message localMessage2 = ProviderTestUtils.setupMessage(
2107d738cb7e89353c51c567e466a135b54337f310dAndrew Stadler                "local-message", accountId, mailboxId, false, true, mProviderContext);
2117d51b7a05ba07377e3df0b07c2aaa430a8b5bc42Andy Stadler        final Message legacyMessage2 = prepareLegacyMessageWithAttachments(2, true);
2127d738cb7e89353c51c567e466a135b54337f310dAndrew Stadler        convertAndCheckcheckAddedAttachments(localMessage2, legacyMessage2);
2137d738cb7e89353c51c567e466a135b54337f310dAndrew Stadler    }
2143f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler
2157d738cb7e89353c51c567e466a135b54337f310dAndrew Stadler    /**
2167d738cb7e89353c51c567e466a135b54337f310dAndrew Stadler     * Helper for testAddAttachments
2177d738cb7e89353c51c567e466a135b54337f310dAndrew Stadler     */
2187d738cb7e89353c51c567e466a135b54337f310dAndrew Stadler    private void convertAndCheckcheckAddedAttachments(final EmailContent.Message localMessage,
2197d738cb7e89353c51c567e466a135b54337f310dAndrew Stadler            final Message legacyMessage) throws MessagingException, IOException {
2203f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler        // Now, convert from legacy to provider and see what happens
2213f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler        ArrayList<Part> viewables = new ArrayList<Part>();
2223f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler        ArrayList<Part> attachments = new ArrayList<Part>();
2233f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler        MimeUtility.collectParts(legacyMessage, viewables, attachments);
2247d51b7a05ba07377e3df0b07c2aaa430a8b5bc42Andy Stadler        LegacyConversions.updateAttachments(mProviderContext, localMessage, attachments);
2253f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler
2263f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler        // Read back all attachments for message and check field values
2273f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler        Uri uri = ContentUris.withAppendedId(Attachment.MESSAGE_ID_URI, localMessage.mId);
2283f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler        Cursor c = mProviderContext.getContentResolver().query(uri, Attachment.CONTENT_PROJECTION,
2293f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler                null, null, null);
2303f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler        try {
2313f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler            assertEquals(2, c.getCount());
2323f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler            while (c.moveToNext()) {
2333f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler                Attachment attachment = Attachment.getContent(c, Attachment.class);
234e3a17f1438e454518a58fc0841bb615344acf865Andy Stadler                if ("100".equals(attachment.mLocation)) {
23575a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank                    checkAttachment("attachment1Part", attachments.get(0), attachment,
23675a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank                            localMessage.mAccountKey);
237e3a17f1438e454518a58fc0841bb615344acf865Andy Stadler                } else if ("101".equals(attachment.mLocation)) {
23875a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank                    checkAttachment("attachment2Part", attachments.get(1), attachment,
23975a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank                            localMessage.mAccountKey);
2403f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler                } else {
2413f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler                    fail("Unexpected attachment with location " + attachment.mLocation);
2423f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler                }
2433f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler            }
2443f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler        } finally {
2453f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler            c.close();
2463f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler        }
2473f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler    }
2483f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler
2493f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler    /**
250e3a17f1438e454518a58fc0841bb615344acf865Andy Stadler     * Test that only "attachment" or "inline" attachments are captured and added.
251e3a17f1438e454518a58fc0841bb615344acf865Andy Stadler     * @throws MessagingException
252e3a17f1438e454518a58fc0841bb615344acf865Andy Stadler     * @throws IOException
253e3a17f1438e454518a58fc0841bb615344acf865Andy Stadler     */
254e3a17f1438e454518a58fc0841bb615344acf865Andy Stadler    public void testAttachmentDispositions() throws MessagingException, IOException {
255e3a17f1438e454518a58fc0841bb615344acf865Andy Stadler        // Prepare a local message to add the attachments to
256e3a17f1438e454518a58fc0841bb615344acf865Andy Stadler        final long accountId = 1;
257e3a17f1438e454518a58fc0841bb615344acf865Andy Stadler        final long mailboxId = 1;
258e3a17f1438e454518a58fc0841bb615344acf865Andy Stadler
259e3a17f1438e454518a58fc0841bb615344acf865Andy Stadler        // Prepare the three attachments we want to test
260e3a17f1438e454518a58fc0841bb615344acf865Andy Stadler        BodyPart[] sourceAttachments = new BodyPart[3];
261e3a17f1438e454518a58fc0841bb615344acf865Andy Stadler        BodyPart attachmentPart;
262e3a17f1438e454518a58fc0841bb615344acf865Andy Stadler
263e3a17f1438e454518a58fc0841bb615344acf865Andy Stadler        // 1. Standard attachment
264e3a17f1438e454518a58fc0841bb615344acf865Andy Stadler        attachmentPart = MessageTestUtils.bodyPart("image/jpg", null);
265e3a17f1438e454518a58fc0841bb615344acf865Andy Stadler        attachmentPart.setHeader(MimeHeader.HEADER_CONTENT_TYPE, "image/jpg");
266e3a17f1438e454518a58fc0841bb615344acf865Andy Stadler        attachmentPart.setHeader(MimeHeader.HEADER_CONTENT_TRANSFER_ENCODING, "base64");
267e3a17f1438e454518a58fc0841bb615344acf865Andy Stadler        attachmentPart.setHeader(MimeHeader.HEADER_CONTENT_DISPOSITION,
268e3a17f1438e454518a58fc0841bb615344acf865Andy Stadler                "attachment;\n filename=\"file-1\";\n size=100");
269e3a17f1438e454518a58fc0841bb615344acf865Andy Stadler        attachmentPart.setHeader(MimeHeader.HEADER_ANDROID_ATTACHMENT_STORE_DATA, "100");
270e3a17f1438e454518a58fc0841bb615344acf865Andy Stadler        sourceAttachments[0] = attachmentPart;
271e3a17f1438e454518a58fc0841bb615344acf865Andy Stadler
272e3a17f1438e454518a58fc0841bb615344acf865Andy Stadler        // 2. Inline attachment
273e3a17f1438e454518a58fc0841bb615344acf865Andy Stadler        attachmentPart = MessageTestUtils.bodyPart("image/gif", null);
274e3a17f1438e454518a58fc0841bb615344acf865Andy Stadler        attachmentPart.setHeader(MimeHeader.HEADER_CONTENT_TYPE, "image/gif");
275e3a17f1438e454518a58fc0841bb615344acf865Andy Stadler        attachmentPart.setHeader(MimeHeader.HEADER_CONTENT_TRANSFER_ENCODING, "base64");
276e3a17f1438e454518a58fc0841bb615344acf865Andy Stadler        attachmentPart.setHeader(MimeHeader.HEADER_CONTENT_DISPOSITION,
277e3a17f1438e454518a58fc0841bb615344acf865Andy Stadler                "inline;\n filename=\"file-2\";\n size=200");
278e3a17f1438e454518a58fc0841bb615344acf865Andy Stadler        attachmentPart.setHeader(MimeHeader.HEADER_ANDROID_ATTACHMENT_STORE_DATA, "101");
279e3a17f1438e454518a58fc0841bb615344acf865Andy Stadler        sourceAttachments[1] = attachmentPart;
280e3a17f1438e454518a58fc0841bb615344acf865Andy Stadler
281e3a17f1438e454518a58fc0841bb615344acf865Andy Stadler        // 3. Neither (use VCALENDAR)
282e3a17f1438e454518a58fc0841bb615344acf865Andy Stadler        attachmentPart = MessageTestUtils.bodyPart("text/calendar", null);
283e3a17f1438e454518a58fc0841bb615344acf865Andy Stadler        attachmentPart.setHeader(MimeHeader.HEADER_CONTENT_TYPE,
284e3a17f1438e454518a58fc0841bb615344acf865Andy Stadler                "text/calendar; charset=UTF-8; method=REQUEST");
285e3a17f1438e454518a58fc0841bb615344acf865Andy Stadler        attachmentPart.setHeader(MimeHeader.HEADER_CONTENT_TRANSFER_ENCODING, "7bit");
286e3a17f1438e454518a58fc0841bb615344acf865Andy Stadler        attachmentPart.setHeader(MimeHeader.HEADER_ANDROID_ATTACHMENT_STORE_DATA, "102");
287e3a17f1438e454518a58fc0841bb615344acf865Andy Stadler        sourceAttachments[2] = attachmentPart;
288e3a17f1438e454518a58fc0841bb615344acf865Andy Stadler
289e3a17f1438e454518a58fc0841bb615344acf865Andy Stadler        // Prepare local message (destination) and legacy message w/attachments (source)
290e3a17f1438e454518a58fc0841bb615344acf865Andy Stadler        final EmailContent.Message localMessage = ProviderTestUtils.setupMessage(
291e3a17f1438e454518a58fc0841bb615344acf865Andy Stadler                "local-message", accountId, mailboxId, false, true, mProviderContext);
292e3a17f1438e454518a58fc0841bb615344acf865Andy Stadler        final Message legacyMessage = prepareLegacyMessageWithAttachments(sourceAttachments);
293e3a17f1438e454518a58fc0841bb615344acf865Andy Stadler        convertAndCheckcheckAddedAttachments(localMessage, legacyMessage);
294e3a17f1438e454518a58fc0841bb615344acf865Andy Stadler
295e3a17f1438e454518a58fc0841bb615344acf865Andy Stadler        // Run the conversion and check for the converted attachments - this test asserts
296e3a17f1438e454518a58fc0841bb615344acf865Andy Stadler        // that there are two attachments numbered 100 & 101 (so will fail if it finds 102)
297e3a17f1438e454518a58fc0841bb615344acf865Andy Stadler        convertAndCheckcheckAddedAttachments(localMessage, legacyMessage);
298e3a17f1438e454518a58fc0841bb615344acf865Andy Stadler    }
299e3a17f1438e454518a58fc0841bb615344acf865Andy Stadler
300e3a17f1438e454518a58fc0841bb615344acf865Andy Stadler    /**
3015b0a12c199198870161876996296b1262c17408eAndrew Stadler     * Test that attachments aren't re-added in the DB.  This supports the "partial download"
3025b0a12c199198870161876996296b1262c17408eAndrew Stadler     * nature of POP messages.
3035b0a12c199198870161876996296b1262c17408eAndrew Stadler     */
3045b0a12c199198870161876996296b1262c17408eAndrew Stadler    public void testAddDuplicateAttachments() throws MessagingException, IOException {
3055b0a12c199198870161876996296b1262c17408eAndrew Stadler        // Prepare a local message to add the attachments to
3065b0a12c199198870161876996296b1262c17408eAndrew Stadler        final long accountId = 1;
3075b0a12c199198870161876996296b1262c17408eAndrew Stadler        final long mailboxId = 1;
3085b0a12c199198870161876996296b1262c17408eAndrew Stadler        final EmailContent.Message localMessage = ProviderTestUtils.setupMessage(
3095b0a12c199198870161876996296b1262c17408eAndrew Stadler                "local-message", accountId, mailboxId, false, true, mProviderContext);
3105b0a12c199198870161876996296b1262c17408eAndrew Stadler
3115b0a12c199198870161876996296b1262c17408eAndrew Stadler        // Prepare a legacy message with attachments
3127d51b7a05ba07377e3df0b07c2aaa430a8b5bc42Andy Stadler        Message legacyMessage = prepareLegacyMessageWithAttachments(2, false);
3135b0a12c199198870161876996296b1262c17408eAndrew Stadler
3145b0a12c199198870161876996296b1262c17408eAndrew Stadler        // Now, convert from legacy to provider and see what happens
3155b0a12c199198870161876996296b1262c17408eAndrew Stadler        ArrayList<Part> viewables = new ArrayList<Part>();
3165b0a12c199198870161876996296b1262c17408eAndrew Stadler        ArrayList<Part> attachments = new ArrayList<Part>();
3175b0a12c199198870161876996296b1262c17408eAndrew Stadler        MimeUtility.collectParts(legacyMessage, viewables, attachments);
3187d51b7a05ba07377e3df0b07c2aaa430a8b5bc42Andy Stadler        LegacyConversions.updateAttachments(mProviderContext, localMessage, attachments);
3195b0a12c199198870161876996296b1262c17408eAndrew Stadler
3205b0a12c199198870161876996296b1262c17408eAndrew Stadler        // Confirm two attachment objects created
3215b0a12c199198870161876996296b1262c17408eAndrew Stadler        Uri uri = ContentUris.withAppendedId(Attachment.MESSAGE_ID_URI, localMessage.mId);
3225b0a12c199198870161876996296b1262c17408eAndrew Stadler        assertEquals(2, EmailContent.count(mProviderContext, uri, null, null));
3235b0a12c199198870161876996296b1262c17408eAndrew Stadler
3245b0a12c199198870161876996296b1262c17408eAndrew Stadler        // Now add the attachments again and confirm there are still only two
3257d51b7a05ba07377e3df0b07c2aaa430a8b5bc42Andy Stadler        LegacyConversions.updateAttachments(mProviderContext, localMessage, attachments);
3265b0a12c199198870161876996296b1262c17408eAndrew Stadler        assertEquals(2, EmailContent.count(mProviderContext, uri, null, null));
3275b0a12c199198870161876996296b1262c17408eAndrew Stadler
3285b0a12c199198870161876996296b1262c17408eAndrew Stadler        // Now add a 3rd & 4th attachment and make sure the total is 4, not 2 or 6
3297d51b7a05ba07377e3df0b07c2aaa430a8b5bc42Andy Stadler        legacyMessage = prepareLegacyMessageWithAttachments(4, false);
3305b0a12c199198870161876996296b1262c17408eAndrew Stadler        viewables = new ArrayList<Part>();
3315b0a12c199198870161876996296b1262c17408eAndrew Stadler        attachments = new ArrayList<Part>();
3325b0a12c199198870161876996296b1262c17408eAndrew Stadler        MimeUtility.collectParts(legacyMessage, viewables, attachments);
3337d51b7a05ba07377e3df0b07c2aaa430a8b5bc42Andy Stadler        LegacyConversions.updateAttachments(mProviderContext, localMessage, attachments);
3345b0a12c199198870161876996296b1262c17408eAndrew Stadler        assertEquals(4, EmailContent.count(mProviderContext, uri, null, null));
3355b0a12c199198870161876996296b1262c17408eAndrew Stadler    }
3365b0a12c199198870161876996296b1262c17408eAndrew Stadler
3375b0a12c199198870161876996296b1262c17408eAndrew Stadler    /**
3385b0a12c199198870161876996296b1262c17408eAndrew Stadler     * Prepare a legacy message with 1+ attachments
339fd249f61dd9c5fd1e7e0abffcb09b9e285d82baeAndrew Stadler     * @param numAttachments how many attachments to add
3407d738cb7e89353c51c567e466a135b54337f310dAndrew Stadler     * @param filenameInDisposition False: attachment names are sent as content-type:name.  True:
3417d738cb7e89353c51c567e466a135b54337f310dAndrew Stadler     *          attachment names are sent as content-disposition:filename.
3425b0a12c199198870161876996296b1262c17408eAndrew Stadler     */
3437d51b7a05ba07377e3df0b07c2aaa430a8b5bc42Andy Stadler    private Message prepareLegacyMessageWithAttachments(int numAttachments,
3447d738cb7e89353c51c567e466a135b54337f310dAndrew Stadler            boolean filenameInDisposition) throws MessagingException {
345e3a17f1438e454518a58fc0841bb615344acf865Andy Stadler        BodyPart[] attachmentParts = new BodyPart[numAttachments];
346e3a17f1438e454518a58fc0841bb615344acf865Andy Stadler        for (int i = 0; i < numAttachments; ++i) {
3477d738cb7e89353c51c567e466a135b54337f310dAndrew Stadler            // construct parameter parts for content-type:name or content-disposition:filename.
3487d738cb7e89353c51c567e466a135b54337f310dAndrew Stadler            String name = "";
3497d738cb7e89353c51c567e466a135b54337f310dAndrew Stadler            String filename = "";
3507d738cb7e89353c51c567e466a135b54337f310dAndrew Stadler            String quotedName = "\"test-attachment-" + i + "\"";
3517d738cb7e89353c51c567e466a135b54337f310dAndrew Stadler            if (filenameInDisposition) {
3527d738cb7e89353c51c567e466a135b54337f310dAndrew Stadler                filename = ";\n filename=" + quotedName;
3537d738cb7e89353c51c567e466a135b54337f310dAndrew Stadler            } else {
3547d738cb7e89353c51c567e466a135b54337f310dAndrew Stadler                name = ";\n name=" + quotedName;
3557d738cb7e89353c51c567e466a135b54337f310dAndrew Stadler            }
356fd249f61dd9c5fd1e7e0abffcb09b9e285d82baeAndrew Stadler
3577d51b7a05ba07377e3df0b07c2aaa430a8b5bc42Andy Stadler            // generate an attachment that came from a server
3587d51b7a05ba07377e3df0b07c2aaa430a8b5bc42Andy Stadler            BodyPart attachmentPart = MessageTestUtils.bodyPart("image/jpg", null);
359fd249f61dd9c5fd1e7e0abffcb09b9e285d82baeAndrew Stadler
3607d51b7a05ba07377e3df0b07c2aaa430a8b5bc42Andy Stadler            // name=attachmentN size=N00 location=10N
3617d51b7a05ba07377e3df0b07c2aaa430a8b5bc42Andy Stadler            attachmentPart.setHeader(MimeHeader.HEADER_CONTENT_TYPE, "image/jpg" + name);
3627d51b7a05ba07377e3df0b07c2aaa430a8b5bc42Andy Stadler            attachmentPart.setHeader(MimeHeader.HEADER_CONTENT_TRANSFER_ENCODING, "base64");
3637d51b7a05ba07377e3df0b07c2aaa430a8b5bc42Andy Stadler            attachmentPart.setHeader(MimeHeader.HEADER_CONTENT_DISPOSITION,
3647d51b7a05ba07377e3df0b07c2aaa430a8b5bc42Andy Stadler                    "attachment" + filename +  ";\n size=" + (i+1) + "00");
3657d51b7a05ba07377e3df0b07c2aaa430a8b5bc42Andy Stadler            attachmentPart.setHeader(MimeHeader.HEADER_ANDROID_ATTACHMENT_STORE_DATA, "10" + i);
3667d51b7a05ba07377e3df0b07c2aaa430a8b5bc42Andy Stadler
3677d51b7a05ba07377e3df0b07c2aaa430a8b5bc42Andy Stadler            attachmentParts[i] = attachmentPart;
3685b0a12c199198870161876996296b1262c17408eAndrew Stadler        }
3695b0a12c199198870161876996296b1262c17408eAndrew Stadler
370e3a17f1438e454518a58fc0841bb615344acf865Andy Stadler        return prepareLegacyMessageWithAttachments(attachmentParts);
371e3a17f1438e454518a58fc0841bb615344acf865Andy Stadler    }
372e3a17f1438e454518a58fc0841bb615344acf865Andy Stadler
373e3a17f1438e454518a58fc0841bb615344acf865Andy Stadler    /**
374e3a17f1438e454518a58fc0841bb615344acf865Andy Stadler     * Prepare a legacy message with 1+ attachments
375e3a17f1438e454518a58fc0841bb615344acf865Andy Stadler     * @param attachments array containing one or more attachments
376e3a17f1438e454518a58fc0841bb615344acf865Andy Stadler     */
377e3a17f1438e454518a58fc0841bb615344acf865Andy Stadler    private Message prepareLegacyMessageWithAttachments(BodyPart[] attachments)
378e3a17f1438e454518a58fc0841bb615344acf865Andy Stadler            throws MessagingException {
379e3a17f1438e454518a58fc0841bb615344acf865Andy Stadler        // Build the multipart that holds the attachments
380e3a17f1438e454518a58fc0841bb615344acf865Andy Stadler        MultipartBuilder mpBuilder = new MultipartBuilder("multipart/mixed");
381e3a17f1438e454518a58fc0841bb615344acf865Andy Stadler        for (int i = 0; i < attachments.length; ++i) {
382e3a17f1438e454518a58fc0841bb615344acf865Andy Stadler            mpBuilder.addBodyPart(attachments[i]);
383e3a17f1438e454518a58fc0841bb615344acf865Andy Stadler        }
384e3a17f1438e454518a58fc0841bb615344acf865Andy Stadler
3855b0a12c199198870161876996296b1262c17408eAndrew Stadler        // Now build a message with them
3865b0a12c199198870161876996296b1262c17408eAndrew Stadler        final Message legacyMessage = new MessageBuilder()
3875b0a12c199198870161876996296b1262c17408eAndrew Stadler            .setBody(new MultipartBuilder("multipart/mixed")
3885b0a12c199198870161876996296b1262c17408eAndrew Stadler                     .addBodyPart(MessageTestUtils.bodyPart("text/html", null))
3895b0a12c199198870161876996296b1262c17408eAndrew Stadler                     .addBodyPart(mpBuilder.buildBodyPart())
3905b0a12c199198870161876996296b1262c17408eAndrew Stadler                     .build())
3915b0a12c199198870161876996296b1262c17408eAndrew Stadler                .build();
3925b0a12c199198870161876996296b1262c17408eAndrew Stadler
3935b0a12c199198870161876996296b1262c17408eAndrew Stadler        return legacyMessage;
3945b0a12c199198870161876996296b1262c17408eAndrew Stadler    }
3955b0a12c199198870161876996296b1262c17408eAndrew Stadler
3965b0a12c199198870161876996296b1262c17408eAndrew Stadler    /**
3975b0a12c199198870161876996296b1262c17408eAndrew Stadler     * Test the stringInequal helper
3985b0a12c199198870161876996296b1262c17408eAndrew Stadler     */
3995b0a12c199198870161876996296b1262c17408eAndrew Stadler    public void testStringInequal() {
4005b0a12c199198870161876996296b1262c17408eAndrew Stadler        // Pairs that are "equal"
4015b0a12c199198870161876996296b1262c17408eAndrew Stadler        assertFalse(LegacyConversions.stringNotEqual(null, null));
4025b0a12c199198870161876996296b1262c17408eAndrew Stadler        assertFalse(LegacyConversions.stringNotEqual(null, ""));
4035b0a12c199198870161876996296b1262c17408eAndrew Stadler        assertFalse(LegacyConversions.stringNotEqual("", null));
4045b0a12c199198870161876996296b1262c17408eAndrew Stadler        assertFalse(LegacyConversions.stringNotEqual("", ""));
4055b0a12c199198870161876996296b1262c17408eAndrew Stadler        assertFalse(LegacyConversions.stringNotEqual("string-equal", "string-equal"));
4065b0a12c199198870161876996296b1262c17408eAndrew Stadler        // Pairs that are "inequal"
4075b0a12c199198870161876996296b1262c17408eAndrew Stadler        assertTrue(LegacyConversions.stringNotEqual(null, "string-inequal"));
4085b0a12c199198870161876996296b1262c17408eAndrew Stadler        assertTrue(LegacyConversions.stringNotEqual("", "string-inequal"));
4095b0a12c199198870161876996296b1262c17408eAndrew Stadler        assertTrue(LegacyConversions.stringNotEqual("string-inequal", null));
4105b0a12c199198870161876996296b1262c17408eAndrew Stadler        assertTrue(LegacyConversions.stringNotEqual("string-inequal", ""));
4115b0a12c199198870161876996296b1262c17408eAndrew Stadler        assertTrue(LegacyConversions.stringNotEqual("string-inequal-a", "string-inequal-b"));
4125b0a12c199198870161876996296b1262c17408eAndrew Stadler    }
4135b0a12c199198870161876996296b1262c17408eAndrew Stadler
4145b0a12c199198870161876996296b1262c17408eAndrew Stadler    /**
4153f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler     * Compare attachment that was converted from Part (expected) to Provider Attachment (actual)
416515d830e8755d3674e04bcc60d7f85b4fa7fb202Jerry Xie     *
4173f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler     * TODO content URI should only be set if we also saved a file
4183f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler     * TODO other data encodings
4193f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler     */
42075a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank    private void checkAttachment(String tag, Part expected, EmailContent.Attachment actual,
42175a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank            long accountKey) throws MessagingException {
4223f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler        String contentType = MimeUtility.unfoldAndDecode(expected.getContentType());
4237d738cb7e89353c51c567e466a135b54337f310dAndrew Stadler        String contentTypeName = MimeUtility.getHeaderParameter(contentType, "name");
4243f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler        assertEquals(tag, expected.getMimeType(), actual.mMimeType);
4253f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler        String disposition = expected.getDisposition();
4263f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler        String sizeString = MimeUtility.getHeaderParameter(disposition, "size");
4277d738cb7e89353c51c567e466a135b54337f310dAndrew Stadler        String dispositionFilename = MimeUtility.getHeaderParameter(disposition, "filename");
428fd249f61dd9c5fd1e7e0abffcb09b9e285d82baeAndrew Stadler        long expectedSize = (sizeString != null) ? Long.parseLong(sizeString) : 0;
4293f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler        assertEquals(tag, expectedSize, actual.mSize);
4303f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler        assertEquals(tag, expected.getContentId(), actual.mContentId);
431fd249f61dd9c5fd1e7e0abffcb09b9e285d82baeAndrew Stadler
4327d738cb7e89353c51c567e466a135b54337f310dAndrew Stadler        // filename is either content-type:name or content-disposition:filename
4337d738cb7e89353c51c567e466a135b54337f310dAndrew Stadler        String expectedName = (contentTypeName != null) ? contentTypeName : dispositionFilename;
4347d738cb7e89353c51c567e466a135b54337f310dAndrew Stadler        assertEquals(tag, expectedName, actual.mFileName);
4357d738cb7e89353c51c567e466a135b54337f310dAndrew Stadler
4367d51b7a05ba07377e3df0b07c2aaa430a8b5bc42Andy Stadler        // content URI should be null
437515d830e8755d3674e04bcc60d7f85b4fa7fb202Jerry Xie        assertNull(tag, actual.getContentUri());
438fd249f61dd9c5fd1e7e0abffcb09b9e285d82baeAndrew Stadler
4393f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler        assertTrue(tag, 0 != actual.mMessageKey);
440fd249f61dd9c5fd1e7e0abffcb09b9e285d82baeAndrew Stadler
441fd249f61dd9c5fd1e7e0abffcb09b9e285d82baeAndrew Stadler        // location is either both null or both matching
442fd249f61dd9c5fd1e7e0abffcb09b9e285d82baeAndrew Stadler        String expectedPartId = null;
443fd249f61dd9c5fd1e7e0abffcb09b9e285d82baeAndrew Stadler        String[] storeData = expected.getHeader(MimeHeader.HEADER_ANDROID_ATTACHMENT_STORE_DATA);
444fd249f61dd9c5fd1e7e0abffcb09b9e285d82baeAndrew Stadler        if (storeData != null && storeData.length > 0) {
445fd249f61dd9c5fd1e7e0abffcb09b9e285d82baeAndrew Stadler            expectedPartId = storeData[0];
446fd249f61dd9c5fd1e7e0abffcb09b9e285d82baeAndrew Stadler        }
4473f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler        assertEquals(tag, expectedPartId, actual.mLocation);
4483f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler        assertEquals(tag, "B", actual.mEncoding);
44975a873be8420e50f0aeb5a77716358ee0ca66b01Marc Blank        assertEquals(tag, accountKey, actual.mAccountKey);
4503f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler    }
4513f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler
4523f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler    /**
4533f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler     * TODO: Sunny day test of adding attachments from a POP message.
4543f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler     */
4553f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler
456c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler    /**
457c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler     * Sunny day tests of converting an original message to a legacy message
458c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler     */
459c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler    public void testMakeLegacyMessage() throws MessagingException {
460c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler        // Set up and store a message in the provider
461c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler        long account1Id = 1;
462c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler        long mailbox1Id = 1;
463c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler
464c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler        // Test message 1: No body
465c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler        EmailContent.Message localMessage1 = ProviderTestUtils.setupMessage("make-legacy",
466c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler                account1Id, mailbox1Id, false, true, mProviderContext);
467c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler        Message getMessage1 = LegacyConversions.makeMessage(mProviderContext, localMessage1);
468c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler        checkLegacyMessage("no body", localMessage1, getMessage1);
469c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler
470c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler        // Test message 2: Simple body
471c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler        EmailContent.Message localMessage2 = ProviderTestUtils.setupMessage("make-legacy",
472c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler                account1Id, mailbox1Id, true, false, mProviderContext);
473c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler        localMessage2.mTextReply = null;
474c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler        localMessage2.mHtmlReply = null;
475c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler        localMessage2.mIntroText = null;
476c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler        localMessage2.mFlags &= ~EmailContent.Message.FLAG_TYPE_MASK;
477c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler        localMessage2.save(mProviderContext);
478c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler        Message getMessage2 = LegacyConversions.makeMessage(mProviderContext, localMessage2);
479c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler        checkLegacyMessage("simple body", localMessage2, getMessage2);
480c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler
481c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler        // Test message 3: Body + replied-to text
482c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler        EmailContent.Message localMessage3 = ProviderTestUtils.setupMessage("make-legacy",
483c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler                account1Id, mailbox1Id, true, false, mProviderContext);
484c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler        localMessage3.mFlags &= ~EmailContent.Message.FLAG_TYPE_MASK;
485c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler        localMessage3.mFlags |= EmailContent.Message.FLAG_TYPE_REPLY;
486c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler        localMessage3.save(mProviderContext);
487c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler        Message getMessage3 = LegacyConversions.makeMessage(mProviderContext, localMessage3);
488c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler        checkLegacyMessage("reply-to", localMessage3, getMessage3);
489c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler
490c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler        // Test message 4: Body + forwarded text
491c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler        EmailContent.Message localMessage4 = ProviderTestUtils.setupMessage("make-legacy",
492c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler                account1Id, mailbox1Id, true, false, mProviderContext);
493c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler        localMessage4.mFlags &= ~EmailContent.Message.FLAG_TYPE_MASK;
494c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler        localMessage4.mFlags |= EmailContent.Message.FLAG_TYPE_FORWARD;
495c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler        localMessage4.save(mProviderContext);
496c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler        Message getMessage4 = LegacyConversions.makeMessage(mProviderContext, localMessage4);
497c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler        checkLegacyMessage("forwarding", localMessage4, getMessage4);
498c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler    }
499c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler
500c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler    /**
501eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler     * Check equality of a pair of converted messages
502eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler     */
503eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler    private void checkProviderMessage(String tag, Message expect, EmailContent.Message actual)
504eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler            throws MessagingException {
505eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler        assertEquals(tag, expect.getUid(), actual.mServerId);
506eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler        assertEquals(tag, expect.getSubject(), actual.mSubject);
507eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler        assertEquals(tag, Address.pack(expect.getFrom()), actual.mFrom);
508eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler        assertEquals(tag, expect.getSentDate().getTime(), actual.mTimeStamp);
509eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler        assertEquals(tag, Address.pack(expect.getRecipients(RecipientType.TO)), actual.mTo);
510eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler        assertEquals(tag, Address.pack(expect.getRecipients(RecipientType.CC)), actual.mCc);
511eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler        assertEquals(tag, ((MimeMessage)expect).getMessageId(), actual.mMessageId);
512eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler        assertEquals(tag, expect.isSet(Flag.SEEN), actual.mFlagRead);
513eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler        assertEquals(tag, expect.isSet(Flag.FLAGGED), actual.mFlagFavorite);
514eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler    }
515eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler
5165b0a12c199198870161876996296b1262c17408eAndrew Stadler    /**
517eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler     * Check equality of a pair of converted messages
518c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler     */
519c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler    private void checkLegacyMessage(String tag, EmailContent.Message expect, Message actual)
520c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler            throws MessagingException {
521c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler        assertEquals(tag, expect.mServerId, actual.getUid());
522eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler        assertEquals(tag, expect.mServerTimeStamp, actual.getInternalDate().getTime());
523c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler        assertEquals(tag, expect.mSubject, actual.getSubject());
524c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler        assertEquals(tag, expect.mFrom, Address.pack(actual.getFrom()));
525c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler        assertEquals(tag, expect.mTimeStamp, actual.getSentDate().getTime());
526c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler        assertEquals(tag, expect.mTo, Address.pack(actual.getRecipients(RecipientType.TO)));
527c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler        assertEquals(tag, expect.mCc, Address.pack(actual.getRecipients(RecipientType.CC)));
528eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler        assertEquals(tag, expect.mBcc, Address.pack(actual.getRecipients(RecipientType.BCC)));
529eb7752bf695b2a93854e0bb89ddbbc2236bb9aeaAndrew Stadler        assertEquals(tag, expect.mReplyTo, Address.pack(actual.getReplyTo()));
530c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler        assertEquals(tag, expect.mMessageId, ((MimeMessage)actual).getMessageId());
531c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler        // check flags
532c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler        assertEquals(tag, expect.mFlagRead, actual.isSet(Flag.SEEN));
533c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler        assertEquals(tag, expect.mFlagFavorite, actual.isSet(Flag.FLAGGED));
534c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler
535c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler        // Check the body of the message
536c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler        ArrayList<Part> viewables = new ArrayList<Part>();
537c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler        ArrayList<Part> attachments = new ArrayList<Part>();
538c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler        MimeUtility.collectParts(actual, viewables, attachments);
539c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler        String get1Text = null;
540c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler        String get1Html = null;
541c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler        String get1TextReply = null;
542c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler        String get1HtmlReply = null;
543c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler        String get1TextIntro = null;
544c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler        for (Part viewable : viewables) {
545c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler            String text = MimeUtility.getTextFromPart(viewable);
546c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler            boolean isHtml = viewable.getMimeType().equalsIgnoreCase("text/html");
547c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler            String[] headers = viewable.getHeader(MimeHeader.HEADER_ANDROID_BODY_QUOTED_PART);
548c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler            if (headers != null) {
549c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler                String header = headers[0];
550c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler                boolean isReply = LegacyConversions.BODY_QUOTED_PART_REPLY.equalsIgnoreCase(header);
551c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler                boolean isFwd = LegacyConversions.BODY_QUOTED_PART_FORWARD.equalsIgnoreCase(header);
552c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler                boolean isIntro = LegacyConversions.BODY_QUOTED_PART_INTRO.equalsIgnoreCase(header);
553c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler                if (isReply || isFwd) {
554c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler                    if (isHtml) {
555c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler                        get1HtmlReply = text;
556c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler                    } else {
557c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler                        get1TextReply = text;
558c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler                    }
559c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler                } else if (isIntro) {
560c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler                    get1TextIntro = text;
561c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler                }
562c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler                // Check flags
563c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler                int replyTypeFlags = expect.mFlags & EmailContent.Message.FLAG_TYPE_MASK;
564c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler                if (isReply) {
565c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler                    assertEquals(tag, EmailContent.Message.FLAG_TYPE_REPLY, replyTypeFlags);
566c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler                }
567c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler                if (isFwd) {
568c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler                    assertEquals(tag, EmailContent.Message.FLAG_TYPE_FORWARD, replyTypeFlags);
569c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler                }
570c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler            } else {
571c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler                if (isHtml) {
572c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler                    get1Html = text;
573c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler                } else {
574c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler                    get1Text = text;
575c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler                }
576c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler            }
577c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler        }
578c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler        assertEquals(tag, expect.mText, get1Text);
579c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler        assertEquals(tag, expect.mHtml, get1Html);
580c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler        assertEquals(tag, expect.mTextReply, get1TextReply);
581c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler        assertEquals(tag, expect.mHtmlReply, get1HtmlReply);
582c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler        assertEquals(tag, expect.mIntroText, get1TextIntro);
583c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler
584c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler        // TODO Check the attachments
585c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler
586c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler//      cv.put("attachment_count", attachments.size());
587c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler    }
5883f1ac4da947f426775c9546f2e37206f58ce1a6eAndrew Stadler}
589