2009-03-04 03:32:22 +00:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2009 The Android Open Source Project
|
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*/
|
|
|
|
|
2011-02-10 02:47:43 +00:00
|
|
|
package com.android.emailcommon.internet;
|
2009-03-04 03:32:22 +00:00
|
|
|
|
2014-01-25 00:43:36 +00:00
|
|
|
import android.test.AndroidTestCase;
|
|
|
|
import android.test.suitebuilder.annotation.MediumTest;
|
|
|
|
import android.test.suitebuilder.annotation.SmallTest;
|
|
|
|
|
2011-02-11 23:05:17 +00:00
|
|
|
import com.android.emailcommon.TempDirectory;
|
2011-02-10 02:47:43 +00:00
|
|
|
import com.android.emailcommon.mail.Address;
|
|
|
|
import com.android.emailcommon.mail.Flag;
|
|
|
|
import com.android.emailcommon.mail.Message.RecipientType;
|
2011-02-11 23:05:17 +00:00
|
|
|
import com.android.emailcommon.mail.MessagingException;
|
2009-03-04 03:32:22 +00:00
|
|
|
|
2009-12-08 20:59:40 +00:00
|
|
|
import java.io.ByteArrayInputStream;
|
2009-05-28 02:03:34 +00:00
|
|
|
import java.io.ByteArrayOutputStream;
|
2009-12-08 20:59:40 +00:00
|
|
|
import java.io.IOException;
|
2009-03-04 03:32:22 +00:00
|
|
|
import java.text.ParseException;
|
|
|
|
import java.text.SimpleDateFormat;
|
|
|
|
import java.util.Date;
|
|
|
|
import java.util.Locale;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This is a series of unit tests for the MimeMessage class. These tests must be locally
|
|
|
|
* complete - no server(s) required.
|
|
|
|
*/
|
|
|
|
@SmallTest
|
2010-04-23 01:03:00 +00:00
|
|
|
public class MimeMessageTest extends AndroidTestCase {
|
2010-02-10 19:32:05 +00:00
|
|
|
|
2009-03-25 02:53:32 +00:00
|
|
|
/** up arrow, down arrow, left arrow, right arrow */
|
|
|
|
private final String SHORT_UNICODE = "\u2191\u2193\u2190\u2192";
|
|
|
|
private final String SHORT_UNICODE_ENCODED = "=?UTF-8?B?4oaR4oaT4oaQ4oaS?=";
|
2010-02-10 19:32:05 +00:00
|
|
|
|
2009-03-25 02:53:32 +00:00
|
|
|
/** a string without any unicode */
|
|
|
|
private final String SHORT_PLAIN = "abcd";
|
2010-02-10 19:32:05 +00:00
|
|
|
|
2009-03-25 02:53:32 +00:00
|
|
|
/** longer unicode strings */
|
2010-02-10 19:32:05 +00:00
|
|
|
private final String LONG_UNICODE_16 = SHORT_UNICODE + SHORT_UNICODE +
|
2009-03-25 02:53:32 +00:00
|
|
|
SHORT_UNICODE + SHORT_UNICODE;
|
2010-02-10 19:32:05 +00:00
|
|
|
private final String LONG_UNICODE_64 = LONG_UNICODE_16 + LONG_UNICODE_16 +
|
2009-03-25 02:53:32 +00:00
|
|
|
LONG_UNICODE_16 + LONG_UNICODE_16;
|
|
|
|
|
|
|
|
/** longer plain strings (with fold points) */
|
|
|
|
private final String LONG_PLAIN_16 = "abcdefgh ijklmno";
|
2010-02-10 19:32:05 +00:00
|
|
|
private final String LONG_PLAIN_64 =
|
2009-03-25 02:53:32 +00:00
|
|
|
LONG_PLAIN_16 + LONG_PLAIN_16 + LONG_PLAIN_16 + LONG_PLAIN_16;
|
2010-02-10 19:32:05 +00:00
|
|
|
private final String LONG_PLAIN_256 =
|
2009-03-25 02:53:32 +00:00
|
|
|
LONG_PLAIN_64 + LONG_PLAIN_64 + LONG_PLAIN_64 + LONG_PLAIN_64;
|
2009-03-04 03:32:22 +00:00
|
|
|
|
2010-04-23 01:03:00 +00:00
|
|
|
@Override
|
|
|
|
protected void setUp() throws Exception {
|
|
|
|
super.setUp();
|
2011-02-11 23:05:17 +00:00
|
|
|
TempDirectory.setTempDirectory(getContext());
|
2010-04-23 01:03:00 +00:00
|
|
|
}
|
|
|
|
|
2009-03-04 03:32:22 +00:00
|
|
|
/**
|
|
|
|
* Confirms that setSentDate() correctly set the "Date" header of a Mime message.
|
2010-02-10 19:32:05 +00:00
|
|
|
*
|
2009-03-04 03:32:22 +00:00
|
|
|
* We tries a same test twice using two locales, Locale.US and the other, since
|
|
|
|
* MimeMessage depends on the date formatter, which may emit wrong date format
|
|
|
|
* in the locale other than Locale.US.
|
|
|
|
* @throws MessagingException
|
|
|
|
* @throws ParseException
|
|
|
|
*/
|
2009-06-18 19:16:28 +00:00
|
|
|
@MediumTest
|
2009-03-04 03:32:22 +00:00
|
|
|
public void testSetSentDate() throws MessagingException, ParseException {
|
|
|
|
Locale savedLocale = Locale.getDefault();
|
|
|
|
Locale.setDefault(Locale.US);
|
2010-02-10 19:32:05 +00:00
|
|
|
doTestSetSentDate();
|
2009-03-04 03:32:22 +00:00
|
|
|
Locale.setDefault(Locale.JAPAN);
|
2010-02-10 19:32:05 +00:00
|
|
|
doTestSetSentDate();
|
2009-03-04 03:32:22 +00:00
|
|
|
Locale.setDefault(savedLocale);
|
|
|
|
}
|
2010-02-10 19:32:05 +00:00
|
|
|
|
2009-03-04 03:32:22 +00:00
|
|
|
private void doTestSetSentDate() throws MessagingException, ParseException {
|
2010-02-10 19:32:05 +00:00
|
|
|
// "Thu, 01 Jan 2009 09:00:00 +0000" => 1230800400000L
|
2009-03-04 03:32:22 +00:00
|
|
|
long expectedTime = 1230800400000L;
|
|
|
|
Date date = new Date(expectedTime);
|
|
|
|
MimeMessage message = new MimeMessage();
|
|
|
|
message.setSentDate(date);
|
|
|
|
String[] headers = message.getHeader("Date");
|
|
|
|
assertEquals(1, headers.length);
|
|
|
|
// Explicitly specify the locale so that the object does not depend on the default
|
|
|
|
// locale.
|
|
|
|
SimpleDateFormat format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss Z", Locale.US);
|
2010-02-10 19:32:05 +00:00
|
|
|
|
2009-03-04 03:32:22 +00:00
|
|
|
Date result = format.parse(headers[0]);
|
|
|
|
assertEquals(expectedTime, result.getTime());
|
|
|
|
}
|
2010-02-10 19:32:05 +00:00
|
|
|
|
2009-03-13 20:04:24 +00:00
|
|
|
/**
|
|
|
|
* Simple tests of the new "Message-ID" header
|
|
|
|
*/
|
|
|
|
public void testMessageId() throws MessagingException {
|
2010-02-10 19:32:05 +00:00
|
|
|
|
2009-03-13 20:04:24 +00:00
|
|
|
// Test 1. Every message gets a default and unique message-id
|
|
|
|
MimeMessage message1 = new MimeMessage();
|
|
|
|
MimeMessage message2 = new MimeMessage();
|
|
|
|
String id1 = message1.getMessageId();
|
|
|
|
String id2 = message2.getMessageId();
|
|
|
|
assertNotNull(id1);
|
|
|
|
assertNotNull(id2);
|
|
|
|
assertFalse("Message-ID should be unique", id1.equals(id2));
|
2010-02-10 19:32:05 +00:00
|
|
|
|
2009-03-13 20:04:24 +00:00
|
|
|
// Test 2. Set and get using API
|
|
|
|
final String testId1 = "test-message-id-one";
|
|
|
|
message1.setMessageId(testId1);
|
|
|
|
assertEquals("set and get Message-ID", testId1, message1.getMessageId());
|
2010-02-10 19:32:05 +00:00
|
|
|
|
2009-03-13 20:04:24 +00:00
|
|
|
// Test 3. Should only be one Message-ID per message
|
|
|
|
final String testId2 = "test-message-id-two";
|
|
|
|
message2.setMessageId(testId1);
|
|
|
|
message2.setMessageId(testId2);
|
|
|
|
assertEquals("set and get Message-ID", testId2, message2.getMessageId());
|
|
|
|
}
|
2009-03-19 00:39:48 +00:00
|
|
|
|
2009-03-25 02:53:32 +00:00
|
|
|
/**
|
2009-03-19 00:39:48 +00:00
|
|
|
* Confirm getContentID() correctly works.
|
|
|
|
*/
|
|
|
|
public void testGetContentId() throws MessagingException {
|
|
|
|
MimeMessage message = new MimeMessage();
|
|
|
|
|
|
|
|
// no content-id
|
|
|
|
assertNull(message.getContentId());
|
|
|
|
|
|
|
|
// normal case
|
|
|
|
final String cid1 = "cid.1@android.com";
|
|
|
|
message.setHeader(MimeHeader.HEADER_CONTENT_ID, cid1);
|
|
|
|
assertEquals(cid1, message.getContentId());
|
|
|
|
|
|
|
|
// surrounded by optional bracket
|
|
|
|
message.setHeader(MimeHeader.HEADER_CONTENT_ID, "<" + cid1 + ">");
|
|
|
|
assertEquals(cid1, message.getContentId());
|
|
|
|
}
|
2010-02-10 19:32:05 +00:00
|
|
|
|
2009-03-25 02:53:32 +00:00
|
|
|
/**
|
|
|
|
* Confirm that setSubject() works with plain strings
|
|
|
|
*/
|
|
|
|
public void testSetSubjectPlain() throws MessagingException {
|
|
|
|
MimeMessage message = new MimeMessage();
|
|
|
|
|
|
|
|
message.setSubject(SHORT_PLAIN);
|
2010-02-10 19:32:05 +00:00
|
|
|
|
2009-03-25 02:53:32 +00:00
|
|
|
// test 1: readback
|
|
|
|
assertEquals("plain subjects", SHORT_PLAIN, message.getSubject());
|
2010-02-10 19:32:05 +00:00
|
|
|
|
2009-03-25 02:53:32 +00:00
|
|
|
// test 2: raw readback is not escaped
|
|
|
|
String rawHeader = message.getFirstHeader("Subject");
|
|
|
|
assertEquals("plain subject not encoded", -1, rawHeader.indexOf("=?"));
|
2010-02-10 19:32:05 +00:00
|
|
|
|
2009-03-25 02:53:32 +00:00
|
|
|
// test 3: long subject (shouldn't fold)
|
|
|
|
message.setSubject(LONG_PLAIN_64);
|
|
|
|
rawHeader = message.getFirstHeader("Subject");
|
|
|
|
String[] split = rawHeader.split("\r\n");
|
|
|
|
assertEquals("64 shouldn't fold", 1, split.length);
|
2010-02-10 19:32:05 +00:00
|
|
|
|
2009-03-25 02:53:32 +00:00
|
|
|
// test 4: very long subject (should fold)
|
|
|
|
message.setSubject(LONG_PLAIN_256);
|
|
|
|
rawHeader = message.getFirstHeader("Subject");
|
|
|
|
split = rawHeader.split("\r\n");
|
|
|
|
assertTrue("long subject should fold", split.length > 1);
|
|
|
|
for (String s : split) {
|
|
|
|
assertTrue("split lines max length 78", s.length() <= 76); // 76+\r\n = 78
|
|
|
|
String trimmed = s.trim();
|
|
|
|
assertFalse("split lines are not encoded", trimmed.startsWith("=?"));
|
|
|
|
}
|
|
|
|
}
|
2010-02-10 19:32:05 +00:00
|
|
|
|
2009-03-25 02:53:32 +00:00
|
|
|
/**
|
|
|
|
* Confirm that setSubject() works with unicode strings
|
|
|
|
*/
|
|
|
|
public void testSetSubject() throws MessagingException {
|
|
|
|
MimeMessage message = new MimeMessage();
|
|
|
|
|
|
|
|
message.setSubject(SHORT_UNICODE);
|
2010-02-10 19:32:05 +00:00
|
|
|
|
2009-03-25 02:53:32 +00:00
|
|
|
// test 1: readback in unicode
|
|
|
|
assertEquals("unicode readback", SHORT_UNICODE, message.getSubject());
|
2010-02-10 19:32:05 +00:00
|
|
|
|
2009-03-25 02:53:32 +00:00
|
|
|
// test 2: raw readback is escaped
|
|
|
|
String rawHeader = message.getFirstHeader("Subject");
|
|
|
|
assertEquals("raw readback", SHORT_UNICODE_ENCODED, rawHeader);
|
|
|
|
}
|
2010-02-10 19:32:05 +00:00
|
|
|
|
2009-03-25 02:53:32 +00:00
|
|
|
/**
|
|
|
|
* Confirm folding operations on unicode subjects
|
|
|
|
*/
|
|
|
|
public void testSetLongSubject() throws MessagingException {
|
|
|
|
MimeMessage message = new MimeMessage();
|
2010-02-10 19:32:05 +00:00
|
|
|
|
2009-03-25 02:53:32 +00:00
|
|
|
// test 1: long unicode - readback in unicode
|
|
|
|
message.setSubject(LONG_UNICODE_16);
|
|
|
|
assertEquals("unicode readback 16", LONG_UNICODE_16, message.getSubject());
|
2010-02-10 19:32:05 +00:00
|
|
|
|
2009-03-25 02:53:32 +00:00
|
|
|
// test 2: longer unicode (will fold)
|
|
|
|
message.setSubject(LONG_UNICODE_64);
|
|
|
|
assertEquals("unicode readback 64", LONG_UNICODE_64, message.getSubject());
|
2010-02-10 19:32:05 +00:00
|
|
|
|
2009-03-25 02:53:32 +00:00
|
|
|
// test 3: check folding & encoding
|
|
|
|
String rawHeader = message.getFirstHeader("Subject");
|
|
|
|
String[] split = rawHeader.split("\r\n");
|
|
|
|
assertTrue("long subject should fold", split.length > 1);
|
|
|
|
for (String s : split) {
|
|
|
|
assertTrue("split lines max length 78", s.length() <= 76); // 76+\r\n = 78
|
|
|
|
String trimmed = s.trim();
|
2010-02-10 19:32:05 +00:00
|
|
|
assertTrue("split lines are encoded",
|
2009-03-25 02:53:32 +00:00
|
|
|
trimmed.startsWith("=?") && trimmed.endsWith("?="));
|
|
|
|
}
|
|
|
|
}
|
2010-02-10 19:32:05 +00:00
|
|
|
|
2009-04-15 22:29:00 +00:00
|
|
|
/**
|
2009-04-30 17:18:00 +00:00
|
|
|
* Test for encoding address field.
|
|
|
|
*/
|
|
|
|
public void testEncodingAddressField() throws MessagingException {
|
|
|
|
Address noName1 = new Address("noname1@dom1.com");
|
|
|
|
Address noName2 = new Address("<noname2@dom2.com>", "");
|
|
|
|
Address simpleName = new Address("address3@dom3.org", "simple long and long long name");
|
|
|
|
Address dquoteName = new Address("address4@dom4.org", "name,4,long long name");
|
|
|
|
Address quotedName = new Address("bigG@dom5.net", "big \"G\"");
|
|
|
|
Address utf16Name = new Address("<address6@co.jp>", "\"\u65E5\u672C\u8A9E\"");
|
|
|
|
Address utf32Name = new Address("<address8@ne.jp>", "\uD834\uDF01\uD834\uDF46");
|
2010-02-10 19:32:05 +00:00
|
|
|
|
2009-04-30 17:18:00 +00:00
|
|
|
MimeMessage message = new MimeMessage();
|
2010-02-10 19:32:05 +00:00
|
|
|
|
2009-04-30 17:18:00 +00:00
|
|
|
message.setFrom(noName1);
|
|
|
|
message.setRecipient(RecipientType.TO, noName2);
|
|
|
|
message.setRecipients(RecipientType.CC, new Address[] { simpleName, dquoteName });
|
|
|
|
message.setReplyTo(new Address[] { quotedName, utf16Name, utf32Name });
|
2010-02-10 19:32:05 +00:00
|
|
|
|
2009-04-30 17:18:00 +00:00
|
|
|
String[] from = message.getHeader("From");
|
|
|
|
String[] to = message.getHeader("To");
|
|
|
|
String[] cc = message.getHeader("Cc");
|
|
|
|
String[] replyTo = message.getHeader("Reply-to");
|
2010-02-10 19:32:05 +00:00
|
|
|
|
|
|
|
assertEquals("from address count", 1, from.length);
|
2009-04-30 17:18:00 +00:00
|
|
|
assertEquals("no name 1", "noname1@dom1.com", from[0]);
|
2010-02-10 19:32:05 +00:00
|
|
|
|
|
|
|
assertEquals("to address count", 1, to.length);
|
2009-04-30 17:18:00 +00:00
|
|
|
assertEquals("no name 2", "noname2@dom2.com", to[0]);
|
2010-02-10 19:32:05 +00:00
|
|
|
|
2009-04-30 17:18:00 +00:00
|
|
|
// folded.
|
2010-02-10 19:32:05 +00:00
|
|
|
assertEquals("cc address count", 1, cc.length);
|
2009-04-30 17:18:00 +00:00
|
|
|
assertEquals("simple name & double quoted name",
|
|
|
|
"simple long and long long name <address3@dom3.org>, \"name,4,long long\r\n"
|
|
|
|
+ " name\" <address4@dom4.org>",
|
|
|
|
cc[0]);
|
2010-02-10 19:32:05 +00:00
|
|
|
|
2009-04-30 17:18:00 +00:00
|
|
|
// folded and encoded.
|
2010-02-10 19:32:05 +00:00
|
|
|
assertEquals("reply-to address count", 1, replyTo.length);
|
2009-04-30 17:18:00 +00:00
|
|
|
assertEquals("quoted name & encoded name",
|
|
|
|
"\"big \\\"G\\\"\" <bigG@dom5.net>, =?UTF-8?B?5pel5pys6Kqe?=\r\n"
|
|
|
|
+ " <address6@co.jp>, =?UTF-8?B?8J2MgfCdjYY=?= <address8@ne.jp>",
|
|
|
|
replyTo[0]);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Test for parsing address field.
|
|
|
|
*/
|
2014-01-25 00:43:36 +00:00
|
|
|
public void testParsingAddressField() throws MessagingException {
|
2009-04-30 17:18:00 +00:00
|
|
|
MimeMessage message = new MimeMessage();
|
2010-02-10 19:32:05 +00:00
|
|
|
|
2009-04-30 17:18:00 +00:00
|
|
|
message.setHeader("From", "noname1@dom1.com");
|
|
|
|
message.setHeader("To", "<noname2@dom2.com>");
|
|
|
|
// folded.
|
|
|
|
message.setHeader("Cc",
|
|
|
|
"simple name <address3@dom3.org>,\r\n"
|
|
|
|
+ " \"name,4\" <address4@dom4.org>");
|
|
|
|
// folded and encoded.
|
2010-02-10 19:32:05 +00:00
|
|
|
message.setHeader("Reply-to",
|
2009-04-30 17:18:00 +00:00
|
|
|
"\"big \\\"G\\\"\" <bigG@dom5.net>,\r\n"
|
|
|
|
+ " =?UTF-8?B?5pel5pys6Kqe?=\r\n"
|
|
|
|
+ " <address6@co.jp>,\n"
|
|
|
|
+ " \"=?UTF-8?B?8J2MgfCdjYY=?=\" <address8@ne.jp>");
|
2010-02-10 19:32:05 +00:00
|
|
|
|
2009-04-30 17:18:00 +00:00
|
|
|
Address[] from = message.getFrom();
|
|
|
|
Address[] to = message.getRecipients(RecipientType.TO);
|
|
|
|
Address[] cc = message.getRecipients(RecipientType.CC);
|
|
|
|
Address[] replyTo = message.getReplyTo();
|
2010-02-10 19:32:05 +00:00
|
|
|
|
|
|
|
assertEquals("from address count", 1, from.length);
|
2009-04-30 17:18:00 +00:00
|
|
|
assertEquals("no name 1 address", "noname1@dom1.com", from[0].getAddress());
|
|
|
|
assertNull("no name 1 name", from[0].getPersonal());
|
2010-02-10 19:32:05 +00:00
|
|
|
|
|
|
|
assertEquals("to address count", 1, to.length);
|
2009-04-30 17:18:00 +00:00
|
|
|
assertEquals("no name 2 address", "noname2@dom2.com", to[0].getAddress());
|
|
|
|
assertNull("no name 2 name", to[0].getPersonal());
|
|
|
|
|
2010-02-10 19:32:05 +00:00
|
|
|
assertEquals("cc address count", 2, cc.length);
|
2009-04-30 17:18:00 +00:00
|
|
|
assertEquals("simple name address", "address3@dom3.org", cc[0].getAddress());
|
|
|
|
assertEquals("simple name name", "simple name", cc[0].getPersonal());
|
|
|
|
assertEquals("double quoted name address", "address4@dom4.org", cc[1].getAddress());
|
|
|
|
assertEquals("double quoted name name", "name,4", cc[1].getPersonal());
|
|
|
|
|
2010-02-10 19:32:05 +00:00
|
|
|
assertEquals("reply-to address count", 3, replyTo.length);
|
2009-04-30 17:18:00 +00:00
|
|
|
assertEquals("quoted name address", "bigG@dom5.net", replyTo[0].getAddress());
|
|
|
|
assertEquals("quoted name name", "big \"G\"", replyTo[0].getPersonal());
|
|
|
|
assertEquals("utf-16 name address", "address6@co.jp", replyTo[1].getAddress());
|
|
|
|
assertEquals("utf-16 name name", "\u65E5\u672C\u8A9E", replyTo[1].getPersonal());
|
|
|
|
assertEquals("utf-32 name address", "address8@ne.jp", replyTo[2].getAddress());
|
|
|
|
assertEquals("utf-32 name name", "\uD834\uDF01\uD834\uDF46", replyTo[2].getPersonal());
|
|
|
|
}
|
2010-02-10 19:32:05 +00:00
|
|
|
|
2009-04-30 17:18:00 +00:00
|
|
|
/*
|
2009-04-15 22:29:00 +00:00
|
|
|
* Test setting & getting store-specific flags
|
|
|
|
*/
|
|
|
|
public void testStoreFlags() throws MessagingException {
|
|
|
|
MimeMessage message = new MimeMessage();
|
|
|
|
|
|
|
|
// Message should create with no flags
|
|
|
|
Flag[] flags = message.getFlags();
|
|
|
|
assertEquals(0, flags.length);
|
|
|
|
|
|
|
|
// Set a store flag
|
|
|
|
message.setFlag(Flag.X_STORE_1, true);
|
|
|
|
assertTrue(message.isSet(Flag.X_STORE_1));
|
|
|
|
assertFalse(message.isSet(Flag.X_STORE_2));
|
|
|
|
|
|
|
|
// Set another
|
|
|
|
message.setFlag(Flag.X_STORE_2, true);
|
|
|
|
assertTrue(message.isSet(Flag.X_STORE_1));
|
|
|
|
assertTrue(message.isSet(Flag.X_STORE_2));
|
|
|
|
|
|
|
|
// Set some and clear some
|
|
|
|
message.setFlag(Flag.X_STORE_1, false);
|
|
|
|
assertFalse(message.isSet(Flag.X_STORE_1));
|
|
|
|
assertTrue(message.isSet(Flag.X_STORE_2));
|
|
|
|
|
|
|
|
}
|
2009-03-25 02:53:32 +00:00
|
|
|
|
2009-05-28 02:03:34 +00:00
|
|
|
/*
|
|
|
|
* Test for setExtendedHeader() and getExtendedHeader()
|
|
|
|
*/
|
|
|
|
public void testExtendedHeader() throws MessagingException {
|
|
|
|
MimeMessage message = new MimeMessage();
|
2010-02-10 19:32:05 +00:00
|
|
|
|
2009-05-28 02:03:34 +00:00
|
|
|
assertNull("non existent header", message.getExtendedHeader("X-Non-Existent"));
|
2010-02-10 19:32:05 +00:00
|
|
|
|
2009-05-28 02:03:34 +00:00
|
|
|
message.setExtendedHeader("X-Header1", "value1");
|
|
|
|
message.setExtendedHeader("X-Header2", "value2\n value3\r\n value4\r\n");
|
|
|
|
assertEquals("simple value", "value1",
|
|
|
|
message.getExtendedHeader("X-Header1"));
|
|
|
|
assertEquals("multi line value", "value2 value3 value4",
|
|
|
|
message.getExtendedHeader("X-Header2"));
|
|
|
|
assertNull("non existent header 2", message.getExtendedHeader("X-Non-Existent"));
|
2010-02-10 19:32:05 +00:00
|
|
|
|
2009-05-28 02:03:34 +00:00
|
|
|
message.setExtendedHeader("X-Header1", "value4");
|
|
|
|
assertEquals("over written value", "value4", message.getExtendedHeader("X-Header1"));
|
2010-02-10 19:32:05 +00:00
|
|
|
|
2009-05-28 02:03:34 +00:00
|
|
|
message.setExtendedHeader("X-Header1", null);
|
|
|
|
assertNull("remove header", message.getExtendedHeader("X-Header1"));
|
|
|
|
}
|
2010-02-10 19:32:05 +00:00
|
|
|
|
2009-05-28 02:03:34 +00:00
|
|
|
/*
|
|
|
|
* Test for setExtendedHeaders() and getExtendedheaders()
|
|
|
|
*/
|
|
|
|
public void testExtendedHeaders() throws MessagingException {
|
|
|
|
MimeMessage message = new MimeMessage();
|
|
|
|
|
|
|
|
assertNull("new message", message.getExtendedHeaders());
|
|
|
|
message.setExtendedHeaders(null);
|
|
|
|
assertNull("null headers", message.getExtendedHeaders());
|
|
|
|
message.setExtendedHeaders("");
|
|
|
|
assertNull("empty headers", message.getExtendedHeaders());
|
2010-02-10 19:32:05 +00:00
|
|
|
|
2009-05-28 02:03:34 +00:00
|
|
|
message.setExtendedHeaders("X-Header1: value1\r\n");
|
|
|
|
assertEquals("header 1 value", "value1", message.getExtendedHeader("X-Header1"));
|
|
|
|
assertEquals("header 1", "X-Header1: value1\r\n", message.getExtendedHeaders());
|
2010-02-10 19:32:05 +00:00
|
|
|
|
2009-05-28 02:03:34 +00:00
|
|
|
message.setExtendedHeaders(null);
|
|
|
|
message.setExtendedHeader("X-Header2", "value2");
|
|
|
|
message.setExtendedHeader("X-Header3", "value3\n value4\r\n value5\r\n");
|
|
|
|
assertEquals("headers 2,3",
|
|
|
|
"X-Header2: value2\r\n" +
|
|
|
|
"X-Header3: value3 value4 value5\r\n",
|
|
|
|
message.getExtendedHeaders());
|
|
|
|
|
|
|
|
message.setExtendedHeaders(
|
|
|
|
"X-Header3: value3 value4 value5\r\n" +
|
|
|
|
"X-Header2: value2\r\n");
|
|
|
|
assertEquals("header 2", "value2", message.getExtendedHeader("X-Header2"));
|
|
|
|
assertEquals("header 3", "value3 value4 value5", message.getExtendedHeader("X-Header3"));
|
|
|
|
assertEquals("headers 3,2",
|
|
|
|
"X-Header3: value3 value4 value5\r\n" +
|
|
|
|
"X-Header2: value2\r\n",
|
|
|
|
message.getExtendedHeaders());
|
|
|
|
}
|
2010-02-10 19:32:05 +00:00
|
|
|
|
2009-05-28 02:03:34 +00:00
|
|
|
/*
|
|
|
|
* Test for writeTo(), only for header part.
|
2010-03-10 04:30:47 +00:00
|
|
|
* NOTE: This test is fragile because it assumes headers will be written in a specific order
|
2009-05-28 02:03:34 +00:00
|
|
|
*/
|
|
|
|
public void testWriteToHeader() throws Exception {
|
|
|
|
MimeMessage message = new MimeMessage();
|
2010-02-10 19:32:05 +00:00
|
|
|
|
2009-05-28 02:03:34 +00:00
|
|
|
message.setHeader("Header1", "value1");
|
|
|
|
message.setHeader(MimeHeader.HEADER_ANDROID_ATTACHMENT_STORE_DATA, "value2");
|
|
|
|
message.setExtendedHeader("X-Header3", "value3");
|
|
|
|
message.setHeader("Header4", "value4");
|
|
|
|
message.setExtendedHeader("X-Header5", "value5");
|
2010-02-10 19:32:05 +00:00
|
|
|
|
2009-05-28 02:03:34 +00:00
|
|
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
|
|
|
message.writeTo(out);
|
|
|
|
out.close();
|
2010-03-10 04:30:47 +00:00
|
|
|
String expectedString =
|
2009-05-28 02:03:34 +00:00
|
|
|
"Header1: value1\r\n" +
|
|
|
|
"Header4: value4\r\n" +
|
2010-03-10 04:30:47 +00:00
|
|
|
"Message-ID: " + message.getMessageId() + "\r\n" +
|
2009-05-28 02:03:34 +00:00
|
|
|
"\r\n";
|
|
|
|
byte[] expected = expectedString.getBytes();
|
|
|
|
byte[] actual = out.toByteArray();
|
|
|
|
assertEquals("output length", expected.length, actual.length);
|
|
|
|
for (int i = 0; i < actual.length; ++i) {
|
|
|
|
assertEquals("output byte["+i+"]", expected[i], actual[i]);
|
|
|
|
}
|
|
|
|
}
|
2010-02-10 19:32:05 +00:00
|
|
|
|
2009-12-08 20:59:40 +00:00
|
|
|
/**
|
|
|
|
* Test for parsing headers with extra whitespace and commennts.
|
|
|
|
*
|
|
|
|
* The lines up to Content-Type were copied directly out of RFC 2822
|
|
|
|
* "Section A.5. White space, comments, and other oddities"
|
|
|
|
*/
|
2013-12-17 02:18:51 +00:00
|
|
|
public void brokentestWhiteSpace() throws MessagingException, IOException {
|
2009-12-08 20:59:40 +00:00
|
|
|
String entireMessage =
|
|
|
|
"From: Pete(A wonderful \\) chap) <pete(his account)@silly.test(his host)>\r\n"+
|
|
|
|
"To:A Group(Some people)\r\n"+
|
|
|
|
" :Chris Jones <c@(Chris's host.)public.example>,\r\n"+
|
|
|
|
" joe@example.org,\r\n"+
|
|
|
|
" John <jdoe@one.test> (my dear friend); (the end of the group)\r\n"+
|
|
|
|
"Cc:(Empty list)(start)Undisclosed recipients :(nobody(that I know)) ;\r\n"+
|
|
|
|
"Date: Thu,\r\n"+
|
|
|
|
" 13\r\n"+
|
|
|
|
" Feb\r\n"+
|
|
|
|
" 1969\r\n"+
|
|
|
|
" 23:32\r\n"+
|
|
|
|
" -0330 (Newfoundland Time)\r\n"+
|
|
|
|
"Message-ID: <testabcd.1234@silly.test>\r\n"+
|
|
|
|
"Content-Type: \r\n"+
|
|
|
|
" TEXT/hTML \r\n"+
|
|
|
|
" ; x-blah=\"y-blah\" ; \r\n"+
|
|
|
|
" CHARSET=\"us-ascii\" ; (comment)\r\n"+
|
|
|
|
"\r\n"+
|
|
|
|
"<html><body>Testing.</body></html>\r\n";
|
|
|
|
MimeMessage mm = null;
|
|
|
|
mm = new MimeMessage(new ByteArrayInputStream(
|
|
|
|
entireMessage.getBytes("us-ascii")));
|
|
|
|
assertTrue(mm.getMimeType(), MimeUtility.mimeTypeMatches("text/html",mm.getMimeType()));
|
|
|
|
assertEquals(new Date(-27723480000L),mm.getSentDate());
|
|
|
|
assertEquals("<testabcd.1234@silly.test>",mm.getMessageId());
|
|
|
|
Address[] toAddresses = mm.getRecipients(MimeMessage.RecipientType.TO);
|
|
|
|
assertEquals("joe@example.org", toAddresses[1].getAddress());
|
|
|
|
assertEquals("jdoe@one.test", toAddresses[2].getAddress());
|
|
|
|
|
|
|
|
|
|
|
|
// Note: The parentheses in the middle of email addresses are not removed.
|
|
|
|
//assertEquals("c@public.example", toAddresses[0].getAddress());
|
|
|
|
//assertEquals("pete@silly.test",mm.getFrom()[0].getAddress());
|
|
|
|
}
|
|
|
|
|
2010-02-10 19:32:05 +00:00
|
|
|
/**
|
|
|
|
* Confirm parser doesn't crash when seeing "Undisclosed recipients:;".
|
|
|
|
*/
|
|
|
|
public void testUndisclosedRecipients() throws MessagingException, IOException {
|
|
|
|
String entireMessage =
|
|
|
|
"To:Undisclosed recipients:;\r\n"+
|
|
|
|
"Cc:Undisclosed recipients:;\r\n"+
|
|
|
|
"Bcc:Undisclosed recipients:;\r\n"+
|
|
|
|
"\r\n";
|
|
|
|
MimeMessage mm = null;
|
|
|
|
mm = new MimeMessage(new ByteArrayInputStream(
|
|
|
|
entireMessage.getBytes("us-ascii")));
|
|
|
|
|
|
|
|
assertEquals(0, mm.getRecipients(MimeMessage.RecipientType.TO).length);
|
|
|
|
assertEquals(0, mm.getRecipients(MimeMessage.RecipientType.CC).length);
|
|
|
|
assertEquals(0, mm.getRecipients(MimeMessage.RecipientType.BCC).length);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Confirm parser doesn't crash when seeing invalid headers/addresses.
|
|
|
|
*/
|
|
|
|
public void testInvalidHeaders() throws MessagingException, IOException {
|
|
|
|
String entireMessage =
|
|
|
|
"To:\r\n"+
|
|
|
|
"Cc:!invalid!address!, a@b.com\r\n"+
|
|
|
|
"Bcc:Undisclosed recipients;\r\n"+ // no colon at the end
|
|
|
|
"invalid header\r\n"+
|
|
|
|
"Message-ID:<testabcd.1234@silly.test>\r\n"+
|
|
|
|
"\r\n"+
|
|
|
|
"Testing\r\n";
|
|
|
|
MimeMessage mm = null;
|
|
|
|
mm = new MimeMessage(new ByteArrayInputStream(
|
|
|
|
entireMessage.getBytes("us-ascii")));
|
|
|
|
|
|
|
|
assertEquals(0, mm.getRecipients(MimeMessage.RecipientType.TO).length);
|
|
|
|
assertEquals(1, mm.getRecipients(MimeMessage.RecipientType.CC).length);
|
|
|
|
assertEquals("a@b.com", mm.getRecipients(MimeMessage.RecipientType.CC)[0].getAddress());
|
|
|
|
assertEquals(0, mm.getRecipients(MimeMessage.RecipientType.BCC).length);
|
Follow-up to MimeMessage efficiency improvements.
I missed a case where message-id should not be set locally, which is
the case where the Mime parser clears all headers *and* does not find
a message-id. The parsed MimeMessage should accurately reflect this.
In the old code, the local id was created at construction time and then
immediately discarded by the parser (calling headers.clear()).
In the new code, I was generating a message-id any time I couldn't find
one. Now, when explicitly cleared or removed, I set a boolean to inhibit
automatic generation of a new one.
I also missed the fact that a missing message-id no longer throws an
exception, it simply returns null, and so I changed the code that was
catching that exception to simply check for null.
(Note: Clearly, modeling of legacy behavior is becoming annoying here;
It would be better to do away with all of the automatic logic, and simply
generate message-id locally when appropriate: On locally-generated
messages. I don't want to touch this for the current release, but I left
a note in the code to this effect.)
Bug: 2504774
Change-Id: Ibfcbd2363c7ae39ee6d44e4c3295f88258cb4945
2010-03-11 00:42:49 +00:00
|
|
|
assertEquals("<testabcd.1234@silly.test>", mm.getMessageId());
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Confirm parser w/o a message-id inhibits a local message-id from being generated
|
|
|
|
*/
|
|
|
|
public void testParseNoMessageId() throws MessagingException, IOException {
|
|
|
|
String entireMessage =
|
|
|
|
"To: user@domain.com\r\n" +
|
|
|
|
"\r\n" +
|
|
|
|
"Testing\r\n";
|
|
|
|
MimeMessage mm = null;
|
|
|
|
mm = new MimeMessage(new ByteArrayInputStream(entireMessage.getBytes("us-ascii")));
|
|
|
|
|
|
|
|
assertNull(mm.getMessageId());
|
2010-02-10 19:32:05 +00:00
|
|
|
}
|
|
|
|
|
2010-04-23 01:03:00 +00:00
|
|
|
/**
|
|
|
|
* Make sure the parser accepts the "eBay style" date format.
|
|
|
|
*
|
|
|
|
* Messages from ebay have been seen that they use the wrong date format.
|
2011-02-11 23:05:17 +00:00
|
|
|
* @see com.android.emailcommon.utility.Utility#cleanUpMimeDate
|
2010-04-23 01:03:00 +00:00
|
|
|
*/
|
|
|
|
public void testEbayDate() throws MessagingException, IOException {
|
|
|
|
String entireMessage =
|
|
|
|
"To:a@b.com\r\n" +
|
|
|
|
"Date:Thu, 10 Dec 09 15:08:08 GMT-0700" +
|
|
|
|
"\r\n" +
|
|
|
|
"\r\n";
|
|
|
|
MimeMessage mm = null;
|
|
|
|
mm = new MimeMessage(new ByteArrayInputStream(entireMessage.getBytes("us-ascii")));
|
|
|
|
Date actual = mm.getSentDate();
|
|
|
|
Date expected = new Date(Date.UTC(109, 11, 10, 15, 8, 8) + 7 * 60 * 60 * 1000);
|
|
|
|
assertEquals(expected, actual);
|
|
|
|
}
|
|
|
|
|
2009-05-28 02:03:34 +00:00
|
|
|
// TODO more test for writeTo()
|
2009-04-30 17:18:00 +00:00
|
|
|
}
|