commit
b30ee72d76
5 changed files with 357 additions and 67 deletions
|
@ -35,7 +35,7 @@ dependencies {
|
|||
|
||||
testCompile 'org.robolectric:robolectric:3.0'
|
||||
testCompile 'junit:junit:4.12'
|
||||
testCompile 'org.mockito:mockito-all:1.10.19'
|
||||
testCompile 'org.mockito:mockito-core:1.10.19'
|
||||
}
|
||||
|
||||
android {
|
||||
|
|
|
@ -85,6 +85,7 @@ import com.fsck.k9.fragment.ProgressDialogFragment.CancelListener;
|
|||
import com.fsck.k9.helper.Contacts;
|
||||
import com.fsck.k9.helper.HtmlConverter;
|
||||
import com.fsck.k9.helper.IdentityHelper;
|
||||
import com.fsck.k9.helper.MailTo;
|
||||
import com.fsck.k9.helper.SimpleTextWatcher;
|
||||
import com.fsck.k9.helper.Utility;
|
||||
import com.fsck.k9.mail.Address;
|
||||
|
@ -815,8 +816,9 @@ public class MessageCompose extends K9Activity implements OnClickListener,
|
|||
*/
|
||||
if (intent.getData() != null) {
|
||||
Uri uri = intent.getData();
|
||||
if ("mailto".equals(uri.getScheme())) {
|
||||
initializeFromMailto(uri);
|
||||
if (MailTo.isMailTo(uri)) {
|
||||
MailTo mailTo = MailTo.parse(uri);
|
||||
initializeFromMailto(mailTo);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2795,53 +2797,23 @@ public class MessageCompose extends K9Activity implements OnClickListener,
|
|||
* When we are launched with an intent that includes a mailto: URI, we can actually
|
||||
* gather quite a few of our message fields from it.
|
||||
*
|
||||
* @param mailtoUri
|
||||
* The mailto: URI we use to initialize the message fields.
|
||||
* @param mailTo
|
||||
* The MailTo object we use to initialize message field
|
||||
*/
|
||||
private void initializeFromMailto(Uri mailtoUri) {
|
||||
/*
|
||||
* mailto URIs are not hierarchical. So calling getQueryParameters()
|
||||
* will throw an UnsupportedOperationException. We avoid this by
|
||||
* creating a new hierarchical dummy Uri object with the query
|
||||
* parameters of the original URI.
|
||||
*/
|
||||
CaseInsensitiveParamWrapper uri = new CaseInsensitiveParamWrapper(
|
||||
Uri.parse("foo://bar?" + mailtoUri.getEncodedQuery()));
|
||||
private void initializeFromMailto(MailTo mailTo) {
|
||||
recipientPresenter.initFromMailto(mailTo);
|
||||
|
||||
recipientPresenter.initFromMailto(mailtoUri, uri);
|
||||
|
||||
// Read subject from the "subject" parameter.
|
||||
List<String> subject = uri.getQueryParameters("subject");
|
||||
if (!subject.isEmpty()) {
|
||||
mSubjectView.setText(subject.get(0));
|
||||
String subject = mailTo.getSubject();
|
||||
if (subject != null && !subject.isEmpty()) {
|
||||
mSubjectView.setText(subject);
|
||||
}
|
||||
|
||||
// Read message body from the "body" parameter.
|
||||
List<String> body = uri.getQueryParameters("body");
|
||||
if (!body.isEmpty()) {
|
||||
mMessageContentView.setCharacters(body.get(0));
|
||||
String body = mailTo.getBody();
|
||||
if (body != null && !subject.isEmpty()) {
|
||||
mMessageContentView.setCharacters(body);
|
||||
}
|
||||
}
|
||||
|
||||
static class CaseInsensitiveParamWrapper {
|
||||
private final Uri uri;
|
||||
private Set<String> mParamNames;
|
||||
|
||||
public CaseInsensitiveParamWrapper(Uri uri) {
|
||||
this.uri = uri;
|
||||
}
|
||||
|
||||
public List<String> getQueryParameters(String key) {
|
||||
final List<String> params = new ArrayList<String>();
|
||||
for (String paramName : uri.getQueryParameterNames()) {
|
||||
if (paramName.equalsIgnoreCase(key)) {
|
||||
params.addAll(uri.getQueryParameters(paramName));
|
||||
}
|
||||
}
|
||||
return params;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class SendMessageTask extends AsyncTask<Void, Void, Void> {
|
||||
@Override
|
||||
|
|
|
@ -17,9 +17,9 @@ import android.view.Menu;
|
|||
import com.fsck.k9.Account;
|
||||
import com.fsck.k9.Identity;
|
||||
import com.fsck.k9.R;
|
||||
import com.fsck.k9.activity.MessageCompose.CaseInsensitiveParamWrapper;
|
||||
import com.fsck.k9.activity.RecipientMvpView.CryptoStatusType;
|
||||
import com.fsck.k9.helper.Contacts;
|
||||
import com.fsck.k9.helper.MailTo;
|
||||
import com.fsck.k9.helper.Utility;
|
||||
import com.fsck.k9.mail.Address;
|
||||
import com.fsck.k9.mail.Message;
|
||||
|
@ -158,29 +158,10 @@ public class RecipientPresenter {
|
|||
}
|
||||
}
|
||||
|
||||
public void initFromMailto(Uri mailtoUri, CaseInsensitiveParamWrapper uri) {
|
||||
String schemaSpecific = mailtoUri.getSchemeSpecificPart();
|
||||
int end = schemaSpecific.indexOf('?');
|
||||
if (end == -1) {
|
||||
end = schemaSpecific.length();
|
||||
}
|
||||
|
||||
// Extract the recipient's email address from the mailto URI if there's one.
|
||||
String recipient = Uri.decode(schemaSpecific.substring(0, end));
|
||||
|
||||
// Read additional recipients from the "to" parameter.
|
||||
List<String> to = uri.getQueryParameters("to");
|
||||
if (recipient.length() != 0) {
|
||||
to = new ArrayList<String>(to);
|
||||
to.add(0, recipient);
|
||||
}
|
||||
addToAddresses(addressFromStringArray(to));
|
||||
|
||||
// Read carbon copy recipients from the "cc" parameter.
|
||||
addCcAddresses(addressFromStringArray(uri.getQueryParameters("cc")));
|
||||
|
||||
// Read blind carbon copy recipients from the "bcc" parameter.
|
||||
addBccAddresses(addressFromStringArray(uri.getQueryParameters("bcc")));
|
||||
public void initFromMailto(MailTo mailTo) {
|
||||
addToAddresses(mailTo.getTo());
|
||||
addCcAddresses(mailTo.getCc());
|
||||
addBccAddresses(mailTo.getBcc());
|
||||
}
|
||||
|
||||
public void initFromSendOrViewIntent(Intent intent) {
|
||||
|
|
146
k9mail/src/main/java/com/fsck/k9/helper/MailTo.java
Normal file
146
k9mail/src/main/java/com/fsck/k9/helper/MailTo.java
Normal file
|
@ -0,0 +1,146 @@
|
|||
package com.fsck.k9.helper;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import android.net.Uri;
|
||||
|
||||
import com.fsck.k9.mail.Address;
|
||||
|
||||
|
||||
public final class MailTo {
|
||||
private static final String MAILTO_SCHEME = "mailto";
|
||||
private static final String TO = "to";
|
||||
private static final String BODY = "body";
|
||||
private static final String CC = "cc";
|
||||
private static final String BCC = "bcc";
|
||||
private static final String SUBJECT = "subject";
|
||||
|
||||
private static final Address[] EMPTY_ADDRESS_LIST = new Address[0];
|
||||
|
||||
|
||||
private final Address[] toAddresses;
|
||||
private final Address[] ccAddresses;
|
||||
private final Address[] bccAddresses;
|
||||
private final String subject;
|
||||
private final String body;
|
||||
|
||||
|
||||
public static boolean isMailTo(Uri uri) {
|
||||
return uri != null && MAILTO_SCHEME.equals(uri.getScheme());
|
||||
}
|
||||
|
||||
public static MailTo parse(Uri uri) throws NullPointerException, IllegalArgumentException {
|
||||
if (uri == null || uri.toString() == null) {
|
||||
throw new NullPointerException("Argument 'uri' must not be null");
|
||||
}
|
||||
|
||||
if (!isMailTo(uri)) {
|
||||
throw new IllegalArgumentException("Not a mailto scheme");
|
||||
}
|
||||
|
||||
String schemaSpecific = uri.getSchemeSpecificPart();
|
||||
int end = schemaSpecific.indexOf('?');
|
||||
if (end == -1) {
|
||||
end = schemaSpecific.length();
|
||||
}
|
||||
|
||||
CaseInsensitiveParamWrapper params =
|
||||
new CaseInsensitiveParamWrapper(Uri.parse("foo://bar?" + uri.getEncodedQuery()));
|
||||
|
||||
// Extract the recipient's email address from the mailto URI if there's one.
|
||||
String recipient = Uri.decode(schemaSpecific.substring(0, end));
|
||||
|
||||
List<String> toList = params.getQueryParameters(TO);
|
||||
if (recipient.length() != 0) {
|
||||
toList.add(0, recipient);
|
||||
}
|
||||
|
||||
List<String> ccList = params.getQueryParameters(CC);
|
||||
List<String> bccList = params.getQueryParameters(BCC);
|
||||
|
||||
Address[] toAddresses = toAddressArray(toList);
|
||||
Address[] ccAddresses = toAddressArray(ccList);
|
||||
Address[] bccAddresses = toAddressArray(bccList);
|
||||
|
||||
String subject = getFirstParameterValue(params, SUBJECT);
|
||||
String body = getFirstParameterValue(params, BODY);
|
||||
|
||||
return new MailTo(toAddresses, ccAddresses, bccAddresses, subject, body);
|
||||
}
|
||||
|
||||
private static String getFirstParameterValue(CaseInsensitiveParamWrapper params, String paramName) {
|
||||
List<String> paramValues = params.getQueryParameters(paramName);
|
||||
|
||||
return (paramValues.isEmpty()) ? null : paramValues.get(0);
|
||||
}
|
||||
|
||||
private static Address[] toAddressArray(List<String> recipients) {
|
||||
if (recipients.isEmpty()) {
|
||||
return EMPTY_ADDRESS_LIST;
|
||||
}
|
||||
|
||||
String addressList = toCommaSeparatedString(recipients);
|
||||
return Address.parse(addressList);
|
||||
}
|
||||
|
||||
private static String toCommaSeparatedString(List<String> list) {
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
for (String item : list) {
|
||||
stringBuilder.append(item).append(',');
|
||||
}
|
||||
|
||||
stringBuilder.setLength(stringBuilder.length() - 1);
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
|
||||
private MailTo(Address[] toAddresses, Address[] ccAddresses, Address[] bccAddresses, String subject, String body) {
|
||||
this.toAddresses = toAddresses;
|
||||
this.ccAddresses = ccAddresses;
|
||||
this.bccAddresses = bccAddresses;
|
||||
this.subject = subject;
|
||||
this.body = body;
|
||||
}
|
||||
|
||||
public Address[] getTo() {
|
||||
return toAddresses;
|
||||
}
|
||||
|
||||
public Address[] getCc() {
|
||||
return ccAddresses;
|
||||
}
|
||||
|
||||
public Address[] getBcc() {
|
||||
return bccAddresses;
|
||||
}
|
||||
|
||||
public String getSubject() {
|
||||
return subject;
|
||||
}
|
||||
|
||||
public String getBody() {
|
||||
return body;
|
||||
}
|
||||
|
||||
|
||||
static class CaseInsensitiveParamWrapper {
|
||||
private final Uri uri;
|
||||
|
||||
|
||||
public CaseInsensitiveParamWrapper(Uri uri) {
|
||||
this.uri = uri;
|
||||
}
|
||||
|
||||
public List<String> getQueryParameters(String key) {
|
||||
List<String> params = new ArrayList<String>();
|
||||
for (String paramName : uri.getQueryParameterNames()) {
|
||||
if (paramName.equalsIgnoreCase(key)) {
|
||||
params.addAll(uri.getQueryParameters(paramName));
|
||||
}
|
||||
}
|
||||
|
||||
return params;
|
||||
}
|
||||
}
|
||||
}
|
191
k9mail/src/test/java/com/fsck/k9/helper/MailToTest.java
Normal file
191
k9mail/src/test/java/com/fsck/k9/helper/MailToTest.java
Normal file
|
@ -0,0 +1,191 @@
|
|||
package com.fsck.k9.helper;
|
||||
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import android.net.Uri;
|
||||
|
||||
import com.fsck.k9.helper.MailTo.CaseInsensitiveParamWrapper;
|
||||
import com.fsck.k9.mail.Address;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
import static junit.framework.Assert.assertEquals;
|
||||
import static junit.framework.Assert.assertFalse;
|
||||
import static junit.framework.Assert.assertTrue;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@Config(manifest = Config.NONE, sdk = 21)
|
||||
public class MailToTest {
|
||||
@Rule
|
||||
public ExpectedException exception = ExpectedException.none();
|
||||
|
||||
|
||||
@Test
|
||||
public void testIsMailTo_validMailToURI() {
|
||||
Uri uri = Uri.parse("mailto:nobody");
|
||||
|
||||
boolean result = MailTo.isMailTo(uri);
|
||||
|
||||
assertTrue(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsMailTo_invalidMailToUri() {
|
||||
Uri uri = Uri.parse("http://example.org/");
|
||||
|
||||
boolean result = MailTo.isMailTo(uri);
|
||||
|
||||
assertFalse(result);
|
||||
}
|
||||
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
@Test
|
||||
public void testIsMailTo_nullArgument() {
|
||||
Uri uri = null;
|
||||
|
||||
boolean result = MailTo.isMailTo(uri);
|
||||
|
||||
assertFalse(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parse_withNullArgument_shouldThrow() throws Exception {
|
||||
exception.expect(NullPointerException.class);
|
||||
exception.expectMessage("Argument 'uri' must not be null");
|
||||
|
||||
MailTo.parse(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parse_withoutMailtoUri_shouldThrow() throws Exception {
|
||||
exception.expect(IllegalArgumentException.class);
|
||||
exception.expectMessage("Not a mailto scheme");
|
||||
|
||||
Uri uri = Uri.parse("http://example.org/");
|
||||
|
||||
MailTo.parse(uri);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetTo_singleEmailAddress() {
|
||||
Uri uri = Uri.parse("mailto:test@abc.com");
|
||||
MailTo mailToHelper = MailTo.parse(uri);
|
||||
|
||||
Address[] emailAddressList = mailToHelper.getTo();
|
||||
|
||||
assertEquals(emailAddressList[0].getAddress(), "test@abc.com");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetTo_multipleEmailAddress() {
|
||||
Uri uri = Uri.parse("mailto:test1@abc.com?to=test2@abc.com");
|
||||
MailTo mailToHelper = MailTo.parse(uri);
|
||||
|
||||
Address[] emailAddressList = mailToHelper.getTo();
|
||||
|
||||
assertEquals(emailAddressList[0].getAddress(), "test1@abc.com");
|
||||
assertEquals(emailAddressList[1].getAddress(), "test2@abc.com");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetCc_singleEmailAddress() {
|
||||
Uri uri = Uri.parse("mailto:test1@abc.com?cc=test3@abc.com");
|
||||
MailTo mailToHelper = MailTo.parse(uri);
|
||||
|
||||
Address[] emailAddressList = mailToHelper.getCc();
|
||||
|
||||
assertEquals(emailAddressList[0].getAddress(), "test3@abc.com");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetCc_multipleEmailAddress() {
|
||||
Uri uri = Uri.parse("mailto:test1@abc.com?cc=test3@abc.com,test4@abc.com");
|
||||
MailTo mailToHelper = MailTo.parse(uri);
|
||||
|
||||
Address[] emailAddressList = mailToHelper.getCc();
|
||||
|
||||
assertEquals(emailAddressList[0].getAddress(), "test3@abc.com");
|
||||
assertEquals(emailAddressList[1].getAddress(), "test4@abc.com");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetBcc_singleEmailAddress() {
|
||||
Uri uri = Uri.parse("mailto:?bcc=test3@abc.com");
|
||||
MailTo mailToHelper = MailTo.parse(uri);
|
||||
|
||||
Address[] emailAddressList = mailToHelper.getBcc();
|
||||
|
||||
assertEquals(emailAddressList[0].getAddress(), "test3@abc.com");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetBcc_multipleEmailAddress() {
|
||||
Uri uri = Uri.parse("mailto:?bcc=test3@abc.com&bcc=test4@abc.com");
|
||||
MailTo mailToHelper = MailTo.parse(uri);
|
||||
|
||||
Address[] emailAddressList = mailToHelper.getBcc();
|
||||
|
||||
assertEquals(emailAddressList[0].getAddress(), "test3@abc.com");
|
||||
assertEquals(emailAddressList[1].getAddress(), "test4@abc.com");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSubject() {
|
||||
Uri uri = Uri.parse("mailto:?subject=Hello");
|
||||
MailTo mailToHelper = MailTo.parse(uri);
|
||||
|
||||
String subject = mailToHelper.getSubject();
|
||||
|
||||
assertEquals(subject, "Hello");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetBody() {
|
||||
Uri uri = Uri.parse("mailto:?body=Test%20Body&something=else");
|
||||
MailTo mailToHelper = MailTo.parse(uri);
|
||||
|
||||
String subject = mailToHelper.getBody();
|
||||
|
||||
assertEquals(subject, "Test Body");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCaseInsensitiveParamWrapper() {
|
||||
Uri uri = Uri.parse("scheme://authority?a=one&b=two&c=three");
|
||||
CaseInsensitiveParamWrapper caseInsensitiveParamWrapper = new CaseInsensitiveParamWrapper(uri);
|
||||
|
||||
List<String> result = caseInsensitiveParamWrapper.getQueryParameters("b");
|
||||
|
||||
assertThat(Collections.singletonList("two"), is(result));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCaseInsensitiveParamWrapper_multipleMatchingQueryParameters() {
|
||||
Uri uri = Uri.parse("scheme://authority?xname=one&name=two&Name=Three&NAME=FOUR");
|
||||
CaseInsensitiveParamWrapper caseInsensitiveParamWrapper = new CaseInsensitiveParamWrapper(uri);
|
||||
|
||||
List<String> result = caseInsensitiveParamWrapper.getQueryParameters("name");
|
||||
|
||||
assertThat(Arrays.asList("two", "Three", "FOUR"), is(result));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCaseInsensitiveParamWrapper_withoutQueryParameters() {
|
||||
Uri uri = Uri.parse("scheme://authority");
|
||||
CaseInsensitiveParamWrapper caseInsensitiveParamWrapper = new CaseInsensitiveParamWrapper(uri);
|
||||
|
||||
List<String> result = caseInsensitiveParamWrapper.getQueryParameters("name");
|
||||
|
||||
assertThat(Collections.<String>emptyList(), is(result));
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue