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.emailcommon.utility.AttachmentUtilities;
|
||||||
import com.android.mail.providers.UIProvider;
|
import com.android.mail.providers.UIProvider;
|
||||||
import com.android.mail.utils.LogUtils;
|
import com.android.mail.utils.LogUtils;
|
||||||
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
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
|
* Add a single attachment part to the message
|
||||||
*
|
*
|
||||||
@ -203,40 +257,8 @@ public class LegacyConversions {
|
|||||||
public static void addOneAttachment(final Context context,
|
public static void addOneAttachment(final Context context,
|
||||||
final EmailContent.Message localMessage, final Part part)
|
final EmailContent.Message localMessage, final Part part)
|
||||||
throws MessagingException, IOException {
|
throws MessagingException, IOException {
|
||||||
// Transfer fields from mime format to provider format
|
final Attachment localAttachment = mimePartToAttachment(part);
|
||||||
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
|
|
||||||
localAttachment.mMessageKey = localMessage.mId;
|
localAttachment.mMessageKey = localMessage.mId;
|
||||||
localAttachment.mLocation = partId;
|
|
||||||
localAttachment.mEncoding = "B"; // TODO - convert other known encodings
|
|
||||||
localAttachment.mAccountKey = localMessage.mAccountKey;
|
localAttachment.mAccountKey = localMessage.mAccountKey;
|
||||||
|
|
||||||
if (DEBUG_ATTACHMENTS) {
|
if (DEBUG_ATTACHMENTS) {
|
||||||
@ -469,7 +491,8 @@ public class LegacyConversions {
|
|||||||
* @param contentId as referenced from cid: uris in the message body (if applicable)
|
* @param contentId as referenced from cid: uris in the message body (if applicable)
|
||||||
* @param content unencoded bytes
|
* @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 Long contentSize, final String filename, final String contentId,
|
||||||
final InputStream content) throws MessagingException {
|
final InputStream content) throws MessagingException {
|
||||||
final Base64Body body = new Base64Body(content);
|
final Base64Body body = new Base64Body(content);
|
||||||
|
@ -16,23 +16,41 @@
|
|||||||
|
|
||||||
package com.android.email;
|
package com.android.email;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
import android.test.AndroidTestCase;
|
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.MimeBodyPart;
|
||||||
import com.android.emailcommon.internet.MimeMessage;
|
import com.android.emailcommon.internet.MimeMessage;
|
||||||
|
import com.android.emailcommon.internet.MimeMultipart;
|
||||||
import com.android.emailcommon.mail.Address;
|
import com.android.emailcommon.mail.Address;
|
||||||
import com.android.emailcommon.mail.Message.RecipientType;
|
import com.android.emailcommon.mail.Message.RecipientType;
|
||||||
import com.android.emailcommon.mail.MessagingException;
|
import com.android.emailcommon.mail.MessagingException;
|
||||||
|
import com.android.emailcommon.mail.Multipart;
|
||||||
import com.android.emailcommon.mail.Part;
|
import com.android.emailcommon.mail.Part;
|
||||||
import com.android.emailcommon.provider.EmailContent;
|
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;
|
||||||
import com.android.emailcommon.utility.ConversionUtilities.BodyFieldData;
|
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.ArrayList;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
|
@SmallTest
|
||||||
public class LegacyConversionsTest extends AndroidTestCase {
|
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.
|
* 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);
|
final BodyFieldData data = ConversionUtilities.parseBodyFields(viewables);
|
||||||
assertNull(data.textContent);
|
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