IMAPReplyTest.java
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.net.imap;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.IOException;
import java.util.stream.Stream;
import org.apache.commons.net.MalformedServerReplyException;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
public class IMAPReplyTest {
private static Stream<String> invalidLiteralCommands() {
return Stream.of(
"",
"{",
"}",
"{}",
"{foobar}",
"STORE +FLAGS.SILENT \\DELETED {",
"STORE +FLAGS.SILENT \\DELETED }",
"STORE +FLAGS.SILENT \\DELETED {-1}",
"STORE +FLAGS.SILENT \\DELETED {-10}",
"STORE +FLAGS.SILENT \\DELETED {-2147483648}"
);
}
private static Stream<Arguments> literalCommands() {
return Stream.of(
Arguments.of(310, "A003 APPEND saved-messages (\\Seen) {310}"),
Arguments.of(6, "A284 SEARCH CHARSET UTF-8 TEXT {6}"),
Arguments.of(7, "FRED FOOBAR {7}"),
Arguments.of(102856, "A044 BLURDYBLOOP {102856}"),
Arguments.of(342, "* 12 FETCH (BODY[HEADER] {342}"),
Arguments.of(0, "X999 LOGIN {0}"),
Arguments.of(Integer.MAX_VALUE, "X999 LOGIN {2147483647}")
);
}
@ParameterizedTest(name = "reply line `{1}` contains literal {0}")
@MethodSource("literalCommands")
public void literalCount(final int expectedLiteral, final String replyLine) {
assertEquals(expectedLiteral, IMAPReply.literalCount(replyLine));
}
@ParameterizedTest(name = "reply line `{0}` does not contain any literal")
@MethodSource("invalidLiteralCommands")
public void literalCountInvalid(final String replyLine) {
assertEquals(-1, IMAPReply.literalCount(replyLine));
}
@Test
public void testGetReplyCodeBadLine() throws IOException {
final String badLine = "A044 BAD No such command as \"FOOBAR\"";
assertEquals(IMAPReply.BAD, IMAPReply.getReplyCode(badLine));
}
@Test
public void testGetReplyCodeContinuationLine() throws IOException {
final String continuationLine = "+ Ready for additional command text";
assertEquals(IMAPReply.CONT, IMAPReply.getReplyCode(continuationLine));
}
@Test
public void testGetReplyCodeMalformedLine() {
final String malformedTaggedLine = "A064 FOO-BAR 0";
final MalformedServerReplyException replyException = assertThrows(MalformedServerReplyException.class,
() -> IMAPReply.getReplyCode(malformedTaggedLine));
assertEquals("Received unexpected IMAP protocol response from server: 'A064 FOO-BAR 0'.", replyException.getMessage());
}
@Test
public void testGetReplyCodeNoLine() throws IOException {
final String noLine = "A223 NO COPY failed: disk is full";
assertEquals(IMAPReply.NO, IMAPReply.getReplyCode(noLine));
}
@Test
public void testGetReplyCodeOkLine() throws IOException {
assertEquals(IMAPReply.OK, IMAPReply.getReplyCode("A001 OK LOGIN completed"));
assertEquals(IMAPReply.OK, IMAPReply.getReplyCode("AAAA OK [CAPABILITY IMAP4rev1 SASL-IR LOGIN-REFERRALS ID ENABLE IDLE SORT"
+ " SORT=DISPLAY THREAD=REFERENCES THREAD=REFS THREAD=ORDEREDSUBJECT" + " MULTIAPPEND URL-PARTIAL CATENATE UNSELECT CHILDREN NAMESPACE UIDPLUS"
+ " LIST-EXTENDED I18NLEVEL=1 CONDSTORE QRESYNC ESEARCH ESORT SEARCHRES WITHIN"
+ " CONTEXT=SEARCH LIST-STATUS BINARY MOVE SNIPPET=FUZZY PREVIEW=FUZZY PREVIEW"
+ " STATUS=SIZE SAVEDATE XLIST LITERAL+ NOTIFY SPECIAL-USE] Logged in"));
// [NET-734] IMAP login fails with 3.11.1
assertEquals(IMAPReply.OK, IMAPReply.getReplyCode(
"CBJJ OK [CAPABILITY IMAP4rev1 SASL-IR LOGIN-REFERRALS ENABLE IDLE ID SORT SORT=DISPLAY THREAD=REFERENCES THREAD=REFS THREAD=ORDEREDSUBJECT"
+ " MULTIAPPEND URL-PARTIAL CATENATE UNSELECT CHILDREN NAMESPACE UIDPLUS LIST-EXTENDED I18NLEVEL=1 CONDSTORE QRESYNC ESEARCH ESORT"
+ " SEARCHRES WITHIN CONTEXT=SEARCH LIST-STATUS BINARY MOVE STATUS=SIZE SAVEDATE LITERAL+ QUOTA] Logged in"));
}
@Test
public void testGetUntaggedReplyCodeBadLine() throws IOException {
final String badLine = "* BAD Empty command line";
assertEquals(IMAPReply.BAD, IMAPReply.getUntaggedReplyCode(badLine));
}
@Test
public void testGetUntaggedReplyCodeContinuationLine() throws IOException {
final String continuationLine = "+ Ready for additional command text";
assertEquals(IMAPReply.CONT, IMAPReply.getUntaggedReplyCode(continuationLine));
}
@Test
public void testGetUntaggedReplyCodeMalformedLine() {
// invalid experimental comm response (missing X prefix)
final String malformedUntaggedLine = "* FOO-BAR hello-world";
final MalformedServerReplyException replyException = assertThrows(MalformedServerReplyException.class,
() -> IMAPReply.getUntaggedReplyCode(malformedUntaggedLine));
assertEquals("Received unexpected IMAP protocol response from server: '* FOO-BAR hello-world'.", replyException.getMessage());
}
@Test
public void testGetUntaggedReplyCodeNoLine() throws IOException {
final String noLine = "* NO Disk is 98% full, please delete unnecessary data";
assertEquals(IMAPReply.NO, IMAPReply.getUntaggedReplyCode(noLine));
}
@Test
public void testGetUntaggedReplyCodeOkLine() throws IOException {
assertEquals(IMAPReply.OK, IMAPReply.getUntaggedReplyCode("* OK Salvage successful, no data lost"));
assertEquals(IMAPReply.OK,
IMAPReply.getUntaggedReplyCode("* OK The Microsoft Exchange IMAP4 service is ready. [xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx]"));
assertEquals(IMAPReply.OK, IMAPReply.getUntaggedReplyCode("* OK The Microsoft Exchange IMAP4 service is ready. " +
"[TQBXADIAUABSADIAMQAwADEAQwBBADAAMAAzADYALgBuAGEAbQBwAHIAZAAyADEALgBwAHIAbwBkAC4AbwB1AHQAbABvAG8AawAuAGMAbwBtAA==]"));
}
@Test
public void testIsContinuationReplyCode() {
final int replyCode = 3;
assertTrue(IMAPReply.isContinuation(replyCode));
}
@Test
public void testIsContinuationReplyCodeInvalidCode() {
final int invalidContinuationReplyCode = 1;
assertFalse(IMAPReply.isContinuation(invalidContinuationReplyCode));
}
@Test
public void testIsContinuationReplyLine() {
final String replyLine = "+FLAGS completed";
assertTrue(IMAPReply.isContinuation(replyLine));
}
@Test
public void testIsContinuationReplyLineInvalidLine() {
final String invalidContinuationReplyLine = "* 22 EXPUNGE";
assertFalse(IMAPReply.isContinuation(invalidContinuationReplyLine));
}
@Test
public void testIsSuccessReplyCode() {
final int successfulReplyCode = 0;
assertTrue(IMAPReply.isSuccess(successfulReplyCode));
}
@Test
public void testIsSuccessReplyCodeUnsuccessfulCode() {
final int unsuccessfulReplyCode = 2;
assertFalse(IMAPReply.isSuccess(unsuccessfulReplyCode));
}
@Test
public void testIsUntaggedReplyLine() {
final String replyLine = "* 18 EXISTS";
assertTrue(IMAPReply.isUntagged(replyLine));
}
@Test
public void testIsUntaggedReplyLineInvalidLine() {
final String taggedLine = "a001 OK LOGOUT completed";
assertFalse(IMAPReply.isUntagged(taggedLine));
}
}