package er.javamail; import java.util.LinkedList; import java.util.List; import javax.mail.Address; import javax.mail.Message; import javax.mail.MessagingException; import javax.mail.Session; import javax.mail.Transport; import javax.mail.URLName; import javax.mail.internet.AddressException; import junit.framework.TestCase; import er.extensions.foundation.ERXProperties; public class ERMailSenderTest extends TestCase { public List<RelayInfo> relays() { List<RelayInfo> relays = new LinkedList<>(); relays.add(new RelayInfo(null, "mail.pobox.com", "mschrag@pobox.com", "mschrag@pobox.com")); relays.add(new RelayInfo("other", "mailother.pobox.com", "mschrag@pobox.com", "mschrag@pobox.com")); return relays; } public RelayInfo defaultRelay() { return relays().get(0); } @Override protected void setUp() throws Exception { super.setUp(); for (RelayInfo relay : relays()) { if (relay.contextString == null) { System.setProperty("er.javamail.smtpHost", relay.host); } else { System.setProperty("er.javamail.smtpHost." + relay.contextString, relay.host); } } ERXProperties.setStringForKey("smtptest", "mail.smtp.protocol"); ERJavaMail.sharedInstance().finishInitialization(); TestSMTPTransport.clearSentMessages(); } protected void sendTestMessage(RelayInfo relay, boolean sendNow) throws AddressException, MessagingException { ERMailDeliveryPlainText mailDelivery = new ERMailDeliveryPlainText(); mailDelivery.setSubject("Test Subject"); mailDelivery.setToAddress(relay.fromAddress); mailDelivery.setFromAddress(relay.toAddress); mailDelivery.setTextContent("Test Message"); mailDelivery.setContextString(relay.contextString); mailDelivery.sendMail(sendNow); } protected void testSendMessageNowWithRelay(RelayInfo relay) throws MessagingException { sendTestMessage(relay, true); List<SentMessage> sentMessages = TestSMTPTransport.sentMessages(); assertEquals(1, sentMessages.size()); assertEquals(relay.host, sentMessages.get(0).transport.getSession().getProperty("mail.smtptest.host")); } public void testSendMessageNowDefaultRelay() throws MessagingException { testSendMessageNowWithRelay(defaultRelay()); } public void testSendMessageNowOtherRelay() throws MessagingException { testSendMessageNowWithRelay(relays().get(1)); } protected void waitForMessages(int count) { for (long startTime = System.currentTimeMillis(); TestSMTPTransport.sentMessages().size() < count && System.currentTimeMillis() - startTime < 10000;) { // DO NOTHING } } protected void testSendMessageDeferredWithRelay(RelayInfo relay) throws MessagingException { sendTestMessage(relay, false); waitForMessages(1); List<SentMessage> sentMessages = TestSMTPTransport.sentMessages(); assertEquals(1, sentMessages.size()); assertEquals(relay.host, sentMessages.get(0).transport.getSession().getProperty("mail.smtptest.host")); } public void testSendMessageDeferredDefaultRelay() throws MessagingException { testSendMessageDeferredWithRelay(defaultRelay()); } public void testSendMessageDeferredOtherRelay() throws MessagingException { testSendMessageDeferredWithRelay(relays().get(1)); } public void testSendTwoMessagesDeferredMixedRelays() throws AddressException, MessagingException { sendTestMessage(relays().get(0), false); sendTestMessage(relays().get(1), false); waitForMessages(2); List<SentMessage> sentMessages = TestSMTPTransport.sentMessages(); assertEquals(2, sentMessages.size()); assertEquals(relays().get(0).host, sentMessages.get(0).transport.getSession().getProperty("mail.smtptest.host")); assertEquals(relays().get(1).host, sentMessages.get(1).transport.getSession().getProperty("mail.smtptest.host")); } public static class SentMessage { public TestSMTPTransport transport; public Message message; public Address[] addresses; public SentMessage(TestSMTPTransport transport, Message message, Address[] addresses) { this.transport = transport; this.message = message; this.addresses = addresses; } } public static class TestSMTPTransport extends Transport { private static List<SentMessage> _sentMessages = new LinkedList<>(); public TestSMTPTransport(Session session, URLName urlname) { super(session, urlname); } public Session getSession() { return session; } @Override public void sendMessage(Message message, Address[] addresses) throws MessagingException { synchronized (_sentMessages) { _sentMessages.add(new SentMessage(this, message, addresses)); } } @Override public void connect() throws MessagingException { // DO NOTHING } @Override public void connect(String host, int port, String user, String password) throws MessagingException { // DO NOTHING } @Override public void connect(String user, String password) throws MessagingException { // DO NOTHING } @Override public void connect(String host, String user, String password) throws MessagingException { // DO NOTHING } public static void clearSentMessages() { synchronized (_sentMessages) { _sentMessages.clear(); } } public static List<SentMessage> sentMessages() { synchronized (_sentMessages) { return new LinkedList<>(_sentMessages); } } } public static class RelayInfo { public String contextString; public String host; public String fromAddress; public String toAddress; public RelayInfo(String contextString, String host, String fromAddress, String toAddress) { this.contextString = contextString; this.host = host; this.fromAddress = fromAddress; this.toAddress = toAddress; } } }