Merge pull request #2777 from k9mail/simplify-message-extract
Some updates to MessageViewInfoExtractor
This commit is contained in:
commit
6ececc378a
7 changed files with 267 additions and 112 deletions
|
@ -233,7 +233,7 @@ public class MessageCryptoStructureDetector {
|
||||||
return dataUnavailable || protocolMatches;
|
return dataUnavailable || protocolMatches;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isPartMultipartEncrypted(Part part) {
|
public static boolean isPartMultipartEncrypted(Part part) {
|
||||||
if (!isSameMimeType(part.getMimeType(), MULTIPART_ENCRYPTED)) {
|
if (!isSameMimeType(part.getMimeType(), MULTIPART_ENCRYPTED)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package com.fsck.k9.mailstore;
|
package com.fsck.k9.mailstore;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import com.fsck.k9.mail.Message;
|
import com.fsck.k9.mail.Message;
|
||||||
|
@ -36,24 +37,24 @@ public class MessageViewInfo {
|
||||||
this.extraAttachments = extraAttachments;
|
this.extraAttachments = extraAttachments;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MessageViewInfo createWithExtractedContent(
|
static MessageViewInfo createWithExtractedContent(Message message, boolean isMessageIncomplete,
|
||||||
Message message, boolean isMessageIncomplete, Part rootPart,
|
String text, List<AttachmentViewInfo> attachments, AttachmentResolver attachmentResolver) {
|
||||||
String text, List<AttachmentViewInfo> attachments,
|
|
||||||
CryptoResultAnnotation cryptoResultAnnotation,
|
|
||||||
AttachmentResolver attachmentResolver,
|
|
||||||
String extraText, List<AttachmentViewInfo> extraAttachments
|
|
||||||
) {
|
|
||||||
return new MessageViewInfo(
|
return new MessageViewInfo(
|
||||||
message, isMessageIncomplete, rootPart,
|
message, isMessageIncomplete, message, text, attachments, null, attachmentResolver, null,
|
||||||
text, attachments,
|
Collections.<AttachmentViewInfo>emptyList());
|
||||||
cryptoResultAnnotation,
|
|
||||||
attachmentResolver,
|
|
||||||
extraText, extraAttachments
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MessageViewInfo createWithErrorState(Message message, boolean isMessageIncomplete) {
|
public static MessageViewInfo createWithErrorState(Message message, boolean isMessageIncomplete) {
|
||||||
return new MessageViewInfo(message, isMessageIncomplete, null, null, null, null, null, null, null);
|
return new MessageViewInfo(message, isMessageIncomplete, null, null, null, null, null, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MessageViewInfo withCryptoData(CryptoResultAnnotation rootPartAnnotation, String extraViewableText,
|
||||||
|
List<AttachmentViewInfo> extraAttachmentInfos) {
|
||||||
|
return new MessageViewInfo(
|
||||||
|
message, isMessageIncomplete, rootPart, text, attachments,
|
||||||
|
rootPartAnnotation,
|
||||||
|
attachmentResolver,
|
||||||
|
extraViewableText, extraAttachmentInfos
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,22 +12,24 @@ import android.support.annotation.VisibleForTesting;
|
||||||
import android.support.annotation.WorkerThread;
|
import android.support.annotation.WorkerThread;
|
||||||
|
|
||||||
import com.fsck.k9.Globals;
|
import com.fsck.k9.Globals;
|
||||||
|
import com.fsck.k9.K9;
|
||||||
import com.fsck.k9.R;
|
import com.fsck.k9.R;
|
||||||
|
import com.fsck.k9.crypto.MessageCryptoStructureDetector;
|
||||||
import com.fsck.k9.mail.Address;
|
import com.fsck.k9.mail.Address;
|
||||||
import com.fsck.k9.mail.Flag;
|
import com.fsck.k9.mail.Flag;
|
||||||
import com.fsck.k9.mail.Message;
|
import com.fsck.k9.mail.Message;
|
||||||
import com.fsck.k9.mail.MessagingException;
|
import com.fsck.k9.mail.MessagingException;
|
||||||
import com.fsck.k9.mail.Part;
|
import com.fsck.k9.mail.Part;
|
||||||
import com.fsck.k9.mail.internet.MessageExtractor;
|
import com.fsck.k9.mail.internet.MessageExtractor;
|
||||||
|
import com.fsck.k9.mail.internet.MimeUtility;
|
||||||
import com.fsck.k9.mail.internet.Viewable;
|
import com.fsck.k9.mail.internet.Viewable;
|
||||||
import com.fsck.k9.mail.internet.Viewable.Flowed;
|
import com.fsck.k9.mail.internet.Viewable.Flowed;
|
||||||
|
import com.fsck.k9.mailstore.CryptoResultAnnotation.CryptoError;
|
||||||
import com.fsck.k9.mailstore.util.FlowedMessageUtils;
|
import com.fsck.k9.mailstore.util.FlowedMessageUtils;
|
||||||
import com.fsck.k9.message.extractors.AttachmentInfoExtractor;
|
import com.fsck.k9.message.extractors.AttachmentInfoExtractor;
|
||||||
import com.fsck.k9.message.html.HtmlConverter;
|
import com.fsck.k9.message.html.HtmlConverter;
|
||||||
import com.fsck.k9.message.html.HtmlProcessor;
|
import com.fsck.k9.message.html.HtmlProcessor;
|
||||||
import com.fsck.k9.ui.crypto.MessageCryptoAnnotations;
|
import com.fsck.k9.ui.crypto.MessageCryptoAnnotations;
|
||||||
import com.fsck.k9.ui.crypto.MessageCryptoSplitter;
|
|
||||||
import com.fsck.k9.ui.crypto.MessageCryptoSplitter.CryptoMessageParts;
|
|
||||||
import org.openintents.openpgp.util.OpenPgpUtils;
|
import org.openintents.openpgp.util.OpenPgpUtils;
|
||||||
import timber.log.Timber;
|
import timber.log.Timber;
|
||||||
|
|
||||||
|
@ -69,45 +71,61 @@ public class MessageViewInfoExtractor {
|
||||||
}
|
}
|
||||||
|
|
||||||
@WorkerThread
|
@WorkerThread
|
||||||
public MessageViewInfo extractMessageForView(Message message, @Nullable MessageCryptoAnnotations annotations)
|
public MessageViewInfo extractMessageForView(Message message, @Nullable MessageCryptoAnnotations cryptoAnnotations)
|
||||||
throws MessagingException {
|
throws MessagingException {
|
||||||
Part rootPart;
|
ArrayList<Part> extraParts = new ArrayList<>();
|
||||||
CryptoResultAnnotation cryptoResultAnnotation;
|
Part cryptoContentPart = MessageCryptoStructureDetector.findPrimaryEncryptedOrSignedPart(message, extraParts);
|
||||||
List<Part> extraParts;
|
|
||||||
|
|
||||||
CryptoMessageParts cryptoMessageParts = MessageCryptoSplitter.split(message, annotations);
|
if (cryptoContentPart == null) {
|
||||||
if (cryptoMessageParts != null) {
|
if (cryptoAnnotations != null && !cryptoAnnotations.isEmpty()) {
|
||||||
rootPart = cryptoMessageParts.contentPart;
|
Timber.e("Got crypto message cryptoContentAnnotations but no crypto root part!");
|
||||||
cryptoResultAnnotation = cryptoMessageParts.contentCryptoAnnotation;
|
|
||||||
extraParts = cryptoMessageParts.extraParts;
|
|
||||||
} else {
|
|
||||||
if (annotations != null && !annotations.isEmpty()) {
|
|
||||||
Timber.e("Got message annotations but no crypto root part!");
|
|
||||||
}
|
}
|
||||||
rootPart = message;
|
return extractSimpleMessageForView(message, message);
|
||||||
cryptoResultAnnotation = null;
|
|
||||||
extraParts = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
List<AttachmentViewInfo> attachmentInfos = new ArrayList<>();
|
boolean isOpenPgpEncrypted = (MessageCryptoStructureDetector.isPartMultipartEncrypted(cryptoContentPart) &&
|
||||||
ViewableExtractedText viewable = extractViewableAndAttachments(
|
MessageCryptoStructureDetector.isMultipartEncryptedOpenPgpProtocol(cryptoContentPart)) ||
|
||||||
Collections.singletonList(rootPart), attachmentInfos);
|
MessageCryptoStructureDetector.isPartPgpInlineEncrypted(cryptoContentPart);
|
||||||
|
if (!K9.isOpenPgpProviderConfigured() && isOpenPgpEncrypted) {
|
||||||
|
CryptoResultAnnotation noProviderAnnotation = CryptoResultAnnotation.createErrorAnnotation(
|
||||||
|
CryptoError.OPENPGP_ENCRYPTED_NO_PROVIDER, null);
|
||||||
|
return MessageViewInfo.createWithErrorState(message, false)
|
||||||
|
.withCryptoData(noProviderAnnotation, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
CryptoResultAnnotation cryptoContentPartAnnotation =
|
||||||
|
cryptoAnnotations != null ? cryptoAnnotations.get(cryptoContentPart) : null;
|
||||||
|
if (cryptoContentPartAnnotation != null) {
|
||||||
|
return extractCryptoMessageForView(message, extraParts, cryptoContentPart, cryptoContentPartAnnotation);
|
||||||
|
}
|
||||||
|
|
||||||
|
return extractSimpleMessageForView(message, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
private MessageViewInfo extractCryptoMessageForView(Message message,
|
||||||
|
ArrayList<Part> extraParts, Part cryptoContentPart, CryptoResultAnnotation cryptoContentPartAnnotation)
|
||||||
|
throws MessagingException {
|
||||||
|
if (cryptoContentPartAnnotation != null && cryptoContentPartAnnotation.hasReplacementData()) {
|
||||||
|
cryptoContentPart = cryptoContentPartAnnotation.getReplacementData();
|
||||||
|
}
|
||||||
|
|
||||||
List<AttachmentViewInfo> extraAttachmentInfos = new ArrayList<>();
|
List<AttachmentViewInfo> extraAttachmentInfos = new ArrayList<>();
|
||||||
String extraViewableText = null;
|
ViewableExtractedText extraViewable = extractViewableAndAttachments(extraParts, extraAttachmentInfos);
|
||||||
if (extraParts != null) {
|
|
||||||
ViewableExtractedText extraViewable =
|
|
||||||
extractViewableAndAttachments(extraParts, extraAttachmentInfos);
|
|
||||||
extraViewableText = extraViewable.text;
|
|
||||||
}
|
|
||||||
|
|
||||||
AttachmentResolver attachmentResolver = AttachmentResolver.createFromPart(rootPart);
|
MessageViewInfo messageViewInfo = extractSimpleMessageForView(message, cryptoContentPart);
|
||||||
|
return messageViewInfo.withCryptoData(cryptoContentPartAnnotation, extraViewable.text, extraAttachmentInfos);
|
||||||
|
}
|
||||||
|
|
||||||
boolean isMessageIncomplete = !message.isSet(Flag.X_DOWNLOADED_FULL) ||
|
private MessageViewInfo extractSimpleMessageForView(Message message, Part contentPart) throws MessagingException {
|
||||||
MessageExtractor.hasMissingParts(message);
|
List<AttachmentViewInfo> attachmentInfos = new ArrayList<>();
|
||||||
|
ViewableExtractedText viewable = extractViewableAndAttachments(
|
||||||
|
Collections.singletonList(contentPart), attachmentInfos);
|
||||||
|
AttachmentResolver attachmentResolver = AttachmentResolver.createFromPart(contentPart);
|
||||||
|
boolean isMessageIncomplete =
|
||||||
|
!message.isSet(Flag.X_DOWNLOADED_FULL) || MessageExtractor.hasMissingParts(message);
|
||||||
|
|
||||||
return MessageViewInfo.createWithExtractedContent(message, isMessageIncomplete, rootPart, viewable.html,
|
return MessageViewInfo.createWithExtractedContent(
|
||||||
attachmentInfos, cryptoResultAnnotation, attachmentResolver, extraViewableText, extraAttachmentInfos);
|
message, isMessageIncomplete, viewable.html, attachmentInfos, attachmentResolver);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ViewableExtractedText extractViewableAndAttachments(List<Part> parts,
|
private ViewableExtractedText extractViewableAndAttachments(List<Part> parts,
|
||||||
|
|
|
@ -12,11 +12,7 @@ import com.fsck.k9.mailstore.CryptoResultAnnotation;
|
||||||
public class MessageCryptoAnnotations {
|
public class MessageCryptoAnnotations {
|
||||||
private HashMap<Part, CryptoResultAnnotation> annotations = new HashMap<>();
|
private HashMap<Part, CryptoResultAnnotation> annotations = new HashMap<>();
|
||||||
|
|
||||||
MessageCryptoAnnotations() {
|
public void put(Part part, CryptoResultAnnotation annotation) {
|
||||||
// Package-private constructor
|
|
||||||
}
|
|
||||||
|
|
||||||
void put(Part part, CryptoResultAnnotation annotation) {
|
|
||||||
annotations.put(part, annotation);
|
annotations.put(part, annotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,60 +0,0 @@
|
||||||
package com.fsck.k9.ui.crypto;
|
|
||||||
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import android.support.annotation.NonNull;
|
|
||||||
import android.support.annotation.Nullable;
|
|
||||||
|
|
||||||
import com.fsck.k9.crypto.MessageCryptoStructureDetector;
|
|
||||||
import com.fsck.k9.mail.Message;
|
|
||||||
import com.fsck.k9.mail.Part;
|
|
||||||
import com.fsck.k9.mailstore.CryptoResultAnnotation;
|
|
||||||
import com.fsck.k9.mailstore.CryptoResultAnnotation.CryptoError;
|
|
||||||
|
|
||||||
|
|
||||||
public class MessageCryptoSplitter {
|
|
||||||
private MessageCryptoSplitter() { }
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public static CryptoMessageParts split(@NonNull Message message, @Nullable MessageCryptoAnnotations annotations) {
|
|
||||||
ArrayList<Part> extraParts = new ArrayList<>();
|
|
||||||
Part primaryPart = MessageCryptoStructureDetector.findPrimaryEncryptedOrSignedPart(message, extraParts);
|
|
||||||
if (primaryPart == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (annotations == null) {
|
|
||||||
CryptoResultAnnotation rootPartAnnotation =
|
|
||||||
CryptoResultAnnotation.createErrorAnnotation(CryptoError.OPENPGP_ENCRYPTED_NO_PROVIDER, null);
|
|
||||||
return new CryptoMessageParts(primaryPart, rootPartAnnotation, extraParts);
|
|
||||||
}
|
|
||||||
|
|
||||||
CryptoResultAnnotation rootPartAnnotation = annotations.get(primaryPart);
|
|
||||||
Part rootPart;
|
|
||||||
if (rootPartAnnotation != null && rootPartAnnotation.hasReplacementData()) {
|
|
||||||
rootPart = rootPartAnnotation.getReplacementData();
|
|
||||||
} else {
|
|
||||||
rootPart = primaryPart;
|
|
||||||
}
|
|
||||||
|
|
||||||
return new CryptoMessageParts(rootPart, rootPartAnnotation, extraParts);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class CryptoMessageParts {
|
|
||||||
public final Part contentPart;
|
|
||||||
@Nullable
|
|
||||||
public final CryptoResultAnnotation contentCryptoAnnotation;
|
|
||||||
|
|
||||||
public final List<Part> extraParts;
|
|
||||||
|
|
||||||
CryptoMessageParts(Part contentPart, @Nullable CryptoResultAnnotation contentCryptoAnnotation, List<Part> extraParts) {
|
|
||||||
this.contentPart = contentPart;
|
|
||||||
this.contentCryptoAnnotation = contentCryptoAnnotation;
|
|
||||||
this.extraParts = Collections.unmodifiableList(extraParts);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -9,11 +9,14 @@ import java.util.Locale;
|
||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
|
|
||||||
import android.app.Application;
|
import android.app.Application;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
|
||||||
import com.fsck.k9.GlobalsHelper;
|
import com.fsck.k9.GlobalsHelper;
|
||||||
import com.fsck.k9.K9RobolectricTestRunner;
|
import com.fsck.k9.K9RobolectricTestRunner;
|
||||||
import com.fsck.k9.activity.K9ActivityCommon;
|
import com.fsck.k9.activity.K9ActivityCommon;
|
||||||
import com.fsck.k9.mail.Address;
|
import com.fsck.k9.mail.Address;
|
||||||
|
import com.fsck.k9.mail.BodyPart;
|
||||||
|
import com.fsck.k9.mail.Message;
|
||||||
import com.fsck.k9.mail.Message.RecipientType;
|
import com.fsck.k9.mail.Message.RecipientType;
|
||||||
import com.fsck.k9.mail.MessagingException;
|
import com.fsck.k9.mail.MessagingException;
|
||||||
import com.fsck.k9.mail.Part;
|
import com.fsck.k9.mail.Part;
|
||||||
|
@ -26,8 +29,11 @@ import com.fsck.k9.mail.internet.MimeMultipart;
|
||||||
import com.fsck.k9.mail.internet.TextBody;
|
import com.fsck.k9.mail.internet.TextBody;
|
||||||
import com.fsck.k9.mail.internet.Viewable;
|
import com.fsck.k9.mail.internet.Viewable;
|
||||||
import com.fsck.k9.mail.internet.Viewable.MessageHeader;
|
import com.fsck.k9.mail.internet.Viewable.MessageHeader;
|
||||||
|
import com.fsck.k9.mailstore.CryptoResultAnnotation.CryptoError;
|
||||||
import com.fsck.k9.mailstore.MessageViewInfoExtractor.ViewableExtractedText;
|
import com.fsck.k9.mailstore.MessageViewInfoExtractor.ViewableExtractedText;
|
||||||
|
import com.fsck.k9.message.extractors.AttachmentInfoExtractor;
|
||||||
import com.fsck.k9.message.html.HtmlProcessor;
|
import com.fsck.k9.message.html.HtmlProcessor;
|
||||||
|
import com.fsck.k9.ui.crypto.MessageCryptoAnnotations;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
@ -35,13 +41,21 @@ import org.mockito.invocation.InvocationOnMock;
|
||||||
import org.mockito.stubbing.Answer;
|
import org.mockito.stubbing.Answer;
|
||||||
import org.robolectric.RuntimeEnvironment;
|
import org.robolectric.RuntimeEnvironment;
|
||||||
|
|
||||||
|
import static com.fsck.k9.message.TestMessageConstructionUtils.bodypart;
|
||||||
|
import static com.fsck.k9.message.TestMessageConstructionUtils.messageFromBody;
|
||||||
|
import static com.fsck.k9.message.TestMessageConstructionUtils.multipart;
|
||||||
import static junit.framework.Assert.assertEquals;
|
import static junit.framework.Assert.assertEquals;
|
||||||
|
import static junit.framework.Assert.assertNull;
|
||||||
import static junit.framework.Assert.assertSame;
|
import static junit.framework.Assert.assertSame;
|
||||||
|
import static junit.framework.Assert.assertTrue;
|
||||||
import static org.mockito.Matchers.anyString;
|
import static org.mockito.Matchers.anyString;
|
||||||
|
import static org.mockito.Mockito.doReturn;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.spy;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
|
||||||
|
@SuppressWarnings("WeakerAccess")
|
||||||
@RunWith(K9RobolectricTestRunner.class)
|
@RunWith(K9RobolectricTestRunner.class)
|
||||||
public class MessageViewInfoExtractorTest {
|
public class MessageViewInfoExtractorTest {
|
||||||
public static final String BODY_TEXT = "K-9 Mail rocks :>";
|
public static final String BODY_TEXT = "K-9 Mail rocks :>";
|
||||||
|
@ -51,6 +65,7 @@ public class MessageViewInfoExtractorTest {
|
||||||
|
|
||||||
private MessageViewInfoExtractor messageViewInfoExtractor;
|
private MessageViewInfoExtractor messageViewInfoExtractor;
|
||||||
private Application context;
|
private Application context;
|
||||||
|
private AttachmentInfoExtractor attachmentInfoExtractor;
|
||||||
|
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
|
@ -60,7 +75,8 @@ public class MessageViewInfoExtractorTest {
|
||||||
GlobalsHelper.setContext(context);
|
GlobalsHelper.setContext(context);
|
||||||
|
|
||||||
HtmlProcessor htmlProcessor = createFakeHtmlProcessor();
|
HtmlProcessor htmlProcessor = createFakeHtmlProcessor();
|
||||||
messageViewInfoExtractor = new MessageViewInfoExtractor(context,null, htmlProcessor);
|
attachmentInfoExtractor = spy(AttachmentInfoExtractor.getInstance());
|
||||||
|
messageViewInfoExtractor = new MessageViewInfoExtractor(context, attachmentInfoExtractor, htmlProcessor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -359,6 +375,190 @@ public class MessageViewInfoExtractorTest {
|
||||||
assertEquals(expectedHtmlText, firstMessageExtractedText.html);
|
assertEquals(expectedHtmlText, firstMessageExtractedText.html);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void extractMessage_withAttachment() throws Exception {
|
||||||
|
BodyPart attachmentPart = bodypart("application/octet-stream");
|
||||||
|
Message message = messageFromBody(multipart("mixed",
|
||||||
|
bodypart("text/plain", "text"),
|
||||||
|
attachmentPart
|
||||||
|
));
|
||||||
|
AttachmentViewInfo attachmentViewInfo = mock(AttachmentViewInfo.class);
|
||||||
|
setupAttachmentInfoForPart(attachmentPart, attachmentViewInfo);
|
||||||
|
|
||||||
|
|
||||||
|
MessageViewInfo messageViewInfo = messageViewInfoExtractor.extractMessageForView(message, null);
|
||||||
|
|
||||||
|
|
||||||
|
assertEquals("<pre class=\"k9mail\">text</pre>", messageViewInfo.text);
|
||||||
|
assertSame(attachmentViewInfo, messageViewInfo.attachments.get(0));
|
||||||
|
assertNull(messageViewInfo.cryptoResultAnnotation);
|
||||||
|
assertTrue(messageViewInfo.extraAttachments.isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void extractMessage_withCryptoAnnotation() throws Exception {
|
||||||
|
Message message = messageFromBody(multipart("signed", "protocol=\"application/pgp-signature\"",
|
||||||
|
bodypart("text/plain", "text"),
|
||||||
|
bodypart("application/pgp-signature")
|
||||||
|
));
|
||||||
|
CryptoResultAnnotation annotation = CryptoResultAnnotation.createOpenPgpResultAnnotation(
|
||||||
|
null, null, null, null, null, false);
|
||||||
|
MessageCryptoAnnotations messageCryptoAnnotations = createAnnotations(message, annotation);
|
||||||
|
|
||||||
|
|
||||||
|
MessageViewInfo messageViewInfo = messageViewInfoExtractor.extractMessageForView(message, messageCryptoAnnotations);
|
||||||
|
|
||||||
|
|
||||||
|
assertEquals("<pre class=\"k9mail\">text</pre>", messageViewInfo.text);
|
||||||
|
assertSame(annotation, messageViewInfo.cryptoResultAnnotation);
|
||||||
|
assertTrue(messageViewInfo.attachments.isEmpty());
|
||||||
|
assertTrue(messageViewInfo.extraAttachments.isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void extractMessage_withCryptoAnnotation_andReplacementPart() throws Exception {
|
||||||
|
Message message = messageFromBody(multipart("signed", "protocol=\"application/pgp-signature\"",
|
||||||
|
bodypart("text/plain", "text"),
|
||||||
|
bodypart("application/pgp-signature")
|
||||||
|
));
|
||||||
|
MimeBodyPart replacementPart = bodypart("text/plain", "replacement text");
|
||||||
|
CryptoResultAnnotation annotation = CryptoResultAnnotation.createOpenPgpResultAnnotation(
|
||||||
|
null, null, null, null, replacementPart, false);
|
||||||
|
MessageCryptoAnnotations messageCryptoAnnotations = createAnnotations(message, annotation);
|
||||||
|
|
||||||
|
|
||||||
|
MessageViewInfo messageViewInfo = messageViewInfoExtractor.extractMessageForView(message, messageCryptoAnnotations);
|
||||||
|
|
||||||
|
|
||||||
|
assertEquals("<pre class=\"k9mail\">replacement text</pre>", messageViewInfo.text);
|
||||||
|
assertSame(annotation, messageViewInfo.cryptoResultAnnotation);
|
||||||
|
assertTrue(messageViewInfo.attachments.isEmpty());
|
||||||
|
assertTrue(messageViewInfo.extraAttachments.isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void extractMessage_withCryptoAnnotation_andExtraText() throws Exception {
|
||||||
|
MimeBodyPart signedPart = multipart("signed", "protocol=\"application/pgp-signature\"",
|
||||||
|
bodypart("text/plain", "text"),
|
||||||
|
bodypart("application/pgp-signature")
|
||||||
|
);
|
||||||
|
BodyPart extraText = bodypart("text/plain", "extra text");
|
||||||
|
Message message = messageFromBody(multipart("mixed",
|
||||||
|
signedPart,
|
||||||
|
extraText
|
||||||
|
));
|
||||||
|
CryptoResultAnnotation annotation = CryptoResultAnnotation.createOpenPgpResultAnnotation(
|
||||||
|
null, null, null, null, null, false);
|
||||||
|
MessageCryptoAnnotations messageCryptoAnnotations = createAnnotations(signedPart, annotation);
|
||||||
|
|
||||||
|
|
||||||
|
MessageViewInfo messageViewInfo = messageViewInfoExtractor.extractMessageForView(message, messageCryptoAnnotations);
|
||||||
|
|
||||||
|
|
||||||
|
assertEquals("<pre class=\"k9mail\">text</pre>", messageViewInfo.text);
|
||||||
|
assertSame(annotation, messageViewInfo.cryptoResultAnnotation);
|
||||||
|
assertEquals("extra text", messageViewInfo.extraText);
|
||||||
|
assertTrue(messageViewInfo.attachments.isEmpty());
|
||||||
|
assertTrue(messageViewInfo.extraAttachments.isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void extractMessage_withCryptoAnnotation_andExtraAttachment() throws Exception {
|
||||||
|
MimeBodyPart signedPart = multipart("signed", "protocol=\"application/pgp-signature\"",
|
||||||
|
bodypart("text/plain", "text"),
|
||||||
|
bodypart("application/pgp-signature")
|
||||||
|
);
|
||||||
|
BodyPart extraAttachment = bodypart("application/octet-stream");
|
||||||
|
Message message = messageFromBody(multipart("mixed",
|
||||||
|
signedPart,
|
||||||
|
extraAttachment
|
||||||
|
));
|
||||||
|
CryptoResultAnnotation annotation = CryptoResultAnnotation.createOpenPgpResultAnnotation(
|
||||||
|
null, null, null, null, null, false);
|
||||||
|
MessageCryptoAnnotations messageCryptoAnnotations = createAnnotations(signedPart, annotation);
|
||||||
|
|
||||||
|
AttachmentViewInfo attachmentViewInfo = mock(AttachmentViewInfo.class);
|
||||||
|
setupAttachmentInfoForPart(extraAttachment, attachmentViewInfo);
|
||||||
|
|
||||||
|
|
||||||
|
MessageViewInfo messageViewInfo = messageViewInfoExtractor.extractMessageForView(message, messageCryptoAnnotations);
|
||||||
|
|
||||||
|
|
||||||
|
assertEquals("<pre class=\"k9mail\">text</pre>", messageViewInfo.text);
|
||||||
|
assertSame(annotation, messageViewInfo.cryptoResultAnnotation);
|
||||||
|
assertSame(attachmentViewInfo, messageViewInfo.extraAttachments.get(0));
|
||||||
|
assertTrue(messageViewInfo.attachments.isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void extractMessage_openPgpEncrypted_withoutAnnotations() throws Exception {
|
||||||
|
Message message = messageFromBody(
|
||||||
|
multipart("encrypted", "protocol=\"application/pgp-encrypted\"",
|
||||||
|
bodypart("application/pgp-encrypted"),
|
||||||
|
bodypart("application/octet-stream")
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
MessageViewInfo messageViewInfo = messageViewInfoExtractor.extractMessageForView(message, null);
|
||||||
|
|
||||||
|
assertEquals(CryptoError.OPENPGP_ENCRYPTED_NO_PROVIDER, messageViewInfo.cryptoResultAnnotation.getErrorType());
|
||||||
|
assertNull(messageViewInfo.text);
|
||||||
|
assertNull(messageViewInfo.attachments);
|
||||||
|
assertNull(messageViewInfo.extraAttachments);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void extractMessage_multipartSigned_UnknownProtocol() throws Exception {
|
||||||
|
Message message = messageFromBody(
|
||||||
|
multipart("signed", "protocol=\"application/pkcs7-signature\"",
|
||||||
|
bodypart("text/plain", "text"),
|
||||||
|
bodypart("application/pkcs7-signature", "signature")
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
MessageViewInfo messageViewInfo = messageViewInfoExtractor.extractMessageForView(message, null);
|
||||||
|
|
||||||
|
assertEquals("<pre class=\"k9mail\">text</pre>", messageViewInfo.text);
|
||||||
|
assertNull(messageViewInfo.cryptoResultAnnotation);
|
||||||
|
assertTrue(messageViewInfo.attachments.isEmpty());
|
||||||
|
assertTrue(messageViewInfo.extraAttachments.isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void extractMessage_multipartSigned_UnknownProtocol_withExtraAttachments() throws Exception {
|
||||||
|
BodyPart extraAttachment = bodypart("application/octet-stream");
|
||||||
|
Message message = messageFromBody(
|
||||||
|
multipart("mixed",
|
||||||
|
multipart("signed", "protocol=\"application/pkcs7-signature\"",
|
||||||
|
bodypart("text/plain", "text"),
|
||||||
|
bodypart("application/pkcs7-signature", "signature")
|
||||||
|
),
|
||||||
|
extraAttachment
|
||||||
|
)
|
||||||
|
);
|
||||||
|
AttachmentViewInfo mock = mock(AttachmentViewInfo.class);
|
||||||
|
setupAttachmentInfoForPart(extraAttachment, mock);
|
||||||
|
|
||||||
|
MessageViewInfo messageViewInfo = messageViewInfoExtractor.extractMessageForView(message, null);
|
||||||
|
|
||||||
|
assertEquals("<pre class=\"k9mail\">text</pre>", messageViewInfo.text);
|
||||||
|
assertNull(messageViewInfo.cryptoResultAnnotation);
|
||||||
|
assertSame(mock, messageViewInfo.attachments.get(0));
|
||||||
|
assertTrue(messageViewInfo.extraAttachments.isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
void setupAttachmentInfoForPart(BodyPart extraAttachment, AttachmentViewInfo attachmentViewInfo)
|
||||||
|
throws MessagingException {
|
||||||
|
doReturn(attachmentViewInfo).when(attachmentInfoExtractor).extractAttachmentInfo(extraAttachment);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
MessageCryptoAnnotations createAnnotations(Part part, CryptoResultAnnotation annotation) {
|
||||||
|
MessageCryptoAnnotations messageCryptoAnnotations = new MessageCryptoAnnotations();
|
||||||
|
messageCryptoAnnotations.put(part, annotation);
|
||||||
|
return messageCryptoAnnotations;
|
||||||
|
}
|
||||||
|
|
||||||
HtmlProcessor createFakeHtmlProcessor() {
|
HtmlProcessor createFakeHtmlProcessor() {
|
||||||
HtmlProcessor htmlProcessor = mock(HtmlProcessor.class);
|
HtmlProcessor htmlProcessor = mock(HtmlProcessor.class);
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,7 @@ public class TestMessageConstructionUtils {
|
||||||
return new MimeBodyPart(null, type);
|
return new MimeBodyPart(null, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BodyPart bodypart(String type, String text) throws MessagingException {
|
public static MimeBodyPart bodypart(String type, String text) throws MessagingException {
|
||||||
TextBody textBody = new TextBody(text);
|
TextBody textBody = new TextBody(text);
|
||||||
return new MimeBodyPart(textBody, type);
|
return new MimeBodyPart(textBody, type);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue