DO NOT MERGE: Handle multiple IMAP SEARCH results.
Apparently IMAP servers may return multiple SEARCH responses for a single SEARCH command, and we need to handle all of them. Before the IMAP rework there was 3 methods that issued the SEARCH command. Two of them ware doing it right, but the other wasn't, which was what I copied from, unfortunately! In case you're wondering, originally the test for this method was done through upper methods, e.g. getMessage(). Bug 2911647 Backport of Ia50072944d5b01c1e59541c3a966067b13910cc4 Change-Id: Iab5d3fa21e403f2e1043990112154fbb72322b02
This commit is contained in:
parent
8aa79ba695
commit
29f0638f4d
|
@ -744,7 +744,7 @@ public class ImapStore extends Store {
|
||||||
throw new Error("ImapStore.delete() not yet implemented");
|
throw new Error("ImapStore.delete() not yet implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
private String[] searchForUids(String searchCriteria)
|
/* package */ String[] searchForUids(String searchCriteria)
|
||||||
throws MessagingException {
|
throws MessagingException {
|
||||||
checkOpen();
|
checkOpen();
|
||||||
List<ImapResponse> responses;
|
List<ImapResponse> responses;
|
||||||
|
@ -758,29 +758,23 @@ public class ImapStore extends Store {
|
||||||
throw ioExceptionHandler(mConnection, ioe);
|
throw ioExceptionHandler(mConnection, ioe);
|
||||||
}
|
}
|
||||||
// S: * SEARCH 2 3 6
|
// S: * SEARCH 2 3 6
|
||||||
|
final ArrayList<String> uids = new ArrayList<String>();
|
||||||
for (ImapResponse response : responses) {
|
for (ImapResponse response : responses) {
|
||||||
if (!response.isDataResponse(0, ImapConstants.SEARCH)) {
|
if (!response.isDataResponse(0, ImapConstants.SEARCH)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// Found SEARCH response data
|
// Found SEARCH response data
|
||||||
final int count = response.size() - 1;
|
|
||||||
if (count <= 0) {
|
|
||||||
return Utility.EMPTY_STRINGS; // ... but no UIDs in it! Return empty array.
|
|
||||||
}
|
|
||||||
|
|
||||||
ArrayList<String> ret = new ArrayList<String>(count);
|
|
||||||
for (int i = 1; i < response.size(); i++) {
|
for (int i = 1; i < response.size(); i++) {
|
||||||
ImapString s = response.getStringOrEmpty(i);
|
ImapString s = response.getStringOrEmpty(i);
|
||||||
if (s.isString()) {
|
if (s.isString()) {
|
||||||
ret.add(s.getString());
|
uids.add(s.getString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ret.toArray(Utility.EMPTY_STRINGS);
|
|
||||||
}
|
}
|
||||||
|
return uids.toArray(Utility.EMPTY_STRINGS);
|
||||||
} finally {
|
} finally {
|
||||||
mConnection.destroyResponses();
|
mConnection.destroyResponses();
|
||||||
}
|
}
|
||||||
return Utility.EMPTY_STRINGS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1264,6 +1264,67 @@ public class ImapStoreUnitTests extends AndroidTestCase {
|
||||||
// TODO: Test NO response. (src message not found)
|
// TODO: Test NO response. (src message not found)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testSearchForUids() throws Exception {
|
||||||
|
MockTransport mock = openAndInjectMockTransport();
|
||||||
|
setupOpenFolder(mock);
|
||||||
|
mFolder.open(OpenMode.READ_WRITE, null);
|
||||||
|
|
||||||
|
// Single results
|
||||||
|
mock.expect(
|
||||||
|
getNextTag(false) + " UID SEARCH X",
|
||||||
|
new String[] {
|
||||||
|
"* sEARCH 1",
|
||||||
|
getNextTag(true) + " oK success"
|
||||||
|
});
|
||||||
|
MoreAsserts.assertEquals(new String[] {
|
||||||
|
"1"
|
||||||
|
}, mFolder.searchForUids("X"));
|
||||||
|
|
||||||
|
// Multiple results, including SEARCH with no UIDs.
|
||||||
|
mock.expect(
|
||||||
|
getNextTag(false) + " UID SEARCH UID 123",
|
||||||
|
new String[] {
|
||||||
|
"* sEARCH 123 4 567",
|
||||||
|
"* search",
|
||||||
|
"* sEARCH 0",
|
||||||
|
"* SEARCH",
|
||||||
|
"* sEARCH 100 200 300",
|
||||||
|
getNextTag(true) + " oK success"
|
||||||
|
});
|
||||||
|
MoreAsserts.assertEquals(new String[] {
|
||||||
|
"123", "4", "567", "0", "100", "200", "300"
|
||||||
|
}, mFolder.searchForUids("UID 123"));
|
||||||
|
|
||||||
|
// NO result
|
||||||
|
mock.expect(
|
||||||
|
getNextTag(false) + " UID SEARCH SOME CRITERIA",
|
||||||
|
new String[] {
|
||||||
|
getNextTag(true) + " nO not found"
|
||||||
|
});
|
||||||
|
MoreAsserts.assertEquals(new String[] {
|
||||||
|
}, mFolder.searchForUids("SOME CRITERIA"));
|
||||||
|
|
||||||
|
// OK result, but result is empty. (Probably against RFC)
|
||||||
|
mock.expect(
|
||||||
|
getNextTag(false) + " UID SEARCH SOME CRITERIA",
|
||||||
|
new String[] {
|
||||||
|
getNextTag(true) + " oK success"
|
||||||
|
});
|
||||||
|
MoreAsserts.assertEquals(new String[] {
|
||||||
|
}, mFolder.searchForUids("SOME CRITERIA"));
|
||||||
|
|
||||||
|
// OK result with empty search response.
|
||||||
|
mock.expect(
|
||||||
|
getNextTag(false) + " UID SEARCH SOME CRITERIA",
|
||||||
|
new String[] {
|
||||||
|
"* search",
|
||||||
|
getNextTag(true) + " oK success"
|
||||||
|
});
|
||||||
|
MoreAsserts.assertEquals(new String[] {
|
||||||
|
}, mFolder.searchForUids("SOME CRITERIA"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public void testGetMessage() throws Exception {
|
public void testGetMessage() throws Exception {
|
||||||
MockTransport mock = openAndInjectMockTransport();
|
MockTransport mock = openAndInjectMockTransport();
|
||||||
setupOpenFolder(mock);
|
setupOpenFolder(mock);
|
||||||
|
|
Loading…
Reference in New Issue