Uploaded image for project: 'PUBLIC - Liferay Faces'
  1. PUBLIC - Liferay Faces
  2. FACES-2616

Bridge TCK encodeActionURLWithModeRenderTest depends on a non-standard feature in Trinidad client-side state saving in order to restore MultiRequestTest.jsp in the RESTORE_VIEW phase of the JSF lifecycle

    Details

      Description

      The JSR 378 TCK was originally developed under JSR 329 for Portlet 2.0 + JSF 1.2. In order to facilitate XHR+ResourceRequest type requirements, the TCK depends on Apache Trinidad. In addition, the TCK utilized Trinidad's client-side state saving feature, as described by the following context-param in the TCK's WEB-INF/web.xml descriptor:

      <!-- Use client-side state saving.  In Trinidad, it is an
      	 optimized, token-based mechanism that is almost always a
      	 better choice than the standard JSF server-side state saving. -->
      <context-param>
      	<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
      	<param-value>client</param-value>
      </context-param>
      

      TestPage117 (encodeActionURLWithModeRenderTest) starts out with MultiRequestTest.jsp which is a simple form:

      <h:form>
      	<h:panelGrid columns="1">
      		<h:commandButton value="Run Test" action="#{test.runActionTest}"/>
      	</h:panelGrid>
      </h:form>
      

      This will render an HTML form like the following:

      <form method="post" action="...">
         ...
      </form>
      

      Thanks to TestSuiteViewHandlerImpl.java, the value of the action attribute will be a JSF actionURL with the following URL parameters appended (prior to encoding of the URL):

      javax.portlet.faces.PortletMode=edit&param1=testValue
      

      When clicking on the commandButton, this should dispatch a full page HTTP POST to a portlet ActionURL. When the GenericTestSuitePortlet.processAction(ActionRequest actionRequest,ActionResponse actionResponse) method is invoked, the following should be true:

      actionRequest.getPortletMode().equals(PortletMode.EDIT.toString()) // #1
      actionRequest.getParameter("param1").equals("testValue") // #2
      actionRequest.getParameter("_facesViewIdRender") == null // #3
      

      Because #3 is null, the bridge implementation will not know which view is to be restored in the RESTORE_VIEW phase of the JSF lifecycle, and as a result it will need to restore the MultiRequestTestResultRenderCheck.jsp view as specified in the TCK's WEB-INF/portlet.xml descriptor in order to determine the view for EDIT mode:

      <init-param>
      	<name>javax.portlet.faces.defaultViewId.edit</name>
      	<value>/tests/MultiRequestTestResultRenderCheck.jsp</value>
      </init-param>
      

      The problem is that Trinidad client-side state saving has a non-standard feature such that the viewId for MultiRequestTest.jsp is encoded in the client-side javax.faces.ViewState hidden field. This in turn causes MultiRequestTest.jsp to be restored rather than MultiRequestTestResultRenderCheck.jsp.
      The TCK incorrectly depends on this, as is evidenced by the Tests.encodeActionURLWithModeRenderTest(TestRunnerBean) method having a condition for Bridge.PortletPhase.ACTION_PHASE. Such a condition could only be true if MultiRequestTest.jsp were restored (which is the Trinidad behavior). In order to compensate for this, the TCK has a navigation-rule in the WEB-INF/faces-config.xml descriptor that causes the MultiRequestTestResultRenderCheck.jsp to be rendered in the RENDER_RESPONSE phase of the JSF lifecycle:

      <navigation-case>
      	<from-outcome>encodeActionURLWithModeRenderTest</from-outcome>
      	<to-view-id>/tests/MultiRequestTestResultRenderCheck.xhtml</to-view-id>
      </navigation-case>
      

      The following tasks must be part of fixing this problem so that the TCK executes the test correctly:
      1. Introduce a new ActionURLWithModePortlet class that extends GenericFacesTestSuitePortlet.java
      2. Have ActionURLWithModePortlet.processAction(ActionRequest,ActionResponse) call actionResponse.setRenderParameter(String,Object) in order to save the portlet mode and the value of the "param1" parameter as render parameters that can be picked up in the RENDER_PHASE of the portlet lifecycle.
      3. Modify the Tests.encodeActionURLWithModeRenderTest(TestRunnerBean) method so that it consults Bridge.PortletPhase.RENDER_PHASE instead of Bridge.PortletPhase.ACTION_PHASE
      4. Remove the navigation-rule from faces-config.xml (but only when FACES-2550 is complete – the navigation rule will still be required as long as Trinidad is part of the TCK)

        Attachments

          Activity

            People

            • Assignee:
              neil.griffin Neil Griffin
              Reporter:
              neil.griffin Neil Griffin
              Participants of an Issue:
            • Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: