0 Replies Latest reply on May 1, 2009 5:03 PM by Stan Silvert

    Conversation scope use of HttpSession

    Stan Silvert Newbie

      I'm (once again) changing the way that JSFUnit accesses objects in conversation scope and I'd like to run it by the Seam team.

      I need to be able to say things like this from a JSFUnit test:

      Hotel hotel = (Hotel)JSFUnitServerSession.getManagedBeanValue("#{hotel}");  // where hotel is in conv scope
      assertEquals("Hilton Diagonal Mar", hotel.getName());

      The basic problem is that during a JSFUnit test, we are in-container examining objects after the JSF request is completely over.  So things are in a state that Seam doesn't expect.  To make a long story short, some Seam APIs work and others don't.  I've gotten some direction from Pete on how to solve this and I've gotten things to mostly work.  But users ran into some cases where my old approach didn't work.

      With my new approach, I'm still doing the conversation setup/teardown copied from ContextualHttpServletRequest. 

      To get the actual objects in conversation scope, I first get the conversationId by parsing session attributes.  I have to do this because at this stage, Manager.instance().getCurrentConversationId() will return the wrong Id.

      Find the conversationId by parsing the HttpSession attributes:
      // figure out the conversationId based on attributes in the session
         private static String findConversationId()
            HttpSession session = WebConversationFactory.getSessionFromThreadLocal();
            for (Enumeration names = session.getAttributeNames(); names.hasMoreElements();)
               String name = (String)names.nextElement();
               if (name.startsWith(ScopeType.CONVERSATION.getPrefix()))
                  String conversationKey = name.substring(ScopeType.CONVERSATION.getPrefix().length() + 1);
                  return conversationKey.substring(0, conversationKey.indexOf('$'));
            return null;

      So my first question is, Will this always work?.  Is it possible to have two HttpSession attributes with different conversationId's at the same time? 

      Second, I create a new Map containing all the attributes in the HttpSession and pass that to a new ServerConversationContext:

      Context conversationContext = new ServerConversationContext(sessionMap(), convId);

      Now I can query this Context from my EL resolver and it works in JSFUnit. 

      Can you guys foresee any problems with this?  Thanks in advance for your help.