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.window;
18  
19  import java.util.ArrayList;
20  import java.util.HashMap;
21  import java.util.List;
22  
23  import junit.framework.Assert;
24  import junit.framework.Test;
25  import junit.framework.TestCase;
26  import junit.framework.TestSuite;
27  
28  import org.apache.jetspeed.PortletFactoryMock;
29  import org.apache.jetspeed.components.portletentity.PortletEntityAccessComponent;
30  import org.apache.jetspeed.container.window.PortletWindowAccessor;
31  import org.apache.jetspeed.container.window.impl.PortletWindowAccessorImpl;
32  import org.apache.jetspeed.om.common.portlet.MutablePortletEntity;
33  import org.apache.jetspeed.om.page.ContentFragment;
34  import org.apache.jetspeed.om.page.Fragment;
35  import org.apache.jetspeed.om.page.ContentFragmentImpl;
36  import org.apache.pluto.om.window.PortletWindow;
37  import org.apache.pluto.om.window.PortletWindowList;
38  import org.apache.pluto.om.window.PortletWindowListCtrl;
39  import org.jmock.Mock;
40  import org.jmock.core.Invocation;
41  import org.jmock.core.InvocationMatcher;
42  import org.jmock.core.matcher.InvokeAtLeastOnceMatcher;
43  import org.jmock.core.matcher.InvokeOnceMatcher;
44  import org.jmock.core.stub.CustomStub;
45  import org.jmock.core.stub.ReturnStub;
46  
47  /***
48   * @author <a href="mailto:weaver@apache.org">Scott T. Weaver</a>
49   * 
50  */
51  public class TestWindows extends TestCase
52  {
53      protected PortletWindowAccessor windowAccess;
54      protected Mock fragMock;
55      protected Mock entityAccessMock;
56      protected Mock entityMock;
57      protected Mock windowListMock;
58  
59      public static Test suite()
60      {
61          // All methods starting with "test" will be executed in the test suite.
62          return new TestSuite(TestWindows.class);
63      }
64  
65      /***
66       * <p>
67       * setUp
68       * </p>
69       * 
70       * @see junit.framework.TestCase#setUp()
71       * @throws java.lang.Exception
72       */
73      protected void setUp() throws Exception
74      {
75          super.setUp();
76          entityAccessMock = new Mock(PortletEntityAccessComponent.class);
77          fragMock = new Mock(Fragment.class);
78          entityMock = new Mock(MutablePortletEntity.class);
79          windowListMock = new Mock(CompositeWindowList.class);
80          windowAccess = new PortletWindowAccessorImpl((PortletEntityAccessComponent) entityAccessMock.proxy(), PortletFactoryMock.instance,true);
81      }
82  
83      public void testWindowAccess() throws Exception
84      {
85          List windows = new ArrayList();
86          ContentFragment f1 = new ContentFragmentImpl((Fragment) fragMock.proxy(), new HashMap());
87          MutablePortletEntity entity = (MutablePortletEntity) entityMock.proxy();
88          CompositeWindowList windowList = (CompositeWindowList) windowListMock.proxy();
89          entityAccessMock.expects(new InvokeAtLeastOnceMatcher()).method("getPortletEntityForFragment")
90                  .withAnyArguments().will(new ReturnStub(entity));
91          fragMock.expects(new InvokeAtLeastOnceMatcher()).method("getId").withNoArguments()
92                  .will(new ReturnStub("frag1"));
93          entityMock.expects(new InvokeAtLeastOnceMatcher()).method("getPortletWindowList").withNoArguments().will(
94                  new ReturnStub(windowList));
95  
96          windowListMock.expects(new InvokeCountMatcher(4)).method("add").withAnyArguments().will(
97                  new ListAppendStub(windows));
98          
99  
100         PortletWindow window = windowAccess.getPortletWindow(f1);
101         assertNotNull(window);
102         assertEquals("frag1", window.getId().toString());
103 
104         // Make sure the portlet entity's window list got updated
105         assertEquals(1, windows.size());
106 
107         PortletWindow windowInList = (PortletWindow) windows.get(0);
108 
109         // The window in the entities list should be the same as the one
110         // returned by getPortletWindow(f1)
111         assertEquals(windowInList, window);
112 
113         // remove the window
114         windowAccess.removeWindow(window);
115 
116         // Calling this after a remove go through th procedure of adding a newly
117         // created window
118         // back the portlet entity's list. We check this through vefirying calls
119         // to our mocks
120         windowAccess.getPortletWindow(f1);
121         
122         // Test same remove but via entity
123         windowAccess.removeWindow(window);              
124 
125         assertNotNull(windowAccess.getPortletWindow(f1));                
126         
127         windowListMock.expects(new InvokeOnceMatcher()).method("iterator").withNoArguments().will(new ReturnStub(windows.iterator()));
128 
129 /*        
130         windowAccess.removeWindows(entity);  
131         
132         windowAccess.getPortletWindow(f1);
133         // Double that second call bypasses creating a new window
134         //windowAccess.getPortletWindow(f1);
135         
136         windowListMock.verify();         
137 */
138     }
139 
140     interface CompositeWindowList extends PortletWindowList, PortletWindowListCtrl
141     {
142 
143     }
144 
145     class ListAppendStub extends CustomStub
146     {
147        
148         List list;
149 
150         /***
151          * @param arg0
152          */
153         public ListAppendStub( List list )
154         {
155             super("Appends object to a list");
156             this.list = list;
157         }
158 
159         /***
160          * <p>
161          * invoke
162          * </p>
163          * 
164          * @see org.jmock.core.Stub#invoke(org.jmock.core.Invocation)
165          * @param arg0
166          * @return @throws
167          *         java.lang.Throwable
168          */
169         public Object invoke( Invocation invocation ) throws Throwable
170         {
171             list.add(invocation.parameterValues.get(0));
172             return null;
173         }
174     }
175 
176     /***
177      * Inline copy of InvokeCountMatcher from latest jMock Development Snapshot: 20050628-175146
178      * so we don't need to depend on their SNAPSHOT release anymore but can fallback on their 1.0.1 version.
179      * (doesn't seem they are going to release a new real version soon as it has been ages since 1.0.1 came out)
180      * @author <a href="mailto:ate@douma.nu">Ate Douma</a>
181      *
182      */
183     private static class InvokeCountMatcher implements InvocationMatcher
184     {
185         private int invocationCount = 0;
186 
187         private int expectedCount;
188 
189         public InvokeCountMatcher(int expectedCount)
190         {
191             this.expectedCount = expectedCount;
192         }
193 
194         public boolean matches(Invocation invocation)
195         {
196             return getInvocationCount() < expectedCount;
197         }
198 
199         public void verify()
200         {
201             verifyHasBeenInvokedExactly(expectedCount);
202         }
203 
204         public boolean hasDescription()
205         {
206             return true;
207         }
208 
209         public StringBuffer describeTo(StringBuffer buffer)
210         {
211             return buffer.append("expected ").append(expectedCount).append(" times, invoked ").append(
212                             getInvocationCount()).append(" times");
213         }
214 
215         public int getInvocationCount()
216         {
217             return invocationCount;
218         }
219 
220         public boolean hasBeenInvoked()
221         {
222             return invocationCount > 0;
223         }
224 
225         public void invoked(Invocation invocation)
226         {
227             invocationCount++;
228         }
229 
230         public void verifyHasBeenInvoked()
231         {
232             Assert.assertTrue("expected method was not invoked", hasBeenInvoked());
233         }
234 
235         public void verifyHasBeenInvokedExactly(int expectedCount)
236         {
237             Assert.assertTrue("expected method was not invoked the expected number of times: expected " + expectedCount
238                             + " times, was invoked " + invocationCount + " times", invocationCount == expectedCount);
239         }
240 
241     }
242 }