Currently Being Moderated

JSFUnitTestingSecurePages

VERSION 8

Created on: Nov 21, 2007 10:54 PM by Matt Wringe - Last Modified:  Aug 28, 2008 12:33 PM by Stan Silvert

Testing Secure Pages

 

Most applications have at least some pages that require authenticated access.  So you will need your test to log in to the application before you start testing the secure page.  JSFUnit provides a way to easily log in when the JSFSession is started.

 

 

We do this using the Strategy pattern.  You provide an implementation of InitialRequestStrategy.  For applications that use JEE container-managed security, JSFUnit has built-in strategy objects for BASIC and FORM authentication.

 

Testing with BASIC authentication.

Here is an example using the BasicAuthenticationStrategy.

 

 


WebClientSpec wcSpec = new WebClientSpec("/mysecurepage.jsf");
wcSpec.setInitialRequestStrategy(new BasicAuthenticationStrategy("username", "password"));
JSFSession jsfSession = new JSFSession(wcSpec);
JSFClientSession client = jsfSession.getJSFClientSession();
JSFServerSession server = jsfSession.getJSFServerSession();

 

 

 

 

Testing with FORM authentication.

For form authentication, you use the FormAuthenticationStrategy.  Besides user name and password, you will usually need to provide a reference to the submit button so that JSFUnit can automatically submit the form.

 

 


<form method="POST" action="j_security_check" name="loginform" id="loginform">
  <tr>
    <td>username</td><td><input type="text" name="j_username"/></td>
  </tr>
  <tr>
    <td>password</td><td><input type="password" name="j_password"/></td>
  </tr>
     <tr><td><input type="submit" name="login_button" value="login"/></td></tr>
  </form>

 

 


WebClientSpec wcSpec = new WebClientSpec("/mysecurepage.jsf");
FormAuthenticationStrategy formAuth = new FormAuthenticationStrategy("username", "password");
formAuth.setSubmitComponent("login_button");
wcSpec.setInitialRequestStrategy(formAuth);
JSFSession jsfSession = new JSFSession(wcSpec);
JSFClientSession client = jsfSession.getJSFClientSession();
JSFServerSession server = jsfSession.getJSFServerSession();

 

 

 

 

Note that the reference to the submit button, "login_button", is the value of the "name" attribute and not the "id" attribute.  If you do not call formAuth.setSubmitComponent(), it will default to "Submit".

 

Testing non-JEE authentication

For any application that does not use container-managed BASIC or FORM authentication, you will need to write your own  implementation of InitialRequestStrategy.  The javadoc is here.  Usually, you will just subclass SimpleInitialRequestStrategy and then use the HtmlUnit API to get you past whatever security is in place.  The source code for FormAuthenticationStrategy serves as a good example:


public class FormAuthenticationStrategy extends SimpleInitialRequestStrategy
{

   private String userName;
   private String password;
   private String submitComponent = "Submit";

   public FormAuthenticationStrategy(String userName, String password)
   {
      this.userName = userName;
      this.password = password;
   }
   
   
   public void setSubmitComponent(String submitComponent)
   {
      this.submitComponent = submitComponent;
   }
   
   /**
    * Perform the initial request and provide FORM authentication 
    * credentials when challenged.
    *
    * @param wcSpec The WebClient specification.
    *
    * @return The requested page if authentication passed.  Otherwise, return
    *         the error page specified in web.xml.
    */
   public Page doInitialRequest(WebClientSpec wcSpec) throws IOException
   {
      HtmlPage page = (HtmlPage)super.doInitialRequest(wcSpec);
      setValue(page, "j_username", this.userName);
      setValue(page, "j_password", this.password);
      return clickSubmitComponent(page);
   }
   
   protected Page clickSubmitComponent(HtmlPage page) throws IOException
   {
      HtmlElement htmlElement = getElement(page, this.submitComponent);
      if (!(htmlElement instanceof ClickableElement))
      {
         throw new IllegalStateException("Component with name=" + this.submitComponent + " is not a ClickableElement.");
      }
      
      ClickableElement clickable = (ClickableElement)htmlElement;
      return clickable.click();
   }
   
   protected void setValue(HtmlPage page, String elementName, String value)
   {
      HtmlElement element = getElement(page, elementName);
      if (!(element instanceof HtmlInput))
      {
         throw new IllegalStateException("Component with name=" + elementName + " is not an HtmlInput element.");
      }
      HtmlInput inputElement = (HtmlInput)element;
      inputElement.setValueAttribute(value);
   }
   
   protected HtmlElement getElement(HtmlPage page, String elementName)
   {
      List<HtmlElement> elements = page.getHtmlElementsByName(elementName);
      if (elements.size() == 0) 
      {
         throw new IllegalStateException("Component with name=" + elementName + " was not found on the login page.");
      } 
      if (elements.size() > 1) 
      {
         throw new IllegalStateException("More than one component with name=" + elementName + " was found on the login page.");
      }
      
      return elements.get(0);
   }

 

 

 

Referenced by:

 

 

 

Average User Rating
(0 ratings)




There are no comments on this article

More Like This

  • Retrieving data ...

Incoming Links

More by Matt Wringe