Added a test for IMAP APPEND

It's a preliminary change for IMAP bug fixes.

Also,
- Fixed a potential bug in ImapFolder.setFlags where it'd throw
  StringIndexOutOfBoundsException if flags is empty.

- Added a generic flag to proguard.flags so that now all methods with
  the "ForTest" sufix are automatically preserved.
  Turned out it wasn't needed for this CL, but it should come in handy
  someday.

Bug 2538076
Change-Id: I49a08afc196c7b7f1f30477dfc38ac5381045d84
This commit is contained in:
Makoto Onuki 2010-04-02 11:09:12 -07:00
parent dc0753373e
commit af6724527e
5 changed files with 89 additions and 16 deletions

View File

@ -26,6 +26,10 @@
# Keep names that are used only by unit tests
-keep class ** {
*** *ForTest(...);
}
-keepclasseswithmembers class com.android.email.GroupMessagingListener {
*** removeListener(com.android.email.MessagingListener);
}
@ -168,4 +172,3 @@
-keep class org.apache.james.mime4j.message.Message {
*;
}

View File

@ -117,7 +117,11 @@ public abstract class Message implements Part, Body {
return getFlagSet().toArray(new Flag[] {});
}
public void setFlag(Flag flag, boolean set) throws MessagingException {
/**
* Set/clear a flag directly, without involving overrides of {@link #setFlag} in subclasses.
* Only used for testing.
*/
public final void setFlagDirectlyForTest(Flag flag, boolean set) throws MessagingException {
if (set) {
getFlagSet().add(flag);
} else {
@ -125,6 +129,10 @@ public abstract class Message implements Part, Body {
}
}
public void setFlag(Flag flag, boolean set) throws MessagingException {
setFlagDirectlyForTest(flag, set);
}
/**
* This method calls setFlag(Flag, boolean)
* @param flags

View File

@ -1265,22 +1265,26 @@ public class ImapStore extends Store {
uidList.append(messages[i].getUid());
}
StringBuilder flagList = new StringBuilder();
for (int i = 0, count = flags.length; i < count; i++) {
Flag flag = flags[i];
if (flag == Flag.SEEN) {
flagList.append(" \\Seen");
} else if (flag == Flag.DELETED) {
flagList.append(" \\Deleted");
} else if (flag == Flag.FLAGGED) {
flagList.append(" \\Flagged");
String allFlags = "";
if (flags.length > 0) {
StringBuilder flagList = new StringBuilder();
for (int i = 0, count = flags.length; i < count; i++) {
Flag flag = flags[i];
if (flag == Flag.SEEN) {
flagList.append(" \\Seen"); // TODO this can be a field of Flag...
} else if (flag == Flag.DELETED) {
flagList.append(" \\Deleted");
} else if (flag == Flag.FLAGGED) {
flagList.append(" \\Flagged");
}
}
allFlags = flagList.substring(1);
}
try {
mConnection.executeSimpleCommand(String.format("UID STORE %s %sFLAGS.SILENT (%s)",
uidList,
value ? "+" : "-",
flagList.substring(1))); // Remove the first space
allFlags));
}
catch (IOException ioe) {
throw ioExceptionHandler(mConnection, ioe);
@ -1513,6 +1517,7 @@ public class ImapStore extends Store {
this.mSize = size;
}
@Override
public void parse(InputStream in) throws IOException, MessagingException {
super.parse(in);
}

View File

@ -16,6 +16,7 @@
package com.android.email.mail.store;
import com.android.email.mail.Address;
import com.android.email.mail.FetchProfile;
import com.android.email.mail.Flag;
import com.android.email.mail.Folder;
@ -25,8 +26,11 @@ import com.android.email.mail.Part;
import com.android.email.mail.Transport;
import com.android.email.mail.Folder.FolderType;
import com.android.email.mail.Folder.OpenMode;
import com.android.email.mail.Message.RecipientType;
import com.android.email.mail.internet.BinaryTempFileBody;
import com.android.email.mail.internet.MimeUtility;
import com.android.email.mail.internet.TextBody;
import com.android.email.mail.store.ImapStore.ImapMessage;
import com.android.email.mail.transport.DiscourseLogger;
import com.android.email.mail.transport.MockTransport;
@ -48,6 +52,7 @@ import java.util.Locale;
*/
@SmallTest
public class ImapStoreUnitTests extends AndroidTestCase {
private final static String[] NO_REPLY = new String[0];
/* These values are provided by setUp() */
private ImapStore mStore = null;
@ -555,4 +560,43 @@ public class ImapStoreUnitTests extends AndroidTestCase {
// And the message is "SEEN".
assertTrue(message1.isSet(Flag.SEEN));
}
public void testAppendMessages() throws Exception {
MockTransport mock = openAndInjectMockTransport();
setupOpenFolder(mock);
mFolder.open(OpenMode.READ_WRITE, null);
ImapMessage message = (ImapMessage) mFolder.createMessage("1");
message.setFrom(new Address("me@test.com"));
message.setRecipient(RecipientType.TO, new Address("you@test.com"));
message.setMessageId("<message.id@test.com>");
message.setFlagDirectlyForTest(Flag.SEEN, true);
message.setBody(new TextBody("Test Body"));
// + go ahead
// * 12345 EXISTS
// OK [APPENDUID 627684530 17] (Success)
mock.expect(getNextTag(false) + " APPEND \\\"INBOX\\\" \\(\\\\Seen\\) \\{166\\}",
new String[] {"+ go ahead"});
mock.expectLiterally("From: me@test.com", NO_REPLY);
mock.expectLiterally("To: you@test.com", NO_REPLY);
mock.expectLiterally("Message-ID: <message.id@test.com>", NO_REPLY);
mock.expectLiterally("Content-Type: text/plain;", NO_REPLY);
mock.expectLiterally(" charset=utf-8", NO_REPLY);
mock.expectLiterally("Content-Transfer-Encoding: base64", NO_REPLY);
mock.expectLiterally("", NO_REPLY);
mock.expectLiterally("VGVzdCBCb2R5", NO_REPLY);
mock.expectLiterally("", new String[] {
"* 7 EXISTS",
getNextTag(true) + " OK [APPENDUID 1234567 13] (Success)"
});
mFolder.appendMessages(new Message[] {message});
mock.close();
assertEquals("13", message.getUid());
assertEquals(7, mFolder.getMessageCount());
}
}

View File

@ -26,6 +26,9 @@ import java.io.OutputStream;
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.regex.Pattern;
import junit.framework.Assert;
/**
* This is a mock Transport that is used to test protocols that use MailTransport.
@ -115,7 +118,15 @@ public class MockTransport implements Transport {
Transaction pair = new Transaction(pattern, responses);
mPairs.add(pair);
}
/**
* Same as {@link #expect(String, String[])}, but the first arg is taken literally, rather than
* as a regexp.
*/
public void expectLiterally(String literal, String[] responses) {
expect("^" + Pattern.quote(literal) + "$", responses);
}
/**
* Tell the Mock Transport that we expect it to be closed. This will preserve
* the remaining entries in the expect() stream and allow us to "ride over" the close (which
@ -192,7 +203,7 @@ public class MockTransport implements Transport {
}
public OutputStream getOutputStream() {
SmtpSenderUnitTests.assertTrue(mOpen);
Assert.assertTrue(mOpen);
return new MockOutputStream();
}
@ -302,9 +313,11 @@ public class MockTransport implements Transport {
Log.d(LOG_TAG, ">>> " + s);
}
SmtpSenderUnitTests.assertTrue(mOpen);
SmtpSenderUnitTests.assertTrue("Overflow writing to MockTransport", 0 != mPairs.size());
SmtpSenderUnitTests.assertTrue("Overflow writing to MockTransport: Getting " + s,
0 != mPairs.size());
Transaction pair = mPairs.remove(0);
SmtpSenderUnitTests.assertTrue("Unexpected string written to MockTransport",
SmtpSenderUnitTests.assertTrue("Unexpected string written to MockTransport: Actual=" + s
+ " Expected=" + pair.mPattern,
pair.mPattern != null && s.matches(pair.mPattern));
if (pair.mResponses != null) {
sendResponse(pair.mResponses);