package junit; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.Socket; import java.util.Date; import java.util.Iterator; import java.util.Properties; import javax.mail.Message; import javax.mail.MessagingException; import javax.mail.Session; import javax.mail.Transport; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeMessage; import junit.framework.TestCase; import org.mailster.smtp.api.MessageListener; import org.mailster.smtp.api.MessageListenerAdapter; import org.mailster.smtp.api.handler.SessionContext; import org.mailster.smtp.core.TooMuchDataException; import wiser.Wiser; import wiser.WiserMessage; /** * @author De Oliveira Edouard <doe_wanted@yahoo.fr> */ public class WiserFailuresTest extends TestCase { private final static String FROM_ADDRESS = "from-addr@localhost"; private final static String HOST_NAME = "localhost"; private final static String TO_ADDRESS = "to-addr@localhost"; private final static int SMTP_PORT = 10081; private BufferedReader input; private PrintWriter output; private Wiser server; private Socket socket; private int counter; public WiserFailuresTest(String name) { super(name); } protected void setUp() throws Exception { super.setUp(); server = new Wiser(); server.setPort(SMTP_PORT); server.start(); socket = new Socket(HOST_NAME, SMTP_PORT); input = new BufferedReader(new InputStreamReader(socket.getInputStream())); output = new PrintWriter(socket.getOutputStream(), true); counter = 0; } protected void tearDown() throws Exception { super.tearDown(); try { input.close(); } catch (Exception e){ e.printStackTrace(); } try { output.close(); } catch (Exception e){ e.printStackTrace(); } try { socket.close(); } catch (Exception e){ e.printStackTrace(); } try { server.stop(); } catch (Exception e){ e.printStackTrace(); } } /** * See http://sourceforge.net/tracker/index.php?func=detail&aid=1474700&group_id=78413&atid=553186 for discussion * about this bug */ public void testMailFromAfterReset() throws IOException, MessagingException { assertConnect(); sendExtendedHello(HOST_NAME); sendMailFrom(FROM_ADDRESS); sendReceiptTo(TO_ADDRESS); sendReset(); sendMailFrom(FROM_ADDRESS); sendReceiptTo(TO_ADDRESS); sendDataStart(); send(""); send("Body"); sendDataEnd(); sendQuit(); assertEquals(1, server.getMessages().size()); Iterator<WiserMessage> emailIter = server.getMessages().iterator(); WiserMessage email = emailIter.next(); assertEquals("Body", email.getMimeMessage().getContent().toString()); } /** * See http://sourceforge.net/tracker/index.php?func=detail&aid=1474700&group_id=78413&atid=553186 for discussion * about this bug */ public void testMailFromWithInitialReset() throws IOException, MessagingException { assertConnect(); sendReset(); sendMailFrom(FROM_ADDRESS); sendReceiptTo(TO_ADDRESS); sendDataStart(); send(""); send("Body"); sendDataEnd(); sendQuit(); assertEquals(1, server.getMessages().size()); Iterator<WiserMessage> emailIter = server.getMessages().iterator(); WiserMessage email = emailIter.next(); assertEquals("Body", email.getMimeMessage().getContent().toString()); } public void testSendEncodedMessage() throws IOException, MessagingException { String body = "\u3042\u3044\u3046\u3048\u304a"; // some Japanese letters String charset = "iso-2022-jp"; try { sendMessageWithCharset(SMTP_PORT, "sender@hereagain.com", "EncodedMessage", body, "receivingagain@there.com", charset); } catch (Exception e) { e.printStackTrace(); fail("Unexpected exception: " + e); } assertEquals(1, server.getMessages().size()); Iterator<WiserMessage> emailIter = server.getMessages().iterator(); WiserMessage email = emailIter.next(); assertEquals(body, email.getMimeMessage().getContent().toString()); } public void testSendMessageWithCarriageReturn() throws IOException, MessagingException { String bodyWithCR = "\r\n\r\nKeep these\r\npesky\r\n\r\ncarriage returns\r\n"; try { sendMessage(SMTP_PORT, "sender@hereagain.com", "CRTest", bodyWithCR, "receivingagain@there.com"); } catch (Exception e) { e.printStackTrace(); fail("Unexpected exception: " + e); } assertEquals(1, server.getMessages().size()); Iterator<WiserMessage> emailIter = server.getMessages().iterator(); WiserMessage email = emailIter.next(); String received = email.getMimeMessage().getContent().toString(); // last \r\n will be treated as part of the data termination by javamail // Transport ... so we compare the body without the last 2 chars assertEquals(bodyWithCR.substring(0, bodyWithCR.length()-2), received); } public void testListenersAndContextAttributes() throws IOException { try { MimeMessage[] mimeMessages = new MimeMessage[2]; Properties mailProps = getMailProperties(SMTP_PORT); Session session = Session.getInstance(mailProps, null); session.setDebug(true); mimeMessages[0] = createMessage(session, "sender@whatever.com", "receiver@home.com", "Doodle1", "Bug1"); mimeMessages[1] = createMessage(session, "sender@whatever.com", "receiver@home.com", "Doodle2", "Bug2"); server.getServer().getDeliveryHandlerFactory().addListener(new MessageListenerAdapter() { public boolean accept(SessionContext ctx, String from, String recipient) { ctx.addAttribute("prop2", "prop2_value"); return true; } }); Transport transport = session.getTransport("smtp"); transport.connect("localhost", SMTP_PORT, null, null); transport.sendMessage(mimeMessages[0], mimeMessages[0].getAllRecipients()); transport.close(); server.getServer().getDeliveryHandlerFactory().addListener(new MessageListener() { public void deliver(SessionContext ctx, String from, String recipient, InputStream data) throws TooMuchDataException, IOException { counter++; assertEquals("prop1_value", (String) ctx.getAttribute("prop1")); assertEquals("prop2_value", (String) ctx.getAttribute("prop2")); } public boolean accept(SessionContext ctx, String from, String recipient) { ctx.addAttribute("prop1", "prop1_value"); return true; } }); transport.connect("localhost", SMTP_PORT, null, null); transport.sendMessage(mimeMessages[1], mimeMessages[1].getAllRecipients()); transport.close(); } catch (MessagingException e) { e.printStackTrace(); fail("Unexpected exception: " + e); } assertEquals(1, counter); assertEquals(2, server.getMessages().size()); } public void testSendTwoMessagesSameConnection() throws IOException { try { MimeMessage[] mimeMessages = new MimeMessage[2]; Properties mailProps = getMailProperties(SMTP_PORT); Session session = Session.getInstance(mailProps, null); session.setDebug(true); mimeMessages[0] = createMessage(session, "sender@whatever.com", "receiver@home.com", "Doodle1", "Bug1"); mimeMessages[1] = createMessage(session, "sender@whatever.com", "receiver@home.com", "Doodle2", "Bug2"); Transport transport = session.getTransport("smtp"); transport.connect("localhost", SMTP_PORT, null, null); for (MimeMessage mimeMessage : mimeMessages) { transport.sendMessage(mimeMessage, mimeMessage.getAllRecipients()); } transport.close(); } catch (MessagingException e) { e.printStackTrace(); fail("Unexpected exception: " + e); } assertEquals(2, server.getMessages().size()); } public void testSendTwoMsgsWithLogin() throws MessagingException, IOException { try { String From = "sender@here.com"; String To = "receiver@there.com"; String Subject = "Test"; String body = "Test Body"; Session session = Session.getInstance(getMailProperties(SMTP_PORT), null); Message msg = new MimeMessage(session); msg.setFrom(new InternetAddress(From)); msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(To, false)); msg.setSubject(Subject); msg.setText(body); msg.setHeader("X-Mailer", "here"); msg.setSentDate(new Date()); Transport transport = null; try { transport = session.getTransport("smtp"); transport.connect(HOST_NAME, SMTP_PORT, "ddd", "ddd"); assertEquals(0, server.getMessages().size()); transport.sendMessage(msg, InternetAddress.parse(To, false)); assertEquals(1, server.getMessages().size()); transport.sendMessage(msg, InternetAddress.parse("receivingagain@there.com", false)); assertEquals(2, server.getMessages().size()); } catch (javax.mail.MessagingException me) { me.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } finally { if (transport != null) transport.close(); } } catch (Exception e) { e.printStackTrace(); } Iterator<WiserMessage> emailIter = server.getMessages().iterator(); WiserMessage email = emailIter.next(); MimeMessage mime = email.getMimeMessage(); assertEquals("Test", mime.getHeader("Subject")[0]); assertEquals("Test Body", mime.getContent().toString()); } private Properties getMailProperties(int port) { Properties mailProps = new Properties(); mailProps.setProperty("mail.smtp.host", "localhost"); mailProps.setProperty("mail.smtp.port", "" + port); mailProps.setProperty("mail.smtp.sendpartial", "true"); return mailProps; } private void sendMessage(int port, String from, String subject, String body, String to) throws MessagingException, IOException { Properties mailProps = getMailProperties(SMTP_PORT); Session session = Session.getInstance(mailProps, null); //session.setDebug(true); MimeMessage msg = createMessage(session, from, to, subject, body); Transport.send(msg); } private MimeMessage createMessage(Session session, String from, String to, String subject, String body) throws MessagingException, IOException { MimeMessage msg = new MimeMessage(session); msg.setFrom(new InternetAddress(from)); msg.setSubject(subject); msg.setSentDate(new Date()); msg.setText(body); msg.setRecipient(Message.RecipientType.TO, new InternetAddress(to)); return msg; } private void sendMessageWithCharset(int port, String from, String subject, String body, String to, String charset) throws MessagingException { Properties mailProps = getMailProperties(port); Session session = Session.getInstance(mailProps, null); //session.setDebug(true); MimeMessage msg = createMessageWithCharset(session, from, to, subject, body, charset); Transport.send(msg); } private MimeMessage createMessageWithCharset( Session session, String from, String to, String subject, String body, String charset) throws MessagingException { MimeMessage msg = new MimeMessage(session); msg.setFrom(new InternetAddress(from)); msg.setSubject(subject); msg.setSentDate(new Date()); if (charset != null) { msg.setText(body, charset); msg.setHeader("Content-Transfer-Encoding", "7bit"); } else msg.setText(body); msg.setRecipient(Message.RecipientType.TO, new InternetAddress(to)); return msg; } private void assertConnect() throws IOException { String response = readInput(); assertTrue(response, response.startsWith("220")); } private void sendDataEnd() throws IOException { send("."); String response = readInput(); assertTrue(response, response.startsWith("250")); } private void sendDataStart() throws IOException { send("DATA"); String response = readInput(); assertTrue(response, response.startsWith("354")); } private void sendExtendedHello(String hostName) throws IOException { send("EHLO " + hostName); String response = readInput(); assertTrue(response, response.startsWith("250")); } private void sendMailFrom(String fromAddress) throws IOException { send("MAIL FROM:<" + fromAddress + ">"); String response = readInput(); assertTrue(response, response.startsWith("250")); } private void sendQuit() throws IOException { send("QUIT"); String response = readInput(); assertTrue(response, response.startsWith("221")); } private void sendReceiptTo(String toAddress) throws IOException { send("RCPT TO:<" + toAddress + ">"); String response = readInput(); assertTrue(response, response.startsWith("250")); } private void sendReset() throws IOException { send("RSET"); String response = readInput(); assertTrue(response, response.startsWith("250")); } private void send(String msg) throws IOException { // Force \r\n since println() behaves differently on different platforms output.print(msg + "\r\n"); output.flush(); } private String readInput() { StringBuilder sb = new StringBuilder(); try { do { sb.append(input.readLine()).append("\n"); } while (input.ready()); } catch (IOException e) { e.printStackTrace(); } return sb.toString(); } }