[ 
http://www.stripesframework.org/jira/browse/STS-803?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13074#comment-13074
 ] 

Remi VANKEISBELCK commented on STS-803:
---------------------------------------

I have created a test case based on your code snippets  :
https://github.com/vankeisb/stripes-sts-803 

This indeed verifies that this bug is fixed in 1.5.8-SNAPSHOT. 

Thanks a lot Dave :)

> MockRoundtrip:: trip.getActionBean() returns NULL 1st run but OK 2nd+
> ---------------------------------------------------------------------
>
>                 Key: STS-803
>                 URL: http://www.stripesframework.org/jira/browse/STS-803
>             Project: Stripes
>          Issue Type: Bug
>    Affects Versions: Release 1.5.5
>            Reporter: Nikolaos
>            Assignee: Ben Gunter
>             Fix For: Release 1.5.8, Release 1.6
>
>
> While the issue outlined below is "Minor" there are 2 reasons why I am 
> flagging this as "Major":
> (1) as it affects testing it does impede normal testing in that an expected 
> non-null return of trip.getActionBean() and subsequent assertion failure test 
> can not be made... so test code needs to be padded to expect and treat an 
> error case as a normal case... problematic but yes not the end of the world
> (2) but the bigger reason is b/c Stripes UrlBinding mechanism determines one 
> set of bindings when the Stripes initializes... and then as Stripes runs 
> modifies those bindings... which is cause for concern / alarm as this may 
> have adverse side effects on non-test / production code... i.e. I would 
> expect Stripes to initialize the bindings properly from the get go and 
> service all requests uniformly (also I am not so sure these changes occur at 
> a specified point in time i.e. I don't think they necessarily occur after the 
> 1st hit of a given UrlBinding and I also wonder how all other bindings are 
> affected... in any event it may be harmless but at this point appears a 
> little unsettling ;-)
> What follows is the e-mail sent to the list verbatim:
> ======================================
> This issue is very bizarre and VERY interesting indeed.
> I run 2 "identical" TestNG tests in a unit test - back to back - and the 1st 
> fails and the 2nd succeeds:
>     @DataProvider(name = "userIssueRequests")
>     public Object[][] userIssueRequests() {
>         return new Object[][] {
>                 { ShareActionBean.class, "en_US", "/share/3gi/_/edit", 
> "/share/3gi/_/view" },
>                 { ShareActionBean.class, "en_US", "/share/3gi/_/edit", 
> "/share/3gi/_/view" },
>         };
>     }
> ShareActionBean has the following URL binding:
> @UrlBinding("/share/{uuidRadix}/{titleUrlified}/{$event}")
> And the following default handler:
>     @DefaultHandler
>     @DontValidate
>     public final Resolution view() {
>         return (super.view(VIEW));
>     }
> The test involves the following (relevant) code:
>         MockRoundtrip trip = new MockRoundtrip(context, actionBeanUrl, new 
> MockHttpSession(context));
>         trip.execute();
>         ShareActionBean bean = trip.getActionBean(ShareActionBean.class);
> In BOTH cases the ShareActionBean is created and the "edit" handler (as per 
> URL) is invoked.  All is well... so far...
> However, In the 1st run  bean  is NULL and in the 2nd run  bean  returns the 
> action bean that handled the request... HUH????
> So, I did some debugging... if we drill down into trip.getActionBean(...) we 
> find the following method:
>     public <A extends ActionBean> A getActionBean(Class<A> type) {
>         A bean = (A) this.request.getAttribute(getUrlBinding(type, 
> this.context));
>         if (bean == null) {
>             bean = (A) 
> this.request.getSession().getAttribute(getUrlBinding(type, this.context));
>         }
>         return bean;
>     }
> Here is where it gets REALLY interesting - if we simply focus on the 1st line 
> of the method call:
>         A bean = (A) this.request.getAttribute(getUrlBinding(type, 
> this.context));
> We find that   getUrlBinding(type, this.context)  returns the following as 
> the key to the outer method call:
> /share/{uuidRadix}/{titleUrlified}/{$event=view}
> And in the 1st run   this.request.getAttribute(...)   has a map that contains:
> __stripes_resolved_action=/share/{uuidRadix}/{titleUrlified}/{$event},
> /share/{uuidRadix}/{titleUrlified}/{$event}=org.lightagents.ui.web.action.content.ShareActionBean@10fd9d27,
>  actionBean=org.lightagents.ui.web.action.content.ShareActionBean@10fd9d27, 
> __current_flash_scope=-1806527276, 
> _stripes_defaultMessages=[org.lightagents.ui.stripes.extended.LocalizableMessageWarning@779dc644]}
>  
> whereas in the 2nd run   this.request.getAttribute(...)   has a map that 
> contains:
> __stripes_resolved_action=/share/{uuidRadix}/{titleUrlified}/{$event=view},
> /share/{uuidRadix}/{titleUrlified}/{$event=view}=org.lightagents.ui.web.action.content.ShareActionBean@44dd7637,
>  actionBean=org.lightagents.ui.web.action.content.ShareActionBean@44dd7637, 
> __current_flash_scope=-624278302, 
> _stripes_defaultMessages=[org.lightagents.ui.stripes.extended.LocalizableMessageWarning@779dc644]}
> How can Stripes produce 2 different URL bindings for the same ActionBean in 
> the same run????
> This behaviour is not only odd but worrisome if there is a bug at work here 
> that may affect non-Test code.
> Now what is more interesting is that the ShareActionBean is setup with the 
> Application logic such that if user is trying to change a Share that they do 
> not have access to that they are redirected to the default handler with a 
> message i.e.:
> /share/3gi/_/view?__fsk=-1806527276
> So we have the following things happening:
> (A) Stripes UrlBinding's are determined when Stripes fires up and receives an 
> initial request.  At this point the ShareActionBean is referenced to have 
> cached UrlBinding of:
> /share/{uuidRadix}/{titleUrlified}/{$event}
> (B) Run #1 - we test the request to  "/share/3gi/_/edit" and the 
> ShareActionBean "edit" event handler redirects to "/share" with params  "3gi" 
>  and  "_" and as such no explicitly specified "event" handler so the default 
> one should be determined by Stripes.
> But that causes UrlBindingParameter.getDefaultValue() to execute to determine 
> that the "event" value for this action bean is the @DefaultHandler method 
> "view"
> At this point though this changes the UrlBinding component for 
> ShareActionBean to have "event" with  defaultValue = "view" and moreover the 
> ShareActionBean cached UrlBinding from this point forward is:
> /share/{uuidRadix}/{titleUrlified}/{$event=view}
> (C) However when the trip.getActionBean(...) method fires a lookup for the 
> request attribute the key it got initially is used:
> /share/{uuidRadix}/{titleUrlified}/{$event}
> And of course this fails and no ActionBean is returned b/c this no longer 
> maps to any cached UrlBinding.
> (D) When Run #2 comes along and does the same thing the same thing occurs as 
> in Run #1 except from the start this time though the cached UrlBinding is:
> /share/{uuidRadix}/{titleUrlified}/{$event=view}
> And nothing changes and all is well in that the  trip.getActionBean(...)  
> method return the ShareActionBean instance
> So it appears that as long as an explicit  "event"  parameter is supplied the 
> getDefaultValue() method will not get called on the  "event"  
> UrlBindingParameter  and until then the binding of the ActionBean will not 
> have the default value embedded in it for  "event"  but once a default event 
> URL is produced that bindings will appear differently.
> Shouldn't Stripes ensure from the get-go try to trigger the  
> getDefaultValue()  for   "event" to have it incorporated in the UrlBinding 
> cached????
> What a ride!!!!
> --Nikolaos
> UrlBindingParameter.java:
>     public String getDefaultValue() {
>         // for $event parameters with no explicit default value, get default 
> from action resolver
>         if (this.defaultValue == null && PARAMETER_NAME_EVENT.equals(name)) {
>             try {
>                 Method defaultHandler = 
> StripesFilter.getConfiguration().getActionResolver()
>                         .getDefaultHandler(beanClass);
>                 HandlesEvent annotation = 
> defaultHandler.getAnnotation(HandlesEvent.class);
>                 if (annotation != null)
>                     this.defaultValue = annotation.value();
>                 else
>                     this.defaultValue = defaultHandler.getName();
>             }
>             catch (Exception e) {
>                 /* Ignore any exceptions and just return null. */
>             }
>         }
>         return defaultValue;
>     }

-- 
This message is automatically generated by JIRA.
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

------------------------------------------------------------------------------
"Accelerate Dev Cycles with Automated Cross-Browser Testing - For FREE
Instantly run your Selenium tests across 300+ browser/OS combos.
Get unparalleled scalability from the best Selenium testing platform available
Simple to use. Nothing to install. Get started now for free."
http://p.sf.net/sfu/SauceLabs
_______________________________________________
Stripes-development mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/stripes-development

Reply via email to