1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    * 
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   * 
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.jetspeed.decoration;
18  
19  import java.util.ArrayList;
20  import java.util.HashMap;
21  import java.util.Iterator;
22  import java.util.Locale;
23  import java.util.Properties;
24  
25  import javax.servlet.ServletContext;
26  import javax.servlet.http.HttpServletRequest;
27  import javax.servlet.http.HttpSession;
28  
29  import org.apache.jetspeed.PortalReservedParameters;
30  import org.apache.jetspeed.om.page.Fragment;
31  import org.apache.jetspeed.om.page.Page;
32  import org.apache.jetspeed.request.RequestContext;
33  import org.apache.jetspeed.util.Path;
34  import org.jmock.Mock;
35  import org.jmock.MockObjectTestCase;
36  import org.jmock.core.Constraint;
37  import org.jmock.core.InvocationMatcher;
38  
39  public class TestDecorations extends MockObjectTestCase
40  {
41      private Path testPathHtmlEn;
42      private Path testPath;
43      private Mock prcMock;
44      private Mock rvMock;
45      private PathResolverCache prc;
46      private ResourceValidator rv;
47      private Properties config;
48      private Page page;
49      private RequestContext requestContext;
50      private Mock pageMock;
51      private Mock factoryMock;
52      private Mock fragmentMock;
53      private Mock requestContextMock;
54      private Fragment fragment;
55      private Mock childFragmentMock;
56      private Fragment childFragment;
57      private Mock layoutMock;
58      private LayoutDecoration layout;
59      private Mock portletDecorMock;
60      private PortletDecoration portletDecor;
61      private DecorationFactory factory;
62  
63      protected void themeInitExpectations()
64      {
65          pageMock = new Mock(Page.class);
66          page = (Page) pageMock.proxy();
67          factoryMock = new Mock(DecorationFactory.class);
68          factory = (DecorationFactory) factoryMock.proxy();
69          requestContextMock = new Mock(RequestContext.class);
70          requestContext = (RequestContext) requestContextMock.proxy();
71          fragmentMock = new Mock(Fragment.class);
72          fragment = (Fragment) fragmentMock.proxy();
73          childFragmentMock = new Mock(Fragment.class);
74          childFragment = (Fragment) childFragmentMock.proxy();
75          layoutMock = new Mock(LayoutDecoration.class);
76          layout = (LayoutDecoration) layoutMock.proxy();
77          portletDecorMock = new Mock(PortletDecoration.class);
78          portletDecor = (PortletDecoration) portletDecorMock.proxy();
79          
80          // Define expected behavior
81  
82                                 
83          ArrayList list = new ArrayList(1);
84          list.add(childFragment);
85          
86          expectAndReturn(fragmentMock, "getType", "layout");
87          
88          expectAndReturn(fragmentMock, "getFragments", list);
89            
90          expectAndReturn(atLeastOnce(), fragmentMock, "getId", "001");
91        
92          expectAndReturn(atLeastOnce(), childFragmentMock, "getId", "002");   
93  
94          expectAndReturn(childFragmentMock, "getFragments", null);
95          expectAndReturn(childFragmentMock, "getType", "portlet");
96      }
97  
98      protected void setUp1() throws Exception
99      {
100         super.setUp();
101         
102         prcMock = new Mock(PathResolverCache.class);
103         prcMock.expects(atLeastOnce()).method("getPath").withAnyArguments().will(returnValue(null));
104         prcMock.expects(atLeastOnce()).method("addPath").withAnyArguments().isVoid();
105         
106         rvMock = new Mock(ResourceValidator.class);
107         
108         prc = (PathResolverCache)prcMock.proxy();
109         rv = (ResourceValidator)rvMock.proxy();
110         
111         config = new Properties();
112         config.setProperty("name", "test");
113         
114         testPath = new Path("/decorations/test");
115         testPathHtmlEn = new Path("/decorations/test/html/en");
116     }
117 
118     public void testSimpleLocation() throws Exception
119     {
120         setUp1();
121       
122         String expectedResult = testPathHtmlEn.getChild("/images/myimage.gif").toString();
123         rvMock.expects(once()).method("resourceExists").with(eq(expectedResult)).will(returnValue(true));
124 
125         BaseDecoration decoration = new BaseDecoration(config, rv, testPath, testPathHtmlEn, prc );
126         
127         String result = decoration.getResource("/images/myimage.gif");
128 
129         assertNotNull(result);
130         assertEquals(expectedResult, result);
131         
132         verify();
133     }
134     
135     public void testResolution() throws Exception
136     {
137         setUp1();
138         
139         Path testPath = testPathHtmlEn;
140         String failure1 = testPath.getChild("/images/myimage.gif").toString();
141         testPath = testPath.removeLastPathSegment();
142         String failure2 = testPath.getChild("/images/myimage.gif").toString();
143         testPath = testPath.removeLastPathSegment();
144         String success = testPath.getChild("/images/myimage.gif").toString();
145         
146         Constraint[] constraints = new Constraint[]{eq(failure1), eq(failure2), eq(success)};
147         
148         rvMock.expects(atLeastOnce()).method("resourceExists").with(new OnConsecutiveInvokes(constraints))
149               .will(onConsecutiveCalls(returnValue(false), returnValue(false), returnValue(true)));
150         
151         BaseDecoration decoration = new BaseDecoration(config, rv, testPath, testPathHtmlEn, prc);
152         
153         String result = decoration.getResource("/images/myimage.gif");
154         
155         assertNotNull(result);
156         assertEquals(success, result);
157         
158         verify();
159 
160     }
161     
162     public void testTheme()
163     {
164         themeInitExpectations();
165         
166         expectAndReturn(pageMock, "getRootFragment", fragment);
167 
168         expectAndReturn(factoryMock, 
169                         "isDesktopEnabled", 
170                         new Constraint[] {eq(requestContext)}, 
171                         Boolean.FALSE);
172         
173         expectAndReturn(factoryMock, 
174                 "getDecoration", 
175                 new Constraint[] {eq(page), eq(fragment), eq(requestContext)}, 
176                 layout);
177             
178         expectAndReturn(factoryMock, 
179                 "getDecoration", 
180                 new Constraint[] {eq(page), eq(childFragment), eq(requestContext)}, 
181                 portletDecor);
182         
183         expectAndReturn(layoutMock, "getStyleSheet", "/decorations/layout/test/html/css/styles.css");
184         expectAndReturn(layoutMock, "getStyleSheetPortal", null);
185         
186         expectAndReturn(portletDecorMock, "getStyleSheet", "/decorations/portlet/test/html/css/styles.css");
187         expectAndReturn(portletDecorMock, "getStyleSheetPortal", null);
188         portletDecorMock.expects(atLeastOnce()).method("getName").withNoArguments().will(returnValue("tigris"));
189         
190         fragmentMock.expects(once()).method("getId")
191                                     .withNoArguments()
192                                     .will(returnValue("001"));    
193 
194         childFragmentMock.expects(once()).method("getId")
195                                          .withNoArguments()
196                                          .will(returnValue("002")); 
197                                          
198         
199         Theme theme = new PageTheme(page, factory, requestContext);
200         
201         assertEquals(layout, theme.getPageLayoutDecoration());
202         
203         assertEquals(2, theme.getStyleSheets().size());
204         
205         Iterator itr = theme.getStyleSheets().iterator();
206         assertEquals("/decorations/layout/test/html/css/styles.css", itr.next());
207         assertEquals("/decorations/portlet/test/html/css/styles.css", itr.next());
208         
209         assertEquals(layout, theme.getDecoration(fragment));
210         assertEquals(portletDecor, theme.getDecoration(childFragment));
211         
212         verify();
213     }
214 
215     public void testDecortaionFactory()
216     {      
217         
218         rvMock = new Mock(ResourceValidator.class);
219         rv = (ResourceValidator)rvMock.proxy();
220         rvMock.expects(atLeastOnce()).method("resourceExists")
221                                      .withAnyArguments()
222                                      .will(returnValue(false));
223         
224         // Define expected behavior
225         Mock servletContextMock = new Mock(ServletContext.class);
226         
227         DecorationFactoryImpl testFactory = new DecorationFactoryImpl("/decorations", rv);
228         testFactory.setServletContext((ServletContext)servletContextMock.proxy());
229         
230         themeInitExpectations();
231         
232         expectAndReturn(atLeastOnce(),requestContextMock, "getAttribute", new Constraint[] {eq("desktop.enabled")}, Boolean.FALSE);
233 
234         expectAndReturn(fragmentMock, "getDecorator", "myLayoutDecorator");
235          
236         expectAndReturn(fragmentMock, "getType", Fragment.LAYOUT);
237 
238         expectAndReturn(childFragmentMock, "getType", Fragment.PORTLET);
239         
240 //        expectAndReturn(pageMock, "getRootFragment", fragment);
241         
242         expectAndReturn(atLeastOnce(), requestContextMock, "getMediaType", "html");
243         
244         expectAndReturn(atLeastOnce(), requestContextMock, "getLocale", Locale.ENGLISH);   
245         
246         StringReaderInputStream is1 = new StringReaderInputStream("id=myLayoutDecorator");
247         StringReaderInputStream is2 = new StringReaderInputStream("id=myPortletDecoration");
248         
249         expectAndReturn(atLeastOnce(), servletContextMock, "getResourceAsStream",new Constraint[] {eq("/decorations/layout/myLayoutDecorator/decorator.properties")}, is1);
250         expectAndReturn(atLeastOnce(), servletContextMock, "getResourceAsStream",new Constraint[] {eq("/decorations/portlet/myPortletDecoration/decorator.properties")}, is2);
251         expectAndReturn(atLeastOnce(), servletContextMock, "getResourceAsStream",new Constraint[] {eq("/decorations/layout/myLayoutDecorator/decoratordesktop.properties")}, is1);
252         expectAndReturn(atLeastOnce(), servletContextMock, "getResourceAsStream",new Constraint[] {eq("/decorations/portlet/myPortletDecoration/decoratordesktop.properties")}, is2);
253                 
254         Mock servletRequestMock = new Mock(HttpServletRequest.class);
255         Mock sessionMock = new Mock(HttpSession.class);
256         
257         expectAndReturn(atLeastOnce(), servletRequestMock, "getSession", sessionMock.proxy());
258         expectAndReturn(atLeastOnce(), requestContextMock, "getRequest", servletRequestMock.proxy());
259         
260         expectAndReturn(atLeastOnce(), sessionMock, "getAttribute", new Constraint[]{eq(PortalReservedParameters.RESOVLER_CACHE_ATTR)}, new HashMap());
261         //expectAndReturn(sessionMock, "getAttribute", PortalReservedParameters.RESOVLER_CACHE_ATTR);
262 
263         expectAndReturn(childFragmentMock, "getDecorator", "myPortletDecoration");
264 
265         expectAndReturn(pageMock, "getRootFragment", fragment);
266 
267         Theme theme = testFactory.getTheme(page, requestContext);
268         
269         Decoration result1 = theme.getDecoration(fragment);
270         
271         assertNotNull(result1);
272         assertEquals("myLayoutDecorator", result1.getName());
273         
274         Decoration result2 = theme.getDecoration(childFragment);
275         assertNotNull(result2);
276         assertEquals("myPortletDecoration", result2.getName());
277         
278         verify();
279         
280     }
281     
282     protected void expectAndReturn(Mock mock, String methodName, Object returnValue)
283     {
284         mock.expects(once()).method(methodName)
285                             .withNoArguments()
286                             .will(returnValue(returnValue));
287     }
288     
289     protected void expectAndReturn(Mock mock, String methodName, Constraint[] constraints, Object returnValue)
290     {
291         mock.expects(once()).method(methodName)
292                             .with(constraints)
293                             .will(returnValue(returnValue));
294     }
295     
296     protected void expectAndReturn(InvocationMatcher matcher, Mock mock, String methodName, Object returnValue)
297     {
298         mock.expects(matcher).method(methodName)
299                             .withNoArguments()
300                             .will(returnValue(returnValue));
301     }
302     
303     protected void expectAndReturn(InvocationMatcher matcher, Mock mock, String methodName, Constraint[] constraints, Object returnValue)
304     {
305         mock.expects(matcher).method(methodName)
306                             .with(constraints)
307                             .will(returnValue(returnValue));
308     }
309 }