Make ImapStore.getFolders() return the proper server ID

This commit is contained in:
cketti 2020-04-07 20:37:55 +02:00
parent 37eea88f82
commit 8abac750af
4 changed files with 78 additions and 40 deletions

View file

@ -14,10 +14,13 @@ internal class CommandRefreshFolderList(
val foldersToCreate = mutableListOf<FolderInfo>()
for (folder in foldersOnServer) {
if (folder.serverId !in oldFolderServerIds) {
foldersToCreate.add(FolderInfo(folder.serverId, folder.name, folder.type))
// TODO: Start using the proper server ID. For now we still use the old server ID.
val serverId = folder.oldServerId ?: continue
if (serverId !in oldFolderServerIds) {
foldersToCreate.add(FolderInfo(serverId, folder.name, folder.type))
} else {
backendStorage.changeFolder(folder.serverId, folder.name, folder.type)
backendStorage.changeFolder(serverId, folder.name, folder.type)
}
}
backendStorage.createFolders(foldersToCreate)

View file

@ -5,5 +5,6 @@ import com.fsck.k9.mail.FolderType
data class FolderListItem(
val serverId: String,
val name: String,
val type: FolderType
val type: FolderType,
val oldServerId: String?
)

View file

@ -178,30 +178,16 @@ public class ImapStore {
Map<String, FolderListItem> folderMap = new HashMap<>(listResponses.size());
for (ListResponse listResponse : listResponses) {
String decodedFolderName;
try {
decodedFolderName = folderNameCodec.decode(listResponse.getName());
} catch (CharacterCodingException e) {
Timber.w(e, "Folder name not correctly encoded with the UTF-7 variant as defined by RFC 3501: %s",
listResponse.getName());
//TODO: Use the raw name returned by the server for all commands that require
// a folder name. Use the decoded name only for showing it to the user.
// We currently just skip folders with malformed names.
continue;
}
String folder = decodedFolderName;
String serverId = listResponse.getName();
if (pathDelimiter == null) {
pathDelimiter = listResponse.getHierarchyDelimiter();
combinedPrefix = null;
}
if (ImapFolder.INBOX.equalsIgnoreCase(folder)) {
if (ImapFolder.INBOX.equalsIgnoreCase(serverId)) {
continue;
} else if (folder.equals(storeConfig.getOutboxFolder())) {
} else if (serverId.equals(storeConfig.getOutboxFolder())) {
/*
* There is a folder on the server with the same name as our local
* outbox. Until we have a good plan to deal with this situation
@ -212,10 +198,8 @@ public class ImapStore {
continue;
}
folder = removePrefixFromFolderName(folder);
if (folder == null) {
continue;
}
String name = getFolderDisplayName(serverId);
String oldServerId = getOldServerId(serverId);
FolderType type;
if (listResponse.hasAttribute("\\Archive") || listResponse.hasAttribute("\\All")) {
@ -232,21 +216,47 @@ public class ImapStore {
type = FolderType.REGULAR;
}
String name = folder;
FolderListItem existingItem = folderMap.get(folder);
FolderListItem existingItem = folderMap.get(serverId);
if (existingItem == null || existingItem.getType() == FolderType.REGULAR) {
folderMap.put(folder, new FolderListItem(folder, name, type));
folderMap.put(serverId, new FolderListItem(serverId, name, type, oldServerId));
}
}
List<FolderListItem> folders = new ArrayList<>(folderMap.size() + 1);
folders.add(new FolderListItem(ImapFolder.INBOX, ImapFolder.INBOX, FolderType.INBOX));
folders.add(new FolderListItem(ImapFolder.INBOX, ImapFolder.INBOX, FolderType.INBOX, ImapFolder.INBOX));
folders.addAll(folderMap.values());
return folders;
}
private String getFolderDisplayName(String serverId) {
String decodedFolderName;
try {
decodedFolderName = folderNameCodec.decode(serverId);
} catch (CharacterCodingException e) {
Timber.w(e, "Folder name not correctly encoded with the UTF-7 variant as defined by RFC 3501: %s",
serverId);
decodedFolderName = serverId;
}
String folderNameWithoutPrefix = removePrefixFromFolderName(decodedFolderName);
return folderNameWithoutPrefix != null ? folderNameWithoutPrefix : decodedFolderName;
}
@Nullable
private String getOldServerId(String serverId) {
String decodedFolderName;
try {
decodedFolderName = folderNameCodec.decode(serverId);
} catch (CharacterCodingException e) {
// Previous versions of K-9 Mail ignored folders with invalid UTF-7 encoding
return null;
}
return removePrefixFromFolderName(decodedFolderName);
}
@Nullable
private String removePrefixFromFolderName(String folderName) {
String prefix = getCombinedPrefix();

View file

@ -170,7 +170,7 @@ public class ImapStoreTest {
List<FolderListItem> result = imapStore.getFolders();
assertNotNull(result);
assertEquals(Sets.newSet("INBOX", "Folder.SubFolder"), extractFolderNames(result));
assertEquals(Sets.newSet("INBOX", "Folder.SubFolder"), extractFolderServerIds(result));
}
@Test
@ -198,11 +198,11 @@ public class ImapStoreTest {
List<FolderListItem> result = imapStore.getFolders();
assertNotNull(result);
assertEquals(Sets.newSet("INBOX", "Folder.SubFolder"), extractFolderNames(result));
assertEquals(Sets.newSet("INBOX", "Folder.SubFolder"), extractFolderServerIds(result));
}
@Test
public void getFolders_withNamespacePrefix_shouldRemoveNamespacePrefix() throws Exception {
public void getFolders_withNamespacePrefix() throws Exception {
ImapConnection imapConnection = mock(ImapConnection.class);
List<ImapResponse> imapResponses = Arrays.asList(
createImapResponse("* LIST () \".\" \"INBOX\""),
@ -217,12 +217,13 @@ public class ImapStoreTest {
List<FolderListItem> result = imapStore.getFolders();
assertNotNull(result);
assertEquals(Sets.newSet("INBOX", "INBOX.FolderOne", "INBOX.FolderTwo"), extractFolderServerIds(result));
assertEquals(Sets.newSet("INBOX", "FolderOne", "FolderTwo"), extractFolderNames(result));
assertEquals(Sets.newSet("INBOX", "FolderOne", "FolderTwo"), extractOldFolderServerIds(result));
}
@Test
public void getFolders_withFolderNotMatchingNamespacePrefix_shouldExcludeFolderWithoutPrefix()
throws Exception {
public void getFolders_withFolderNotMatchingNamespacePrefix() throws Exception {
ImapConnection imapConnection = mock(ImapConnection.class);
List<ImapResponse> imapResponses = Arrays.asList(
createImapResponse("* LIST () \".\" \"INBOX\""),
@ -237,7 +238,9 @@ public class ImapStoreTest {
List<FolderListItem> result = imapStore.getFolders();
assertNotNull(result);
assertEquals(Sets.newSet("INBOX", "FolderOne"), extractFolderNames(result));
assertEquals(Sets.newSet("INBOX", "INBOX.FolderOne", "FolderTwo"), extractFolderServerIds(result));
assertEquals(Sets.newSet("INBOX", "FolderOne", "FolderTwo"), extractFolderNames(result));
assertEquals(Sets.newSet("INBOX", "FolderOne"), extractOldFolderServerIds(result));
}
@Test
@ -260,7 +263,7 @@ public class ImapStoreTest {
assertNotNull(result);
assertEquals(2, result.size());
FolderListItem junkFolder = getFolderByName(result, "Junk");
FolderListItem junkFolder = getFolderByServerId(result, "Junk");
assertNotNull(junkFolder);
assertEquals(FolderType.SPAM, junkFolder.getType());
}
@ -382,18 +385,39 @@ public class ImapStoreTest {
return storeConfig;
}
private Set<String> extractFolderServerIds(List<FolderListItem> folders) {
Set<String> folderServerIds = new HashSet<>(folders.size());
for (FolderListItem folder : folders) {
folderServerIds.add(folder.getServerId());
}
return folderServerIds;
}
private Set<String> extractFolderNames(List<FolderListItem> folders) {
Set<String> folderNames = new HashSet<>(folders.size());
for (FolderListItem folder : folders) {
folderNames.add(folder.getServerId());
folderNames.add(folder.getName());
}
return folderNames;
}
private FolderListItem getFolderByName(List<FolderListItem> result, String folderName) {
private Set<String> extractOldFolderServerIds(List<FolderListItem> folders) {
Set<String> folderNames = new HashSet<>(folders.size());
for (FolderListItem folder : folders) {
String oldServerId = folder.getOldServerId();
if (oldServerId != null) {
folderNames.add(oldServerId);
}
}
return folderNames;
}
private FolderListItem getFolderByServerId(List<FolderListItem> result, String serverId) {
for (FolderListItem imapFolder : result) {
if (imapFolder.getServerId().equals(folderName)) {
if (imapFolder.getServerId().equals(serverId)) {
return imapFolder;
}
}