Merge pull request #1553 from k9mail/message-builder-tests
MessageBuilder refactorings for tests
This commit is contained in:
commit
1cc7c499f9
29 changed files with 447 additions and 123 deletions
|
@ -221,7 +221,7 @@ public class PgpMimeMessageTest {
|
|||
InputStream messageInputStream = new ByteArrayInputStream(messageSource.getBytes());
|
||||
MimeMessage message;
|
||||
try {
|
||||
message = new MimeMessage(messageInputStream, true);
|
||||
message = MimeMessage.parseMimeMessage(messageInputStream, true);
|
||||
} finally {
|
||||
messageInputStream.close();
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@ import java.io.InputStream;
|
|||
|
||||
import android.support.test.InstrumentationRegistry;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
import android.test.AndroidTestCase;
|
||||
|
||||
import com.fsck.k9.mail.internet.BinaryTempFileBody;
|
||||
import com.fsck.k9.mail.internet.MimeMessage;
|
||||
|
@ -58,7 +57,7 @@ public class ReconstructMessageTest {
|
|||
InputStream messageInputStream = new ByteArrayInputStream(messageSource.getBytes());
|
||||
MimeMessage message;
|
||||
try {
|
||||
message = new MimeMessage(messageInputStream, true);
|
||||
message = MimeMessage.parseMimeMessage(messageInputStream, true);
|
||||
} finally {
|
||||
messageInputStream.close();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
package com.fsck.k9.mail;
|
||||
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.Random;
|
||||
|
||||
import android.support.annotation.VisibleForTesting;
|
||||
|
||||
|
||||
public class BoundaryGenerator {
|
||||
private static final BoundaryGenerator INSTANCE = new BoundaryGenerator(new Random());
|
||||
|
||||
|
||||
private final Random random;
|
||||
|
||||
|
||||
public static BoundaryGenerator getInstance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
BoundaryGenerator(Random random) {
|
||||
this.random = random;
|
||||
}
|
||||
|
||||
public String generateBoundary() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("----");
|
||||
for (int i = 0; i < 30; i++) {
|
||||
sb.append(Integer.toString(random.nextInt(36), 36));
|
||||
}
|
||||
return sb.toString().toUpperCase(Locale.US);
|
||||
}
|
||||
}
|
|
@ -39,7 +39,7 @@ public class BinaryTempFileMessageBody extends BinaryTempFileBody implements Com
|
|||
* could be sent along without processing. But since we
|
||||
* don't know, we recursively parse it.
|
||||
*/
|
||||
MimeMessage message = new MimeMessage(in, true);
|
||||
MimeMessage message = MimeMessage.parseMimeMessage(in, true);
|
||||
message.setUsing7bitTransport();
|
||||
message.writeTo(out);
|
||||
} else {
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
package com.fsck.k9.mail.internet;
|
||||
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.UUID;
|
||||
|
||||
import android.support.annotation.VisibleForTesting;
|
||||
|
||||
import com.fsck.k9.mail.Address;
|
||||
import com.fsck.k9.mail.Message;
|
||||
|
||||
|
||||
public class MessageIdGenerator {
|
||||
public static MessageIdGenerator getInstance() {
|
||||
return new MessageIdGenerator();
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
MessageIdGenerator() {
|
||||
}
|
||||
|
||||
public String generateMessageId(Message message) {
|
||||
String hostname = null;
|
||||
|
||||
Address[] from = message.getFrom();
|
||||
if (from != null && from.length >= 1) {
|
||||
hostname = from[0].getHostname();
|
||||
}
|
||||
|
||||
if (hostname == null) {
|
||||
Address[] replyTo = message.getReplyTo();
|
||||
if (replyTo != null && replyTo.length >= 1) {
|
||||
hostname = replyTo[0].getHostname();
|
||||
}
|
||||
}
|
||||
|
||||
if (hostname == null) {
|
||||
hostname = "email.android.com";
|
||||
}
|
||||
|
||||
String uuid = generateUuid();
|
||||
return "<" + uuid + "@" + hostname + ">";
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
protected String generateUuid() {
|
||||
// We use upper case here to match Apple Mail Message-ID format (for privacy)
|
||||
return UUID.randomUUID().toString().toUpperCase(Locale.US);
|
||||
}
|
||||
}
|
|
@ -14,7 +14,6 @@ import java.util.LinkedList;
|
|||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
import java.util.TimeZone;
|
||||
import java.util.UUID;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
|
@ -61,20 +60,14 @@ public class MimeMessage extends Message {
|
|||
protected int mSize;
|
||||
private String serverExtra;
|
||||
|
||||
public MimeMessage() {
|
||||
|
||||
public static MimeMessage parseMimeMessage(InputStream in, boolean recurse) throws IOException, MessagingException {
|
||||
MimeMessage mimeMessage = new MimeMessage();
|
||||
mimeMessage.parse(in, recurse);
|
||||
return mimeMessage;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parse the given InputStream using Apache Mime4J to build a MimeMessage.
|
||||
*
|
||||
* @param in
|
||||
* @param recurse A boolean indicating to recurse through all nested MimeMessage subparts.
|
||||
* @throws IOException
|
||||
* @throws MessagingException
|
||||
*/
|
||||
public MimeMessage(InputStream in, boolean recurse) throws IOException, MessagingException {
|
||||
parse(in, recurse);
|
||||
public MimeMessage() {
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -319,27 +312,6 @@ public class MimeMessage extends Message {
|
|||
return mMessageId;
|
||||
}
|
||||
|
||||
public void generateMessageId() throws MessagingException {
|
||||
String hostname = null;
|
||||
|
||||
if (mFrom != null && mFrom.length >= 1) {
|
||||
hostname = mFrom[0].getHostname();
|
||||
}
|
||||
|
||||
if (hostname == null && mReplyTo != null && mReplyTo.length >= 1) {
|
||||
hostname = mReplyTo[0].getHostname();
|
||||
}
|
||||
|
||||
if (hostname == null) {
|
||||
hostname = "email.android.com";
|
||||
}
|
||||
|
||||
/* We use upper case here to match Apple Mail Message-ID format (for privacy) */
|
||||
String messageId = "<" + UUID.randomUUID().toString().toUpperCase(Locale.US) + "@" + hostname + ">";
|
||||
|
||||
setMessageId(messageId);
|
||||
}
|
||||
|
||||
public void setMessageId(String messageId) {
|
||||
setHeader("Message-ID", messageId);
|
||||
mMessageId = messageId;
|
||||
|
@ -529,15 +501,11 @@ public class MimeMessage extends Message {
|
|||
expect(Part.class);
|
||||
|
||||
Part e = (Part)stack.peek();
|
||||
try {
|
||||
String mimeType = bd.getMimeType();
|
||||
String boundary = bd.getBoundary();
|
||||
MimeMultipart multiPart = new MimeMultipart(mimeType, boundary);
|
||||
e.setBody(multiPart);
|
||||
stack.addFirst(multiPart);
|
||||
} catch (MessagingException me) {
|
||||
throw new MimeException(me.getMessage(), me);
|
||||
}
|
||||
String mimeType = bd.getMimeType();
|
||||
String boundary = bd.getBoundary();
|
||||
MimeMultipart multiPart = new MimeMultipart(mimeType, boundary);
|
||||
e.setBody(multiPart);
|
||||
stack.addFirst(multiPart);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,26 +1,35 @@
|
|||
|
||||
package com.fsck.k9.mail.internet;
|
||||
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
|
||||
import com.fsck.k9.mail.BodyPart;
|
||||
import com.fsck.k9.mail.BoundaryGenerator;
|
||||
import com.fsck.k9.mail.MessagingException;
|
||||
import com.fsck.k9.mail.Multipart;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.Locale;
|
||||
import java.util.Random;
|
||||
|
||||
public class MimeMultipart extends Multipart {
|
||||
private String mimeType;
|
||||
private byte[] preamble;
|
||||
private byte[] epilogue;
|
||||
private final String boundary;
|
||||
|
||||
public MimeMultipart() throws MessagingException {
|
||||
boundary = generateBoundary();
|
||||
setSubType("mixed");
|
||||
|
||||
public static MimeMultipart newInstance() {
|
||||
String boundary = BoundaryGenerator.getInstance().generateBoundary();
|
||||
return new MimeMultipart(boundary);
|
||||
}
|
||||
|
||||
public MimeMultipart(String mimeType, String boundary) throws MessagingException {
|
||||
public MimeMultipart(String boundary) {
|
||||
this("multipart/mixed", boundary);
|
||||
}
|
||||
|
||||
public MimeMultipart(String mimeType, String boundary) {
|
||||
if (mimeType == null) {
|
||||
throw new IllegalArgumentException("mimeType can't be null");
|
||||
}
|
||||
|
@ -32,16 +41,6 @@ public class MimeMultipart extends Multipart {
|
|||
this.boundary = boundary;
|
||||
}
|
||||
|
||||
public static String generateBoundary() {
|
||||
Random random = new Random();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("----");
|
||||
for (int i = 0; i < 30; i++) {
|
||||
sb.append(Integer.toString(random.nextInt(36), 36));
|
||||
}
|
||||
return sb.toString().toUpperCase(Locale.US);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBoundary() {
|
||||
return boundary;
|
||||
|
|
|
@ -986,7 +986,7 @@ class ImapFolder extends Folder<ImapMessage> {
|
|||
/*
|
||||
* This is a multipart/*
|
||||
*/
|
||||
MimeMultipart mp = new MimeMultipart();
|
||||
MimeMultipart mp = MimeMultipart.newInstance();
|
||||
for (int i = 0, count = bs.size(); i < count; i++) {
|
||||
if (bs.get(i) instanceof ImapList) {
|
||||
/*
|
||||
|
|
|
@ -23,7 +23,6 @@ class ImapMessage extends MimeMessage {
|
|||
super.setFlag(flag, set);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setFlag(Flag flag, boolean set) throws MessagingException {
|
||||
super.setFlag(flag, set);
|
||||
|
|
|
@ -1184,7 +1184,7 @@ public class Pop3Store extends RemoteStore {
|
|||
}//Pop3Folder
|
||||
|
||||
static class Pop3Message extends MimeMessage {
|
||||
public Pop3Message(String uid, Pop3Folder folder) {
|
||||
Pop3Message(String uid, Pop3Folder folder) {
|
||||
mUid = uid;
|
||||
mFolder = folder;
|
||||
mSize = -1;
|
||||
|
|
|
@ -21,6 +21,7 @@ import static com.fsck.k9.mail.helper.UrlEncodingHelper.encodeUtf8;
|
|||
class WebDavMessage extends MimeMessage {
|
||||
private String mUrl = "";
|
||||
|
||||
|
||||
WebDavMessage(String uid, Folder folder) {
|
||||
this.mUid = uid;
|
||||
this.mFolder = folder;
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
package com.fsck.k9.mail;
|
||||
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.mockito.stubbing.OngoingStubbing;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
|
||||
public class BoundaryGeneratorTest {
|
||||
@Test
|
||||
public void generateBoundary_allZeros() throws Exception {
|
||||
Random random = createRandom(0);
|
||||
BoundaryGenerator boundaryGenerator = new BoundaryGenerator(random);
|
||||
|
||||
String result = boundaryGenerator.generateBoundary();
|
||||
|
||||
assertEquals("----000000000000000000000000000000", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void generateBoundary() throws Exception {
|
||||
Random random = createRandom(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
|
||||
23, 24, 25, 26, 27, 28, 35);
|
||||
BoundaryGenerator boundaryGenerator = new BoundaryGenerator(random);
|
||||
|
||||
String result = boundaryGenerator.generateBoundary();
|
||||
|
||||
assertEquals("----0123456789ABCDEFGHIJKLMNOPQRSZ", result);
|
||||
}
|
||||
|
||||
private Random createRandom(int... values) {
|
||||
Random random = mock(Random.class);
|
||||
|
||||
OngoingStubbing<Integer> ongoingStubbing = when(random.nextInt(36));
|
||||
for (int value : values) {
|
||||
ongoingStubbing = ongoingStubbing.thenReturn(value);
|
||||
}
|
||||
|
||||
return random;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
package com.fsck.k9.mail.internet;
|
||||
|
||||
|
||||
import com.fsck.k9.mail.Address;
|
||||
import com.fsck.k9.mail.Message;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@Config(manifest = Config.NONE, sdk = 21)
|
||||
public class MessageIdGeneratorTest {
|
||||
private MessageIdGenerator messageIdGenerator;
|
||||
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
messageIdGenerator = new MessageIdGenerator() {
|
||||
@Override
|
||||
protected String generateUuid() {
|
||||
return "00000000-0000-4000-0000-000000000000";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Test
|
||||
public void generateMessageId_withFromAndReplyToAddress() throws Exception {
|
||||
Message message = new MimeMessage();
|
||||
message.setFrom(new Address("alice@example.org"));
|
||||
message.setReplyTo(Address.parse("bob@example.com"));
|
||||
|
||||
String result = messageIdGenerator.generateMessageId(message);
|
||||
|
||||
assertEquals("<00000000-0000-4000-0000-000000000000@example.org>", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void generateMessageId_withReplyToAddress() throws Exception {
|
||||
Message message = new MimeMessage();
|
||||
message.setReplyTo(Address.parse("bob@example.com"));
|
||||
|
||||
String result = messageIdGenerator.generateMessageId(message);
|
||||
|
||||
assertEquals("<00000000-0000-4000-0000-000000000000@example.com>", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void generateMessageId_withoutRelevantHeaders() throws Exception {
|
||||
Message message = new MimeMessage();
|
||||
|
||||
String result = messageIdGenerator.generateMessageId(message);
|
||||
|
||||
assertEquals("<00000000-0000-4000-0000-000000000000@email.android.com>", result);
|
||||
}
|
||||
}
|
|
@ -210,11 +210,11 @@ public class MimeMessageParseTest {
|
|||
}
|
||||
|
||||
private static MimeMessage parseWithoutRecurse(InputStream data) throws Exception {
|
||||
return new MimeMessage(data, false);
|
||||
return MimeMessage.parseMimeMessage(data, false);
|
||||
}
|
||||
|
||||
private static MimeMessage parseWithRecurse(InputStream data) throws Exception {
|
||||
return new MimeMessage(data, true);
|
||||
return MimeMessage.parseMimeMessage(data, true);
|
||||
}
|
||||
|
||||
private static void checkAddresses(Address[] actual, String... expected) {
|
||||
|
|
|
@ -128,7 +128,7 @@ public class ReconstructMessageFromDatabaseTest extends ApplicationTestCase<K9>
|
|||
protected MimeMessage parseMessage() throws IOException, MessagingException {
|
||||
InputStream messageInputStream = new ByteArrayInputStream(MESSAGE_SOURCE.getBytes());
|
||||
try {
|
||||
return new MimeMessage(messageInputStream, true);
|
||||
return MimeMessage.parseMimeMessage(messageInputStream, true);
|
||||
} finally {
|
||||
messageInputStream.close();
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.fsck.k9.activity;
|
||||
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
@ -716,14 +717,16 @@ public class MessageCompose extends K9Activity implements OnClickListener,
|
|||
return null;
|
||||
}
|
||||
|
||||
PgpMessageBuilder pgpBuilder = new PgpMessageBuilder(getApplicationContext());
|
||||
PgpMessageBuilder pgpBuilder = PgpMessageBuilder.newInstance();
|
||||
recipientPresenter.builderSetProperties(pgpBuilder);
|
||||
builder = pgpBuilder;
|
||||
} else {
|
||||
builder = new SimpleMessageBuilder(getApplicationContext());
|
||||
builder = SimpleMessageBuilder.newInstance();
|
||||
}
|
||||
|
||||
builder.setSubject(mSubjectView.getText().toString())
|
||||
.setSentDate(new Date())
|
||||
.setHideTimeZone(K9.hideTimeZone())
|
||||
.setTo(recipientPresenter.getToAddresses())
|
||||
.setCc(recipientPresenter.getCcAddresses())
|
||||
.setBcc(recipientPresenter.getBccAddresses())
|
||||
|
|
|
@ -22,11 +22,9 @@ import com.fsck.k9.Account;
|
|||
import com.fsck.k9.Identity;
|
||||
import com.fsck.k9.K9;
|
||||
import com.fsck.k9.R;
|
||||
import com.fsck.k9.activity.MessageCompose;
|
||||
import com.fsck.k9.activity.compose.ComposeCryptoStatus.AttachErrorState;
|
||||
import com.fsck.k9.activity.compose.ComposeCryptoStatus.ComposeCryptoStatusBuilder;
|
||||
import com.fsck.k9.activity.compose.ComposeCryptoStatus.SendErrorState;
|
||||
import com.fsck.k9.activity.misc.Attachment;
|
||||
import com.fsck.k9.helper.Contacts;
|
||||
import com.fsck.k9.helper.MailTo;
|
||||
import com.fsck.k9.helper.ReplyToParser;
|
||||
|
@ -35,7 +33,6 @@ import com.fsck.k9.mail.Address;
|
|||
import com.fsck.k9.mail.Flag;
|
||||
import com.fsck.k9.mail.Message;
|
||||
import com.fsck.k9.mail.Message.RecipientType;
|
||||
import com.fsck.k9.mailstore.LocalMessage;
|
||||
import com.fsck.k9.message.ComposePgpInlineDecider;
|
||||
import com.fsck.k9.message.PgpMessageBuilder;
|
||||
import com.fsck.k9.view.RecipientSelectView.Recipient;
|
||||
|
|
|
@ -21,7 +21,7 @@ class AttachmentMessageBodyUtil {
|
|||
* could be sent along without processing. But since we
|
||||
* don't know, we recursively parse it.
|
||||
*/
|
||||
MimeMessage message = new MimeMessage(in, true);
|
||||
MimeMessage message = MimeMessage.parseMimeMessage(in, true);
|
||||
message.setUsing7bitTransport();
|
||||
message.writeTo(out);
|
||||
} else {
|
||||
|
|
|
@ -36,6 +36,7 @@ import com.fsck.k9.helper.Utility;
|
|||
import com.fsck.k9.mail.Address;
|
||||
import com.fsck.k9.mail.Body;
|
||||
import com.fsck.k9.mail.BodyPart;
|
||||
import com.fsck.k9.mail.BoundaryGenerator;
|
||||
import com.fsck.k9.mail.FetchProfile;
|
||||
import com.fsck.k9.mail.Flag;
|
||||
import com.fsck.k9.mail.Folder;
|
||||
|
@ -1416,7 +1417,7 @@ public class LocalFolder extends Folder<LocalMessage> implements Serializable {
|
|||
cv.put("decoded_body_size", attachment.size);
|
||||
|
||||
if (MimeUtility.isMultipart(part.getMimeType())) {
|
||||
cv.put("boundary", MimeMultipart.generateBoundary());
|
||||
cv.put("boundary", BoundaryGenerator.getInstance().generateBoundary());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@ public class LocalMessage extends MimeMessage {
|
|||
private String mimeType;
|
||||
private PreviewType previewType;
|
||||
|
||||
|
||||
private LocalMessage(LocalStore localStore) {
|
||||
this.localStore = localStore;
|
||||
}
|
||||
|
@ -50,6 +51,7 @@ public class LocalMessage extends MimeMessage {
|
|||
this.mFolder = folder;
|
||||
}
|
||||
|
||||
|
||||
void populateFromGetMessageCursor(Cursor cursor) throws MessagingException {
|
||||
final String subject = cursor.getString(0);
|
||||
this.setSubject(subject == null ? "" : subject);
|
||||
|
@ -496,7 +498,7 @@ public class LocalMessage extends MimeMessage {
|
|||
|
||||
@Override
|
||||
public LocalMessage clone() {
|
||||
LocalMessage message = new LocalMessage(this.localStore);
|
||||
LocalMessage message = new LocalMessage(localStore);
|
||||
super.copy(message);
|
||||
|
||||
message.mId = mId;
|
||||
|
|
|
@ -144,17 +144,14 @@ public class MimePartStreamParser {
|
|||
@Override
|
||||
public void startMultipart(BodyDescriptor bd) throws MimeException {
|
||||
Part part = (Part) stack.peek();
|
||||
try {
|
||||
String mimeType = bd.getMimeType();
|
||||
String boundary = bd.getBoundary();
|
||||
|
||||
MimeMultipart multipart = new MimeMultipart(mimeType, boundary);
|
||||
part.setBody(multipart);
|
||||
String mimeType = bd.getMimeType();
|
||||
String boundary = bd.getBoundary();
|
||||
|
||||
stack.push(multipart);
|
||||
} catch (MessagingException e) {
|
||||
throw new MimeException(e);
|
||||
}
|
||||
MimeMultipart multipart = new MimeMultipart(mimeType, boundary);
|
||||
part.setBody(multipart);
|
||||
|
||||
stack.push(multipart);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -20,9 +20,11 @@ import com.fsck.k9.activity.MessageReference;
|
|||
import com.fsck.k9.activity.misc.Attachment;
|
||||
import com.fsck.k9.mail.Address;
|
||||
import com.fsck.k9.mail.Body;
|
||||
import com.fsck.k9.mail.BoundaryGenerator;
|
||||
import com.fsck.k9.mail.Flag;
|
||||
import com.fsck.k9.mail.Message.RecipientType;
|
||||
import com.fsck.k9.mail.MessagingException;
|
||||
import com.fsck.k9.mail.internet.MessageIdGenerator;
|
||||
import com.fsck.k9.mail.internet.MimeBodyPart;
|
||||
import com.fsck.k9.mail.internet.MimeHeader;
|
||||
import com.fsck.k9.mail.internet.MimeMessage;
|
||||
|
@ -38,8 +40,13 @@ import org.apache.james.mime4j.util.MimeUtil;
|
|||
|
||||
public abstract class MessageBuilder {
|
||||
private final Context context;
|
||||
private final MessageIdGenerator messageIdGenerator;
|
||||
private final BoundaryGenerator boundaryGenerator;
|
||||
|
||||
|
||||
private String subject;
|
||||
private Date sentDate;
|
||||
private boolean hideTimeZone;
|
||||
private Address[] to;
|
||||
private Address[] cc;
|
||||
private Address[] bcc;
|
||||
|
@ -64,8 +71,10 @@ public abstract class MessageBuilder {
|
|||
private boolean isDraft;
|
||||
private boolean isPgpInlineEnabled;
|
||||
|
||||
public MessageBuilder(Context context) {
|
||||
protected MessageBuilder(Context context, MessageIdGenerator messageIdGenerator, BoundaryGenerator boundaryGenerator) {
|
||||
this.context = context;
|
||||
this.messageIdGenerator = messageIdGenerator;
|
||||
this.boundaryGenerator = boundaryGenerator;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -84,7 +93,7 @@ public abstract class MessageBuilder {
|
|||
}
|
||||
|
||||
private void buildHeader(MimeMessage message) throws MessagingException {
|
||||
message.addSentDate(new Date(), K9.hideTimeZone());
|
||||
message.addSentDate(sentDate, hideTimeZone);
|
||||
Address from = new Address(identity.getEmail(), identity.getName());
|
||||
message.setFrom(from);
|
||||
message.setRecipients(RecipientType.TO, to);
|
||||
|
@ -115,12 +124,18 @@ public abstract class MessageBuilder {
|
|||
message.setReferences(references);
|
||||
}
|
||||
|
||||
message.generateMessageId();
|
||||
String messageId = messageIdGenerator.generateMessageId(message);
|
||||
message.setMessageId(messageId);
|
||||
|
||||
if (isDraft && isPgpInlineEnabled) {
|
||||
message.setFlag(Flag.X_DRAFT_OPENPGP_INLINE, true);
|
||||
}
|
||||
}
|
||||
|
||||
protected MimeMultipart createMimeMultipart() {
|
||||
String boundary = boundaryGenerator.generateBoundary();
|
||||
return new MimeMultipart(boundary);
|
||||
}
|
||||
|
||||
private void buildBody(MimeMessage message) throws MessagingException {
|
||||
// Build the body.
|
||||
|
@ -137,7 +152,7 @@ public abstract class MessageBuilder {
|
|||
// HTML message (with alternative text part)
|
||||
|
||||
// This is the compiled MIME part for an HTML message.
|
||||
MimeMultipart composedMimeMessage = new MimeMultipart();
|
||||
MimeMultipart composedMimeMessage = createMimeMultipart();
|
||||
composedMimeMessage.setSubType("alternative"); // Let the receiver select either the text or the HTML part.
|
||||
composedMimeMessage.addBodyPart(new MimeBodyPart(body, "text/html"));
|
||||
bodyPlain = buildText(isDraft, SimpleMessageFormat.TEXT);
|
||||
|
@ -148,7 +163,7 @@ public abstract class MessageBuilder {
|
|||
// whole message (mp here), of which one part is a MimeMultipart container
|
||||
// (composedMimeMessage) with the user's composed messages, and subsequent parts for
|
||||
// the attachments.
|
||||
MimeMultipart mp = new MimeMultipart();
|
||||
MimeMultipart mp = createMimeMultipart();
|
||||
mp.addBodyPart(new MimeBodyPart(composedMimeMessage));
|
||||
addAttachmentsToMessage(mp);
|
||||
MimeMessageHelper.setBody(message, mp);
|
||||
|
@ -159,7 +174,7 @@ public abstract class MessageBuilder {
|
|||
} else if (messageFormat == SimpleMessageFormat.TEXT) {
|
||||
// Text-only message.
|
||||
if (hasAttachments) {
|
||||
MimeMultipart mp = new MimeMultipart();
|
||||
MimeMultipart mp = createMimeMultipart();
|
||||
mp.addBodyPart(new MimeBodyPart(body, "text/plain"));
|
||||
addAttachmentsToMessage(mp);
|
||||
MimeMessageHelper.setBody(message, mp);
|
||||
|
@ -331,6 +346,16 @@ public abstract class MessageBuilder {
|
|||
return this;
|
||||
}
|
||||
|
||||
public MessageBuilder setSentDate(Date sentDate) {
|
||||
this.sentDate = sentDate;
|
||||
return this;
|
||||
}
|
||||
|
||||
public MessageBuilder setHideTimeZone(boolean hideTimeZone) {
|
||||
this.hideTimeZone = hideTimeZone;
|
||||
return this;
|
||||
}
|
||||
|
||||
public MessageBuilder setTo(List<Address> to) {
|
||||
this.to = to.toArray(new Address[to.size()]);
|
||||
return this;
|
||||
|
|
|
@ -10,14 +10,18 @@ import android.content.Context;
|
|||
import android.content.Intent;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.VisibleForTesting;
|
||||
import android.util.Log;
|
||||
|
||||
import com.fsck.k9.Globals;
|
||||
import com.fsck.k9.K9;
|
||||
import com.fsck.k9.activity.compose.ComposeCryptoStatus;
|
||||
import com.fsck.k9.mail.Body;
|
||||
import com.fsck.k9.mail.BodyPart;
|
||||
import com.fsck.k9.mail.BoundaryGenerator;
|
||||
import com.fsck.k9.mail.MessagingException;
|
||||
import com.fsck.k9.mail.internet.BinaryTempFileBody;
|
||||
import com.fsck.k9.mail.internet.MessageIdGenerator;
|
||||
import com.fsck.k9.mail.internet.MimeBodyPart;
|
||||
import com.fsck.k9.mail.internet.MimeHeader;
|
||||
import com.fsck.k9.mail.internet.MimeMessage;
|
||||
|
@ -44,10 +48,20 @@ public class PgpMessageBuilder extends MessageBuilder {
|
|||
private boolean opportunisticSkipEncryption;
|
||||
private boolean opportunisticSecondPass;
|
||||
|
||||
public PgpMessageBuilder(Context context) {
|
||||
super(context);
|
||||
|
||||
public static PgpMessageBuilder newInstance() {
|
||||
Context context = Globals.getContext();
|
||||
MessageIdGenerator messageIdGenerator = MessageIdGenerator.getInstance();
|
||||
BoundaryGenerator boundaryGenerator = BoundaryGenerator.getInstance();
|
||||
return new PgpMessageBuilder(context, messageIdGenerator, boundaryGenerator);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
PgpMessageBuilder(Context context, MessageIdGenerator messageIdGenerator, BoundaryGenerator boundaryGenerator) {
|
||||
super(context, messageIdGenerator, boundaryGenerator);
|
||||
}
|
||||
|
||||
|
||||
public void setOpenPgpApi(OpenPgpApi openPgpApi) {
|
||||
this.openPgpApi = openPgpApi;
|
||||
}
|
||||
|
@ -269,7 +283,7 @@ public class PgpMessageBuilder extends MessageBuilder {
|
|||
throw new MessagingException("didn't find expected RESULT_DETACHED_SIGNATURE in api call result");
|
||||
}
|
||||
|
||||
MimeMultipart multipartSigned = new MimeMultipart();
|
||||
MimeMultipart multipartSigned = createMimeMultipart();
|
||||
multipartSigned.setSubType("signed");
|
||||
multipartSigned.addBodyPart(signedBodyPart);
|
||||
multipartSigned.addBodyPart(
|
||||
|
@ -293,7 +307,7 @@ public class PgpMessageBuilder extends MessageBuilder {
|
|||
throw new IllegalStateException("call to mimeBuildEncryptedMessage while encryption isn't enabled!");
|
||||
}
|
||||
|
||||
MimeMultipart multipartEncrypted = new MimeMultipart();
|
||||
MimeMultipart multipartEncrypted = createMimeMultipart();
|
||||
multipartEncrypted.setSubType("encrypted");
|
||||
multipartEncrypted.addBodyPart(new MimeBodyPart(new TextBody("Version: 1"), "application/pgp-encrypted"));
|
||||
multipartEncrypted.addBodyPart(new MimeBodyPart(encryptedBodyPart, "application/octet-stream"));
|
||||
|
@ -327,5 +341,4 @@ public class PgpMessageBuilder extends MessageBuilder {
|
|||
public void setCryptoStatus(ComposeCryptoStatus cryptoStatus) {
|
||||
this.cryptoStatus = cryptoStatus;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3,16 +3,27 @@ package com.fsck.k9.message;
|
|||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.AsyncTask;
|
||||
import android.support.annotation.VisibleForTesting;
|
||||
|
||||
import com.fsck.k9.Globals;
|
||||
import com.fsck.k9.mail.BoundaryGenerator;
|
||||
import com.fsck.k9.mail.MessagingException;
|
||||
import com.fsck.k9.mail.internet.MessageIdGenerator;
|
||||
import com.fsck.k9.mail.internet.MimeMessage;
|
||||
|
||||
|
||||
public class SimpleMessageBuilder extends MessageBuilder {
|
||||
|
||||
public SimpleMessageBuilder(Context context) {
|
||||
super(context);
|
||||
public static SimpleMessageBuilder newInstance() {
|
||||
Context context = Globals.getContext();
|
||||
MessageIdGenerator messageIdGenerator = MessageIdGenerator.getInstance();
|
||||
BoundaryGenerator boundaryGenerator = BoundaryGenerator.getInstance();
|
||||
return new SimpleMessageBuilder(context, messageIdGenerator, boundaryGenerator);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
SimpleMessageBuilder(Context context, MessageIdGenerator messageIdGenerator, BoundaryGenerator boundaryGenerator) {
|
||||
super(context, messageIdGenerator, boundaryGenerator);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -55,7 +55,7 @@ public class MessageDecryptVerifierTest {
|
|||
@Test
|
||||
public void findEncryptedPartsShouldReturnEmptyEncryptedPart() throws Exception {
|
||||
MimeMessage message = new MimeMessage();
|
||||
MimeMultipart multipartEncrypted = new MimeMultipart();
|
||||
MimeMultipart multipartEncrypted = MimeMultipart.newInstance();
|
||||
multipartEncrypted.setSubType("encrypted");
|
||||
MimeMessageHelper.setBody(message, multipartEncrypted);
|
||||
setContentTypeWithProtocol(message, MIME_TYPE_MULTIPART_ENCRYPTED, PROTCOL_PGP_ENCRYPTED);
|
||||
|
@ -69,11 +69,11 @@ public class MessageDecryptVerifierTest {
|
|||
@Test
|
||||
public void findEncryptedPartsShouldReturnMultipleEncryptedParts() throws Exception {
|
||||
MimeMessage message = new MimeMessage();
|
||||
MimeMultipart multipartMixed = new MimeMultipart();
|
||||
MimeMultipart multipartMixed = MimeMultipart.newInstance();
|
||||
multipartMixed.setSubType("mixed");
|
||||
MimeMessageHelper.setBody(message, multipartMixed);
|
||||
|
||||
MimeMultipart multipartEncryptedOne = new MimeMultipart();
|
||||
MimeMultipart multipartEncryptedOne = MimeMultipart.newInstance();
|
||||
multipartEncryptedOne.setSubType("encrypted");
|
||||
MimeBodyPart bodyPartOne = new MimeBodyPart(multipartEncryptedOne);
|
||||
setContentTypeWithProtocol(bodyPartOne, MIME_TYPE_MULTIPART_ENCRYPTED, PROTCOL_PGP_ENCRYPTED);
|
||||
|
@ -82,7 +82,7 @@ public class MessageDecryptVerifierTest {
|
|||
MimeBodyPart bodyPartTwo = new MimeBodyPart(null, "text/plain");
|
||||
multipartMixed.addBodyPart(bodyPartTwo);
|
||||
|
||||
MimeMultipart multipartEncryptedThree = new MimeMultipart();
|
||||
MimeMultipart multipartEncryptedThree = MimeMultipart.newInstance();
|
||||
multipartEncryptedThree.setSubType("encrypted");
|
||||
MimeBodyPart bodyPartThree = new MimeBodyPart(multipartEncryptedThree);
|
||||
setContentTypeWithProtocol(bodyPartThree, MIME_TYPE_MULTIPART_ENCRYPTED, PROTCOL_PGP_ENCRYPTED);
|
||||
|
@ -279,7 +279,7 @@ public class MessageDecryptVerifierTest {
|
|||
}
|
||||
|
||||
MimeBodyPart multipart(String type, BodyPart... subParts) throws MessagingException {
|
||||
MimeMultipart multiPart = new MimeMultipart();
|
||||
MimeMultipart multiPart = MimeMultipart.newInstance();
|
||||
multiPart.setSubType(type);
|
||||
for (BodyPart subPart : subParts) {
|
||||
multiPart.addBodyPart(subPart);
|
||||
|
|
|
@ -52,7 +52,7 @@ public class AttachmentResolverTest {
|
|||
|
||||
@Test
|
||||
public void buildCidMap__onMultipartWithNoParts__shouldReturnEmptyMap() throws Exception {
|
||||
Multipart multipartBody = new MimeMultipart();
|
||||
Multipart multipartBody = MimeMultipart.newInstance();
|
||||
Part multipartPart = new MimeBodyPart(multipartBody);
|
||||
|
||||
Map<String,Uri> result = AttachmentResolver.buildCidToAttachmentUriMap(attachmentInfoExtractor, multipartPart);
|
||||
|
@ -62,7 +62,7 @@ public class AttachmentResolverTest {
|
|||
|
||||
@Test
|
||||
public void buildCidMap__onMultipartWithEmptyBodyPart__shouldReturnEmptyMap() throws Exception {
|
||||
Multipart multipartBody = new MimeMultipart();
|
||||
Multipart multipartBody = MimeMultipart.newInstance();
|
||||
BodyPart bodyPart = spy(new MimeBodyPart());
|
||||
Part multipartPart = new MimeBodyPart(multipartBody);
|
||||
multipartBody.addBodyPart(bodyPart);
|
||||
|
@ -75,7 +75,7 @@ public class AttachmentResolverTest {
|
|||
|
||||
@Test
|
||||
public void buildCidMap__onTwoPart__shouldReturnBothUris() throws Exception {
|
||||
Multipart multipartBody = new MimeMultipart();
|
||||
Multipart multipartBody = MimeMultipart.newInstance();
|
||||
Part multipartPart = new MimeBodyPart(multipartBody);
|
||||
|
||||
BodyPart subPart1 = new MimeBodyPart();
|
||||
|
|
|
@ -151,7 +151,7 @@ public class MessageViewInfoExtractorTest {
|
|||
TextBody body2 = new TextBody(bodyText2);
|
||||
|
||||
// Create multipart/mixed part
|
||||
MimeMultipart multipart = new MimeMultipart();
|
||||
MimeMultipart multipart = MimeMultipart.newInstance();
|
||||
MimeBodyPart bodyPart1 = new MimeBodyPart(body1, "text/plain");
|
||||
MimeBodyPart bodyPart2 = new MimeBodyPart(body2, "text/plain");
|
||||
multipart.addBodyPart(bodyPart1);
|
||||
|
@ -209,7 +209,7 @@ public class MessageViewInfoExtractorTest {
|
|||
MimeMessageHelper.setBody(innerMessage, innerBody);
|
||||
|
||||
// Create multipart/mixed part
|
||||
MimeMultipart multipart = new MimeMultipart();
|
||||
MimeMultipart multipart = MimeMultipart.newInstance();
|
||||
MimeBodyPart bodyPart1 = new MimeBodyPart(textBody, "text/plain");
|
||||
MimeBodyPart bodyPart2 = new MimeBodyPart(innerMessage, "message/rfc822");
|
||||
bodyPart2.setHeader("Content-Disposition", "inline; filename=\"message.eml\"");
|
||||
|
|
|
@ -2,20 +2,30 @@ package com.fsck.k9.message;
|
|||
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
|
||||
import android.app.Application;
|
||||
|
||||
import com.fsck.k9.Account.QuoteStyle;
|
||||
import com.fsck.k9.Identity;
|
||||
import com.fsck.k9.activity.misc.Attachment;
|
||||
import com.fsck.k9.mail.Address;
|
||||
import com.fsck.k9.mail.Body;
|
||||
import com.fsck.k9.mail.BoundaryGenerator;
|
||||
import com.fsck.k9.mail.Message;
|
||||
import com.fsck.k9.mail.Message.RecipientType;
|
||||
import com.fsck.k9.mail.MessagingException;
|
||||
import com.fsck.k9.mail.internet.MessageIdGenerator;
|
||||
import com.fsck.k9.mail.internet.MimeMessage;
|
||||
import com.fsck.k9.message.MessageBuilder.Callback;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
|
@ -32,12 +42,14 @@ import static org.mockito.Matchers.eq;
|
|||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@Config(manifest = "src/main/AndroidManifest.xml", sdk = 21)
|
||||
public class MessageBuilderTest {
|
||||
public static final String TEST_MESSAGE_TEXT = "message text";
|
||||
public static final String TEST_MESSAGE_TEXT = "soviet message\r\ntext ☭";
|
||||
public static final String TEST_ATTACHMENT_TEXT = "text data in attachment";
|
||||
public static final String TEST_SUBJECT = "test_subject";
|
||||
public static final Address TEST_IDENTITY_ADDRESS = new Address("test@example.org", "tester");
|
||||
public static final Address[] TEST_TO = new Address[] {
|
||||
|
@ -46,9 +58,72 @@ public class MessageBuilderTest {
|
|||
public static final Address[] TEST_CC = new Address[] { new Address("cc@example.org", "cc recip") };
|
||||
public static final Address[] TEST_BCC = new Address[] { new Address("bcc@example.org", "bcc recip") };
|
||||
|
||||
public static final String TEST_MESSAGE_ID = "<00000000-0000-007B-0000-0000000000EA@example.org>";
|
||||
public static final String BOUNDARY_1 = "----boundary1";
|
||||
public static final String BOUNDARY_2 = "----boundary2";
|
||||
public static final String BOUNDARY_3 = "----boundary3";
|
||||
|
||||
public static final Date SENT_DATE = new Date(10000000000L);
|
||||
public static final String MESSAGE_HEADERS =
|
||||
"Date: Sun, 26 Apr 1970 18:46:40 +0100\r\n" +
|
||||
"From: tester <test@example.org>\r\n" +
|
||||
"To: recip 1 <to1@example.org>,recip 2 <to2@example.org>\r\n" +
|
||||
"CC: cc recip <cc@example.org>\r\n" +
|
||||
"BCC: bcc recip <bcc@example.org>\r\n" +
|
||||
"Subject: test_subject\r\n" +
|
||||
"User-Agent: K-9 Mail for Android\r\n" +
|
||||
"In-Reply-To: inreplyto\r\n" +
|
||||
"References: references\r\n" +
|
||||
"Message-ID: " + TEST_MESSAGE_ID + "\r\n" +
|
||||
"MIME-Version: 1.0\r\n";
|
||||
public static final String MESSAGE_CONTENT =
|
||||
"Content-Type: text/plain;\r\n" +
|
||||
" charset=utf-8\r\n" +
|
||||
"Content-Transfer-Encoding: 8bit\r\n" +
|
||||
"\r\n" +
|
||||
"soviet message\r\n" +
|
||||
"text ☭";
|
||||
public static final String MESSAGE_CONTENT_WITH_ATTACH =
|
||||
"Content-Type: multipart/mixed; boundary=\"" + BOUNDARY_1 + "\"\r\n" +
|
||||
"Content-Transfer-Encoding: 8bit\r\n" +
|
||||
"\r\n" +
|
||||
"--" + BOUNDARY_1 + "\r\n" +
|
||||
"Content-Type: text/plain;\r\n" +
|
||||
" charset=utf-8\r\n" +
|
||||
"Content-Transfer-Encoding: 8bit\r\n" +
|
||||
"\r\n" +
|
||||
"soviet message\r\n" +
|
||||
"text ☭\r\n" +
|
||||
"--" + BOUNDARY_1 + "\r\n" +
|
||||
"Content-Type: text/plain;\r\n" +
|
||||
" name=\"attach.txt\"\r\n" +
|
||||
"Content-Transfer-Encoding: base64\r\n" +
|
||||
"Content-Disposition: attachment;\r\n" +
|
||||
" filename=\"attach.txt\";\r\n" +
|
||||
" size=23\r\n" +
|
||||
"\r\n" +
|
||||
"dGV4dCBkYXRhIGluIGF0dGFjaG1lbnQ=\r\n" +
|
||||
"\r\n" +
|
||||
"--" + BOUNDARY_1 + "--\r\n";
|
||||
|
||||
|
||||
private Application context;
|
||||
private MessageIdGenerator messageIdGenerator;
|
||||
private BoundaryGenerator boundaryGenerator;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
messageIdGenerator = mock(MessageIdGenerator.class);
|
||||
when(messageIdGenerator.generateMessageId(any(Message.class))).thenReturn(TEST_MESSAGE_ID);
|
||||
|
||||
boundaryGenerator = mock(BoundaryGenerator.class);
|
||||
when(boundaryGenerator.generateBoundary()).thenReturn(BOUNDARY_1, BOUNDARY_2, BOUNDARY_3);
|
||||
|
||||
context = RuntimeEnvironment.application;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void build__shouldSucceed() throws MessagingException {
|
||||
public void build__shouldSucceed() throws Exception {
|
||||
MessageBuilder messageBuilder = createSimpleMessageBuilder();
|
||||
|
||||
|
||||
|
@ -68,6 +143,43 @@ public class MessageBuilderTest {
|
|||
assertArrayEquals(TEST_TO, mimeMessage.getRecipients(RecipientType.TO));
|
||||
assertArrayEquals(TEST_CC, mimeMessage.getRecipients(RecipientType.CC));
|
||||
assertArrayEquals(TEST_BCC, mimeMessage.getRecipients(RecipientType.BCC));
|
||||
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
mimeMessage.writeTo(bos);
|
||||
assertEquals(MESSAGE_HEADERS + MESSAGE_CONTENT, bos.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void build__withAttachment__shouldSucceed() throws Exception {
|
||||
MessageBuilder messageBuilder = createSimpleMessageBuilder();
|
||||
Attachment attachment = createAttachmentWithContent("text/plain", "attach.txt", TEST_ATTACHMENT_TEXT.getBytes());
|
||||
messageBuilder.setAttachments(Collections.singletonList(attachment));
|
||||
|
||||
Callback mockCallback = mock(Callback.class);
|
||||
messageBuilder.buildAsync(mockCallback);
|
||||
|
||||
|
||||
ArgumentCaptor<MimeMessage> mimeMessageCaptor = ArgumentCaptor.forClass(MimeMessage.class);
|
||||
verify(mockCallback).onMessageBuildSuccess(mimeMessageCaptor.capture(), eq(false));
|
||||
verifyNoMoreInteractions(mockCallback);
|
||||
|
||||
MimeMessage mimeMessage = mimeMessageCaptor.getValue();
|
||||
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
mimeMessage.writeTo(bos);
|
||||
assertEquals(MESSAGE_HEADERS + MESSAGE_CONTENT_WITH_ATTACH, bos.toString());
|
||||
}
|
||||
|
||||
private Attachment createAttachmentWithContent(String mimeType, String filename, byte[] content) throws Exception {
|
||||
File tempFile = File.createTempFile("pre", ".tmp");
|
||||
tempFile.deleteOnExit();
|
||||
FileOutputStream fileOutputStream = new FileOutputStream(tempFile);
|
||||
fileOutputStream.write(content);
|
||||
fileOutputStream.close();
|
||||
|
||||
return Attachment.createAttachment(null, 0, mimeType)
|
||||
.deriveWithMetadataLoaded(mimeType, filename, content.length)
|
||||
.deriveWithLoadComplete(tempFile.getAbsolutePath());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -93,7 +205,7 @@ public class MessageBuilderTest {
|
|||
|
||||
@Test
|
||||
public void buildWithException__shouldThrow() throws MessagingException {
|
||||
MessageBuilder messageBuilder = new SimpleMessageBuilder(RuntimeEnvironment.application) {
|
||||
MessageBuilder messageBuilder = new SimpleMessageBuilder(context, messageIdGenerator, boundaryGenerator) {
|
||||
@Override
|
||||
protected void buildMessageInternal() {
|
||||
queueMessageBuildException(new MessagingException("expected error"));
|
||||
|
@ -109,7 +221,7 @@ public class MessageBuilderTest {
|
|||
|
||||
@Test
|
||||
public void buildWithException__detachAndReattach__shouldThrow() throws MessagingException {
|
||||
MessageBuilder messageBuilder = new SimpleMessageBuilder(RuntimeEnvironment.application) {
|
||||
MessageBuilder messageBuilder = new SimpleMessageBuilder(context, messageIdGenerator, boundaryGenerator) {
|
||||
@Override
|
||||
protected void buildMessageInternal() {
|
||||
queueMessageBuildException(new MessagingException("expected error"));
|
||||
|
@ -133,8 +245,8 @@ public class MessageBuilderTest {
|
|||
verifyNoMoreInteractions(mockCallback);
|
||||
}
|
||||
|
||||
private static MessageBuilder createSimpleMessageBuilder() {
|
||||
MessageBuilder b = new SimpleMessageBuilder(RuntimeEnvironment.application);
|
||||
private MessageBuilder createSimpleMessageBuilder() {
|
||||
MessageBuilder b = new SimpleMessageBuilder(context, messageIdGenerator, boundaryGenerator);
|
||||
|
||||
Identity identity = new Identity();
|
||||
identity.setName(TEST_IDENTITY_ADDRESS.getPersonal());
|
||||
|
@ -143,6 +255,8 @@ public class MessageBuilderTest {
|
|||
identity.setSignatureUse(false);
|
||||
|
||||
b.setSubject(TEST_SUBJECT)
|
||||
.setSentDate(SENT_DATE)
|
||||
.setHideTimeZone(false)
|
||||
.setTo(Arrays.asList(TEST_TO))
|
||||
.setCc(Arrays.asList(TEST_CC))
|
||||
.setBcc(Arrays.asList(TEST_BCC))
|
||||
|
|
|
@ -8,6 +8,7 @@ import java.io.OutputStream;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.PendingIntent;
|
||||
|
@ -23,8 +24,10 @@ import com.fsck.k9.activity.compose.RecipientPresenter.CryptoProviderState;
|
|||
import com.fsck.k9.activity.misc.Attachment;
|
||||
import com.fsck.k9.mail.Address;
|
||||
import com.fsck.k9.mail.BodyPart;
|
||||
import com.fsck.k9.mail.BoundaryGenerator;
|
||||
import com.fsck.k9.mail.MessagingException;
|
||||
import com.fsck.k9.mail.internet.BinaryTempFileBody;
|
||||
import com.fsck.k9.mail.internet.MessageIdGenerator;
|
||||
import com.fsck.k9.mail.internet.MimeMessage;
|
||||
import com.fsck.k9.mail.internet.MimeMultipart;
|
||||
import com.fsck.k9.mail.internet.MimeUtility;
|
||||
|
@ -413,8 +416,9 @@ public class PgpMessageBuilderTest {
|
|||
}
|
||||
|
||||
private static PgpMessageBuilder createDefaultPgpMessageBuilder(OpenPgpApi openPgpApi) {
|
||||
PgpMessageBuilder b = new PgpMessageBuilder(RuntimeEnvironment.application);
|
||||
b.setOpenPgpApi(openPgpApi);
|
||||
PgpMessageBuilder builder = new PgpMessageBuilder(
|
||||
RuntimeEnvironment.application, MessageIdGenerator.getInstance(), BoundaryGenerator.getInstance());
|
||||
builder.setOpenPgpApi(openPgpApi);
|
||||
|
||||
Identity identity = new Identity();
|
||||
identity.setName("tester");
|
||||
|
@ -422,7 +426,9 @@ public class PgpMessageBuilderTest {
|
|||
identity.setDescription("test identity");
|
||||
identity.setSignatureUse(false);
|
||||
|
||||
b.setSubject("subject")
|
||||
builder.setSubject("subject")
|
||||
.setSentDate(new Date())
|
||||
.setHideTimeZone(false)
|
||||
.setTo(new ArrayList<Address>())
|
||||
.setCc(new ArrayList<Address>())
|
||||
.setBcc(new ArrayList<Address>())
|
||||
|
@ -446,7 +452,7 @@ public class PgpMessageBuilderTest {
|
|||
.setMessageReference(null)
|
||||
.setDraft(false);
|
||||
|
||||
return b;
|
||||
return builder;
|
||||
}
|
||||
|
||||
private static void assertContentOfBodyPartEquals(String reason, BodyPart signatureBodyPart, byte[] expected) {
|
||||
|
@ -500,5 +506,4 @@ public class PgpMessageBuilderTest {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue