Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Unverified Commit 7af9ec1e authored by cketti's avatar cketti Committed by GitHub
Browse files

Merge pull request #3136 from k9mail/GH-701_fix_special_use_folders_with_prefix

Remove namespace prefix from auto-configured special folder names
parents 8843ecb2 ada04840
Loading
Loading
Loading
Loading
+27 −18
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@ import java.util.Map;
import java.util.Set;

import android.net.ConnectivityManager;
import android.support.annotation.Nullable;

import com.fsck.k9.mail.AuthType;
import com.fsck.k9.mail.ConnectionSecurity;
@@ -174,8 +175,6 @@ public class ImapStore extends RemoteStore {
        Set<String> folderNames = new HashSet<>(listResponses.size());

        for (ListResponse listResponse : listResponses) {
            boolean includeFolder = true;

            String decodedFolderName;
            try {
                decodedFolderName = folderNameCodec.decode(listResponse.getName());
@@ -207,24 +206,12 @@ public class ImapStore extends RemoteStore {
                 * we simply ignore the folder on the server.
                 */
                continue;
            } else {
                int prefixLength = getCombinedPrefix().length();
                if (prefixLength > 0) {
                    // Strip prefix from the folder name
                    if (folder.length() >= prefixLength) {
                        folder = folder.substring(prefixLength);
                    }
                    if (!decodedFolderName.equalsIgnoreCase(getCombinedPrefix() + folder)) {
                        includeFolder = false;
                    }
                }
            }

            if (listResponse.hasAttribute("\\NoSelect")) {
                includeFolder = false;
            } else if (listResponse.hasAttribute("\\NoSelect")) {
                continue;
            }

            if (includeFolder) {
            folder = removePrefixFromFolderName(folder);
            if (folder != null) {
                folderNames.add(folder);
            }
        }
@@ -267,6 +254,11 @@ public class ImapStore extends RemoteStore {
                combinedPrefix = null;
            }

            decodedFolderName = removePrefixFromFolderName(decodedFolderName);
            if (decodedFolderName == null) {
                continue;
            }

            if (listResponse.hasAttribute("\\Archive") || listResponse.hasAttribute("\\All")) {
                mStoreConfig.setArchiveFolderName(decodedFolderName);
                if (K9MailLib.isDebug()) {
@@ -296,6 +288,23 @@ public class ImapStore extends RemoteStore {
        }
    }

    @Nullable
    private String removePrefixFromFolderName(String folderName) {
        String prefix = getCombinedPrefix();
        int prefixLength = prefix.length();
        if (prefixLength == 0) {
            return folderName;
        }

        if (!folderName.startsWith(prefix)) {
            // Folder name doesn't start with our configured prefix. But right now when building commands we prefix all
            // folders except the INBOX with the prefix. So we won't be able to use this folder.
            return null;
        }

        return folderName.substring(prefixLength);
    }

    @Override
    public void checkSettings() throws MessagingException {
        try {
+74 −0
Original line number Diff line number Diff line
@@ -131,6 +131,31 @@ public class ImapStoreTest {
        verifyNoMoreInteractions(imapConnection);
    }

    @Test
    public void autoconfigureFolders_removeNamespacePrefix() throws Exception {
        ImapConnection imapConnection = mock(ImapConnection.class);
        when(imapConnection.hasCapability(Capabilities.SPECIAL_USE)).thenReturn(true);
        List<ImapResponse> imapResponses = Arrays.asList(
                createImapResponse("* LIST (\\Drafts) \".\" \"INBOX.Drafts\""),
                createImapResponse("* LIST (\\Sent) \".\" \"INBOX.Sent\""),
                createImapResponse("* LIST (\\Junk) \".\" \"INBOX.Spam\""),
                createImapResponse("* LIST (\\Trash) \".\" \"INBOX.Trash\""),
                createImapResponse("* LIST (\\Archive) \".\" \"INBOX.Archive\""),
                createImapResponse("5 OK Success")
        );
        when(imapConnection.executeSimpleCommand("LIST (SPECIAL-USE) \"\" \"INBOX.*\"")).thenReturn(imapResponses);

        imapStore.setTestCombinedPrefix("INBOX.");
        imapStore.autoconfigureFolders(imapConnection);

        assertEquals("INBOX.", imapStore.getCombinedPrefix());
        verify(storeConfig).setDraftsFolderName("Drafts");
        verify(storeConfig).setSentFolderName("Sent");
        verify(storeConfig).setSpamFolderName("Spam");
        verify(storeConfig).setTrashFolderName("Trash");
        verify(storeConfig).setArchiveFolderName("Archive");
    }

    @Test
    public void getPersonalNamespaces_withForceListAll() throws Exception {
        when(storeConfig.subscribedFoldersOnly()).thenReturn(true);
@@ -197,6 +222,45 @@ public class ImapStoreTest {
        assertEquals(Sets.newSet("INBOX", "Folder.SubFolder"), extractFolderNames(result));
    }

    @Test
    public void getPersonalNamespaces_withNamespacePrefix_shouldRemoveNamespacePrefix() throws Exception {
        ImapConnection imapConnection = mock(ImapConnection.class);
        List<ImapResponse> imapResponses = Arrays.asList(
                createImapResponse("* LIST () \".\" \"INBOX\""),
                createImapResponse("* LIST () \".\" \"INBOX.FolderOne\""),
                createImapResponse("* LIST () \".\" \"INBOX.FolderTwo\""),
                createImapResponse("5 OK Success")
        );
        when(imapConnection.executeSimpleCommand("LIST \"\" \"INBOX.*\"")).thenReturn(imapResponses);
        imapStore.enqueueImapConnection(imapConnection);
        imapStore.setTestCombinedPrefix("INBOX.");

        List<ImapFolder> result = imapStore.getPersonalNamespaces(false);

        assertNotNull(result);
        assertEquals(Sets.newSet("INBOX", "FolderOne", "FolderTwo"), extractFolderNames(result));
    }

    @Test
    public void getPersonalNamespaces_withFolderNotMatchingNamespacePrefix_shouldExcludeFolderWithoutPrefix()
            throws Exception {
        ImapConnection imapConnection = mock(ImapConnection.class);
        List<ImapResponse> imapResponses = Arrays.asList(
                createImapResponse("* LIST () \".\" \"INBOX\""),
                createImapResponse("* LIST () \".\" \"INBOX.FolderOne\""),
                createImapResponse("* LIST () \".\" \"FolderTwo\""),
                createImapResponse("5 OK Success")
        );
        when(imapConnection.executeSimpleCommand("LIST \"\" \"INBOX.*\"")).thenReturn(imapResponses);
        imapStore.enqueueImapConnection(imapConnection);
        imapStore.setTestCombinedPrefix("INBOX.");

        List<ImapFolder> result = imapStore.getPersonalNamespaces(false);

        assertNotNull(result);
        assertEquals(Sets.newSet("INBOX", "FolderOne"), extractFolderNames(result));
    }

    @Test
    public void getPersonalNamespaces_withoutException_shouldLeaveImapConnectionOpen() throws Exception {
        ImapConnection imapConnection = mock(ImapConnection.class);
@@ -313,6 +377,7 @@ public class ImapStoreTest {

    static class TestImapStore extends ImapStore {
        private Deque<ImapConnection> imapConnections = new ArrayDeque<>();
        private String testCombinedPrefix;

        public TestImapStore(StoreConfig storeConfig, TrustedSocketFactory trustedSocketFactory,
                ConnectivityManager connectivityManager, OAuth2TokenProvider oauth2TokenProvider) throws MessagingException {
@@ -330,5 +395,14 @@ public class ImapStoreTest {
        public void enqueueImapConnection(ImapConnection imapConnection) {
            imapConnections.add(imapConnection);
        }

        @Override
        String getCombinedPrefix() {
            return testCombinedPrefix != null ? testCombinedPrefix : super.getCombinedPrefix();
        }

        void setTestCombinedPrefix(String prefix) {
            testCombinedPrefix = prefix;
        }
    }
}