diff --git a/k9mail-library/src/androidTest/java/com/fsck/k9/mail/PgpMimeMessageTest.java b/k9mail-library/src/androidTest/java/com/fsck/k9/mail/PgpMimeMessageTest.java index 5fa6f5f1c..dc973718b 100644 --- a/k9mail-library/src/androidTest/java/com/fsck/k9/mail/PgpMimeMessageTest.java +++ b/k9mail-library/src/androidTest/java/com/fsck/k9/mail/PgpMimeMessageTest.java @@ -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(); } diff --git a/k9mail-library/src/androidTest/java/com/fsck/k9/mail/ReconstructMessageTest.java b/k9mail-library/src/androidTest/java/com/fsck/k9/mail/ReconstructMessageTest.java index fbf32f5e7..634eaf284 100644 --- a/k9mail-library/src/androidTest/java/com/fsck/k9/mail/ReconstructMessageTest.java +++ b/k9mail-library/src/androidTest/java/com/fsck/k9/mail/ReconstructMessageTest.java @@ -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(); } diff --git a/k9mail-library/src/main/java/com/fsck/k9/mail/BoundaryGenerator.java b/k9mail-library/src/main/java/com/fsck/k9/mail/BoundaryGenerator.java new file mode 100644 index 000000000..fa3f9cc6f --- /dev/null +++ b/k9mail-library/src/main/java/com/fsck/k9/mail/BoundaryGenerator.java @@ -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); + } +} diff --git a/k9mail-library/src/main/java/com/fsck/k9/mail/internet/BinaryTempFileMessageBody.java b/k9mail-library/src/main/java/com/fsck/k9/mail/internet/BinaryTempFileMessageBody.java index d4eb0435d..5ac2fd68a 100644 --- a/k9mail-library/src/main/java/com/fsck/k9/mail/internet/BinaryTempFileMessageBody.java +++ b/k9mail-library/src/main/java/com/fsck/k9/mail/internet/BinaryTempFileMessageBody.java @@ -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 { diff --git a/k9mail-library/src/main/java/com/fsck/k9/mail/internet/MessageIdGenerator.java b/k9mail-library/src/main/java/com/fsck/k9/mail/internet/MessageIdGenerator.java new file mode 100644 index 000000000..b2579ca37 --- /dev/null +++ b/k9mail-library/src/main/java/com/fsck/k9/mail/internet/MessageIdGenerator.java @@ -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); + } +} diff --git a/k9mail-library/src/main/java/com/fsck/k9/mail/internet/MimeMessage.java b/k9mail-library/src/main/java/com/fsck/k9/mail/internet/MimeMessage.java index 93bb0d354..42b3cc483 100644 --- a/k9mail-library/src/main/java/com/fsck/k9/mail/internet/MimeMessage.java +++ b/k9mail-library/src/main/java/com/fsck/k9/mail/internet/MimeMessage.java @@ -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 diff --git a/k9mail-library/src/main/java/com/fsck/k9/mail/internet/MimeMultipart.java b/k9mail-library/src/main/java/com/fsck/k9/mail/internet/MimeMultipart.java index ef10b0435..37a54e8af 100644 --- a/k9mail-library/src/main/java/com/fsck/k9/mail/internet/MimeMultipart.java +++ b/k9mail-library/src/main/java/com/fsck/k9/mail/internet/MimeMultipart.java @@ -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; diff --git a/k9mail-library/src/main/java/com/fsck/k9/mail/store/imap/ImapFolder.java b/k9mail-library/src/main/java/com/fsck/k9/mail/store/imap/ImapFolder.java index 05b10395a..716b788ea 100644 --- a/k9mail-library/src/main/java/com/fsck/k9/mail/store/imap/ImapFolder.java +++ b/k9mail-library/src/main/java/com/fsck/k9/mail/store/imap/ImapFolder.java @@ -986,7 +986,7 @@ class ImapFolder extends Folder { /* * 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) { /* diff --git a/k9mail-library/src/main/java/com/fsck/k9/mail/store/imap/ImapMessage.java b/k9mail-library/src/main/java/com/fsck/k9/mail/store/imap/ImapMessage.java index 54b607549..e533cac6d 100644 --- a/k9mail-library/src/main/java/com/fsck/k9/mail/store/imap/ImapMessage.java +++ b/k9mail-library/src/main/java/com/fsck/k9/mail/store/imap/ImapMessage.java @@ -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); diff --git a/k9mail-library/src/main/java/com/fsck/k9/mail/store/pop3/Pop3Store.java b/k9mail-library/src/main/java/com/fsck/k9/mail/store/pop3/Pop3Store.java index f6334392c..7ea455af2 100644 --- a/k9mail-library/src/main/java/com/fsck/k9/mail/store/pop3/Pop3Store.java +++ b/k9mail-library/src/main/java/com/fsck/k9/mail/store/pop3/Pop3Store.java @@ -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; diff --git a/k9mail-library/src/main/java/com/fsck/k9/mail/store/webdav/WebDavMessage.java b/k9mail-library/src/main/java/com/fsck/k9/mail/store/webdav/WebDavMessage.java index 3d59e3d7c..96d6d90ad 100644 --- a/k9mail-library/src/main/java/com/fsck/k9/mail/store/webdav/WebDavMessage.java +++ b/k9mail-library/src/main/java/com/fsck/k9/mail/store/webdav/WebDavMessage.java @@ -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; diff --git a/k9mail-library/src/test/java/com/fsck/k9/mail/BoundaryGeneratorTest.java b/k9mail-library/src/test/java/com/fsck/k9/mail/BoundaryGeneratorTest.java new file mode 100644 index 000000000..eca4606b7 --- /dev/null +++ b/k9mail-library/src/test/java/com/fsck/k9/mail/BoundaryGeneratorTest.java @@ -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 ongoingStubbing = when(random.nextInt(36)); + for (int value : values) { + ongoingStubbing = ongoingStubbing.thenReturn(value); + } + + return random; + } +} diff --git a/k9mail-library/src/test/java/com/fsck/k9/mail/internet/MessageIdGeneratorTest.java b/k9mail-library/src/test/java/com/fsck/k9/mail/internet/MessageIdGeneratorTest.java new file mode 100644 index 000000000..b893f6245 --- /dev/null +++ b/k9mail-library/src/test/java/com/fsck/k9/mail/internet/MessageIdGeneratorTest.java @@ -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); + } +} diff --git a/k9mail-library/src/test/java/com/fsck/k9/mail/internet/MimeMessageParseTest.java b/k9mail-library/src/test/java/com/fsck/k9/mail/internet/MimeMessageParseTest.java index 0c2838880..cce6dd438 100644 --- a/k9mail-library/src/test/java/com/fsck/k9/mail/internet/MimeMessageParseTest.java +++ b/k9mail-library/src/test/java/com/fsck/k9/mail/internet/MimeMessageParseTest.java @@ -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) { diff --git a/k9mail/src/androidTest/java/com/fsck/k9/mailstore/ReconstructMessageFromDatabaseTest.java b/k9mail/src/androidTest/java/com/fsck/k9/mailstore/ReconstructMessageFromDatabaseTest.java index 9a7249b97..621c60280 100644 --- a/k9mail/src/androidTest/java/com/fsck/k9/mailstore/ReconstructMessageFromDatabaseTest.java +++ b/k9mail/src/androidTest/java/com/fsck/k9/mailstore/ReconstructMessageFromDatabaseTest.java @@ -128,7 +128,7 @@ public class ReconstructMessageFromDatabaseTest extends ApplicationTestCase 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(); } diff --git a/k9mail/src/main/java/com/fsck/k9/activity/MessageCompose.java b/k9mail/src/main/java/com/fsck/k9/activity/MessageCompose.java index c40ce1622..33c29d121 100644 --- a/k9mail/src/main/java/com/fsck/k9/activity/MessageCompose.java +++ b/k9mail/src/main/java/com/fsck/k9/activity/MessageCompose.java @@ -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()) diff --git a/k9mail/src/main/java/com/fsck/k9/activity/compose/RecipientPresenter.java b/k9mail/src/main/java/com/fsck/k9/activity/compose/RecipientPresenter.java index f16b788e7..aeaaedc8a 100644 --- a/k9mail/src/main/java/com/fsck/k9/activity/compose/RecipientPresenter.java +++ b/k9mail/src/main/java/com/fsck/k9/activity/compose/RecipientPresenter.java @@ -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; diff --git a/k9mail/src/main/java/com/fsck/k9/mailstore/AttachmentMessageBodyUtil.java b/k9mail/src/main/java/com/fsck/k9/mailstore/AttachmentMessageBodyUtil.java index 71fc418d6..a1175eb03 100644 --- a/k9mail/src/main/java/com/fsck/k9/mailstore/AttachmentMessageBodyUtil.java +++ b/k9mail/src/main/java/com/fsck/k9/mailstore/AttachmentMessageBodyUtil.java @@ -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 { diff --git a/k9mail/src/main/java/com/fsck/k9/mailstore/LocalFolder.java b/k9mail/src/main/java/com/fsck/k9/mailstore/LocalFolder.java index 271913ec3..a629c09dd 100644 --- a/k9mail/src/main/java/com/fsck/k9/mailstore/LocalFolder.java +++ b/k9mail/src/main/java/com/fsck/k9/mailstore/LocalFolder.java @@ -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 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()); } } diff --git a/k9mail/src/main/java/com/fsck/k9/mailstore/LocalMessage.java b/k9mail/src/main/java/com/fsck/k9/mailstore/LocalMessage.java index 57923ec86..1aa03cca4 100644 --- a/k9mail/src/main/java/com/fsck/k9/mailstore/LocalMessage.java +++ b/k9mail/src/main/java/com/fsck/k9/mailstore/LocalMessage.java @@ -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; diff --git a/k9mail/src/main/java/com/fsck/k9/mailstore/MimePartStreamParser.java b/k9mail/src/main/java/com/fsck/k9/mailstore/MimePartStreamParser.java index 4727ed72b..c8c5bc38d 100644 --- a/k9mail/src/main/java/com/fsck/k9/mailstore/MimePartStreamParser.java +++ b/k9mail/src/main/java/com/fsck/k9/mailstore/MimePartStreamParser.java @@ -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 diff --git a/k9mail/src/main/java/com/fsck/k9/message/MessageBuilder.java b/k9mail/src/main/java/com/fsck/k9/message/MessageBuilder.java index abe713744..005ad91ce 100644 --- a/k9mail/src/main/java/com/fsck/k9/message/MessageBuilder.java +++ b/k9mail/src/main/java/com/fsck/k9/message/MessageBuilder.java @@ -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
to) { this.to = to.toArray(new Address[to.size()]); return this; diff --git a/k9mail/src/main/java/com/fsck/k9/message/PgpMessageBuilder.java b/k9mail/src/main/java/com/fsck/k9/message/PgpMessageBuilder.java index 7e8ba5698..c7b000c51 100644 --- a/k9mail/src/main/java/com/fsck/k9/message/PgpMessageBuilder.java +++ b/k9mail/src/main/java/com/fsck/k9/message/PgpMessageBuilder.java @@ -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; } - } diff --git a/k9mail/src/main/java/com/fsck/k9/message/SimpleMessageBuilder.java b/k9mail/src/main/java/com/fsck/k9/message/SimpleMessageBuilder.java index 596396645..7d9ae635e 100644 --- a/k9mail/src/main/java/com/fsck/k9/message/SimpleMessageBuilder.java +++ b/k9mail/src/main/java/com/fsck/k9/message/SimpleMessageBuilder.java @@ -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 diff --git a/k9mail/src/test/java/com/fsck/k9/crypto/MessageDecryptVerifierTest.java b/k9mail/src/test/java/com/fsck/k9/crypto/MessageDecryptVerifierTest.java index da7358047..3c97b479c 100644 --- a/k9mail/src/test/java/com/fsck/k9/crypto/MessageDecryptVerifierTest.java +++ b/k9mail/src/test/java/com/fsck/k9/crypto/MessageDecryptVerifierTest.java @@ -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); diff --git a/k9mail/src/test/java/com/fsck/k9/mailstore/AttachmentResolverTest.java b/k9mail/src/test/java/com/fsck/k9/mailstore/AttachmentResolverTest.java index 7dd1d2b12..45179310c 100644 --- a/k9mail/src/test/java/com/fsck/k9/mailstore/AttachmentResolverTest.java +++ b/k9mail/src/test/java/com/fsck/k9/mailstore/AttachmentResolverTest.java @@ -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 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(); diff --git a/k9mail/src/test/java/com/fsck/k9/mailstore/MessageViewInfoExtractorTest.java b/k9mail/src/test/java/com/fsck/k9/mailstore/MessageViewInfoExtractorTest.java index 0cb4852da..995b02436 100644 --- a/k9mail/src/test/java/com/fsck/k9/mailstore/MessageViewInfoExtractorTest.java +++ b/k9mail/src/test/java/com/fsck/k9/mailstore/MessageViewInfoExtractorTest.java @@ -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\""); diff --git a/k9mail/src/test/java/com/fsck/k9/message/MessageBuilderTest.java b/k9mail/src/test/java/com/fsck/k9/message/MessageBuilderTest.java index b5d171d7f..6e6b29bf9 100644 --- a/k9mail/src/test/java/com/fsck/k9/message/MessageBuilderTest.java +++ b/k9mail/src/test/java/com/fsck/k9/message/MessageBuilderTest.java @@ -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 \r\n" + + "To: recip 1 ,recip 2 \r\n" + + "CC: cc recip \r\n" + + "BCC: bcc recip \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 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)) diff --git a/k9mail/src/test/java/com/fsck/k9/message/PgpMessageBuilderTest.java b/k9mail/src/test/java/com/fsck/k9/message/PgpMessageBuilderTest.java index dd1472e4a..57f6016fd 100644 --- a/k9mail/src/test/java/com/fsck/k9/message/PgpMessageBuilderTest.java +++ b/k9mail/src/test/java/com/fsck/k9/message/PgpMessageBuilderTest.java @@ -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
()) .setCc(new ArrayList
()) .setBcc(new ArrayList
()) @@ -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 { } } } - }