1   /*
2    * Wallace IMAP Server
3    * Copyright (C) 2004  Robert Newson
4    *
5    * This program is free software; you can redistribute it and/or
6    * modify it under the terms of the GNU General Public License
7    * as published by the Free Software Foundation; either version 2
8    * of the License, or (at your option) any later version.
9    *
10   * This program is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   * GNU General Public License for more details.
14   *
15   * You should have received a copy of the GNU General Public License
16   * along with this program; if not, write to the Free Software
17   * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18   */
19  package net.sf.wallace.mina;
20  
21  import junit.framework.Assert;
22  import junit.framework.TestCase;
23  import junitx.framework.ObjectAssert;
24  import net.sf.wallace.WallaceSession;
25  import net.sf.wallace.messages.AppendMessage;
26  import net.sf.wallace.messages.AuthenticateMessage;
27  import net.sf.wallace.messages.CapabilityMessage;
28  import net.sf.wallace.messages.CheckMessage;
29  import net.sf.wallace.messages.CloseMessage;
30  import net.sf.wallace.messages.CopyMessage;
31  import net.sf.wallace.messages.CreateMessage;
32  import net.sf.wallace.messages.DeleteMessage;
33  import net.sf.wallace.messages.ExamineMessage;
34  import net.sf.wallace.messages.FetchMessage;
35  import net.sf.wallace.messages.ListMessage;
36  import net.sf.wallace.messages.LoginMessage;
37  import net.sf.wallace.messages.LogoutMessage;
38  import net.sf.wallace.messages.LsubMessage;
39  import net.sf.wallace.messages.NoopMessage;
40  import net.sf.wallace.messages.RenameMessage;
41  import net.sf.wallace.messages.SearchMessage;
42  import net.sf.wallace.messages.SelectMessage;
43  import net.sf.wallace.messages.StartTlsMessage;
44  import net.sf.wallace.messages.StatusMessage;
45  import net.sf.wallace.messages.StoreMessage;
46  import net.sf.wallace.messages.SubscribeMessage;
47  import net.sf.wallace.messages.UidMessage;
48  import net.sf.wallace.messages.UnsubscribeMessage;
49  
50  import org.apache.mina.common.ByteBuffer;
51  import org.apache.mina.protocol.ProtocolDecoder;
52  import org.apache.mina.protocol.ProtocolDecoderOutput;
53  import org.apache.mina.protocol.ProtocolSession;
54  import org.easymock.MockControl;
55  
56  /***
57   * @author rnewson
58   */
59  public class IMAP4ProtocolDecoderTest extends TestCase {
60  
61      private ProtocolDecoder decoder;
62  
63      private ProtocolDecoderOutput output;
64  
65      protected Object result;
66  
67      protected void setUp() {
68          decoder = new IMAP4ProtocolCodecFactory().newDecoder();
69          output = new ProtocolDecoderOutput() {
70              public void write(final Object newResult) {
71                  result = newResult;
72              }
73          };
74      }
75  
76      public void testDecodeAppendMessage() throws Exception {
77          decodeBytes("001 APPEND INBOX {10}\r\n0123456789\r\n".getBytes());
78          ObjectAssert.assertInstanceOf(AppendMessage.class, result);
79      }
80  
81      // public void testDecodeAppendMessageWithZeroLengthLiteral() throws
82      // Exception {
83      // decodeBytes("001 APPEND INBOX {0}\r\n\r\n".getBytes());
84      // ObjectAssert.assertInstanceOf(AppendMessage.class, result);
85      // }
86  
87      public void testDecodeAppendMessageInTwoPasses() throws Exception {
88          decodeBytes("001 APPEND INBOX {10}\r\n".getBytes());
89          decodeBytes("0123456789\r\n".getBytes());
90          ObjectAssert.assertInstanceOf(AppendMessage.class, result);
91      }
92  
93      public void testDecodeAppendMessageLiteralPlus() throws Exception {
94          decodeBytes("001 APPEND INBOX {10+}\r\n0123456789\r\n".getBytes());
95          ObjectAssert.assertInstanceOf(AppendMessage.class, result);
96      }
97  
98      public void testDecodeAppendMessageLiteralPlusInTwoPasses() throws Exception {
99          decodeBytes("001 APPEND INBOX {10+}\r\n".getBytes());
100         decodeBytes("0123456789\r\n".getBytes());
101         ObjectAssert.assertInstanceOf(AppendMessage.class, result);
102     }
103 
104     public void testDecodeAuthenticateMessage() throws Exception {
105         decodeBytes("001 AUTHENTICATE\r\n".getBytes());
106         ObjectAssert.assertInstanceOf(AuthenticateMessage.class, result);
107     }
108 
109     public void testDecodeCapabilityMessage() throws Exception {
110         decodeBytes("tag CAPABILITY\r\n".getBytes());
111         ObjectAssert.assertInstanceOf(CapabilityMessage.class, result);
112     }
113 
114     public void testDecodeCheckMessage() throws Exception {
115         decodeBytes("001 CHECK\r\n".getBytes());
116         ObjectAssert.assertInstanceOf(CheckMessage.class, result);
117     }
118 
119     public void testDecodeCloseMessage() throws Exception {
120         decodeBytes("tag CLOSE\r\n".getBytes());
121         ObjectAssert.assertInstanceOf(CloseMessage.class, result);
122     }
123 
124     public void testDecodeCopyMessage() throws Exception {
125         decodeBytes("tag COPY\r\n".getBytes());
126         ObjectAssert.assertInstanceOf(CopyMessage.class, result);
127     }
128 
129     public void testDecodeCreateMessage() throws Exception {
130         decodeBytes("001 CREATE INBOX\r\n".getBytes());
131         ObjectAssert.assertInstanceOf(CreateMessage.class, result);
132     }
133 
134     public void testDecodeDeleteMessage() throws Exception {
135         decodeBytes("001 DELETE INBOX\r\n".getBytes());
136         ObjectAssert.assertInstanceOf(DeleteMessage.class, result);
137     }
138 
139     public void testDecodeExamineMessage() throws Exception {
140         decodeBytes("001 EXAMINE INBOX\r\n".getBytes());
141         ObjectAssert.assertInstanceOf(ExamineMessage.class, result);
142     }
143 
144     public void testDecodeFetchMessage() throws Exception {
145         decodeBytes("001 FETCH\r\n".getBytes());
146         ObjectAssert.assertInstanceOf(FetchMessage.class, result);
147     }
148 
149     public void testDecodeListMessage() throws Exception {
150         decodeBytes("001 LIST INBOX \"%\"\r\n".getBytes());
151         ObjectAssert.assertInstanceOf(ListMessage.class, result);
152     }
153 
154     public void testDecodeLoginMessage() throws Exception {
155         decodeBytes("tag LOGIN username password\r\n".getBytes());
156         ObjectAssert.assertInstanceOf(LoginMessage.class, result);
157     }
158 
159     public void testDecodeLogoutMessage() throws Exception {
160         decodeBytes("tag LOGOUT\r\n".getBytes());
161         ObjectAssert.assertInstanceOf(LogoutMessage.class, result);
162     }
163 
164     public void testDecodeLsubMessage() throws Exception {
165         decodeBytes("tag LSUB INBOX %\r\n".getBytes());
166         ObjectAssert.assertInstanceOf(LsubMessage.class, result);
167     }
168 
169     public void testDecodeNoopMessage() throws Exception {
170         decodeBytes("tag NOOP\r\n".getBytes());
171         ObjectAssert.assertInstanceOf(NoopMessage.class, result);
172     }
173 
174     public void testDecodeRenameMessage() throws Exception {
175         decodeBytes("001 RENAME \"from mailbox\" \"to mailbox\"\r\n".getBytes());
176         final RenameMessage message = (RenameMessage) result;
177         Assert.assertEquals("from mailbox", message.getFrom());
178         Assert.assertEquals("to mailbox", message.getTo());
179     }
180 
181     public void testDecodeSearchMessage() throws Exception {
182         decodeBytes("001 SEARCH\r\n".getBytes());
183         ObjectAssert.assertInstanceOf(SearchMessage.class, result);
184     }
185 
186     public void testDecodeSelectMessage() throws Exception {
187         decodeBytes("001 SELECT INBOX\r\n".getBytes());
188         ObjectAssert.assertInstanceOf(SelectMessage.class, result);
189     }
190 
191     public void testDecodeStartTlsMessage() throws Exception {
192         decodeBytes("001 STARTTLS\r\n".getBytes());
193         ObjectAssert.assertInstanceOf(StartTlsMessage.class, result);
194     }
195 
196     public void testDecodeStatusMessage() throws Exception {
197         decodeBytes("001 STATUS\r\n".getBytes());
198         ObjectAssert.assertInstanceOf(StatusMessage.class, result);
199     }
200 
201     public void testDecodeStoreMessage() throws Exception {
202         decodeBytes("001 STORE\r\n".getBytes());
203         ObjectAssert.assertInstanceOf(StoreMessage.class, result);
204     }
205 
206     public void testDecodeSubscribeMessage() throws Exception {
207         decodeBytes("001 SUBSCRIBE INBOX\r\n".getBytes());
208         ObjectAssert.assertInstanceOf(SubscribeMessage.class, result);
209     }
210 
211     public void testDecodeUidMessage() throws Exception {
212         decodeBytes("001 UID\r\n".getBytes());
213         ObjectAssert.assertInstanceOf(UidMessage.class, result);
214     }
215 
216     public void testDecodeUnsubscribeMessage() throws Exception {
217         decodeBytes("001 UNSUBSCRIBE INBOX\r\n".getBytes());
218         ObjectAssert.assertInstanceOf(UnsubscribeMessage.class, result);
219     }
220 
221     public void testDecodeNeedsProtocolSession() throws Exception {
222         try {
223             decoder.decode(null, null, null);
224         } catch (AssertionError e) {
225             return;
226         }
227         fail("Expected assertion failure.");
228     }
229 
230     private void decodeBytes(final byte[] bytes) throws Exception {
231         final ByteBuffer buffer = ByteBuffer.allocate(bytes.length);
232         buffer.put(bytes);
233         buffer.flip();
234 
235         final MockControl control = MockControl.createNiceControl(ProtocolSession.class);
236         final ProtocolSession protocolSession = (ProtocolSession) control.getMock();
237         final WallaceSession wallaceSession = new WallaceSession();
238         wallaceSession.setSessionHandler(new MinaSessionHandler(protocolSession));
239         control.expectAndReturn(protocolSession.getAttachment(), wallaceSession);
240         control.replay();
241         decoder.decode(protocolSession, buffer, output);
242     }
243 }