2 Replies Latest reply on Nov 11, 2010 5:33 AM by testvogel

    SeamTest problems to get long running conversations and redirect

    testvogel

      Hi,


      I'm trying to write some tests for my Seam Application. The Problem ist, that i never get a conversation id. My conversation id in all test cases is always null.


      Here is my code:


                     String cid = new FacesRequest("/pages/home.seam") {
                          Tab targetTab;
                          int tabCount;
                          @Override
                          protected void updateModelValues() {
                               assert !isSessionInvalid();
                               assert getValue("#{identity.loggedIn}").equals(true);
                               assert getValue("#{TemporarySettings.currentTab.closable}").equals(false);
                               List<Tab> openTabs = (List<Tab>) getValue("#{TemporarySettings.tabs}");
                               tabCount = openTabs.size();
                               Iterator<Tab> iter = openTabs.iterator();
                               assert null != openTabs;
                               assert tabCount > 1;
                               assert openTabs.get(0).getName().equals("home.tabtitle");
                               while (iter.hasNext()) {
                                    if ((targetTab = iter.next()).getName().equals("joblist.tabtitle"))
                                         break;
                               }
                          }
      
                          @Override
                          protected void invokeApplication() {
                               ITemporarySettings temporarySettingsBean = (ITemporarySettings) Contexts.getSessionContext().get(
                                         "TemporarySettings");
                               temporarySettingsBean.setCurrentTabAndRedirect(targetTab, "/pages/joblist/joblist.xhtml");
                          }
                     }.run();
                     cid = new FacesRequest("/pages/joblist/joblist.xhtml") {
                          @Override
                          protected void renderResponse() {
                               ITemporarySettings temporarySettingsBean = (ITemporarySettings) Contexts.getSessionContext().get(
                                         "TemporarySettings");
                               Tab currentTab = (Tab) temporarySettingsBean.getCurrentTab();
                               assert currentTab.getName().equals("joblist.tabtitle");
                               assert getValue("#{TemporarySettings.currentTab.closable}").equals(false);
                               System.out.println(getConversationId());
                          }
                     }.run();
      



      The important part is the invokeApplication() method


                               ITemporarySettings temporarySettingsBean = (ITemporarySettings) Contexts.getSessionContext().get(
                                         "TemporarySettings");
                               temporarySettingsBean.setCurrentTabAndRedirect(targetTab, "/pages/joblist/joblist.xhtml");



      The setCurrentTabAndRedirect Method should start a new long running Conversation and redirect to the new view /pages/joblist/joblist.xml (It worked. I already tested it manually).
      The second FacesRequest tests if the redirect was sucdcessfull and the Conversation became created. I need a second FacesRequest because of the redirect (renderResponse() won't be called in the first FacesRequest).
      The problem is that

      System.out.println(getConversationId());

      always return null.
      The second problem is that i dont wanna call the second FacesRequest with the expected ViewId. I wanna test if the redirection was completed successfully, but if i dont call the FacesRequest with the ViewId the ViewId is null.
      I've started working with SeamTest 1 week ago, so please excuse me is there an elementary mistake in my tests.


      greets,
      testvogel


      (sorry for my bad english)

        • 1. Re: SeamTest problems to get long running conversations and redirect
          toddpi314
          Your seam container can have many conversations. This makes the SeamTest getConversationId() method a bit misleading.

          For instance, if you have a ton of event scoped components a new conversation can be recreated and destroyed per request. This is good, since the EntityManager and Session are Conversation scoped.

          Try this to help debug your situation:



          @Scope(ScopeType.EVENT)
          @Name("org.jboss.seam.core.manager")
          @Install(precedence = Install.DEPLOYMENT)
          @BypassInterceptors
          public class SuperConversationManager extends FacesManager {
              @Override
              public void initializeTemporaryConversation() {
                  super.initializeTemporaryConversation();
                  log.debug("Created Temporary Conversation " + Manager.instance().getCurrentConversationId().toString());
                  logExistingConverstations();
              }
              @Override
              public boolean restoreConversation() {
                  boolean result = super.restoreConversation();
                  if(result)
                      log.debug("Conversation " + Manager.instance().getCurrentConversationId().toString() + " being Restored.");
                  else
                      log.debug("Failed to restore conversation");
                  return result;
              }

              private void logExistingConverstations()
              {
                  StringBuilder str = new StringBuilder();
                  str.append("Active Conversations: ");
                  for(String conversationId : ConversationEntries.instance().getConversationIds())
                      str.append(conversationId + ",");
                  log.debug(str);
              }

              @Override
              public void leaveConversation() {
                  log.debug("Leaving Conversation " + Manager.instance().getCurrentConversationId().toString());
                  super.leaveConversation();
                  logExistingConverstations();
              }

              @Override
              public void beforeRedirect() {
                  log.debug("Conversation " + Manager.instance().getCurrentConversationId().toString() + " being redirected.");
                  super.beforeRedirect();
              }

              @Logger
              private static Log log;

              private void logEndEvent() {
                  log.debug("Conversation " + Manager.instance().getCurrentConversationId().toString() + " Ending.");
                  logExistingConverstations();
              }

              private void logBeginEvent() {
                  log.debug("Conversation " + Manager.instance().getCurrentConversationId().toString() + " Started.");
                  logExistingConverstations();
              }

              @Override
              public void beginConversation() {
                  super.beginConversation();
                  logBeginEvent();
              }

              @Override
              public void beginNestedConversation() {
                  super.beginNestedConversation();
                  logBeginEvent();
              }

              @Override
              public void endConversation(boolean beforeRedirect) {
                  logEndEvent();
                  super.endConversation(beforeRedirect);
              }
          }


          This is not the best way to hook into *all* of the events, but you should get some good console output when the conversation at least begins.

          The key accessor being

          Manager.instance().getCurrentConversationId().toString()

          which can be called from anywhere. Just be aware that it will return the Conversation ID of the current request, not all that are available.


          Another good thing to look for is a Manual Mode Conversation component that @Begin is being called on, without an @End. This could, in some scenarios, create 'hanging' conversations that have never really been committed.


          Hope that helps.
          • 2. Re: SeamTest problems to get long running conversations and redirect
            testvogel

            Hi.


            Thanks for your post but that is not what I'm looking for.
            During some tests I found out that in every FacesRequest a conversation will be created.
            I get the conversation id with


            Manager.instance().getRootConversationId()



            in my tests, but I don't understand why the created Conversation is a RootConversation. This conversation has no ViewId, but the created conversation should have a valid ViewId because I run the FacesRequest with a valid ViewId.
            Why is no normal conversation created so that FacesRequest return the id of the created conversation?