10 Replies Latest reply on Jun 4, 2007 8:57 AM by anescu

    Seam 1.2.1.GA Integration Testing (identity.login)

    mhaubrich

      Hi,

      I have a question about the integration testing of the login process with the 1.2.1 seam version and I hope someone can help me here as I've been trying around for quite some time now on my own to no result...

      Ok... I have the following JSF view: (extract)

      <h:form rendered="#{not identity.loggedIn}">
       #{messages['login.form']}
       <br />
      
       <span class="errors">
       <h:messages globalOnly="true" />
       </span>
      
       <table cellspacing="2" cellpadding="2" border="0" >
       <tr>
       <td>#{messages['login.login']}:</td><td><h:inputText value="#{identity.username}" id="login" /></td>
       </tr>
       <tr>
       <td>#{messages['login.pwd']}:</td><td><h:inputSecret value="#{identity.password}" id="password" /></td>
       </tr>
       <tr>
       <td colspan="2" align="right"><h:commandButton value="#{messages['login.button']}" action="#{identity.login}" /></td>
       </tr>
       </table>
       </h:form>



      In components.xml I have defined my authentication method as follows:

      <security:identity authenticate-method="#{authenticator.authenticate}"/>
      



      My Authenticator interface and AuthenticatorAction class look like so:

      import org.jboss.annotation.ejb.Local;
      
      @Local
      public interface Authenticator {
      
       public boolean authenticate();
      
      }


      import java.io.Serializable;
      
      import org.jboss.seam.annotations.In;
      import org.jboss.seam.annotations.JndiName;
      import org.jboss.seam.annotations.Logger;
      import org.jboss.seam.annotations.Name;
      import org.jboss.seam.contexts.Context;
      import org.jboss.seam.log.Log;
      import org.jboss.seam.security.Identity;
      
      @Name("authenticator")
      public class AuthenticatorAction implements Authenticator, Serializable
      {
       private static final long serialVersionUID = 4836686434984261542L;
      
       private static final String USER_VAR = "currentUser";
      
       @In
       private Context sessionContext;
      
       @Logger
       private Log log;
      
      
       /**
       * validate the username and password
       */
       public boolean authenticate()
       {
      
       User user = ServiceLocator.instance() // find user in database
       .getLoginService()
       .authenticate(Identity.instance().getUsername(), Identity.instance().getPassword());
       if(user==null)
       {
       log.debug("invalid login!");
       return false;
       }
      
       Identity.instance().addRole("user");
      
       if(user.isAdmin()) // add admin role if the user is an admin
       Identity.instance().addRole("admin");
      
       sessionContext.set(USER_VAR, user); // save in session context
      
       log.debug("login successful: #0", user);
      
       return true;
       }
      
      
      }



      And finally my test class:
      import static org.testng.AssertJUnit.*;
      
      import org.jboss.seam.log.Log;
      import org.jboss.seam.log.Logging;
      import org.jboss.seam.mock.SeamTest;
      import org.testng.annotations.Configuration;
      import org.testng.annotations.Test;
      
      public class AuthenticatorActionTest extends SeamTest {
      
      
       @Test
       public void testAuthenticate() throws Exception
       {
      
       new FacesRequest()
       {
      
       @Override
       protected void updateModelValues() throws Exception
       {
       assertFalse("session should be valid", isSessionInvalid()); // assert that the session is NOT invalid
      
       setValue("#{identity.username}", "test"); // inject the login values
       setValue("#{identity.password}", "test");
      
       }
      
       @Override
       protected void invokeApplication()
       {
       invokeMethod("#{identity.login}");
       }
      
       @Override
       protected void renderResponse()
       {
      
       assertTrue("identity.loggedIn", getValue("#{identity.loggedIn}").equals(true)); // make sure that we are logged in
       assertEquals("view id", "/home.xhtml", getViewId() ); // assert that the home-page is being shown
       }
      
       }.run();
      
      
       }
      }



      Now when I run the Test it fails at the
      assertTrue("identity.loggedIn", getValue("#{identity.loggedIn}").equals(true));
      part !

      Am I missing something here ?!

      Thanks for you help !

      Maarten





        • 1. Re: Seam 1.2.1.GA Integration Testing (identity.login)
          mhaubrich

          Hey,

          I just noticed the following exception being thrown:

          ERROR 2007-05-08 11:59:49,578 org.jboss.seam.security.jaas.SeamLoginModule -- Error invoking login method
          java.lang.NullPointerException
           at org.jboss.seam.security.jaas.SeamLoginModule.login(SeamLoginModule.java:104)
           at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
           at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
           at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
           at java.lang.reflect.Method.invoke(Unknown Source)
           at javax.security.auth.login.LoginContext.invoke(Unknown Source)
           at javax.security.auth.login.LoginContext.access$000(Unknown Source)
           at javax.security.auth.login.LoginContext$5.run(Unknown Source)
           at java.security.AccessController.doPrivileged(Native Method)
           at javax.security.auth.login.LoginContext.invokeCreatorPriv(Unknown Source)
           at javax.security.auth.login.LoginContext.login(Unknown Source)
           at org.jboss.seam.security.Identity.authenticate(Identity.java:247)
           at org.jboss.seam.security.Identity.authenticate(Identity.java:240)
           at org.jboss.seam.security.Identity.login(Identity.java:170)
           at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
           at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
           at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
           at java.lang.reflect.Method.invoke(Unknown Source)
           at com.sun.el.parser.AstValue.invoke(AstValue.java:174)
           at com.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:286)
           at org.jboss.seam.util.UnifiedELMethodBinding.invoke(UnifiedELMethodBinding.java:36)
           at org.jboss.seam.actionparam.ActionParamBindingHelper.invokeTheExpression(ActionParamBindingHelper.java:58)
           at org.jboss.seam.actionparam.ActionParamMethodBinding.invoke(ActionParamMethodBinding.java:75)
           at org.jboss.seam.actionparam.ActionParamBindingHelper.invokeTheExpression(ActionParamBindingHelper.java:58)
           at org.jboss.seam.actionparam.ActionParamMethodBinding.invoke(ActionParamMethodBinding.java:75)
           at org.jboss.seam.mock.SeamTest$Request.invokeMethod(SeamTest.java:401)
           at com.booknolia.AuthenticatorTest$1.invokeApplication(AuthenticatorTest.java:48)
           at org.jboss.seam.mock.SeamTest$Request.run(SeamTest.java:489)
           at com.booknolia.AuthenticatorTest.testAuthenticate(AuthenticatorTest.java:66)
           at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
           at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
           at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
           at java.lang.reflect.Method.invoke(Unknown Source)
           at org.testng.internal.MethodHelper.invokeMethod(MethodHelper.java:645)
           at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:479)
           at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:715)
           at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:125)
           at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:109)
           at org.testng.TestRunner.runWorkers(TestRunner.java:673)
           at org.testng.TestRunner.privateRun(TestRunner.java:620)
           at org.testng.TestRunner.run(TestRunner.java:480)
           at org.testng.SuiteRunner.runTest(SuiteRunner.java:278)
           at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:273)
           at org.testng.SuiteRunner.privateRun(SuiteRunner.java:253)
           at org.testng.SuiteRunner.run(SuiteRunner.java:168)
           at org.testng.TestNG.createAndRunSuiteRunners(TestNG.java:987)
           at org.testng.TestNG.runSuitesLocally(TestNG.java:951)
           at org.testng.TestNG.run(TestNG.java:719)
           at org.testng.remote.RemoteTestNG.run(RemoteTestNG.java:73)
           at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:122)


          I assume that in my test environment the #{authenticator.authenticate} is not mapped correctly !

          Any ideas as to how I could fix this ??

          THanks !!
          Maarten

          • 2. Re: Seam 1.2.1.GA Integration Testing (identity.login)
            shane.bryzak

            You have a local interface for AuthenticatorAction yet it is a POJO component, not a session bean. First thing I would try doing is to remove this interface.

            • 3. Re: Seam 1.2.1.GA Integration Testing (identity.login)
              mhaubrich

              Hi Shane,

              thanks for the reply !

              I will remove the interface and post the results.

              Maarten

              • 4. Re: Seam 1.2.1.GA Integration Testing (identity.login)
                mhaubrich

                Hi Shane,

                I tried removing the Interface but I still get the same result.

                Any other ideas ??

                Thanks!
                Maarten

                • 5. Re: Seam 1.2.1.GA Integration Testing (identity.login)
                  shane.bryzak

                  No idea really, all of your code and configuration looks fine to me. If you can post it to JIRA in a deployable form (and assign to me) I'd be happy to take a look for you.

                  • 6. Re: Seam 1.2.1.GA Integration Testing (identity.login)
                    monkeyden

                    Why is your Authenticator interface annotated with @Local, yet your AuthenticatorAction doesn't have a @Stateful or @Stateless annotation?

                    • 7. Re: Seam 1.2.1.GA Integration Testing (identity.login)
                      mhaubrich

                      @Shane: Thanks, I will do that within today.

                      @Monkeyden: Thanks for you reply. Honestly I don't know. I am still learning the Jboss/EJB architecture. What exactly does @Local, @Stateful, @Stateless imply?

                      • 8. Re: Seam 1.2.1.GA Integration Testing (identity.login)
                        mhaubrich

                        I have created a JIRA issue:

                        http://jira.jboss.com/jira/browse/JBSEAM-1318


                        Regards,
                        Maarten

                        • 9. Re: Seam 1.2.1.GA Integration Testing (identity.login)
                          mhaubrich

                          Shane perhaps you can help me with another issue I am having.

                          When performing integration tests I would like to assert that after invoking a certain method the correct JSF view is rendered.

                          But FacesRequest.getViewId() keeps returning null no matter where I redirect from my actions.

                          Also I have tried FacesRequest.getRenderedViewId() to no effect.
                          (I looked into the source and found:

                          /**
                           * Get the view id to be rendered
                           *
                           * @return the JSF view id
                           */
                          protected String getRenderedViewId()
                          {
                           if ( Init.instance().isJbpmInstalled() && Pageflow.instance().isInProcess() )
                           {
                           return Pageflow.instance().getPageViewId();
                           }
                           else
                           {
                           //TODO: not working right now, 'cos no mock navigation handler!
                           return getFacesContext().getViewRoot().getViewId();
                           }
                           }


                          so that could be the reason...

                          Any thoughts on this ?

                          THanks !!
                          Maarten


                          • 10. Re: Seam 1.2.1.GA Integration Testing (identity.login)

                            I found the same problem :(. Can anybody @ JBoss give as a reply? Will it be available in the next beta release? Or GA release?