/*
* Licensed 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
*
* http://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 com.ok2c.lightmtp.message;
import java.nio.channels.ReadableByteChannel;
import java.nio.charset.Charset;
import org.junit.Assert;
import org.junit.Test;
import org.apache.http.impl.nio.reactor.SessionInputBufferImpl;
import org.apache.http.nio.reactor.SessionInputBuffer;
import com.ok2c.lightmtp.SMTPCode;
import com.ok2c.lightmtp.SMTPProtocolException;
import com.ok2c.lightmtp.SMTPReply;
import com.ok2c.lightmtp.mock.ReadableByteChannelMockup;
public class TestSMTPReplyParser {
private final static Charset ASCII = Charset.forName("ASCII");
@Test
public void testConstructor() throws Exception {
SessionInputBuffer inbuf = new SessionInputBufferImpl(4096, 1024, ASCII);
SMTPMessageParser<SMTPReply> parser = new SMTPReplyParser();
Assert.assertNull(parser.parse(inbuf, false));
}
@Test(expected=IllegalArgumentException.class)
public void testInvalidConstructorParam() throws Exception {
SMTPMessageParser<SMTPReply> parser = new SMTPReplyParser();
parser.parse(null, false);
}
@Test
public void testBasicReplyParsing() throws Exception {
SessionInputBuffer inbuf = new SessionInputBufferImpl(4096, 1024, ASCII);
SMTPMessageParser<SMTPReply> parser = new SMTPReplyParser();
String[] input = new String[] {
"250 OK\r\n"
};
ReadableByteChannel channel = new ReadableByteChannelMockup(input, ASCII);
inbuf.fill(channel);
SMTPReply reply = parser.parse(inbuf, false);
Assert.assertNotNull(reply);
Assert.assertEquals(250, reply.getCode());
Assert.assertNull(reply.getEnhancedCode());
Assert.assertEquals("OK", reply.getLine());
}
@Test
public void testMultipleReplyParsing() throws Exception {
SessionInputBuffer inbuf = new SessionInputBufferImpl(4096, 1024, ASCII);
SMTPMessageParser<SMTPReply> parser = new SMTPReplyParser();
String[] input = new String[] {
"250 OK\r\n500 NOT OK\r\n550 NOT OK\r\n"
};
ReadableByteChannel channel = new ReadableByteChannelMockup(input, ASCII);
inbuf.fill(channel);
SMTPReply reply1 = parser.parse(inbuf, false);
Assert.assertNotNull(reply1);
Assert.assertEquals(250, reply1.getCode());
SMTPReply reply2 = parser.parse(inbuf, false);
Assert.assertNotNull(reply2);
Assert.assertEquals(500, reply2.getCode());
SMTPReply reply3 = parser.parse(inbuf, false);
Assert.assertNotNull(reply3);
Assert.assertEquals(550, reply3.getCode());
}
@Test
public void testReplyParsingEndOfStream() throws Exception {
SessionInputBuffer inbuf = new SessionInputBufferImpl(4096, 1024, ASCII);
SMTPMessageParser<SMTPReply> parser = new SMTPReplyParser();
String[] input = new String[] {
"250 OK"
};
ReadableByteChannel channel = new ReadableByteChannelMockup(input, ASCII);
inbuf.fill(channel);
Assert.assertNull(parser.parse(inbuf, false));
SMTPReply reply = parser.parse(inbuf, true);
Assert.assertNotNull(reply);
Assert.assertEquals(250, reply.getCode());
Assert.assertNull(reply.getEnhancedCode());
Assert.assertEquals("OK", reply.getLine());
}
@Test
public void testReplyParsingWithEnhancedCode() throws Exception {
SessionInputBuffer inbuf = new SessionInputBufferImpl(4096, 1024, ASCII);
SMTPMessageParser<SMTPReply> parser = new SMTPReplyParser(true);
Assert.assertNull(parser.parse(inbuf, false));
String[] input = new String[] {
"250 2.5.0 OK\r\n"
};
ReadableByteChannel channel = new ReadableByteChannelMockup(input, ASCII);
inbuf.fill(channel);
SMTPReply reply = parser.parse(inbuf, false);
Assert.assertNotNull(reply);
Assert.assertEquals(250, reply.getCode());
Assert.assertEquals(new SMTPCode(2, 5, 0), reply.getEnhancedCode());
Assert.assertEquals("OK", reply.getLine());
}
@Test
public void testChunkedReplyParsing() throws Exception {
SessionInputBuffer inbuf = new SessionInputBufferImpl(4096, 1024, ASCII);
SMTPMessageParser<SMTPReply> parser = new SMTPReplyParser();
Assert.assertNull(parser.parse(inbuf, false));
String[] input = new String[] {
"25",
"0 ",
"blah ",
"blah\r\n"
};
ReadableByteChannel channel = new ReadableByteChannelMockup(input, ASCII);
inbuf.fill(channel);
Assert.assertNull(parser.parse(inbuf, false));
inbuf.fill(channel);
Assert.assertNull(parser.parse(inbuf, false));
inbuf.fill(channel);
Assert.assertNull(parser.parse(inbuf, false));
inbuf.fill(channel);
SMTPReply reply = parser.parse(inbuf, false);
Assert.assertNotNull(reply);
Assert.assertEquals(250, reply.getCode());
Assert.assertNull(reply.getEnhancedCode());
Assert.assertEquals("blah blah", reply.getLine());
}
@Test
public void testReplyParsingWithLeadingBlanks() throws Exception {
SessionInputBuffer inbuf = new SessionInputBufferImpl(4096, 1024, ASCII);
SMTPMessageParser<SMTPReply> parser = new SMTPReplyParser();
Assert.assertNull(parser.parse(inbuf, false));
String[] input = new String[] {
" 250 OK\r\n"
};
ReadableByteChannel channel = new ReadableByteChannelMockup(input, ASCII);
inbuf.fill(channel);
SMTPReply reply = parser.parse(inbuf, false);
Assert.assertNotNull(reply);
Assert.assertEquals(250, reply.getCode());
Assert.assertNull(reply.getEnhancedCode());
Assert.assertEquals("OK", reply.getLine());
}
@Test
public void testMultilineReplyParsing() throws Exception {
SessionInputBuffer inbuf = new SessionInputBufferImpl(4096, 1024, ASCII);
SMTPMessageParser<SMTPReply> parser = new SMTPReplyParser();
Assert.assertNull(parser.parse(inbuf, false));
String[] input = new String[] {
"250-whatever.com\r\n",
"250-PIPELINING\r\n",
"250-ENHANCEDSTATUSCODES\r\n",
"250 8BITMIME\r\n"
};
ReadableByteChannel channel = new ReadableByteChannelMockup(input, ASCII);
inbuf.fill(channel);
Assert.assertNull(parser.parse(inbuf, false));
inbuf.fill(channel);
Assert.assertNull(parser.parse(inbuf, false));
inbuf.fill(channel);
Assert.assertNull(parser.parse(inbuf, false));
inbuf.fill(channel);
SMTPReply reply = parser.parse(inbuf, false);
Assert.assertEquals(250, reply.getCode());
Assert.assertNull(reply.getEnhancedCode());
Assert.assertNotNull(reply.getLines());
Assert.assertEquals(4, reply.getLines().size());
Assert.assertEquals("whatever.com", reply.getLines().get(0));
Assert.assertEquals("PIPELINING", reply.getLines().get(1));
Assert.assertEquals("ENHANCEDSTATUSCODES", reply.getLines().get(2));
Assert.assertEquals("8BITMIME", reply.getLines().get(3));
}
@Test
public void testMultilineReplyParsingWithEnhancedCode() throws Exception {
SessionInputBuffer inbuf = new SessionInputBufferImpl(4096, 1024, ASCII);
SMTPMessageParser<SMTPReply> parser = new SMTPReplyParser(true);
Assert.assertNull(parser.parse(inbuf, false));
String[] input = new String[] {
"250-2.5.0 whatever.com\r\n",
"250-2.5.0 PIPELINING\r\n",
"250-2.5.0 ENHANCEDSTATUSCODES\r\n",
"250 2.5.0 8BITMIME\r\n"
};
ReadableByteChannel channel = new ReadableByteChannelMockup(input, ASCII);
inbuf.fill(channel);
Assert.assertNull(parser.parse(inbuf, false));
inbuf.fill(channel);
Assert.assertNull(parser.parse(inbuf, false));
inbuf.fill(channel);
Assert.assertNull(parser.parse(inbuf, false));
inbuf.fill(channel);
SMTPReply reply = parser.parse(inbuf, false);
Assert.assertEquals(250, reply.getCode());
Assert.assertEquals(new SMTPCode(2, 5, 0), reply.getEnhancedCode());
Assert.assertNotNull(reply.getLines());
Assert.assertEquals(4, reply.getLines().size());
Assert.assertEquals("whatever.com", reply.getLines().get(0));
Assert.assertEquals("PIPELINING", reply.getLines().get(1));
Assert.assertEquals("ENHANCEDSTATUSCODES", reply.getLines().get(2));
Assert.assertEquals("8BITMIME", reply.getLines().get(3));
}
@Test
public void testChunkedMultilineReplyParsing() throws Exception {
SessionInputBuffer inbuf = new SessionInputBufferImpl(4096, 1024, ASCII);
SMTPMessageParser<SMTPReply> parser = new SMTPReplyParser();
Assert.assertNull(parser.parse(inbuf, false));
String[] input = new String[] {
"25",
"0-wha",
"tever.com",
"\r\n",
"250",
"-PIP",
"ELINING\r",
"\n",
"250",
"-",
"ENHANCEDSTATUSCODES\r\n",
"250",
" ",
"8BITMIME\r\n"
};
ReadableByteChannel channel = new ReadableByteChannelMockup(input, ASCII);
SMTPReply reply = null;
while (reply == null) {
inbuf.fill(channel);
reply = parser.parse(inbuf, false);
}
Assert.assertEquals(250, reply.getCode());
Assert.assertNull(reply.getEnhancedCode());
Assert.assertNotNull(reply.getLines());
Assert.assertEquals(4, reply.getLines().size());
Assert.assertEquals("whatever.com", reply.getLines().get(0));
Assert.assertEquals("PIPELINING", reply.getLines().get(1));
Assert.assertEquals("ENHANCEDSTATUSCODES", reply.getLines().get(2));
Assert.assertEquals("8BITMIME", reply.getLines().get(3));
}
@Test(expected=SMTPProtocolException.class)
public void testParsingInvalidCode() throws Exception {
SessionInputBuffer inbuf = new SessionInputBufferImpl(4096, 1024, ASCII);
SMTPMessageParser<SMTPReply> parser = new SMTPReplyParser();
Assert.assertNull(parser.parse(inbuf, false));
String[] input = new String[] {
"2s0 OK\r\n"
};
ReadableByteChannel channel = new ReadableByteChannelMockup(input, ASCII);
inbuf.fill(channel);
parser.parse(inbuf, false);
}
@Test(expected=SMTPProtocolException.class)
public void testParsingNoCode() throws Exception {
SessionInputBuffer inbuf = new SessionInputBufferImpl(4096, 1024, ASCII);
SMTPMessageParser<SMTPReply> parser = new SMTPReplyParser();
Assert.assertNull(parser.parse(inbuf, false));
String[] input = new String[] {
" OK\r\n"
};
ReadableByteChannel channel = new ReadableByteChannelMockup(input, ASCII);
inbuf.fill(channel);
parser.parse(inbuf, false);
}
@Test(expected=SMTPProtocolException.class)
public void testParsingInvalidCodeDelimiter() throws Exception {
SessionInputBuffer inbuf = new SessionInputBufferImpl(4096, 1024, ASCII);
SMTPMessageParser<SMTPReply> parser = new SMTPReplyParser();
Assert.assertNull(parser.parse(inbuf, false));
String[] input = new String[] {
"250=whatever.com\r\n",
"250 PIPELINING\r\n"
};
ReadableByteChannel channel = new ReadableByteChannelMockup(input, ASCII);
inbuf.fill(channel);
parser.parse(inbuf, false);
}
@Test(expected=SMTPProtocolException.class)
public void testParsingInvalidEnhancedCode1() throws Exception {
SessionInputBuffer inbuf = new SessionInputBufferImpl(4096, 1024, ASCII);
SMTPMessageParser<SMTPReply> parser = new SMTPReplyParser(true);
Assert.assertNull(parser.parse(inbuf, false));
String[] input = new String[] {
"250 dddddd OK\r\n"
};
ReadableByteChannel channel = new ReadableByteChannelMockup(input, ASCII);
inbuf.fill(channel);
parser.parse(inbuf, false);
}
@Test(expected=SMTPProtocolException.class)
public void testParsingInvalidEnhancedCode2() throws Exception {
SessionInputBuffer inbuf = new SessionInputBufferImpl(4096, 1024, ASCII);
SMTPMessageParser<SMTPReply> parser = new SMTPReplyParser(true);
Assert.assertNull(parser.parse(inbuf, false));
String[] input = new String[] {
"250 d.5.0 OK\r\n"
};
ReadableByteChannel channel = new ReadableByteChannelMockup(input, ASCII);
inbuf.fill(channel);
parser.parse(inbuf, false);
}
@Test(expected=SMTPProtocolException.class)
public void testParsingInvalidEnhancedCode3() throws Exception {
SessionInputBuffer inbuf = new SessionInputBufferImpl(4096, 1024, ASCII);
SMTPMessageParser<SMTPReply> parser = new SMTPReplyParser(true);
Assert.assertNull(parser.parse(inbuf, false));
String[] input = new String[] {
"250 2.dddd OK\r\n"
};
ReadableByteChannel channel = new ReadableByteChannelMockup(input, ASCII);
inbuf.fill(channel);
parser.parse(inbuf, false);
}
@Test(expected=SMTPProtocolException.class)
public void testParsingInvalidEnhancedCode4() throws Exception {
SessionInputBuffer inbuf = new SessionInputBufferImpl(4096, 1024, ASCII);
SMTPMessageParser<SMTPReply> parser = new SMTPReplyParser(true);
Assert.assertNull(parser.parse(inbuf, false));
String[] input = new String[] {
"250 2.d.0 OK\r\n"
};
ReadableByteChannel channel = new ReadableByteChannelMockup(input, ASCII);
inbuf.fill(channel);
parser.parse(inbuf, false);
}
@Test(expected=SMTPProtocolException.class)
public void testParsingInvalidEnhancedCode5() throws Exception {
SessionInputBuffer inbuf = new SessionInputBufferImpl(4096, 1024, ASCII);
SMTPMessageParser<SMTPReply> parser = new SMTPReplyParser(true);
Assert.assertNull(parser.parse(inbuf, false));
String[] input = new String[] {
"250 2.5.d OK\r\n"
};
ReadableByteChannel channel = new ReadableByteChannelMockup(input, ASCII);
inbuf.fill(channel);
parser.parse(inbuf, false);
}
@Test(expected=SMTPProtocolException.class)
public void testParsingInvalidEnhancedCode6() throws Exception {
SessionInputBuffer inbuf = new SessionInputBufferImpl(4096, 1024, ASCII);
SMTPMessageParser<SMTPReply> parser = new SMTPReplyParser(true);
Assert.assertNull(parser.parse(inbuf, false));
String[] input = new String[] {
"250 2.5.0\r\n"
};
ReadableByteChannel channel = new ReadableByteChannelMockup(input, ASCII);
inbuf.fill(channel);
parser.parse(inbuf, false);
}
@Test(expected=SMTPProtocolException.class)
public void testParsingInvalidCodeClassMismatch() throws Exception {
SessionInputBuffer inbuf = new SessionInputBufferImpl(4096, 1024, ASCII);
SMTPMessageParser<SMTPReply> parser = new SMTPReplyParser(true);
Assert.assertNull(parser.parse(inbuf, false));
String[] input = new String[] {
"250 3.5.0 OK\r\n"
};
ReadableByteChannel channel = new ReadableByteChannelMockup(input, ASCII);
inbuf.fill(channel);
parser.parse(inbuf, false);
}
@Test(expected=SMTPProtocolException.class)
public void testOverMaxLenReplyParsing() throws Exception {
SessionInputBuffer inbuf = new SessionInputBufferImpl(4096, 1024, ASCII);
SMTPMessageParser<SMTPReply> parser = new SMTPReplyParser(16, false);
Assert.assertNull(parser.parse(inbuf, false));
String[] input = new String[] {
"200 BLAHBLAHBLAHBLAH\r\n"
};
ReadableByteChannel channel = new ReadableByteChannelMockup(input, ASCII);
inbuf.fill(channel);
parser.parse(inbuf, false);
}
}