1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.net.imap;
19
20 import static org.junit.jupiter.api.Assertions.assertEquals;
21 import static org.junit.jupiter.api.Assertions.assertFalse;
22 import static org.junit.jupiter.api.Assertions.assertThrows;
23 import static org.junit.jupiter.api.Assertions.assertTrue;
24
25 import java.io.IOException;
26 import java.util.stream.Stream;
27
28 import org.apache.commons.net.MalformedServerReplyException;
29 import org.junit.jupiter.api.Test;
30 import org.junit.jupiter.params.ParameterizedTest;
31 import org.junit.jupiter.params.provider.Arguments;
32 import org.junit.jupiter.params.provider.MethodSource;
33
34 public class IMAPReplyTest {
35
36 private static Stream<String> invalidLiteralCommands() {
37 return Stream.of(
38 "",
39 "{",
40 "}",
41 "{}",
42 "{foobar}",
43 "STORE +FLAGS.SILENT \\DELETED {",
44 "STORE +FLAGS.SILENT \\DELETED }",
45 "STORE +FLAGS.SILENT \\DELETED {-1}",
46 "STORE +FLAGS.SILENT \\DELETED {-10}",
47 "STORE +FLAGS.SILENT \\DELETED {-2147483648}"
48 );
49 }
50
51 private static Stream<Arguments> literalCommands() {
52 return Stream.of(
53 Arguments.of(310, "A003 APPEND saved-messages (\\Seen) {310}"),
54 Arguments.of(6, "A284 SEARCH CHARSET UTF-8 TEXT {6}"),
55 Arguments.of(7, "FRED FOOBAR {7}"),
56 Arguments.of(102856, "A044 BLURDYBLOOP {102856}"),
57 Arguments.of(342, "* 12 FETCH (BODY[HEADER] {342}"),
58 Arguments.of(0, "X999 LOGIN {0}"),
59 Arguments.of(Integer.MAX_VALUE, "X999 LOGIN {2147483647}")
60 );
61 }
62
63 @ParameterizedTest(name = "reply line `{1}` contains literal {0}")
64 @MethodSource("literalCommands")
65 public void literalCount(final int expectedLiteral, final String replyLine) {
66 assertEquals(expectedLiteral, IMAPReply.literalCount(replyLine));
67 }
68
69 @ParameterizedTest(name = "reply line `{0}` does not contain any literal")
70 @MethodSource("invalidLiteralCommands")
71 public void literalCountInvalid(final String replyLine) {
72 assertEquals(-1, IMAPReply.literalCount(replyLine));
73 }
74
75 @Test
76 public void testGetReplyCodeBadLine() throws IOException {
77 final String badLine = "A044 BAD No such command as \"FOOBAR\"";
78 assertEquals(IMAPReply.BAD, IMAPReply.getReplyCode(badLine));
79 }
80
81 @Test
82 public void testGetReplyCodeContinuationLine() throws IOException {
83 final String continuationLine = "+ Ready for additional command text";
84 assertEquals(IMAPReply.CONT, IMAPReply.getReplyCode(continuationLine));
85 }
86
87 @Test
88 public void testGetReplyCodeMalformedLine() {
89 final String malformedTaggedLine = "A064 FOO-BAR 0";
90 final MalformedServerReplyException replyException = assertThrows(MalformedServerReplyException.class,
91 () -> IMAPReply.getReplyCode(malformedTaggedLine));
92 assertEquals("Received unexpected IMAP protocol response from server: 'A064 FOO-BAR 0'.", replyException.getMessage());
93 }
94
95 @Test
96 public void testGetReplyCodeNoLine() throws IOException {
97 final String noLine = "A223 NO COPY failed: disk is full";
98 assertEquals(IMAPReply.NO, IMAPReply.getReplyCode(noLine));
99 }
100
101 @Test
102 public void testGetReplyCodeOkLine() throws IOException {
103 assertEquals(IMAPReply.OK, IMAPReply.getReplyCode("A001 OK LOGIN completed"));
104 assertEquals(IMAPReply.OK, IMAPReply.getReplyCode("AAAA OK [CAPABILITY IMAP4rev1 SASL-IR LOGIN-REFERRALS ID ENABLE IDLE SORT"
105 + " SORT=DISPLAY THREAD=REFERENCES THREAD=REFS THREAD=ORDEREDSUBJECT" + " MULTIAPPEND URL-PARTIAL CATENATE UNSELECT CHILDREN NAMESPACE UIDPLUS"
106 + " LIST-EXTENDED I18NLEVEL=1 CONDSTORE QRESYNC ESEARCH ESORT SEARCHRES WITHIN"
107 + " CONTEXT=SEARCH LIST-STATUS BINARY MOVE SNIPPET=FUZZY PREVIEW=FUZZY PREVIEW"
108 + " STATUS=SIZE SAVEDATE XLIST LITERAL+ NOTIFY SPECIAL-USE] Logged in"));
109
110 assertEquals(IMAPReply.OK, IMAPReply.getReplyCode(
111 "CBJJ OK [CAPABILITY IMAP4rev1 SASL-IR LOGIN-REFERRALS ENABLE IDLE ID SORT SORT=DISPLAY THREAD=REFERENCES THREAD=REFS THREAD=ORDEREDSUBJECT"
112 + " MULTIAPPEND URL-PARTIAL CATENATE UNSELECT CHILDREN NAMESPACE UIDPLUS LIST-EXTENDED I18NLEVEL=1 CONDSTORE QRESYNC ESEARCH ESORT"
113 + " SEARCHRES WITHIN CONTEXT=SEARCH LIST-STATUS BINARY MOVE STATUS=SIZE SAVEDATE LITERAL+ QUOTA] Logged in"));
114 }
115
116 @Test
117 public void testGetUntaggedReplyCodeBadLine() throws IOException {
118 final String badLine = "* BAD Empty command line";
119 assertEquals(IMAPReply.BAD, IMAPReply.getUntaggedReplyCode(badLine));
120 }
121
122 @Test
123 public void testGetUntaggedReplyCodeContinuationLine() throws IOException {
124 final String continuationLine = "+ Ready for additional command text";
125 assertEquals(IMAPReply.CONT, IMAPReply.getUntaggedReplyCode(continuationLine));
126 }
127
128 @Test
129 public void testGetUntaggedReplyCodeMalformedLine() {
130
131 final String malformedUntaggedLine = "* FOO-BAR hello-world";
132 final MalformedServerReplyException replyException = assertThrows(MalformedServerReplyException.class,
133 () -> IMAPReply.getUntaggedReplyCode(malformedUntaggedLine));
134 assertEquals("Received unexpected IMAP protocol response from server: '* FOO-BAR hello-world'.", replyException.getMessage());
135 }
136
137 @Test
138 public void testGetUntaggedReplyCodeNoLine() throws IOException {
139 final String noLine = "* NO Disk is 98% full, please delete unnecessary data";
140 assertEquals(IMAPReply.NO, IMAPReply.getUntaggedReplyCode(noLine));
141 }
142
143 @Test
144 public void testGetUntaggedReplyCodeOkLine() throws IOException {
145 assertEquals(IMAPReply.OK, IMAPReply.getUntaggedReplyCode("* OK Salvage successful, no data lost"));
146 assertEquals(IMAPReply.OK,
147 IMAPReply.getUntaggedReplyCode("* OK The Microsoft Exchange IMAP4 service is ready. [xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx]"));
148 assertEquals(IMAPReply.OK, IMAPReply.getUntaggedReplyCode("* OK The Microsoft Exchange IMAP4 service is ready. " +
149 "[TQBXADIAUABSADIAMQAwADEAQwBBADAAMAAzADYALgBuAGEAbQBwAHIAZAAyADEALgBwAHIAbwBkAC4AbwB1AHQAbABvAG8AawAuAGMAbwBtAA==]"));
150 }
151
152 @Test
153 public void testIsContinuationReplyCode() {
154 final int replyCode = 3;
155 assertTrue(IMAPReply.isContinuation(replyCode));
156 }
157
158 @Test
159 public void testIsContinuationReplyCodeInvalidCode() {
160 final int invalidContinuationReplyCode = 1;
161 assertFalse(IMAPReply.isContinuation(invalidContinuationReplyCode));
162 }
163
164 @Test
165 public void testIsContinuationReplyLine() {
166 final String replyLine = "+FLAGS completed";
167 assertTrue(IMAPReply.isContinuation(replyLine));
168 }
169
170 @Test
171 public void testIsContinuationReplyLineInvalidLine() {
172 final String invalidContinuationReplyLine = "* 22 EXPUNGE";
173 assertFalse(IMAPReply.isContinuation(invalidContinuationReplyLine));
174 }
175
176 @Test
177 public void testIsSuccessReplyCode() {
178 final int successfulReplyCode = 0;
179 assertTrue(IMAPReply.isSuccess(successfulReplyCode));
180 }
181
182 @Test
183 public void testIsSuccessReplyCodeUnsuccessfulCode() {
184 final int unsuccessfulReplyCode = 2;
185 assertFalse(IMAPReply.isSuccess(unsuccessfulReplyCode));
186 }
187
188 @Test
189 public void testIsUntaggedReplyLine() {
190 final String replyLine = "* 18 EXISTS";
191 assertTrue(IMAPReply.isUntagged(replyLine));
192 }
193
194 @Test
195 public void testIsUntaggedReplyLineInvalidLine() {
196 final String taggedLine = "a001 OK LOGOUT completed";
197 assertFalse(IMAPReply.isUntagged(taggedLine));
198 }
199
200 }