You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by ma...@apache.org on 2010/02/17 15:49:49 UTC

svn commit: r911001 - in /james/hupa/trunk: client/src/main/java/org/apache/hupa/client/ client/src/main/java/org/apache/hupa/client/mvp/ client/src/main/java/org/apache/hupa/client/validation/ client/src/test/java/org/apache/hupa/client/ client/src/te...

Author: manolo
Date: Wed Feb 17 14:49:48 2010
New Revision: 911001

URL: http://svn.apache.org/viewvc?rev=911001&view=rev
Log:
Fixed a pair of bugs related with replying and replying-to messages.
Refactoring of MessageSendPresenter to make easy test it.
Added tests for almost everything in MessageSendPresenter.
Moved validations which can not be run with junit from the presenter to the view.
Minor changes to the common tests classes.

Added:
    james/hupa/trunk/client/src/test/java/org/apache/hupa/client/mock/
    james/hupa/trunk/client/src/test/java/org/apache/hupa/client/mock/MockMessageSendDisplay.java
    james/hupa/trunk/client/src/test/java/org/apache/hupa/client/mock/MockUploader.java
    james/hupa/trunk/client/src/test/java/org/apache/hupa/client/mock/MockWidget.java
    james/hupa/trunk/client/src/test/java/org/apache/hupa/client/mvp/MessageSendPresenterTest.java
    james/hupa/trunk/server/src/main/java/org/apache/hupa/server/mock/MockHttpSessionProvider.java
Modified:
    james/hupa/trunk/client/src/main/java/org/apache/hupa/client/HupaConstants.java
    james/hupa/trunk/client/src/main/java/org/apache/hupa/client/HupaMessages.java
    james/hupa/trunk/client/src/main/java/org/apache/hupa/client/mvp/MessageSendPresenter.java
    james/hupa/trunk/client/src/main/java/org/apache/hupa/client/mvp/MessageSendView.java
    james/hupa/trunk/client/src/main/java/org/apache/hupa/client/validation/EmailListValidator.java
    james/hupa/trunk/client/src/test/java/org/apache/hupa/client/HupaGwtTestCase.java
    james/hupa/trunk/client/src/test/java/org/apache/hupa/client/HupaMvpTestCase.java
    james/hupa/trunk/client/src/test/java/org/apache/hupa/client/guice/GuiceMvpTestModule.java
    james/hupa/trunk/client/src/test/java/org/apache/hupa/client/validation/EmailListValidatorTest.java
    james/hupa/trunk/server/src/main/java/org/apache/hupa/server/guice/DemoModeConstants.java
    james/hupa/trunk/server/src/main/java/org/apache/hupa/server/guice/GuiceServerTestModule.java
    james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/AbstractSendMessageHandler.java
    james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/AbstractSessionHandler.java
    james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/LoginUserHandler.java
    james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/LogoutUserHandler.java
    james/hupa/trunk/server/src/main/java/org/apache/hupa/server/mock/MockHttpSession.java
    james/hupa/trunk/server/src/main/java/org/apache/hupa/server/utils/SessionUtils.java
    james/hupa/trunk/server/src/main/resources/mime/1.msg
    james/hupa/trunk/server/src/test/java/org/apache/hupa/server/HupaGuiceTestCase.java
    james/hupa/trunk/server/src/test/java/org/apache/hupa/server/handler/HandlersTest.java
    james/hupa/trunk/server/src/test/java/org/apache/hupa/server/preferences/InImapUserPreferencesStorageTest.java
    james/hupa/trunk/shared/src/main/java/org/apache/hupa/shared/Util.java
    james/hupa/trunk/shared/src/main/java/org/apache/hupa/shared/data/AbstractMessage.java
    james/hupa/trunk/shared/src/main/java/org/apache/hupa/shared/data/SMTPMessage.java

Modified: james/hupa/trunk/client/src/main/java/org/apache/hupa/client/HupaConstants.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/client/src/main/java/org/apache/hupa/client/HupaConstants.java?rev=911001&r1=911000&r2=911001&view=diff
==============================================================================
--- james/hupa/trunk/client/src/main/java/org/apache/hupa/client/HupaConstants.java (original)
+++ james/hupa/trunk/client/src/main/java/org/apache/hupa/client/HupaConstants.java Wed Feb 17 14:49:48 2010
@@ -19,13 +19,14 @@
 
 package org.apache.hupa.client;
 
+import com.google.gwt.i18n.client.Constants;
+
+import eu.maydu.gwt.validation.client.i18n.StandardValidationMessagesImpl;
 import gwtupload.client.IUploader.UploaderConstants;
 
 import org.apache.hupa.widgets.PagingOptionsConstants;
 import org.apache.hupa.widgets.editor.ToolbarConstants;
 
