Repository: thundernest/k-9
Issue: IMAP: Handle error response when uploading a message

# Expected behavior

When a message is sent, it is copied to the Send directory locally and on the server. If a sync is issued on that folder, then the local Sent will reflect the changes of the server, including any recently sent messages.

# Actual behavior

The messages are copied to the local Sent directory but not the Sent directory on the IMAP account.

Steps to reproduce

* Send a message from K-9.
* Check the Sent directory in another email client.

# Environment

K-9 Mail version: 
Android version: 9
Account type (IMAP, POP3, WebDAV/Exchange): IMAP

Changed files:
mail/protocols/imap/src/test/java/com/fsck/k9/mail/store/imap/ImapFolderTest.kt, mail/protocols/imap/src/main/java/com/fsck/k9/mail/store/imap/ImapFolder.kt

diff --git a/mail/protocols/imap/src/main/java/com/fsck/k9/mail/store/imap/ImapFolder.kt b/mail/protocols/imap/src/main/java/com/fsck/k9/mail/store/imap/ImapFolder.kt
index 6f8ad92ff..ec58f2a17 100644
--- a/mail/protocols/imap/src/main/java/com/fsck/k9/mail/store/imap/ImapFolder.kt
+++ b/mail/protocols/imap/src/main/java/com/fsck/k9/mail/store/imap/ImapFolder.kt
@@ -1013,7 +1013,9 @@ class ImapFolder internal constructor(
                     }
                 } while (response.tag == null)
 
-                if (response.size > 1) {
+                if (response.size < 1 || !ImapResponseParser.equalsIgnoreCase(response[0], Responses.OK)) {
+                    throw NegativeImapResponseException("APPEND failed", listOf(response))
+                } else if (response.size > 1) {
                     /*
                      * If the server supports UIDPLUS, then along with the APPEND response it
                      * will return an APPENDUID response code, e.g.
diff --git a/mail/protocols/imap/src/test/java/com/fsck/k9/mail/store/imap/ImapFolderTest.kt b/mail/protocols/imap/src/test/java/com/fsck/k9/mail/store/imap/ImapFolderTest.kt
index 5bb069fd8..c4600baa5 100644
--- a/mail/protocols/imap/src/test/java/com/fsck/k9/mail/store/imap/ImapFolderTest.kt
+++ b/mail/protocols/imap/src/test/java/com/fsck/k9/mail/store/imap/ImapFolderTest.kt
@@ -869,6 +869,40 @@ class ImapFolderTest {
         verify(imapConnection).sendCommand("APPEND \\"Folder\\" () {0}", false)
     }
 
+    @Test
+    fun appendMessages_withNegativeResponse_shouldThrow() {
+        val folder = createFolder("Folder")
+        prepareImapFolderForOpen(ImapFolder.OPEN_MODE_RW)
+        folder.open(ImapFolder.OPEN_MODE_RW)
+        val messages = listOf(createImapMessage("1"))
+        whenever(imapConnection.readResponse()).thenReturn(createImapResponse("x NO Can't append to this folder"))
+
+        try {
+            folder.appendMessages(messages)
+            fail("Expected exception")
+        } catch (e: NegativeImapResponseException) {
+            assertEquals("APPEND failed", e.message)
+            assertEquals("NO", e.lastResponse[0])
+        }
+    }
+
+    @Test
+    fun appendMessages_withBadResponse_shouldThrow() {
+        val folder = createFolder("Folder")
+        prepareImapFolderForOpen(ImapFolder.OPEN_MODE_RW)
+        folder.open(ImapFolder.OPEN_MODE_RW)
+        val messages = listOf(createImapMessage("1"))
+        whenever(imapConnection.readResponse()).thenReturn(createImapResponse("x BAD [TOOBIG] Message too large."))
+
+        try {
+            folder.appendMessages(messages)
+            fail("Expected exception")
+        } catch (e: NegativeImapResponseException) {
+            assertEquals("APPEND failed", e.message)
+            assertEquals("BAD", e.lastResponse[0])
+        }
+    }
+
     @Test
     fun getUidFromMessageId_withMessageIdHeader_shouldIssueUidSearchCommand() {
         val folder = createFolder("Folder")