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, "getFragments", list);
87            
88          expectAndReturn(atLeastOnce(), fragmentMock, "getId", "001");
89        
90          expectAndReturn(atLeastOnce(), childFragmentMock, "getId", "002");   
91  
92          expectAndReturn(childFragmentMock, "getFragments", null);
93          expectAndReturn(childFragmentMock, "getType", "portlet");
94      }
95  
96      protected void setUp1() throws Exception
97      {
98          super.setUp();
99          
100         prcMock = new Mock(PathResolverCache.class);
101         prcMock.expects(atLeastOnce()).method("getPath").withAnyArguments().will(returnValue(null));
102         prcMock.expects(atLeastOnce()).method("addPath").withAnyArguments().isVoid();
103         
104         rvMock = new Mock(ResourceValidator.class);
105         
106         prc = (PathResolverCache)prcMock.proxy();
107         rv = (ResourceValidator)rvMock.proxy();
108         
109         config = new Properties();
110         config.setProperty("name", "test");
111         
112         testPath = new Path("/decorations/test");
113         testPathHtmlEn = new Path("/decorations/test/html/en");
114     }
115 
116     public void testSimpleLocation() throws Exception
117     {
118         setUp1();
119       
120         String expectedResult = testPathHtmlEn.getChild("/images/myimage.gif").toString();
121         rvMock.expects(once()).method("resourceExists").with(eq(expectedResult)).will(returnValue(true));
122 
123         BaseDecoration decoration = new BaseDecoration(config, rv, testPath, testPathHtmlEn, prc );
124         
125         String result = decoration.getResource("/images/myimage.gif");
126 
127         assertNotNull(result);
128         assertEquals(expectedResult, result);
129         
130         verify();
131     }
132     
133     public void testResolution() throws Exception
134     {
135         setUp1();
136         
137         Path testPath = testPathHtmlEn;
138         String failure1 = testPath.getChild("/images/myimage.gif").toString();
139         testPath = testPath.removeLastPathSegment();
140         String failure2 = testPath.getChild("/images/myimage.gif").toString();
141         testPath = testPath.removeLastPathSegment();
142         String success = testPath.getChild("/images/myimage.gif").toString();
143         
144         Constraint[] constraints = new Constraint[]{eq(failure1), eq(failure2), eq(success)};
145         
146         rvMock.expects(atLeastOnce()).method("resourceExists").with(new OnConsecutiveInvokes(constraints))
147               .will(onConsecutiveCalls(returnValue(false), returnValue(false), returnValue(true)));
148         
149         BaseDecoration decoration = new BaseDecoration(config, rv, testPath, testPathHtmlEn, prc);
150         
151         String result = decoration.getResource("/images/myimage.gif");
152         
153         assertNotNull(result);
154         assertEquals(success, result);
155         
156         verify();
157 
158     }
159     
160     public void testTheme()
161     {
162         themeInitExpectations();
163         
164         expectAndReturn(pageMock, "getRootFragment", fragment);
165 
166         expectAndReturn(factoryMock, 
167                         "isDesktopEnabled", 
168                         new Constraint[] {eq(requestContext)}, 
169                         Boolean.FALSE);
170         
171         expectAndReturn(factoryMock, 
172                 "getDecoration", 
173                 new Constraint[] {eq(page), eq(fragment), eq(requestContext)}, 
174                 layout);
175             
176         expectAndReturn(factoryMock, 
177                 "getDecoration", 
178                 new Constraint[] {eq(page), eq(childFragment), eq(requestContext)}, 
179                 portletDecor);
180         
181         expectAndReturn(layoutMock, "getStyleSheet", "/decorations/layout/test/html/css/styles.css");
182         expectAndReturn(layoutMock, "getStyleSheetPortal", null);
183         
184         expectAndReturn(portletDecorMock, "getStyleSheet", "/decorations/portlet/test/html/css/styles.css");
185         expectAndReturn(portletDecorMock, "getStyleSheetPortal", null);
186         portletDecorMock.expects(atLeastOnce()).method("getName").withNoArguments().will(returnValue("tigris"));
187         
188         fragmentMock.expects(once()).method("getId")
189                                     .withNoArguments()
190                                     .will(returnValue("001"));    
191 
192         childFragmentMock.expects(once()).method("getId")
193                                          .withNoArguments()
194                                          .will(returnValue("002")); 
195                                          
196         
197         Theme theme = new PageTheme(page, factory, requestContext);
198         
199         assertEquals(layout, theme.getPageLayoutDecoration());
200         
201         assertEquals(2, theme.getStyleSheets().size());
202         
203         Iterator itr = theme.getStyleSheets().iterator();
204         assertEquals("/decorations/layout/test/html/css/styles.css", itr.next());
205         assertEquals("/decorations/portlet/test/html/css/styles.css", itr.next());
206         
207         assertEquals(layout, theme.getDecoration(fragment));
208         assertEquals(portletDecor, theme.getDecoration(childFragment));
209         
210         verify();
211     }
212 
213     public void testDecortaionFactory()
214     {      
215         
216         rvMock = new Mock(ResourceValidator.class);
217         rv = (ResourceValidator)rvMock.proxy();
218         rvMock.expects(atLeastOnce()).method("resourceExists")
219                                      .withAnyArguments()
220                                      .will(returnValue(false));
221         
222         // Define expected behavior
223         Mock servletContextMock = new Mock(ServletContext.class);
224         
225         DecorationFactoryImpl testFactory = new DecorationFactoryImpl("/decorations", rv);
226         testFactory.setServletContext((ServletContext)servletContextMock.proxy());
227         
228         themeInitExpectations();
229         
230         expectAndReturn(atLeastOnce(),requestContextMock, "getAttribute", new Constraint[] {eq("desktop.enabled")}, Boolean.FALSE);
231 
232         expectAndReturn(fragmentMock, "getDecorator", "myLayoutDecorator");
233          
234         expectAndReturn(fragmentMock, "getType", Fragment.LAYOUT);
235 
236         expectAndReturn(childFragmentMock, "getType", Fragment.PORTLET);
237         
238 //        expectAndReturn(pageMock, "getRootFragment", fragment);
239         
240         expectAndReturn(atLeastOnce(), requestContextMock, "getMediaType", "html");
241         
242         expectAndReturn(atLeastOnce(), requestContextMock, "getLocale", Locale.ENGLISH);   
243         
244         StringReaderInputStream is1 = new StringReaderInputStream("id=myLayoutDecorator");
245         StringReaderInputStream is2 = new StringReaderInputStream("id=myPortletDecoration");
246         
247         expectAndReturn(atLeastOnce(), servletContextMock, "getResourceAsStream",new Constraint[] {eq("/decorations/layout/myLayoutDecorator/decorator.properties")}, is1);
248         expectAndReturn(atLeastOnce(), servletContextMock, "getResourceAsStream",new Constraint[] {eq("/decorations/portlet/myPortletDecoration/decorator.properties")}, is2);
249         expectAndReturn(atLeastOnce(), servletContextMock, "getResourceAsStream",new Constraint[] {eq("/decorations/layout/myLayoutDecorator/decoratordesktop.properties")}, is1);
250         expectAndReturn(atLeastOnce(), servletContextMock, "getResourceAsStream",new Constraint[] {eq("/decorations/portlet/myPortletDecoration/decoratordesktop.properties")}, is2);
251                 
252         Mock servletRequestMock = new Mock(HttpServletRequest.class);
253         Mock sessionMock = new Mock(HttpSession.class);
254         
255         expectAndReturn(atLeastOnce(), servletRequestMock, "getSession", sessionMock.proxy());
256         expectAndReturn(atLeastOnce(), requestContextMock, "getRequest", servletRequestMock.proxy());
257         
258         expectAndReturn(atLeastOnce(), sessionMock, "getAttribute", new Constraint[]{eq(PortalReservedParameters.RESOVLER_CACHE_ATTR)}, new HashMap());
259         //expectAndReturn(sessionMock, "getAttribute", PortalReservedParameters.RESOVLER_CACHE_ATTR);
260 
261         expectAndReturn(childFragmentMock, "getDecorator", "myPortletDecoration");
262 
263         expectAndReturn(pageMock, "getRootFragment", fragment);
264 
265         Theme theme = testFactory.getTheme(page, requestContext);
266         
267         Decoration result1 = theme.getDecoration(fragment);
268         
269         assertNotNull(result1);
270         assertEquals("myLayoutDecorator", result1.getName());
271         
272         Decoration result2 = theme.getDecoration(childFragment);
273         assertNotNull(result2);
274         assertEquals("myPortletDecoration", result2.getName());
275         
276         verify();
277         
278     }
279     
280     protected void expectAndReturn(Mock mock, String methodName, Object returnValue)
281     {
282         mock.expects(once()).method(methodName)
283                             .withNoArguments()
284                             .will(returnValue(returnValue));
285     }
286     
287     protected void expectAndReturn(Mock mock, String methodName, Constraint[] constraints, Object returnValue)
288     {
289         mock.expects(once()).method(methodName)
290                             .with(constraints)
291                             .will(returnValue(returnValue));
292     }
293     
294     protected void expectAndReturn(InvocationMatcher matcher, Mock mock, String methodName, Object returnValue)
295     {
296         mock.expects(matcher).method(methodName)
297                             .withNoArguments()
298                             .will(returnValue(returnValue));
299     }
300     
301     protected void expectAndReturn(InvocationMatcher matcher, Mock mock, String methodName, Constraint[] constraints, Object returnValue)
302     {
303         mock.expects(matcher).method(methodName)
304                             .with(constraints)
305                             .will(returnValue(returnValue));
306     }
307 }