Merge "Test encode/decode of attachments" into ub-mail-master
This commit is contained in:
commit
5021265826
@ -45,6 +45,7 @@ import com.android.emailcommon.provider.Mailbox;
|
||||
import com.android.emailcommon.utility.AttachmentUtilities;
|
||||
import com.android.mail.providers.UIProvider;
|
||||
import com.android.mail.utils.LogUtils;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
||||
@ -183,6 +184,59 @@ public class LegacyConversions {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a MIME Part object into an Attachment object. Separated for unit testing.
|
||||
*
|
||||
* @param part MIME part object to convert
|
||||
* @return Populated Account object
|
||||
* @throws MessagingException
|
||||
*/
|
||||
@VisibleForTesting
|
||||
protected static Attachment mimePartToAttachment(final Part part) throws MessagingException {
|
||||
// Transfer fields from mime format to provider format
|
||||
final String contentType = MimeUtility.unfoldAndDecode(part.getContentType());
|
||||
|
||||
String name = MimeUtility.getHeaderParameter(contentType, "name");
|
||||
if (TextUtils.isEmpty(name)) {
|
||||
final String contentDisposition = MimeUtility.unfoldAndDecode(part.getDisposition());
|
||||
name = MimeUtility.getHeaderParameter(contentDisposition, "filename");
|
||||
}
|
||||
|
||||
// Incoming attachment: Try to pull size from disposition (if not downloaded yet)
|
||||
long size = 0;
|
||||
final String disposition = part.getDisposition();
|
||||
if (!TextUtils.isEmpty(disposition)) {
|
||||
String s = MimeUtility.getHeaderParameter(disposition, "size");
|
||||
if (!TextUtils.isEmpty(s)) {
|
||||
try {
|
||||
size = Long.parseLong(s);
|
||||
} catch (final NumberFormatException e) {
|
||||
LogUtils.d(LogUtils.TAG, e, "Could not decode size \"%s\" from attachment part",
|
||||
size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get partId for unloaded IMAP attachments (if any)
|
||||
// This is only provided (and used) when we have structure but not the actual attachment
|
||||
final String[] partIds = part.getHeader(MimeHeader.HEADER_ANDROID_ATTACHMENT_STORE_DATA);
|
||||
final String partId = partIds != null ? partIds[0] : null;
|
||||
|
||||
final Attachment localAttachment = new Attachment();
|
||||
|
||||
// Run the mime type through inferMimeType in case we have something generic and can do
|
||||
// better using the filename extension
|
||||
localAttachment.mMimeType = AttachmentUtilities.inferMimeType(name, part.getMimeType());
|
||||
localAttachment.mFileName = name;
|
||||
localAttachment.mSize = size;
|
||||
localAttachment.mContentId = part.getContentId();
|
||||
localAttachment.setContentUri(null); // Will be rewritten by saveAttachmentBody
|
||||
localAttachment.mLocation = partId;
|
||||
localAttachment.mEncoding = "B"; // TODO - convert other known encodings
|
||||
|
||||
return localAttachment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a single attachment part to the message
|
||||
*
|
||||
@ -203,40 +257,8 @@ public class LegacyConversions {
|
||||
public static void addOneAttachment(final Context context,
|
||||
final EmailContent.Message localMessage, final Part part)
|
||||
throws MessagingException, IOException {
|
||||
// Transfer fields from mime format to provider format
|
||||
final String contentType = MimeUtility.unfoldAndDecode(part.getContentType());
|
||||
String name = MimeUtility.getHeaderParameter(contentType, "name");
|
||||
if (name == null) {
|
||||
final String contentDisposition = MimeUtility.unfoldAndDecode(part.getDisposition());
|
||||
name = MimeUtility.getHeaderParameter(contentDisposition, "filename");
|
||||
}
|
||||
|
||||
// Incoming attachment: Try to pull size from disposition (if not downloaded yet)
|
||||
long size = 0;
|
||||
final String disposition = part.getDisposition();
|
||||
if (disposition != null) {
|
||||
String s = MimeUtility.getHeaderParameter(disposition, "size");
|
||||
if (s != null) {
|
||||
size = Long.parseLong(s);
|
||||
}
|
||||
}
|
||||
|
||||
// Get partId for unloaded IMAP attachments (if any)
|
||||
// This is only provided (and used) when we have structure but not the actual attachment
|
||||
final String[] partIds = part.getHeader(MimeHeader.HEADER_ANDROID_ATTACHMENT_STORE_DATA);
|
||||
final String partId = partIds != null ? partIds[0] : null;
|
||||
|
||||
// Run the mime type through inferMimeType in case we have something generic and can do
|
||||
// better using the filename extension
|
||||
final Attachment localAttachment = new Attachment();
|
||||
localAttachment.mMimeType = AttachmentUtilities.inferMimeType(name, part.getMimeType());
|
||||
localAttachment.mFileName = name;
|
||||
localAttachment.mSize = size; // May be reset below if file handled
|
||||
localAttachment.mContentId = part.getContentId();
|
||||
localAttachment.setContentUri(null); // Will be rewritten by saveAttachmentBody
|
||||
final Attachment localAttachment = mimePartToAttachment(part);
|
||||
localAttachment.mMessageKey = localMessage.mId;
|
||||
localAttachment.mLocation = partId;
|
||||
localAttachment.mEncoding = "B"; // TODO - convert other known encodings
|
||||
localAttachment.mAccountKey = localMessage.mAccountKey;
|
||||
|
||||
if (DEBUG_ATTACHMENTS) {
|
||||
@ -469,7 +491,8 @@ public class LegacyConversions {
|
||||
* @param contentId as referenced from cid: uris in the message body (if applicable)
|
||||
* @param content unencoded bytes
|
||||
*/
|
||||
private static void addAttachmentPart(final Multipart mp, final String contentType,
|
||||
@VisibleForTesting
|
||||
protected static void addAttachmentPart(final Multipart mp, final String contentType,
|
||||
final Long contentSize, final String filename, final String contentId,
|
||||
final InputStream content) throws MessagingException {
|
||||
final Base64Body body = new Base64Body(content);
|
||||
|
@ -16,23 +16,41 @@
|
||||
|
||||
package com.android.email;
|
||||
|
||||
import android.content.Context;
|
||||
import android.test.AndroidTestCase;
|
||||
import android.test.suitebuilder.annotation.SmallTest;
|
||||
|
||||
import com.android.emailcommon.TempDirectory;
|
||||
import com.android.emailcommon.internet.MimeBodyPart;
|
||||
import com.android.emailcommon.internet.MimeMessage;
|
||||
import com.android.emailcommon.internet.MimeMultipart;
|
||||
import com.android.emailcommon.mail.Address;
|
||||
import com.android.emailcommon.mail.Message.RecipientType;
|
||||
import com.android.emailcommon.mail.MessagingException;
|
||||
import com.android.emailcommon.mail.Multipart;
|
||||
import com.android.emailcommon.mail.Part;
|
||||
import com.android.emailcommon.provider.EmailContent;
|
||||
import com.android.emailcommon.provider.EmailContent.Attachment;
|
||||
import com.android.emailcommon.utility.ConversionUtilities;
|
||||
import com.android.emailcommon.utility.ConversionUtilities.BodyFieldData;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
|
||||
@SmallTest
|
||||
public class LegacyConversionsTest extends AndroidTestCase {
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
TempDirectory.setTempDirectory(getContext());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test basic fields conversion from Store message to Provider message.
|
||||
*/
|
||||
@ -172,4 +190,74 @@ public class LegacyConversionsTest extends AndroidTestCase {
|
||||
final BodyFieldData data = ConversionUtilities.parseBodyFields(viewables);
|
||||
assertNull(data.textContent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test adding an attachment to a message, and then parsing it back out.
|
||||
* @throws MessagingException
|
||||
*/
|
||||
public void testAttachmentRoundTrip() throws Exception {
|
||||
final Context context = getContext();
|
||||
final MimeMultipart mp = new MimeMultipart();
|
||||
mp.setSubType("mixed");
|
||||
|
||||
final long size;
|
||||
|
||||
final File tempDir = context.getCacheDir();
|
||||
if (!tempDir.isDirectory() && !tempDir.mkdirs()) {
|
||||
fail("Could not create temporary directory");
|
||||
}
|
||||
|
||||
final File tempAttachmentFile = File.createTempFile("testAttachmentRoundTrip", ".txt",
|
||||
tempDir);
|
||||
|
||||
try {
|
||||
final OutputStream attOut = new FileOutputStream(tempAttachmentFile);
|
||||
try {
|
||||
attOut.write("TestData".getBytes());
|
||||
} finally {
|
||||
attOut.close();
|
||||
}
|
||||
size = tempAttachmentFile.length();
|
||||
final InputStream attIn = new FileInputStream(tempAttachmentFile);
|
||||
LegacyConversions.addAttachmentPart(mp, "text/plain", size, "test.txt",
|
||||
"testContentId", attIn);
|
||||
} finally {
|
||||
if (!tempAttachmentFile.delete()) {
|
||||
fail("Setup failure: Could not clean up temp file");
|
||||
}
|
||||
}
|
||||
|
||||
final MimeMessage outMessage = new MimeMessage();
|
||||
outMessage.setBody(mp);
|
||||
|
||||
final MimeMessage inMessage;
|
||||
|
||||
final File tempBodyFile = File.createTempFile("testAttachmentRoundTrip", ".eml",
|
||||
context.getCacheDir());
|
||||
try {
|
||||
final OutputStream bodyOut = new FileOutputStream(tempBodyFile);
|
||||
try {
|
||||
outMessage.writeTo(bodyOut);
|
||||
} finally {
|
||||
bodyOut.close();
|
||||
}
|
||||
final InputStream bodyIn = new FileInputStream(tempBodyFile);
|
||||
try {
|
||||
inMessage = new MimeMessage(bodyIn);
|
||||
} finally {
|
||||
bodyIn.close();
|
||||
}
|
||||
} finally {
|
||||
if (!tempBodyFile.delete()) {
|
||||
fail("Setup failure: Could not clean up temp file");
|
||||
}
|
||||
}
|
||||
final Multipart inBody = (Multipart) inMessage.getBody();
|
||||
final Part attPart = inBody.getBodyPart(0);
|
||||
final Attachment att = LegacyConversions.mimePartToAttachment(attPart);
|
||||
assertEquals(att.mFileName, "test.txt");
|
||||
assertEquals(att.mMimeType, "text/plain");
|
||||
assertEquals(att.mSize, size);
|
||||
assertEquals(att.mContentId, "testContentId");
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user