-import com.google.gwt.i18n.client.Constants;
-
 public interface HupaConstants extends Constants, UploaderConstants, PagingOptionsConstants, ToolbarConstants {
 
     public String usernameLabel();

Modified: james/hupa/trunk/client/src/main/java/org/apache/hupa/client/HupaMessages.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/client/src/main/java/org/apache/hupa/client/HupaMessages.java?rev=911001&r1=911000&r2=911001&view=diff
==============================================================================
--- james/hupa/trunk/client/src/main/java/org/apache/hupa/client/HupaMessages.java (original)
+++ james/hupa/trunk/client/src/main/java/org/apache/hupa/client/HupaMessages.java Wed Feb 17 14:49:48 2010
@@ -21,7 +21,9 @@
 
 import com.google.gwt.i18n.client.Messages;
 
-public interface HupaMessages extends Messages{
+import eu.maydu.gwt.validation.client.i18n.StandardValidationMessagesImpl;
+
+public interface HupaMessages extends Messages, StandardValidationMessagesImpl {
 
     @DefaultMessage("Are you sure you want to delete the selected messages?")
     public String confirmDeleteMessages();

Modified: james/hupa/trunk/client/src/main/java/org/apache/hupa/client/mvp/MessageSendPresenter.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/client/src/main/java/org/apache/hupa/client/mvp/MessageSendPresenter.java?rev=911001&r1=911000&r2=911001&view=diff
==============================================================================
--- james/hupa/trunk/client/src/main/java/org/apache/hupa/client/mvp/MessageSendPresenter.java (original)
+++ james/hupa/trunk/client/src/main/java/org/apache/hupa/client/mvp/MessageSendPresenter.java Wed Feb 17 14:49:48 2010
@@ -22,15 +22,11 @@
 import com.google.gwt.event.dom.client.ClickEvent;
 import com.google.gwt.event.dom.client.ClickHandler;
 import com.google.gwt.event.dom.client.HasClickHandlers;
-import com.google.gwt.user.client.Window;
 import com.google.gwt.user.client.ui.Focusable;
 import com.google.gwt.user.client.ui.HasHTML;
 import com.google.gwt.user.client.ui.HasText;
 import com.google.inject.Inject;
 
-import eu.maydu.gwt.validation.client.DefaultValidationProcessor;
-import eu.maydu.gwt.validation.client.ValidationProcessor;
-import eu.maydu.gwt.validation.client.i18n.ValidationMessages;
 import gwtupload.client.IUploader;
 import gwtupload.client.IUploadStatus.Status;
 import gwtupload.client.IUploader.OnCancelUploaderHandler;
@@ -38,16 +34,13 @@
 import gwtupload.client.IUploader.OnStatusChangedHandler;
 
 import net.customware.gwt.dispatch.client.DispatchAsync;
+import net.customware.gwt.dispatch.shared.Action;
 import net.customware.gwt.presenter.client.EventBus;
 import net.customware.gwt.presenter.client.widget.WidgetDisplay;
 import net.customware.gwt.presenter.client.widget.WidgetPresenter;
 
-import org.apache.hupa.client.HupaCSS;
 import org.apache.hupa.client.HupaCallback;
-import org.apache.hupa.client.validation.AddStyleAction;
 import org.apache.hupa.client.validation.EmailListValidator;
-import org.apache.hupa.client.validation.NotEmptyValidator;
-import org.apache.hupa.client.validation.SetFocusAction;
 import org.apache.hupa.shared.Util;
 import org.apache.hupa.shared.data.IMAPFolder;
 import org.apache.hupa.shared.data.Message;
@@ -56,6 +49,7 @@
 import org.apache.hupa.shared.data.SMTPMessage;
 import org.apache.hupa.shared.data.User;
 import org.apache.hupa.shared.events.BackEvent;
+import org.apache.hupa.shared.events.FlashEvent;
 import org.apache.hupa.shared.events.FolderSelectionEvent;
 import org.apache.hupa.shared.events.FolderSelectionEventHandler;
 import org.apache.hupa.shared.events.LoadMessagesEvent;
@@ -71,6 +65,7 @@
 import org.apache.hupa.widgets.ui.HasEnable;
 
 import java.util.ArrayList;
+import java.util.List;
 
 /**
  * Presenter which handles the sending, reply, replay-all, forward of mails
@@ -83,8 +78,9 @@
     private Type type = Type.NEW;
     private IMAPFolder folder;
     private Message oldmessage;
-    private ValidationMessages vMessages = new ValidationMessages();
-    private ValidationProcessor validator = new DefaultValidationProcessor(vMessages);
+    
+    protected SMTPMessage message = null;
+    
     @SuppressWarnings("unused")
     private MessageDetails oldDetails;
 
@@ -122,40 +118,19 @@
     @Inject
     public MessageSendPresenter(Display display, EventBus eventBus, DispatchAsync dispatcher) {
         super(display, eventBus);
+        this.display = display;
         this.dispatcher = dispatcher;
+        
 
-        SetFocusAction fAction = new SetFocusAction();
-        AddStyleAction sAction = new AddStyleAction(HupaCSS.C_validate, 3000);
-        validator.addValidators("cc", 
-                new EmailListValidator(display.getCcText()).addActionForFailure(sAction).addActionForFailure(fAction));
-        validator.addValidators("bcc", 
-                new EmailListValidator(display.getBccText()).addActionForFailure(sAction).addActionForFailure(fAction));
-        validator.addValidators("to", 
-                new EmailListValidator(display.getToText()).addActionForFailure(sAction).addActionForFailure(fAction),
-                new NotEmptyValidator(display.getToText()).addActionForFailure(sAction).addActionForFailure(fAction));
     }
+    
+    public Display display;
 
     /**
      * The Type for which the SendPresenter will get used
-     * 
      */
     public enum Type {
-        /**
-         * Compose new Mail
-         */
-        NEW,
-        /**
-         * Reply to Mail
-         */
-        REPLY,
-        /**
-         * Reply-all to mail
-         */
-        REPLY_ALL,
-        /**
-         * Forward mail
-         */
-        FORWARD
+        NEW, REPLY, REPLY_ALL, FORWARD
     }
 
     public interface Display extends WidgetDisplay {
@@ -186,122 +161,27 @@
         public void setLoading(boolean loading);
         
         public void fillContactList(Contact[] contacts);
+        
+        public boolean validate();
     }
 
     @Override
     protected void onBind() {
         registerHandler(eventBus.addHandler(LoadMessagesEvent.TYPE, new LoadMessagesEventHandler() {
-
             public void onLoadMessagesEvent(LoadMessagesEvent loadMessagesEvent) {
                 reset();
             }
-
         }));
         registerHandler(eventBus.addHandler(FolderSelectionEvent.TYPE, new FolderSelectionEventHandler() {
-
             public void onFolderSelectionEvent(FolderSelectionEvent event) {
                 reset();
             }
-
-        }));
-
-        registerHandler(display.getSendClick().addClickHandler(new ClickHandler() {
-
-            public void onClick(ClickEvent event) {
-
-                if (validator.validate() == false) {
-                    return;
-                }
-                SMTPMessage message = new SMTPMessage();
-
-                message.setFrom(display.getFromText().getText());
-
-                ArrayList<String> to = new ArrayList<String>();
-                String[] toRaw = display.getToText().getText().split("[,;]+");
-                if (toRaw != null) {
-                    for (int i = 0; i < toRaw.length; i++) {
-                        String toRecip = toRaw[i].trim();
-                        if (toRecip.length() > 0) {
-                            to.add(toRaw[i].trim());
-                        }
-                    }
-                }
-                message.setTo(to);
-
-                ArrayList<String> cc = new ArrayList<String>();
-                String[] ccRaw = display.getCcText().getText().split("[,;]+");
-                if (ccRaw != null) {
-                    for (int i = 0; i < ccRaw.length; i++) {
-                        String ccRecip = ccRaw[i].trim();
-                        if (ccRecip.length() > 0) {
-                            cc.add(ccRaw[i].trim());
-                        }
-                    }
-                }
-                message.setCc(cc);
-
-                message.setSubject(display.getSubjectText().getText());
-                message.setText(display.getMessageHTML().getHTML());
-
-                message.setMessageAttachments(attachments);
-
-                // TODO: good handling of error messages, and use an error
-                // widget instead of Window.alert
-
-                if (type.equals(Type.NEW)) {
-                    display.setLoading(true);
-
-                    dispatcher.execute(new SendMessage(message), new HupaCallback<GenericResult>(dispatcher, eventBus) {
-                        public void callback(GenericResult result) {
-                            if (result.isSuccess()) {
-                                eventBus.fireEvent(new SentMessageEvent());
-                                reset();
-                            } else {
-                                Window.alert(result.getMessage());
-                            }
-                            display.setLoading(false);
-
-                        }
-                    });
-                } else if (type.equals(Type.FORWARD)) {
-                    display.setLoading(true);
-
-                    dispatcher.execute(new ForwardMessage(message, folder, oldmessage.getUid()), new HupaCallback<GenericResult>(dispatcher, eventBus) {
-                        public void callback(GenericResult result) {
-                            if (result.isSuccess()) {
-                                eventBus.fireEvent(new SentMessageEvent());
-                                reset();
-                            } else {
-                                Window.alert(result.getMessage());
-                            }
-                            display.setLoading(false);
-
-                        }
-                    });
-                } else if (type.equals(Type.REPLY) || type.equals(Type.REPLY_ALL)) {
-                    display.setLoading(true);
-
-                    dispatcher.execute(new ReplyMessage(message, folder, oldmessage.getUid()), new HupaCallback<GenericResult>(dispatcher, eventBus) {
-                        public void callback(GenericResult result) {
-                            if (result.isSuccess()) {
-                                eventBus.fireEvent(new SentMessageEvent());
-                                reset();
-                            } else {
-                                Window.alert(result.getMessage());
-                            }
-                            display.setLoading(false);
-                        }
-                    });
-                }
-            }
         }));
-
+        registerHandler(display.getSendClick().addClickHandler(sendClickHandler));
         registerHandler(display.getBackButtonClick().addClickHandler(new ClickHandler() {
-
             public void onClick(ClickEvent event) {
                 eventBus.fireEvent(new BackEvent());
             }
-
         }));
 
         display.getUploader().addOnStatusChangedHandler(onStatusChangedHandler);
@@ -310,6 +190,64 @@
 
         reset();
     }
+    
+    protected ClickHandler sendClickHandler = new ClickHandler() {
+        public void onClick(ClickEvent event) {
+            
+            if (validate() == false) {
+                return;
+            }
+
+            message = new SMTPMessage();
+            message.setFrom(display.getFromText().getText());
+            message.setSubject(display.getSubjectText().getText());
+            message.setText(display.getMessageHTML().getHTML());
+            message.setMessageAttachments(attachments);
+            message.setTo(emailTextToArray(display.getToText().getText()));
+            message.setCc(emailTextToArray(display.getCcText().getText()));
+            message.setBcc(emailTextToArray(display.getBccText().getText()));
+
+            SendMessage command;
+            if (type == Type.NEW) {
+                command = new SendMessage(message);
+            } else if (type == Type.FORWARD) {
+                command = new ForwardMessage(message, folder, oldmessage.getUid());
+            } else {
+                command = new ReplyMessage(message, folder, oldmessage.getUid());
+            }
+            dispatchMessage(dispatcher, eventBus, command);
+        }
+    };
+
+    protected ArrayList<String> emailTextToArray(String emails) {
+        ArrayList<String> cc = new ArrayList<String>();
+        String[] ccRaw = emails.split("[,;]+");
+        if (ccRaw != null) {
+            for (int i = 0; i < ccRaw.length; i++) {
+                String ccRecip = ccRaw[i].trim();
+                if (ccRecip.length() > 0) {
+                    cc.add(ccRaw[i].trim());
+                }
+            }
+        }
+        return cc;
+    }
+    
+    // Although dispatcher and eventBus parameters are not necessary, they are needed for testability
+    protected void dispatchMessage(DispatchAsync dispatcher, final EventBus eventBus, Action<GenericResult> command) {
+        display.setLoading(true);
+        dispatcher.execute(command, new HupaCallback<GenericResult>(dispatcher, eventBus) {
+            public void callback(GenericResult result) {
+                if (result.isSuccess()) {
+                    eventBus.fireEvent(new SentMessageEvent());
+                    reset();
+                } else {
+                    eventBus.fireEvent(new FlashEvent(result.getMessage(), 6000));
+                }
+                display.setLoading(false);
+            }
+        });
+    }
 
     /**
      * Reset everything
@@ -347,53 +285,58 @@
      *            the type
      */
     public void revealDisplay(User user, IMAPFolder folder, Message oldmessage, MessageDetails oldDetails, String mailto, Type type) {
-
         this.reset();
         this.oldmessage = oldmessage;
         this.oldDetails = oldDetails;
         this.folder = folder;
         this.type = type;
-        
+
+        // Get user's contacts, so the user will be able to use suggestion boxes
         dispatcher.execute(new Contacts(),  new HupaCallback<ContactsResult>(dispatcher, eventBus) {
             public void callback(ContactsResult result) {
                 display.fillContactList(result.getContacts());
             }
         }); 
         
+        // Depending on the type, we have to automatically fill the view inputs
         display.getFromText().setText(user.getName());
-
-        if (type.equals(Type.FORWARD)) {
-            if (!oldmessage.getSubject().toLowerCase().startsWith("fwd:"))
+        display.getMessageHTML().setHTML(wrapMessage(oldmessage, oldDetails, type));
+        if (type.equals(Type.NEW) && mailto != null) {
+                display.getToText().setText(mailto);
+        } else if (type.equals(Type.FORWARD)) {
+            if (oldmessage.getSubject() != null && !oldmessage.getSubject().toLowerCase().startsWith("fwd:")) {
                 display.getSubjectText().setText("Fwd: " + oldmessage.getSubject());
+            }
         } else if (type.equals(Type.REPLY) || type.equals(Type.REPLY_ALL)) {
-            if (!oldmessage.getSubject().toLowerCase().startsWith("re:")) {
+            if (oldmessage.getSubject() != null && !oldmessage.getSubject().toLowerCase().startsWith("re:")) {
                 display.getSubjectText().setText("Re: " + oldmessage.getSubject());
             }
-            if (oldmessage.getReplyto() != null) {
-                display.getToText().setText(oldmessage.getReplyto());
-            } else if (type.equals(Type.REPLY)) {
-                display.getToText().setText(oldmessage.getFrom());
+            if (type.equals(Type.REPLY)) { 
+                if (oldmessage.getReplyto() != null && !oldmessage.getFrom().contains(oldmessage.getReplyto())) {
+                    display.getToText().setText(oldmessage.getReplyto());
+                } else {
+                    display.getToText().setText(oldmessage.getFrom());
+                }
             } else {
-                oldmessage.getCc().remove(user.getName());
-                display.getCcText().setText(Util.listToString(oldmessage.getCc()));
-                oldmessage.getTo().remove(user.getName());
-                display.getToText().setText(Util.listToString(oldmessage.getTo()));
+                ArrayList<String> list = new ArrayList<String>();
+                if (oldmessage.getReplyto() != null && !oldmessage.getFrom().contains(oldmessage.getReplyto())) 
+                    list.add(oldmessage.getReplyto());
+                if (oldmessage.getTo() != null)
+                    list.addAll(oldmessage.getTo());
+                if (oldmessage.getCc() != null)
+                    list.addAll(oldmessage.getCc());
+                list = removeEmailFromList(list, user.getName());
+                display.getCcText().setText(Util.listToString(list));
+                if (oldmessage.getTo() != null) {
+                    oldmessage.getTo().remove(user.getName());
+                }
+                display.getToText().setText(oldmessage.getFrom());
             }
         } 
-
-        display.getMessageHTML().setHTML(wrapMessage(oldmessage, oldDetails, type));
-
-        if (mailto != null)
-            display.getToText().setText(mailto);
-        
         display.refresh();
-        
         firePresenterChangedEvent();
-        
         revealDisplay();
-        
         display.getEditorFocus().setFocus(true);
-        
     }
 
     public void revealDisplay(User user, IMAPFolder folder, Message oldmessage, MessageDetails oldDetails, Type type) {
@@ -419,21 +362,21 @@
     
     private static String generateHeader(Message message, Type type) {
         String ret = "<br>";
-        if (message == null)
-            return ret;
-        if (type.equals(Type.FORWARD)) {
-            ret += "--------- Forwarded message --------- <br>";
-            ret += "From: " + message.getFrom().replaceAll("<", "&lt;").replaceAll(">", "&gt;") + "<br>";
-            ret += "Date: " + message.getReceivedDate() + "<br>";
-            ret += "Subject: " + message.getSubject() + "<br>";
-            ArrayList<String> to = new ArrayList<String>();
-            to.addAll(message.getTo());
-            to.addAll(message.getCc());
-            ret += "To: " + Util.listToString(to).replaceAll("<", "&lt;").replaceAll(">", "&gt;") + "<br>";
-        } else if (type.equals(Type.REPLY) || type.equals(Type.REPLY_ALL)) {
-            ret += "On " + message.getReceivedDate();
-            ret += ", " + message.getFrom().replaceAll("<", "&lt;").replaceAll(">", "&gt;");
-            ret += ". wrote:<br>";
+        if (message != null) {
+            if (type.equals(Type.FORWARD)) {
+                ret += "--------- Forwarded message --------- <br>";
+                ret += "From: " + message.getFrom().replaceAll("<", "&lt;").replaceAll(">", "&gt;") + "<br>";
+                ret += "Date: " + message.getReceivedDate() + "<br>";
+                ret += "Subject: " + message.getSubject() + "<br>";
+                ArrayList<String> to = new ArrayList<String>();
+                to.addAll(message.getTo());
+                to.addAll(message.getCc());
+                ret += "To: " + Util.listToString(to).replaceAll("<", "&lt;").replaceAll(">", "&gt;") + "<br>";
+            } else if (type.equals(Type.REPLY) || type.equals(Type.REPLY_ALL)) {
+                ret += "On " + message.getReceivedDate();
+                ret += ", " + message.getFrom().replaceAll("<", "&lt;").replaceAll(">", "&gt;");
+                ret += ". wrote:<br>";
+            }
         }
         return ret + "<br>";
     }
@@ -450,5 +393,25 @@
         }
         return ret;
     }
+    
+    protected boolean validate() {
+        // Don't trust only in view validation
+        return  display.validate() 
+                && display.getToText().getText().trim().length() > 0  
+                && EmailListValidator.isValidAddressList(display.getToText().getText()) 
+                && EmailListValidator.isValidAddressList(display.getCcText().getText()) 
+                && EmailListValidator.isValidAddressList(display.getBccText().getText());
+    }
+    
+    protected ArrayList<String> removeEmailFromList(List<String> list, String email) {
+        ArrayList<String> ret = new ArrayList<String>();
+        String regex = ".*<?\\s*" + email.trim() + "\\s*>?\\s*"; 
+        for(String e: list) {
+            if (! e.matches(regex)) {
+                ret.add(e);
+            }
+        }
+        return ret;
+    }
 
 }

Modified: james/hupa/trunk/client/src/main/java/org/apache/hupa/client/mvp/MessageSendView.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/client/src/main/java/org/apache/hupa/client/mvp/MessageSendView.java?rev=911001&r1=911000&r2=911001&view=diff
==============================================================================
--- james/hupa/trunk/client/src/main/java/org/apache/hupa/client/mvp/MessageSendView.java (original)
+++ james/hupa/trunk/client/src/main/java/org/apache/hupa/client/mvp/MessageSendView.java Wed Feb 17 14:49:48 2010
@@ -31,6 +31,9 @@
 import com.google.gwt.user.client.ui.Widget;
 import com.google.inject.Inject;
 
+import eu.maydu.gwt.validation.client.DefaultValidationProcessor;
+import eu.maydu.gwt.validation.client.ValidationProcessor;
+import eu.maydu.gwt.validation.client.i18n.ValidationMessages;
 import gwtupload.client.BaseUploadStatus;
 import gwtupload.client.IUploadStatus;
 import gwtupload.client.IUploader;
@@ -38,6 +41,11 @@
 
 import org.apache.hupa.client.HupaCSS;
 import org.apache.hupa.client.HupaConstants;
+import org.apache.hupa.client.HupaMessages;
+import org.apache.hupa.client.validation.AddStyleAction;
+import org.apache.hupa.client.validation.EmailListValidator;
+import org.apache.hupa.client.validation.NotEmptyValidator;
+import org.apache.hupa.client.validation.SetFocusAction;
 import org.apache.hupa.client.widgets.CommandsBar;
 import org.apache.hupa.client.widgets.EnableButton;
 import org.apache.hupa.client.widgets.MessageHeaders;
@@ -76,9 +84,11 @@
     private EnableButton sendButton;
     private EnableHyperlink backButton;
     private Loading loading;
+    
+    private ValidationProcessor validator;
 
     @Inject
-    public MessageSendView(HupaConstants constants) {
+    public MessageSendView(HupaConstants constants, HupaMessages messages) {
         
         sendButton = new EnableButton(constants.sendButton());
         backButton = new EnableHyperlink(constants.backButton(),"");
@@ -97,6 +107,7 @@
         
         buttonsBar.add(sendButton);
         buttonsBar.add(loading);
+        buttonsBar.add(new Label("ASDFASF"));
         buttonsBar.add(backButton);
         
         sendContainer.add(headers);
@@ -107,6 +118,21 @@
         loading.hide();
 
         initWidget(sendContainer);
+        
+        SetFocusAction fAction = new SetFocusAction();
+        AddStyleAction sAction = new AddStyleAction(HupaCSS.C_validate, 3000);
+        validator = new DefaultValidationProcessor(new ValidationMessages(messages));
+        validator.addValidators("cc", 
+                new EmailListValidator(getCcText()).addActionForFailure(sAction).addActionForFailure(fAction));
+        validator.addValidators("bcc", 
+                new EmailListValidator(getBccText()).addActionForFailure(sAction).addActionForFailure(fAction));
+        validator.addValidators("to", 
+                new EmailListValidator(getToText()).addActionForFailure(sAction).addActionForFailure(fAction),
+                new NotEmptyValidator(getToText()).addActionForFailure(sAction).addActionForFailure(fAction));
+
+        try {
+        } catch (Exception e) {
+        }
     }
 
     /*
@@ -243,4 +269,8 @@
         to.fillOracle(contacts);
     }
 
+    public boolean validate() {
+        return validator.validate();
+    }
+
 }

Modified: james/hupa/trunk/client/src/main/java/org/apache/hupa/client/validation/EmailListValidator.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/client/src/main/java/org/apache/hupa/client/validation/EmailListValidator.java?rev=911001&r1=911000&r2=911001&view=diff
==============================================================================
--- james/hupa/trunk/client/src/main/java/org/apache/hupa/client/validation/EmailListValidator.java (original)
+++ james/hupa/trunk/client/src/main/java/org/apache/hupa/client/validation/EmailListValidator.java Wed Feb 17 14:49:48 2010
@@ -61,9 +61,7 @@
      * @return isValid
      */
     public static boolean isValidAddressList(String text) {
-        if (text.length() > 0) {
-            if (text.replaceAll("[,:\\s]+", "").isEmpty())
-                return false;
+        if (text != null && text.length() > 0) {
             String[] addresses = text.split("[,;\r\n]+");
             for (int i = 0; i < addresses.length; i++) {
                 if (!addresses[i].trim().isEmpty() && isValidAddress(addresses[i].trim()) == false) {
@@ -80,7 +78,7 @@
      * @param email
      * @return isValid
      */
-    public static boolean isValidAddress(String email) {
+    private static boolean isValidAddress(String email) {
         return email.matches(emailRegex);
     }
 }

Modified: james/hupa/trunk/client/src/test/java/org/apache/hupa/client/HupaGwtTestCase.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/client/src/test/java/org/apache/hupa/client/HupaGwtTestCase.java?rev=911001&r1=911000&r2=911001&view=diff
==============================================================================
--- james/hupa/trunk/client/src/test/java/org/apache/hupa/client/HupaGwtTestCase.java (original)
+++ james/hupa/trunk/client/src/test/java/org/apache/hupa/client/HupaGwtTestCase.java Wed Feb 17 14:49:48 2010
@@ -40,7 +40,7 @@
      *   is compiled to javascript when not returning null
      */
     public String getModuleName() {
-        //return "org.apache.hupa.Hupa";
+        // return "org.apache.hupa.Hupa";
         return null;
     }
 }

Modified: james/hupa/trunk/client/src/test/java/org/apache/hupa/client/HupaMvpTestCase.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/client/src/test/java/org/apache/hupa/client/HupaMvpTestCase.java?rev=911001&r1=911000&r2=911001&view=diff
==============================================================================
--- james/hupa/trunk/client/src/test/java/org/apache/hupa/client/HupaMvpTestCase.java (original)
+++ james/hupa/trunk/client/src/test/java/org/apache/hupa/client/HupaMvpTestCase.java Wed Feb 17 14:49:48 2010
@@ -18,8 +18,10 @@
  ****************************************************************/
 package org.apache.hupa.client;
 
+import com.google.gwt.junit.GWTMockUtilities;
 import com.google.inject.Guice;
 import com.google.inject.Injector;
+import com.google.inject.Module;
 
 import com.sun.mail.imap.IMAPStore;
 
@@ -29,6 +31,7 @@
 import org.apache.hupa.server.IMAPStoreCache;
 import org.apache.hupa.server.guice.GuiceServerTestModule;
 import org.apache.hupa.server.preferences.UserPreferencesStorage;
+import org.apache.hupa.server.utils.SessionUtils;
 import org.apache.hupa.shared.SConsts;
 import org.apache.hupa.shared.data.User;
 
@@ -36,33 +39,41 @@
 import javax.servlet.http.HttpSession;
 
 /**
- * Base class for testing presenters in hupa
+ * Base class for testing presenters in hupa.
+ * Tests extending this class only work in jvm.
  * 
  * @author manolo
  *
  */
 public abstract class HupaMvpTestCase extends TestCase {
+    
+    protected Injector injector = Guice.createInjector(getModules());
 
-    // Create an injector containing both, the server and the client modules.
-    protected Injector injector = Guice.createInjector(new GuiceServerTestModule(), new GuiceMvpTestModule());
-
-    protected HttpSession httpSession = injector.getInstance(HttpSession.class);
-    protected Session session = injector.getInstance(Session.class);
-
-    protected UserPreferencesStorage userPreferences = injector.getInstance(UserPreferencesStorage.class);
-    protected IMAPStoreCache storeCache = injector.getInstance(IMAPStoreCache.class);
-
+    protected HttpSession httpSession;
+    protected Session session;
+    protected UserPreferencesStorage userPreferences;
+    protected IMAPStoreCache storeCache;
     protected User testUser;
     protected IMAPStore store;
+    
+    protected Module[] getModules() {
+        return new Module[]{new GuiceServerTestModule(), new GuiceMvpTestModule()};
+    }
 
     @Override
     protected void setUp() throws Exception {
         try {
+            GWTMockUtilities.disarm();
+            httpSession = injector.getInstance(HttpSession.class);
+            session = injector.getInstance(Session.class);
+            userPreferences = injector.getInstance(UserPreferencesStorage.class);
+            storeCache = injector.getInstance(IMAPStoreCache.class);
+            
+            SessionUtils.cleanSessionAttributes(httpSession);
             testUser = injector.getInstance(User.class);
             store = storeCache.get(testUser);
             httpSession.setAttribute(SConsts.USER_SESS_ATTR, testUser);
         } catch (Exception e) {
         }
     }
-
 }

Modified: james/hupa/trunk/client/src/test/java/org/apache/hupa/client/guice/GuiceMvpTestModule.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/client/src/test/java/org/apache/hupa/client/guice/GuiceMvpTestModule.java?rev=911001&r1=911000&r2=911001&view=diff
==============================================================================
--- james/hupa/trunk/client/src/test/java/org/apache/hupa/client/guice/GuiceMvpTestModule.java (original)
+++ james/hupa/trunk/client/src/test/java/org/apache/hupa/client/guice/GuiceMvpTestModule.java Wed Feb 17 14:49:48 2010
@@ -25,39 +25,54 @@
 
 import net.customware.gwt.dispatch.client.DispatchAsync;
 import net.customware.gwt.dispatch.client.service.DispatchService;
+import net.customware.gwt.dispatch.server.DefaultDispatch;
 import net.customware.gwt.dispatch.server.Dispatch;
 import net.customware.gwt.dispatch.shared.Action;
 import net.customware.gwt.dispatch.shared.ActionException;
 import net.customware.gwt.dispatch.shared.Result;
+import net.customware.gwt.presenter.client.DefaultEventBus;
 import net.customware.gwt.presenter.client.Display;
 import net.customware.gwt.presenter.client.EventBus;
 
-import static org.easymock.EasyMock.createStrictMock;
-
+import org.apache.hupa.client.HupaMessages;
+import org.apache.hupa.client.mock.MockMessageSendDisplay;
 import org.apache.hupa.client.mvp.ContactsPresenter;
+import org.apache.hupa.client.mvp.MessageSendPresenter;
 import org.easymock.EasyMock;
 
 /**
- * Guice module used to test the presenter
+ * Guice module used to test presenters
  * 
  * @author manolo
  *
  */
 public class GuiceMvpTestModule extends AbstractModule {
     
+    // Override either, to change module behavior
+    protected DispatchAsync dispatchAsyncInstance = null;
+    protected Class<? extends DispatchAsync> dispatchAsyncClass = DispatchTestAsync.class;
+    
     @Override
     protected void configure() {
 
-        bind(DispatchService.class).to(DispatchTestService.class).in(Singleton.class);
-        bind(DispatchAsync.class).to(DispatchTestAsync.class).in(Singleton.class);
+        if (dispatchAsyncInstance == null) {
+            bind(DispatchAsync.class).to(dispatchAsyncClass).in(Singleton.class);
+        } else {
+            bind(DispatchAsync.class).toInstance(dispatchAsyncInstance);
+        }
 
-        final EventBus eventBus = createStrictMock(EventBus.class);
-        bind(EventBus.class).toInstance(eventBus);
+        bind(EventBus.class).to(DefaultEventBus.class);
+        
+        bind(DispatchTestAsync.class);
+        
+        HupaMessages messages = EasyMock.createNiceMock(HupaMessages.class);
+        bind(HupaMessages.class).toInstance(messages);
 
         bindDisplay(ContactsPresenter.Display.class);
+        bind(MessageSendPresenter.Display.class).to(MockMessageSendDisplay.class);
     }
 
-    public <D extends Display> void bindDisplay(final Class<D> display) {
+    protected <D extends Display> void bindDisplay(final Class<D> display) {
         final D mockDisplay = EasyMock.createNiceMock(display);
         bind(display).toInstance(mockDisplay);
     }
@@ -76,12 +91,12 @@
         }
     }
 
-    static class DispatchTestAsync implements DispatchAsync {
-        private Dispatch dispatch;
+    static public class DispatchTestAsync implements DispatchAsync {
+        private DefaultDispatch dispatch;
 
         @Inject
         public DispatchTestAsync(Dispatch dispatch) {
-            this.dispatch = dispatch;
+            this.dispatch = (DefaultDispatch)dispatch;
         }
 
         public <A extends Action<R>, R extends Result> void execute(A action, AsyncCallback<R> callback) {
@@ -93,4 +108,5 @@
             }
         }
     }
+
 }
\ No newline at end of file

Added: james/hupa/trunk/client/src/test/java/org/apache/hupa/client/mock/MockMessageSendDisplay.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/client/src/test/java/org/apache/hupa/client/mock/MockMessageSendDisplay.java?rev=911001&view=auto
==============================================================================
--- james/hupa/trunk/client/src/test/java/org/apache/hupa/client/mock/MockMessageSendDisplay.java (added)
+++ james/hupa/trunk/client/src/test/java/org/apache/hupa/client/mock/MockMessageSendDisplay.java Wed Feb 17 14:49:48 2010
@@ -0,0 +1,115 @@
+package org.apache.hupa.client.mock;
+
+import com.google.gwt.event.dom.client.HasClickHandlers;
+import com.google.gwt.user.client.ui.Focusable;
+import com.google.gwt.user.client.ui.HasHTML;
+import com.google.gwt.user.client.ui.HasText;
+import com.google.gwt.user.client.ui.Widget;
+
+import gwtupload.client.IUploader;
+
+import org.apache.hupa.client.mvp.MessageSendPresenter.Display;
+import org.apache.hupa.shared.rpc.ContactsResult.Contact;
+import org.apache.hupa.widgets.ui.HasEnable;
+
+public class MockMessageSendDisplay implements Display {
+
+    HasClickHandlers backClick = new MockWidget();
+    HasText bccText = new MockWidget();
+    HasText ccText = new MockWidget();
+    HasText fromText = new MockWidget();
+    HasHTML messageHtml = new MockWidget();
+
+    HasClickHandlers sendClick = new MockWidget();
+    HasText subjectText = new MockWidget();
+    HasText toText = new MockWidget();
+    Focusable editorFocus = new MockWidget();
+
+    IUploader uploader = new MockUploader();
+
+    public Widget asWidget() {
+        return null;
+    }
+
+    public void fillContactList(Contact[] contacts) {
+    }
+
+    public HasClickHandlers getBackButtonClick() {
+        return backClick;
+    }
+
+    public HasText getBccText() {
+        return bccText;
+    }
+
+    public HasText getCcText() {
+        return ccText;
+    }
+
+    public Focusable getEditorFocus() {
+        return editorFocus;
+    }
+
+    public HasText getFromText() {
+        return fromText;
+    }
+
+    public HasHTML getMessageHTML() {
+        return messageHtml;
+    }
+
+    public HasClickHandlers getSendClick() {
+        return sendClick;
+    }
+
+    public HasEnable getSendEnable() {
+        return null;
+    }
+
+    public HasText getSubjectText() {
+        return subjectText;
+    }
+
+    public HasText getToText() {
+        return toText;
+    }
+
+    public IUploader getUploader() {
+        return uploader;
+    }
+
+    public void refresh() {
+    }
+
+    public void setBccText(HasText bccText) {
+        this.bccText = bccText;
+    }
+
+    public void setCcText(HasText ccText) {
+        this.ccText = ccText;
+    }
+
+    public void setFromText(HasText fromText) {
+        this.fromText = fromText;
+    }
+
+    public void setLoading(boolean loading) {
+    }
+
+    public void setMessageHTML(HasHTML messageHtml) {
+        this.messageHtml = messageHtml;
+    }
+
+    public void setSubjectText(HasText subjectText) {
+        this.subjectText = subjectText;
+    }
+
+    public void setToText(HasText toText) {
+        this.toText = toText;
+    }
+
+    public boolean validate() {
+        return true;
+    }
+
+}

Added: james/hupa/trunk/client/src/test/java/org/apache/hupa/client/mock/MockUploader.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/client/src/test/java/org/apache/hupa/client/mock/MockUploader.java?rev=911001&view=auto
==============================================================================
--- james/hupa/trunk/client/src/test/java/org/apache/hupa/client/mock/MockUploader.java (added)
+++ james/hupa/trunk/client/src/test/java/org/apache/hupa/client/mock/MockUploader.java Wed Feb 17 14:49:48 2010
@@ -0,0 +1,139 @@
+package org.apache.hupa.client.mock;
+
+import com.google.gwt.core.client.JavaScriptObject;
+import com.google.gwt.event.shared.HandlerRegistration;
+import com.google.gwt.user.client.ui.Widget;
+
+import gwtupload.client.IUploadStatus;
+import gwtupload.client.IUploader;
+import gwtupload.client.IUploadStatus.Status;
+
+import java.util.Iterator;
+
+public class MockUploader implements IUploader {
+
+    public HandlerRegistration addOnCancelUploadHandler(OnCancelUploaderHandler handler) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public HandlerRegistration addOnChangeUploadHandler(OnChangeUploaderHandler handler) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public HandlerRegistration addOnFinishUploadHandler(OnFinishUploaderHandler handler) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public HandlerRegistration addOnStartUploadHandler(OnStartUploaderHandler handler) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public HandlerRegistration addOnStatusChangedHandler(OnStatusChangedHandler handler) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public void avoidRepeatFiles(boolean avoidRepeatFiles) {
+        // TODO Auto-generated method stub
+        
+    }
+
+    public void cancel() {
+        // TODO Auto-generated method stub
+        
+    }
+
+    public String fileUrl() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public String getBasename() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public String getFileName() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public String getInputName() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public String getServerResponse() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public Status getStatus() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public void reset() {
+        // TODO Auto-generated method stub
+        
+    }
+
+    public void setFileInputPrefix(String prefix) {
+        // TODO Auto-generated method stub
+        
+    }
+
+    public void setI18Constants(UploaderConstants strs) {
+        // TODO Auto-generated method stub
+        
+    }
+
+    public void setServletPath(String path) {
+        // TODO Auto-generated method stub
+        
+    }
+
+    public void setStatusWidget(IUploadStatus status) {
+        // TODO Auto-generated method stub
+        
+    }
+
+    public void setValidExtensions(String[] ext) {
+        // TODO Auto-generated method stub
+        
+    }
+
+    public void submit() {
+        // TODO Auto-generated method stub
+        
+    }
+
+    public JavaScriptObject getData() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public void add(Widget w) {
+        // TODO Auto-generated method stub
+        
+    }
+
+    public void clear() {
+        // TODO Auto-generated method stub
+        
+    }
+
+    public Iterator<Widget> iterator() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public boolean remove(Widget w) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+}

Added: james/hupa/trunk/client/src/test/java/org/apache/hupa/client/mock/MockWidget.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/client/src/test/java/org/apache/hupa/client/mock/MockWidget.java?rev=911001&view=auto
==============================================================================
--- james/hupa/trunk/client/src/test/java/org/apache/hupa/client/mock/MockWidget.java (added)
+++ james/hupa/trunk/client/src/test/java/org/apache/hupa/client/mock/MockWidget.java Wed Feb 17 14:49:48 2010
@@ -0,0 +1,61 @@
+package org.apache.hupa.client.mock;
+
+import com.google.gwt.event.dom.client.ClickHandler;
+import com.google.gwt.event.dom.client.HasClickHandlers;
+import com.google.gwt.event.shared.GwtEvent;
+import com.google.gwt.event.shared.HandlerRegistration;
+import com.google.gwt.user.client.ui.Focusable;
+import com.google.gwt.user.client.ui.HasHTML;
+import com.google.gwt.user.client.ui.HasText;
+
+import java.util.ArrayList;
+
+public class MockWidget implements HasClickHandlers, HasText, HasHTML, Focusable {
+
+    ArrayList<ClickHandler> handlers = new ArrayList<ClickHandler>();
+    String text="", html="";
+
+    public HandlerRegistration addClickHandler(final ClickHandler handler) {
+        handlers.add(handler);
+        return new HandlerRegistration() {
+            public void removeHandler() {
+                handlers.remove(handler);
+            }
+        };
+    }
+
+    public void fireEvent(GwtEvent<?> event) {
+        for(ClickHandler h: handlers) {
+            h.onClick(null);
+        }
+    }
+
+    public String getText() {
+        return text;
+    }
+
+    public void setText(String text) {
+        this.text = text;
+    }
+
+    public String getHTML() {
+        return html;
+    }
+
+    public void setHTML(String html) {
+        this.html = html;   
+    }
+
+    public int getTabIndex() {
+        return 0;
+    }
+
+    public void setAccessKey(char key) {
+    }
+
+    public void setFocus(boolean focused) {
+    }
+
+    public void setTabIndex(int index) {
+    }
+}

Added: james/hupa/trunk/client/src/test/java/org/apache/hupa/client/mvp/MessageSendPresenterTest.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/client/src/test/java/org/apache/hupa/client/mvp/MessageSendPresenterTest.java?rev=911001&view=auto
==============================================================================
--- james/hupa/trunk/client/src/test/java/org/apache/hupa/client/mvp/MessageSendPresenterTest.java (added)
+++ james/hupa/trunk/client/src/test/java/org/apache/hupa/client/mvp/MessageSendPresenterTest.java Wed Feb 17 14:49:48 2010
@@ -0,0 +1,241 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you 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 org.apache.hupa.client.mvp;
+
+import com.google.inject.Module;
+
+import net.customware.gwt.dispatch.client.DispatchAsync;
+import net.customware.gwt.dispatch.shared.Action;
+import net.customware.gwt.presenter.client.EventBus;
+
+import org.apache.hupa.client.HupaCallback;
+import org.apache.hupa.client.HupaMvpTestCase;
+import org.apache.hupa.client.guice.GuiceMvpTestModule;
+import org.apache.hupa.client.guice.GuiceMvpTestModule.DispatchTestAsync;
+import org.apache.hupa.client.mvp.MessageSendPresenter.Type;
+import org.apache.hupa.server.guice.GuiceServerTestModule;
+import org.apache.hupa.shared.data.IMAPFolder;
+import org.apache.hupa.shared.data.Message;
+import org.apache.hupa.shared.data.MessageDetails;
+import org.apache.hupa.shared.data.SMTPMessage;
+import org.apache.hupa.shared.events.FlashEvent;
+import org.apache.hupa.shared.events.SentMessageEvent;
+import org.apache.hupa.shared.events.ServerStatusEvent;
+import org.apache.hupa.shared.rpc.ForwardMessage;
+import org.apache.hupa.shared.rpc.GenericResult;
+import org.apache.hupa.shared.rpc.ReplyMessage;
+import org.apache.hupa.shared.rpc.SendMessage;
+import org.easymock.EasyMock;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
+public class MessageSendPresenterTest extends HupaMvpTestCase {
+
+    
+    protected Module[] getModules() {
+        return new Module[]{new GuiceServerTestModule(), new GuiceMvpTestModule() {
+            @Override
+            protected void configure() {
+                dispatchAsyncInstance = EasyMock.createStrictMock(DispatchAsync.class);
+                super.configure();
+            }
+        }};
+    }
+
+    MessageSendPresenter presenter = injector.getInstance(MessageSendPresenter.class);
+    MessageSendPresenter.Display display = presenter.getDisplay();
+    
+    public void testRemoveEmailFromList() {
+        String[] list = new String[]{"a@a.a", "e@dom.com", "<e...@dom.com>", "Name <e...@dom.com>", "Name < e@dom.com >"};
+        ArrayList<String> newList = presenter.removeEmailFromList(Arrays.asList(list), " e@dom.com ");
+        assertEquals(1, newList.size());
+    }
+
+    public void testValidations() throws Exception {
+        assertFalse(presenter.validate());
+
+        display.getToText().setText("invalid@address");
+        assertFalse(presenter.validate());
+
+        display.getToText().setText("nobody@domain.com");
+        assertTrue(presenter.validate());
+    }
+
+    public void testDispatchMessage() {
+        SMTPMessage message = new SMTPMessage();
+        message.setFrom("from@dom.com");
+        message.setTo(presenter.emailTextToArray("to@dom.com"));
+        message.setText("message");
+
+        DispatchAsync dispatcher = injector.getInstance(DispatchTestAsync.class);
+        EventBus eventBus = EasyMock.createMock(EventBus.class);
+        
+        // When a success message is sent, the eventbus receives a SentMessageEvent
+        // and the display is reset
+        EasyMock.reset(eventBus);
+        eventBus.fireEvent(EasyMock.isA(ServerStatusEvent.class));
+        eventBus.fireEvent(EasyMock.isA(SentMessageEvent.class));
+        EasyMock.replay(eventBus);
+        display.getToText().setText("whatever");
+        presenter.dispatchMessage(dispatcher, eventBus, new SendMessage(message));
+        assertEquals("", display.getToText().getText());
+        EasyMock.verify(eventBus);
+
+        // When a error happens sending a message, the eventbus receives a FlashEvent
+        // and the display is not reset
+        EasyMock.reset(eventBus);
+        eventBus.fireEvent(EasyMock.isA(ServerStatusEvent.class));
+        eventBus.fireEvent(EasyMock.isA(FlashEvent.class));
+        EasyMock.replay(eventBus);
+        display.getToText().setText("whatever");
+        presenter.dispatchMessage(dispatcher, eventBus, new SendMessage(null));
+        assertEquals("whatever", display.getToText().getText());
+        EasyMock.verify(eventBus);
+    }
+
+    public void testSendInvalidMessage() throws Exception {
+        presenter.onBind();
+        presenter.revealDisplay(testUser);
+        assertEquals(testUser.getName(), display.getFromText().getText());
+        
+        display.getSubjectText().setText("Test");
+        display.getMessageHTML().setHTML("Message");
+        
+        fireSendEvent(null);
+        
+        assertNull(presenter.message);
+        assertEquals("Test", display.getSubjectText().getText());
+        assertEquals("Message", display.getMessageHTML().getHTML());
+    }
+
+    public void testSendMessage() throws Exception {
+        presenter.onBind();
+        presenter.revealDisplay(testUser);
+        assertEquals(testUser.getName(), display.getFromText().getText());
+        
+        display.getToText().setText("to1@dom.com; to2@dom.com");
+        display.getCcText().setText("cc1@dom.com, , cc2@dom.com ");
+        display.getBccText().setText("bcc1@dom.com, bcc2@dom.com");
+        display.getSubjectText().setText("Test");
+        display.getMessageHTML().setHTML("Message");
+        
+        fireSendEvent(SendMessage.class);
+        
+        assertEquals("Test", presenter.message.getSubject());
+        assertEquals("Message", presenter.message.getText());
+        assertEquals(testUser.getName(), presenter.message.getFrom());
+        assertEquals(2, presenter.message.getTo().size());
+        assertEquals("to1@dom.com", presenter.message.getTo().get(0));
+        assertEquals(2, presenter.message.getCc().size());
+        assertEquals(2, presenter.message.getBcc().size());
+    }
+    
+
+    public void testMailTo() throws Exception {
+        presenter.onBind();
+        presenter.revealDisplay(testUser, "mailto@dom.com");
+        assertEquals(testUser.getName(), display.getFromText().getText());
+        assertEquals("mailto@dom.com", display.getToText().getText());
+    }
+    
+    public void testReply() {
+        createMockMessageAndRevealDisplay(Type.REPLY);
+        fireSendEvent(ReplyMessage.class);
+        
+        assertEquals("Re: Subject", presenter.message.getSubject());
+        assertTrue(presenter.message.getText().contains("Message"));
+        assertTrue(presenter.message.getText().contains("from@dom.com"));
+        
+        assertEquals(testUser.getName(), presenter.message.getFrom());
+        assertEquals(1, presenter.message.getTo().size());
+        assertEquals("replyto@dom.com", presenter.message.getTo().get(0));
+        assertEquals(0, presenter.message.getCc().size());
+        assertEquals(0, presenter.message.getBcc().size());
+    }
+
+    public void testReplyAll() {
+        createMockMessageAndRevealDisplay(Type.REPLY_ALL);
+        fireSendEvent(ReplyMessage.class);
+        
+        assertEquals("Re: Subject", presenter.message.getSubject());
+        assertTrue(presenter.message.getText().contains("Message"));
+        assertTrue(presenter.message.getText().contains("from@dom.com"));
+        
+        assertEquals(testUser.getName(), presenter.message.getFrom());
+        assertEquals(1, presenter.message.getTo().size());
+        assertEquals("from@dom.com", presenter.message.getTo().get(0));
+        assertEquals(5, presenter.message.getCc().size());
+        assertEquals("replyto@dom.com", presenter.message.getCc().get(0));
+        assertEquals("to1@dom.com", presenter.message.getCc().get(1));
+        assertEquals("to2@dom.com", presenter.message.getCc().get(2));
+        assertEquals("cc1@dom.com", presenter.message.getCc().get(3));
+        assertEquals("cc2@dom.com", presenter.message.getCc().get(4));
+        assertEquals(0, presenter.message.getBcc().size());
+    }
+
+    public void testForward() {
+        createMockMessageAndRevealDisplay(Type.FORWARD);
+        presenter.getDisplay().getToText().setText("valid@dom.com");
+        fireSendEvent(ForwardMessage.class);
+        
+        assertEquals("Fwd: Subject", presenter.message.getSubject());
+        assertTrue(presenter.message.getText().contains("Message"));
+        assertTrue(presenter.message.getText().contains("from@dom.com"));
+        assertTrue(presenter.message.getText().contains("Forwarded message"));
+        assertTrue(presenter.message.getText().contains("Subject"));
+        assertEquals(testUser.getName(), presenter.message.getFrom());
+        assertEquals(1, presenter.message.getTo().size());
+        assertEquals("valid@dom.com", presenter.message.getTo().get(0));
+        assertEquals(0, presenter.message.getCc().size());
+        assertEquals(0, presenter.message.getBcc().size());
+    }
+    
+    private void createMockMessageAndRevealDisplay(Type type) {
+        Message oldmessage = new Message();
+        oldmessage.setFrom("from@dom.com");
+        ArrayList<String> to = new ArrayList<String>(Arrays.asList(new String[]{"to1@dom.com", "to2@dom.com"}));
+        oldmessage.setTo(to);
+        ArrayList<String> cc = new ArrayList<String>(Arrays.asList(new String[]{"cc1@dom.com", "cc2@dom.com"}));
+        oldmessage.setCc(cc);
+        oldmessage.setReplyto("replyto@dom.com");
+        oldmessage.setSubject("Subject");
+        
+        MessageDetails oldDetails = new MessageDetails();
+        oldDetails.setText("Message");
+        oldDetails.setUid(0l);
+        
+        IMAPFolder folder = new IMAPFolder();
+        folder.setFullName("FOLDER");
+        
+        presenter.bind();
+        presenter.revealDisplay(testUser, folder, oldmessage, oldDetails, type);
+    }
+
+    @SuppressWarnings("unchecked")
+    private void fireSendEvent(Class<? extends Action<GenericResult>> commandClass) {
+        DispatchAsync dispatcher = injector.getInstance(DispatchAsync.class);
+        EasyMock.reset(dispatcher);
+        if (commandClass != null)
+            dispatcher.execute(EasyMock.isA(commandClass), EasyMock.isA(HupaCallback.class));
+        EasyMock.replay(dispatcher);
+        display.getSendClick().fireEvent(null);
+        EasyMock.verify(dispatcher);
+    }
+}

Modified: james/hupa/trunk/client/src/test/java/org/apache/hupa/client/validation/EmailListValidatorTest.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/client/src/test/java/org/apache/hupa/client/validation/EmailListValidatorTest.java?rev=911001&r1=911000&r2=911001&view=diff
==============================================================================
--- james/hupa/trunk/client/src/test/java/org/apache/hupa/client/validation/EmailListValidatorTest.java (original)
+++ james/hupa/trunk/client/src/test/java/org/apache/hupa/client/validation/EmailListValidatorTest.java Wed Feb 17 14:49:48 2010
@@ -27,7 +27,7 @@
         assertTrue(EmailListValidator.isValidAddressList(" abc@abc.def"));
         assertTrue(EmailListValidator.isValidAddressList("<ab...@abc.def>"));
         assertTrue(EmailListValidator.isValidAddressList(" AAA <ab...@abc.def> "));
-        assertFalse(EmailListValidator.isValidAddressList(", , ,"));
+        assertTrue(EmailListValidator.isValidAddressList(", , ,"));
         assertFalse(EmailListValidator.isValidAddressList("abc@abc.def ; ; MMM <mc...@aa>;;;"));
         assertTrue(EmailListValidator.isValidAddressList("abc@abc.def ; ; MMM <mc...@aa.co>;;;"));
         assertTrue(EmailListValidator.isValidAddressList("abc@abc.def\nMMM <mc...@aa.co>;;;"));

Modified: james/hupa/trunk/server/src/main/java/org/apache/hupa/server/guice/DemoModeConstants.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/server/src/main/java/org/apache/hupa/server/guice/DemoModeConstants.java?rev=911001&r1=911000&r2=911001&view=diff
==============================================================================
--- james/hupa/trunk/server/src/main/java/org/apache/hupa/server/guice/DemoModeConstants.java (original)
+++ james/hupa/trunk/server/src/main/java/org/apache/hupa/server/guice/DemoModeConstants.java Wed Feb 17 14:49:48 2010
@@ -60,7 +60,7 @@
             
             put("PostFetchMessageCount", "0");
             
-            put("DefaultUserSessionId", "just_an_id");
+            put("DefaultUserSessionId", "DEMO_ID");
         }
     };
 

Modified: james/hupa/trunk/server/src/main/java/org/apache/hupa/server/guice/GuiceServerTestModule.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/server/src/main/java/org/apache/hupa/server/guice/GuiceServerTestModule.java?rev=911001&r1=911000&r2=911001&view=diff
==============================================================================
--- james/hupa/trunk/server/src/main/java/org/apache/hupa/server/guice/GuiceServerTestModule.java (original)
+++ james/hupa/trunk/server/src/main/java/org/apache/hupa/server/guice/GuiceServerTestModule.java Wed Feb 17 14:49:48 2010
@@ -47,6 +47,7 @@
 import org.apache.hupa.server.handler.ReplyMessageHandler;
 import org.apache.hupa.server.handler.SendMessageHandler;
 import org.apache.hupa.server.mock.MockHttpSession;
+import org.apache.hupa.server.mock.MockHttpSessionProvider;
 import org.apache.hupa.server.mock.MockIMAPStore;
 import org.apache.hupa.server.mock.MockLogProvider;
 import org.apache.hupa.server.preferences.InSessionUserPreferencesStorage;
@@ -84,7 +85,7 @@
         Names.bindProperties(binder(), properties);
         
         bind(Session.class).toProvider(sessionClass);
-        bind(HttpSession.class).to(httpSessionClass).in(Singleton.class);
+        bind(HttpSession.class).toProvider(MockHttpSessionProvider.class);
         bind(Settings.class).toProvider(settingsProviderClass).in(Singleton.class);
         bind(Log.class).toProvider(logClass).in(Singleton.class);
 
@@ -105,7 +106,9 @@
         bind(SendMessageHandler.class);
         bind(ReplyMessageHandler.class);
         bind(ForwardMessageHandler.class);
+        
         bindHandler(ContactsHandler.class);
+        bindHandler(SendMessageHandler.class);
         
         bind(UserPreferencesStorage.class).to(userPreferencesClass);
         
@@ -210,4 +213,5 @@
             put("DefaultUserSessionId", "just_an_id");
         }
     };
+
 }

Modified: james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/AbstractSendMessageHandler.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/AbstractSendMessageHandler.java?rev=911001&r1=911000&r2=911001&view=diff
==============================================================================
--- james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/AbstractSendMessageHandler.java (original)
+++ james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/AbstractSendMessageHandler.java Wed Feb 17 14:49:48 2010
@@ -208,12 +208,14 @@
         List<MessageAttachment> attachments = action.getMessage().getMessageAttachments();
         
         ArrayList<FileItem> items = new ArrayList<FileItem>();
-        for (MessageAttachment attachment: attachments) {
-            FileItem fItem = registry.get(attachment.getName());
-            if (fItem != null)
-                items.add(fItem);
+        if (attachments != null && attachments.size() > 0) {
+            for (MessageAttachment attachment: attachments) {
+                FileItem fItem = registry.get(attachment.getName());
+                if (fItem != null)
+                    items.add(fItem);
+            }
+            logger.debug("Found " + items.size() + " attachmets in the registry.");
         }
-        logger.debug("Found " + items.size() + " attachmets in the registry.");
         return items;
     }
     

Modified: james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/AbstractSessionHandler.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/AbstractSessionHandler.java?rev=911001&r1=911000&r2=911001&view=diff
==============================================================================
--- james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/AbstractSessionHandler.java (original)
+++ james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/AbstractSessionHandler.java Wed Feb 17 14:49:48 2010
@@ -30,6 +30,7 @@
 
 import org.apache.commons.logging.Log;
 import org.apache.hupa.server.IMAPStoreCache;
+import org.apache.hupa.shared.SConsts;
 import org.apache.hupa.shared.data.User;
 import org.apache.hupa.shared.exception.InvalidSessionException;
 
@@ -82,7 +83,7 @@
      * @throws ActionException
      */
     protected User getUser() throws ActionException{
-        User user = (User) sessionProvider.get().getAttribute("user");
+        User user = (User) sessionProvider.get().getAttribute(SConsts.USER_SESS_ATTR);
         if (user == null) {
             throw new InvalidSessionException("User not found in session with id " + sessionProvider.get().getId());
         } else {

Modified: james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/LoginUserHandler.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/LoginUserHandler.java?rev=911001&r1=911000&r2=911001&view=diff
==============================================================================
--- james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/LoginUserHandler.java (original)
+++ james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/LoginUserHandler.java Wed Feb 17 14:49:48 2010
@@ -28,14 +28,13 @@
 
 import org.apache.commons.logging.Log;
 import org.apache.hupa.server.IMAPStoreCache;
+import org.apache.hupa.server.utils.SessionUtils;
 import org.apache.hupa.shared.SConsts;
 import org.apache.hupa.shared.data.Settings;
 import org.apache.hupa.shared.data.User;
 import org.apache.hupa.shared.rpc.LoginUser;
 import org.apache.hupa.shared.rpc.LoginUserResult;
 
-import java.util.ArrayList;
-import java.util.Enumeration;
 
 import javax.servlet.http.HttpSession;
 
@@ -65,7 +64,7 @@
      */
     public LoginUserResult execute(LoginUser action, ExecutionContext context) throws ActionException {
         HttpSession session = sessionProvider.get();
-        cleanSessionAttributes(session);
+        SessionUtils.cleanSessionAttributes(session);
         
         String username = action.getUserName();
         String password = action.getPassword();
@@ -110,20 +109,4 @@
     public Class<LoginUser> getActionType() {
         return LoginUser.class;
     }
-    
-    /**
-     * Remove session attributes, it has to be done in the login and logout actions
-     * @param session
-     */
-    public static void cleanSessionAttributes(HttpSession session) {
-        @SuppressWarnings("unchecked")
-        Enumeration en = session.getAttributeNames();
-        ArrayList<String> toRemove = new ArrayList<String>();
-        while (en.hasMoreElements()) {
-            toRemove.add(en.nextElement().toString());
-        }
-        for (String attr: toRemove) {
-            session.removeAttribute(attr);
-        }
-    }
 }

Modified: james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/LogoutUserHandler.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/LogoutUserHandler.java?rev=911001&r1=911000&r2=911001&view=diff
==============================================================================
--- james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/LogoutUserHandler.java (original)
+++ james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/LogoutUserHandler.java Wed Feb 17 14:49:48 2010
@@ -27,6 +27,7 @@
 
 import org.apache.commons.logging.Log;
 import org.apache.hupa.server.IMAPStoreCache;
+import org.apache.hupa.server.utils.SessionUtils;
 import org.apache.hupa.shared.data.User;
 import org.apache.hupa.shared.rpc.LogoutUser;
 import org.apache.hupa.shared.rpc.LogoutUserResult;
@@ -60,7 +61,7 @@
         cache.delete(user);
         
         // remove user attributes from session
-        LoginUserHandler.cleanSessionAttributes(sessionProvider.get());
+        SessionUtils.cleanSessionAttributes(sessionProvider.get());
         
         return new LogoutUserResult(user);
     }

Modified: james/hupa/trunk/server/src/main/java/org/apache/hupa/server/mock/MockHttpSession.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/server/src/main/java/org/apache/hupa/server/mock/MockHttpSession.java?rev=911001&r1=911000&r2=911001&view=diff
==============================================================================
--- james/hupa/trunk/server/src/main/java/org/apache/hupa/server/mock/MockHttpSession.java (original)
+++ james/hupa/trunk/server/src/main/java/org/apache/hupa/server/mock/MockHttpSession.java Wed Feb 17 14:49:48 2010
@@ -16,7 +16,6 @@
  * specific language governing permissions and limitations      *
  * under the License.                                           *
  ****************************************************************/
-
 package org.apache.hupa.server.mock;
 
 import java.util.ArrayList;
@@ -39,11 +38,12 @@
     private Map<String,Object> valueMap = new HashMap<String, Object>();
     private long cTime;
     private String id;
+    private static int seq = 0;
     
     @Inject
     public MockHttpSession(@Named("DefaultUserSessionId") String id) {
         cTime = System.currentTimeMillis();
-        this.id = id;
+        this.id = id + "-" + seq++;
     }
     
     public Object getAttribute(String name) {

Added: james/hupa/trunk/server/src/main/java/org/apache/hupa/server/mock/MockHttpSessionProvider.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/server/src/main/java/org/apache/hupa/server/mock/MockHttpSessionProvider.java?rev=911001&view=auto
==============================================================================
--- james/hupa/trunk/server/src/main/java/org/apache/hupa/server/mock/MockHttpSessionProvider.java (added)
+++ james/hupa/trunk/server/src/main/java/org/apache/hupa/server/mock/MockHttpSessionProvider.java Wed Feb 17 14:49:48 2010
@@ -0,0 +1,39 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you 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 org.apache.hupa.server.mock;
+
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+import com.google.inject.name.Named;
+
+import javax.servlet.http.HttpSession;
+
+
+public class MockHttpSessionProvider implements Provider<HttpSession> {
+    static HttpSession session = null;
+    @Inject
+    public MockHttpSessionProvider(@Named("DefaultUserSessionId") String id) {
+        if (session == null) {
+            session = new MockHttpSession(id);
+        }
+    }
+    public HttpSession get() {
+        return session;
+    }
+}

Modified: james/hupa/trunk/server/src/main/java/org/apache/hupa/server/utils/SessionUtils.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/server/src/main/java/org/apache/hupa/server/utils/SessionUtils.java?rev=911001&r1=911000&r2=911001&view=diff
==============================================================================
--- james/hupa/trunk/server/src/main/java/org/apache/hupa/server/utils/SessionUtils.java (original)
+++ james/hupa/trunk/server/src/main/java/org/apache/hupa/server/utils/SessionUtils.java Wed Feb 17 14:49:48 2010
@@ -23,6 +23,9 @@
 import org.apache.commons.logging.Log;
 import org.apache.hupa.server.FileItemRegistry;
 
+import java.util.ArrayList;
+import java.util.Enumeration;
+
 import javax.servlet.http.HttpSession;
 
 /**
@@ -38,5 +41,21 @@
         }
         return registry;
     }
+
+    /**
+     * Remove session attributes, it has to be done in the login and logout actions
+     * @param session
+     */
+    public static void cleanSessionAttributes(HttpSession session) {
+        @SuppressWarnings("unchecked")
+        Enumeration en = session.getAttributeNames();
+        ArrayList<String> toRemove = new ArrayList<String>();
+        while (en.hasMoreElements()) {
+            toRemove.add(en.nextElement().toString());
+        }
+        for (String attr: toRemove) {
+            session.removeAttribute(attr);
+        }
+    }
     
 }
\ No newline at end of file

Modified: james/hupa/trunk/server/src/main/resources/mime/1.msg
URL: http://svn.apache.org/viewvc/james/hupa/trunk/server/src/main/resources/mime/1.msg?rev=911001&r1=911000&r2=911001&view=diff
==============================================================================
--- james/hupa/trunk/server/src/main/resources/mime/1.msg (original)
+++ james/hupa/trunk/server/src/main/resources/mime/1.msg Wed Feb 17 14:49:48 2010
@@ -4,7 +4,7 @@
 Delivered-To: nobody@foo.com
 Subject: multipart-mixed and iso-8859 headers
 From: =?ISO-8859-1?Q?Pepe_Pe=F1a?= <no...@foo.com>
-To: nobody@foo.com
+To: nobody@foo.com, other@foo.com
 Content-Type: multipart/mixed; boundary=000e0cd22c42480ee20475f5ff57
 
 --000e0cd22c42480ee20475f5ff57

Modified: james/hupa/trunk/server/src/test/java/org/apache/hupa/server/HupaGuiceTestCase.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/server/src/test/java/org/apache/hupa/server/HupaGuiceTestCase.java?rev=911001&r1=911000&r2=911001&view=diff
==============================================================================
--- james/hupa/trunk/server/src/test/java/org/apache/hupa/server/HupaGuiceTestCase.java (original)
+++ james/hupa/trunk/server/src/test/java/org/apache/hupa/server/HupaGuiceTestCase.java Wed Feb 17 14:49:48 2010
@@ -45,6 +45,7 @@
 import org.apache.hupa.server.handler.ReplyMessageHandler;
 import org.apache.hupa.server.handler.SendMessageHandler;
 import org.apache.hupa.server.preferences.UserPreferencesStorage;
+import org.apache.hupa.server.utils.SessionUtils;
 import org.apache.hupa.shared.SConsts;
 import org.apache.hupa.shared.data.User;
 import org.apache.hupa.shared.rpc.SendMessage;
@@ -54,60 +55,62 @@
 
 public abstract class HupaGuiceTestCase extends TestCase {
 
-    protected Injector injector = Guice.createInjector(getModule());
-
-    protected HttpSession httpSession = injector.getInstance(HttpSession.class);
-    
-    protected ContactsHandler contactsHandler = injector.getInstance(ContactsHandler.class);
-
-    protected IdleHandler idleHandler = injector.getInstance(IdleHandler.class);
-
-    protected CreateFolderHandler createFolderHandler = injector.getInstance(CreateFolderHandler.class);
-    
-    protected DeleteFolderHandler deleteFolderHandler = injector.getInstance(DeleteFolderHandler.class);
-    
-    protected FetchFoldersHandler fetchFoldersHandler = injector.getInstance(FetchFoldersHandler.class);
-    
-    protected FetchMessagesHandler fetchMessagesHandler = injector.getInstance(FetchMessagesHandler.class);
-    
-    protected DeleteMessageByUidHandler deleteMessageByUidHandler = injector.getInstance(DeleteMessageByUidHandler.class);
-    
-    protected AbstractSendMessageHandler<SendMessage> sendMessageHandler = injector.getInstance(SendMessageHandler.class);
-    
-    protected ForwardMessageHandler forwardMessageHandler = injector.getInstance(ForwardMessageHandler.class);
-    
-    protected GetMessageDetailsHandler getDetailsHandler = injector.getInstance(GetMessageDetailsHandler.class);
-    
-    protected Log logger = injector.getInstance(Log.class);
-    
-    protected LoginUserHandler loginUser = injector.getInstance(LoginUserHandler.class);
-    
-    protected LogoutUserHandler logoutUser = injector.getInstance(LogoutUserHandler.class);
-    
-    protected ReplyMessageHandler reMsgHndl = injector.getInstance(ReplyMessageHandler.class);
-    
-    protected Session session = injector.getInstance(Session.class);
-    
-    protected IMAPStoreCache storeCache = injector.getInstance(IMAPStoreCache.class);
+    protected Injector injector = Guice.createInjector(getModules());
     
+    protected ContactsHandler contactsHandler;
+    protected IdleHandler idleHandler;
+    protected CreateFolderHandler createFolderHandler;
+    protected DeleteFolderHandler deleteFolderHandler;
+    protected FetchFoldersHandler fetchFoldersHandler;
+    protected FetchMessagesHandler fetchMessagesHandler;
+    protected DeleteMessageByUidHandler deleteMessageByUidHandler;
+    protected AbstractSendMessageHandler<SendMessage> sendMessageHandler;
+    protected ForwardMessageHandler forwardMessageHandler;
+    protected GetMessageDetailsHandler getDetailsHandler;
+    protected Log logger;
+    protected LoginUserHandler loginUser;
+    protected LogoutUserHandler logoutUser;
+    protected ReplyMessageHandler reMsgHndl;
+    protected Session session;
+    protected IMAPStoreCache storeCache;
     protected User testUser;
-    
-    protected UserPreferencesStorage userPreferences = injector.getInstance(UserPreferencesStorage.class);
-    
+    protected UserPreferencesStorage userPreferences;
     protected IMAPStore store;
+    protected HttpSession httpSession;
     
+    protected Module[] getModules() {
+        return new Module[]{new GuiceServerTestModule()};
+    }
     
     @Override
     protected void setUp() throws Exception {
         try {
+            contactsHandler = injector.getInstance(ContactsHandler.class);
+            idleHandler = injector.getInstance(IdleHandler.class);
+            createFolderHandler = injector.getInstance(CreateFolderHandler.class);
+            deleteFolderHandler = injector.getInstance(DeleteFolderHandler.class);
+            fetchFoldersHandler = injector.getInstance(FetchFoldersHandler.class);
+            fetchMessagesHandler = injector.getInstance(FetchMessagesHandler.class);
+            deleteMessageByUidHandler = injector.getInstance(DeleteMessageByUidHandler.class);
+            sendMessageHandler = injector.getInstance(SendMessageHandler.class);
+            forwardMessageHandler = injector.getInstance(ForwardMessageHandler.class);
+            getDetailsHandler = injector.getInstance(GetMessageDetailsHandler.class);
+            logger = injector.getInstance(Log.class);
+            loginUser = injector.getInstance(LoginUserHandler.class);
+            logoutUser = injector.getInstance(LogoutUserHandler.class);
+            reMsgHndl = injector.getInstance(ReplyMessageHandler.class);
+            session = injector.getInstance(Session.class);
+            storeCache = injector.getInstance(IMAPStoreCache.class);
+            userPreferences = injector.getInstance(UserPreferencesStorage.class);
+            
+            httpSession = injector.getInstance(HttpSession.class);
+            SessionUtils.cleanSessionAttributes(httpSession);
             testUser = injector.getInstance(User.class);
             store = storeCache.get(testUser);
             httpSession.setAttribute(SConsts.USER_SESS_ATTR, testUser);
+            
         } catch (Exception e) {
         }
     }
 
-    protected Module getModule() {
-        return new GuiceServerTestModule();
-    }
 }

Modified: james/hupa/trunk/server/src/test/java/org/apache/hupa/server/handler/HandlersTest.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/server/src/test/java/org/apache/hupa/server/handler/HandlersTest.java?rev=911001&r1=911000&r2=911001&view=diff
==============================================================================
--- james/hupa/trunk/server/src/test/java/org/apache/hupa/server/handler/HandlersTest.java (original)
+++ james/hupa/trunk/server/src/test/java/org/apache/hupa/server/handler/HandlersTest.java Wed Feb 17 14:49:48 2010
@@ -37,21 +37,24 @@
 import javax.mail.MessagingException;
 
 public class HandlersTest extends HupaGuiceTestCase {
+
+    /*
+     These tests should work with Courier, Gmail and any other real IMAP implementations
+     If you want to run these tests against your IMAP server do this:
+        1.- Change properties and classes to do integration tests and
+        2.- Be sure the user and password are set correctly
+    */
+    class MyModule extends GuiceServerTestModule {
+        public MyModule() {
+            // properties = courierProperties;
+            // properties = gmailProperties;
+            // logClass = LogProvider.class;
+        }
+    }
     
     @Override
-    protected Module getModule() {
-        // These tests should work with Courier, Gmail and any other real IMAP implementations
-        // If you want to run these tests against your IMAP server do this:
-        //    1.- Change properties and classes to do integration tests and
-        //    2.- Be sure the user and password are set correctly
-        class MyModule extends GuiceServerTestModule {
-            public MyModule() {
-                // properties = courierProperties;
-                // properties = gmailProperties;
-                // logClass = LogProvider.class;
-            }
-        }
-        return new MyModule();
+    protected Module[] getModules() {
+        return new Module[]{new MyModule()};
     }
 
     public void testLoginAndFetchFolders() {

Modified: james/hupa/trunk/server/src/test/java/org/apache/hupa/server/preferences/InImapUserPreferencesStorageTest.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/server/src/test/java/org/apache/hupa/server/preferences/InImapUserPreferencesStorageTest.java?rev=911001&r1=911000&r2=911001&view=diff
==============================================================================
--- james/hupa/trunk/server/src/test/java/org/apache/hupa/server/preferences/InImapUserPreferencesStorageTest.java (original)
+++ james/hupa/trunk/server/src/test/java/org/apache/hupa/server/preferences/InImapUserPreferencesStorageTest.java Wed Feb 17 14:49:48 2010
@@ -22,12 +22,12 @@
 
 public class InImapUserPreferencesStorageTest extends HupaGuiceTestCase {
 
-    /**
-     * These tests should work with Courier, Gmail and any other real IMAP implementation.
-     * So, if you wanted to run these tests against your IMAP server do this:
-     *   - Set the correct properties.
-     *   - Be sure the user and password are set correctly
-     *   - Comment the delay
+    /*
+       These tests should work with Courier, Gmail and any other real IMAP implementation.
+       So, if you wanted to run these tests against your IMAP server do this:
+         - Set the correct properties.
+         - Be sure the user and password are set correctly
+         - Comment the delay
      */
     static class MyModule extends GuiceServerTestModule {
         public MyModule() {
@@ -39,18 +39,17 @@
             InImapUserPreferencesStorage.IMAP_SAVE_DELAY = 400;
         }
     }
-
+    
     @Override
-    protected Module getModule() {
-        return new MyModule();
+    protected Module[] getModules() {
+        return new Module[]{new MyModule()};
     }
     
     /**
-     * Delete contacts from session and all messages in user's dratfs folder
+     * Delete all messages in user's dratfs folder
      */
     public void setUp() throws Exception {
         super.setUp();
-        httpSession.removeAttribute(InImapUserPreferencesStorage.CONTACTS_ATTR);
         Folder f = storeCache.get(testUser).getFolder(testUser.getSettings().getDraftsFolderName());
         if (f.exists() && f.getMessageCount() > 0) {
             f.open(Folder.READ_WRITE);
@@ -59,7 +58,7 @@
         }
     }
     
-    public void atestAnySerializableObjectCanBeSavedInIMAP() throws Exception {
+    public void testAnySerializableObjectCanBeSavedInIMAP() throws Exception {
         IMAPStore store = storeCache.get(testUser);
         String folderName = testUser.getSettings().getInboxFolderName() + store.getDefaultFolder().getSeparator() + "aFolder";
         String magicSubject = "magicSubject";

Modified: james/hupa/trunk/shared/src/main/java/org/apache/hupa/shared/Util.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/shared/src/main/java/org/apache/hupa/shared/Util.java?rev=911001&r1=911000&r2=911001&view=diff
==============================================================================
--- james/hupa/trunk/shared/src/main/java/org/apache/hupa/shared/Util.java (original)
+++ james/hupa/trunk/shared/src/main/java/org/apache/hupa/shared/Util.java Wed Feb 17 14:49:48 2010
@@ -48,6 +48,8 @@
     }
     
     public static String listToString(List<String> list) {
+        if (list == null)
+            return "";
         StringBuffer sb = new StringBuffer();
         for (int i = 0; i < list.size(); i++) {
             sb.append(list.get(i));

Modified: james/hupa/trunk/shared/src/main/java/org/apache/hupa/shared/data/AbstractMessage.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/shared/src/main/java/org/apache/hupa/shared/data/AbstractMessage.java?rev=911001&r1=911000&r2=911001&view=diff
==============================================================================
--- james/hupa/trunk/shared/src/main/java/org/apache/hupa/shared/data/AbstractMessage.java (original)
+++ james/hupa/trunk/shared/src/main/java/org/apache/hupa/shared/data/AbstractMessage.java Wed Feb 17 14:49:48 2010
@@ -49,7 +49,7 @@
         return "From='" + from 
              + "' To='" + toList
              + "' CC='" + ccList
-             + "' ReplyTo='" + replyto
+             + "' ReplyTo='" + (replyto == null ? "": replyto)
              + "' Subject='" + subject
              + "' Attachments=" + hasAttachment;
     }

Modified: james/hupa/trunk/shared/src/main/java/org/apache/hupa/shared/data/SMTPMessage.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/shared/src/main/java/org/apache/hupa/shared/data/SMTPMessage.java?rev=911001&r1=911000&r2=911001&view=diff
==============================================================================
--- james/hupa/trunk/shared/src/main/java/org/apache/hupa/shared/data/SMTPMessage.java (original)
+++ james/hupa/trunk/shared/src/main/java/org/apache/hupa/shared/data/SMTPMessage.java Wed Feb 17 14:49:48 2010
@@ -38,7 +38,7 @@
             attachNames += m.getName() + " ";
         
         return super.toString()
-             + "Bcc='" + bccList
+             + " Bcc='" + bccList
              + "'\nAttachments=" + attachNames
              + "'\nMessage:\n" + text;
     }



---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org