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.portlets.layout;
18  
19  import java.util.Iterator;
20  
21  import org.apache.jetspeed.om.page.Fragment;
22  import org.apache.jetspeed.om.page.psml.FragmentImpl;
23  import org.jmock.Mock;
24  import org.jmock.MockObjectTestCase;
25  
26  public class TestColumnLayout extends MockObjectTestCase
27  {
28      private static final String[] widths=new String[]{"25%", "50%", "25%"};
29      
30      private ColumnLayout layout;
31  
32      private FragmentImpl f1;
33  
34      private FragmentImpl f2;
35  
36      private FragmentImpl f3;
37  
38      private FragmentImpl f4;
39  
40      private FragmentImpl f5;
41  
42      private FragmentImpl f6;
43      
44      private FragmentImpl f8;
45  
46      public void testBasics() throws Exception
47      {
48          assertEquals(f1, layout.getFirstColumn().iterator().next());
49          
50          // The last column is currently empty
51        //  assertTrue(layout.getLastColumn().isEmpty());
52  
53          assertEquals(3, layout.getNumberOfColumns());
54          Iterator column0 = layout.getColumn(0).iterator();
55          assertNotNull(column0);
56          Iterator column1 = layout.getColumn(1).iterator();
57          assertNotNull(column1);
58          assertNotNull(layout.getColumn(2));
59  
60          int idx = 0;
61          while (column0.hasNext())
62          {
63              idx++;
64              Fragment fragment = (Fragment) column0.next();
65              assertEquals("f" + idx, fragment.getId());
66          }
67  
68          assertEquals(3, idx);
69  
70          assertEquals(f4, column1.next());
71          assertEquals(f5, column1.next());
72          assertEquals(f6, column1.next());
73  
74          Fragment testFragment = layout.getFragmentAt(new LayoutCoordinate(0, 0));
75          assertNotNull(testFragment);
76          assertEquals(f1, testFragment);
77  
78          testFragment = layout.getFragmentAt(new LayoutCoordinate(0, 1));
79          assertNotNull(testFragment);
80          assertEquals(f2, testFragment);
81  
82          testFragment = layout.getFragmentAt(1, 0);
83          assertNotNull(testFragment);
84          assertEquals(f4, testFragment);
85          
86          assertEquals(3, layout.getColumns().size());
87          
88          assertEquals(2, layout.getLastRowNumber(0));
89          assertEquals(2, layout.getLastRowNumber(1));       
90          
91          // test widths
92          assertEquals("25%", layout.getColumnWidth(0));
93          assertEquals("50%", layout.getColumnWidth(1));
94          assertEquals("24.99%", layout.getColumnWidth(2));        
95          assertEquals("0", layout.getColumnWidth(3));        
96  
97          assertEquals("left", layout.getColumnFloat(0));
98          assertEquals("left", layout.getColumnFloat(1));
99          assertEquals("right", layout.getColumnFloat(2));
100         assertEquals("none", layout.getColumnFloat(3));
101     }
102 
103     public void testSameRowSameColumn() throws Exception
104     {
105         FragmentImpl f1 = new FragmentImpl();
106         f1.setId("f1");
107         f1.setName("test");
108         f1.setLayoutRow(0);
109         f1.setLayoutColumn(0);
110 
111         FragmentImpl f2 = new FragmentImpl();
112         f2.setId("f2");
113         f2.setName("test");
114         f2.setLayoutRow(0);
115         f2.setLayoutColumn(0);
116 
117         ColumnLayout layout = new ColumnLayout(3, "test", null);
118         layout.addFragment(f1);
119         layout.addFragment(f2);
120 
121         Iterator column0 = layout.getColumn(0).iterator();
122         // all subsequent fragments that go into the same row will push
123         // the existing fragment down.
124         assertEquals(f2, column0.next());
125         assertEquals(f1, column0.next());
126 
127         Fragment testFragment = layout.getFragmentAt(0, 1);
128         assertNotNull(testFragment);
129         assertEquals(f1, testFragment);
130 
131         testFragment = layout.getFragmentAt(0, 0);
132         assertNotNull(testFragment);
133         assertEquals(f2, testFragment);
134 
135     }
136 
137     public void testColumnNotSet() throws Exception
138     {
139         FragmentImpl f1 = new FragmentImpl();
140         f1.setId("f1");
141         f1.setName("test");
142         f1.setLayoutRow(0);
143         f1.setLayoutColumn(0);
144 
145         FragmentImpl f2 = new FragmentImpl();
146         f2.setId("f2");
147         f2.setName("test");
148         f2.setLayoutRow(0);
149 
150         ColumnLayout layout = new ColumnLayout(3, "test", null);
151         layout.addFragment(f1);
152         layout.addFragment(f2);
153 
154         Fragment testFragment = layout.getFragmentAt(0, 0);
155         assertNotNull(testFragment);
156         assertEquals(f1, testFragment);
157 
158         testFragment = layout.getFragmentAt(2, 0);
159         assertNotNull(testFragment);
160         assertEquals(f2, testFragment);
161 
162         assertNotNull(layout.getFirstColumn());
163         assertNotNull(layout.getLastColumn());
164     }
165 
166     public void testRowNotSet() throws Exception
167     {
168         FragmentImpl f1 = new FragmentImpl();
169         f1.setId("f1");
170         f1.setName("test");
171         f1.setLayoutRow(0);
172         f1.setLayoutColumn(0);
173 
174         FragmentImpl f2 = new FragmentImpl();
175         f2.setId("f2");
176         f2.setName("test");
177         f2.setLayoutColumn(0);
178 
179         ColumnLayout layout = new ColumnLayout(3, "test", null);
180         layout.addFragment(f1);
181         layout.addFragment(f2);
182 
183         Fragment testFragment = layout.getFragmentAt(0, 0);
184         assertNotNull(testFragment);
185         assertEquals(f1, testFragment);
186 
187         testFragment = layout.getFragmentAt(0, 1);
188         assertNotNull(testFragment);
189         assertEquals(f2, testFragment);
190     }
191 
192     public void testColumnLimitExceeded() throws Exception
193     {
194         FragmentImpl f1 = new FragmentImpl();
195         f1.setId("f1");
196         f1.setLayoutRow(0);
197         f1.setLayoutColumn(5);
198 
199         ColumnLayout layout = new ColumnLayout(3, "test", null);
200         layout.addFragment(f1);
201 
202         // Exceeded columns just get dumped into the last column
203         Fragment testFragment = layout.getFragmentAt(2, 0);
204         assertNotNull(testFragment);
205         assertEquals(f1, testFragment);
206     }
207 
208     public void testMovingRight() throws Exception
209     {
210 
211         Fragment movingFragment = layout.getFragmentAt(new LayoutCoordinate(0, 0));
212         assertEquals(f1, movingFragment);
213         assertEquals(f4, layout.getFragmentAt(new LayoutCoordinate(1, 0)));
214 
215         Mock listenerMock = mock(LayoutEventListener.class);
216         layout.addLayoutEventListener((LayoutEventListener) listenerMock.proxy());
217         listenerMock.expects(once()).method("handleEvent").with(eq(createEvent(f1, layout, LayoutEvent.MOVED_RIGHT)));
218         listenerMock.expects(once()).method("handleEvent").with(eq(createEvent(f2, layout, LayoutEvent.MOVED_UP)));
219         listenerMock.expects(once()).method("handleEvent").with(eq(createEvent(f3, layout, LayoutEvent.MOVED_UP)));
220         listenerMock.expects(once()).method("handleEvent").with(eq(createEvent(f4, layout, LayoutEvent.MOVED_DOWN)));
221         listenerMock.expects(once()).method("handleEvent").with(eq(createEvent(f5, layout, LayoutEvent.MOVED_DOWN)));
222         listenerMock.expects(once()).method("handleEvent").with(eq(createEvent(f6, layout, LayoutEvent.MOVED_DOWN)));
223         
224         
225         // moving right
226         layout.moveRight(movingFragment);
227         
228         assertEquals(f1, layout.getFragmentAt(new LayoutCoordinate(1, 0)));
229         assertEquals(f2, layout.getFragmentAt(new LayoutCoordinate(0, 0)));
230         assertEquals(f3, layout.getFragmentAt(new LayoutCoordinate(0, 1)));
231         assertEquals(f4, layout.getFragmentAt(new LayoutCoordinate(1, 1)));
232         assertEquals(f5, layout.getFragmentAt(new LayoutCoordinate(1, 2)));
233         assertEquals(f6, layout.getFragmentAt(new LayoutCoordinate(1, 3)));
234     }
235 
236     public void testMovingLeft() throws Exception
237     {
238         Fragment movingFragment = layout.getFragmentAt(new LayoutCoordinate(1, 0));
239         assertEquals(f4, movingFragment);
240         assertEquals(f1, layout.getFragmentAt(new LayoutCoordinate(0, 0)));
241         
242         Mock listenerMock = mock(LayoutEventListener.class);
243         layout.addLayoutEventListener((LayoutEventListener) listenerMock.proxy());
244         listenerMock.expects(once()).method("handleEvent").with(eq(createEvent(f4, layout, LayoutEvent.MOVED_LEFT)));
245         listenerMock.expects(once()).method("handleEvent").with(eq(createEvent(f5, layout, LayoutEvent.MOVED_UP)));
246         listenerMock.expects(once()).method("handleEvent").with(eq(createEvent(f6, layout, LayoutEvent.MOVED_UP)));
247         listenerMock.expects(once()).method("handleEvent").with(eq(createEvent(f1, layout, LayoutEvent.MOVED_DOWN)));
248         listenerMock.expects(once()).method("handleEvent").with(eq(createEvent(f2, layout, LayoutEvent.MOVED_DOWN)));
249         listenerMock.expects(once()).method("handleEvent").with(eq(createEvent(f3, layout, LayoutEvent.MOVED_DOWN)));
250         
251         layout.moveLeft(f4);
252 
253         assertEquals(f1, layout.getFragmentAt(new LayoutCoordinate(0, 1)));
254         assertEquals(f2, layout.getFragmentAt(new LayoutCoordinate(0, 2)));
255         assertEquals(f3, layout.getFragmentAt(new LayoutCoordinate(0, 3)));
256         assertEquals(f4, layout.getFragmentAt(new LayoutCoordinate(0, 0)));
257         assertEquals(f5, layout.getFragmentAt(new LayoutCoordinate(1, 0)));
258         assertEquals(f6, layout.getFragmentAt(new LayoutCoordinate(1, 1)));
259         
260         listenerMock.reset();       
261         listenerMock.expects(once()).method("handleEvent").with(eq(createEvent(f6, layout, LayoutEvent.MOVED_LEFT)));
262         listenerMock.expects(once()).method("handleEvent").with(eq(createEvent(f1, layout, LayoutEvent.MOVED_DOWN)));
263         listenerMock.expects(once()).method("handleEvent").with(eq(createEvent(f2, layout, LayoutEvent.MOVED_DOWN)));
264         listenerMock.expects(once()).method("handleEvent").with(eq(createEvent(f3, layout, LayoutEvent.MOVED_DOWN)));
265 
266         layout.moveLeft(f6);
267 
268         assertEquals(f1, layout.getFragmentAt(new LayoutCoordinate(0, 2)));
269         assertEquals(f2, layout.getFragmentAt(new LayoutCoordinate(0, 3)));
270         assertEquals(f3, layout.getFragmentAt(new LayoutCoordinate(0, 4)));
271         assertEquals(f4, layout.getFragmentAt(new LayoutCoordinate(0, 0)));
272         assertEquals(f5, layout.getFragmentAt(new LayoutCoordinate(1, 0)));
273         assertEquals(f6, layout.getFragmentAt(new LayoutCoordinate(0, 1)));
274 
275         
276         listenerMock.reset();
277         listenerMock.expects(once()).method("handleEvent").with(eq(createEvent(f5, layout, LayoutEvent.MOVED_LEFT)));
278         listenerMock.expects(once()).method("handleEvent").with(eq(createEvent(f4, layout, LayoutEvent.MOVED_DOWN)));
279         listenerMock.expects(once()).method("handleEvent").with(eq(createEvent(f6, layout, LayoutEvent.MOVED_DOWN)));
280         listenerMock.expects(once()).method("handleEvent").with(eq(createEvent(f1, layout, LayoutEvent.MOVED_DOWN)));
281         listenerMock.expects(once()).method("handleEvent").with(eq(createEvent(f2, layout, LayoutEvent.MOVED_DOWN)));
282         listenerMock.expects(once()).method("handleEvent").with(eq(createEvent(f3, layout, LayoutEvent.MOVED_DOWN)));
283         
284         
285         layout.moveLeft(f5);
286 
287         assertEquals(f1, layout.getFragmentAt(new LayoutCoordinate(0, 3)));
288         assertEquals(f2, layout.getFragmentAt(new LayoutCoordinate(0, 4)));
289         assertEquals(f3, layout.getFragmentAt(new LayoutCoordinate(0, 5)));
290         assertEquals(f4, layout.getFragmentAt(new LayoutCoordinate(0, 1)));
291         assertEquals(f5, layout.getFragmentAt(new LayoutCoordinate(0, 0)));
292         assertEquals(f6, layout.getFragmentAt(new LayoutCoordinate(0, 2)));
293 
294         // This is a test to make sure the next row pointer is being decremented
295         // correctly
296         FragmentImpl f7 = new FragmentImpl();
297         f7.setId("f7");
298         f7.setName("test");
299         f7.setLayoutRow(0);
300         f7.setLayoutColumn(1);
301 
302         listenerMock.reset();
303         LayoutCoordinate coordinate = new LayoutCoordinate(1, 0);
304         LayoutEvent event = new LayoutEvent(LayoutEvent.ADDED, f7, coordinate, coordinate);
305         listenerMock.expects(once()).method("handleEvent").with(eq(event));
306         
307         layout.addFragment(f7);
308 
309         assertEquals(f1, layout.getFragmentAt(new LayoutCoordinate(0, 3)));
310         assertEquals(f2, layout.getFragmentAt(new LayoutCoordinate(0, 4)));
311         assertEquals(f3, layout.getFragmentAt(new LayoutCoordinate(0, 5)));
312         assertEquals(f4, layout.getFragmentAt(new LayoutCoordinate(0, 1)));
313         assertEquals(f5, layout.getFragmentAt(new LayoutCoordinate(0, 0)));
314         assertEquals(f6, layout.getFragmentAt(new LayoutCoordinate(0, 2)));
315         assertEquals(f7, layout.getFragmentAt(new LayoutCoordinate(1, 0)));
316 
317         // test that column consistency is maitained
318         Iterator itr1 = layout.getColumn(1).iterator();
319 
320         itr1.next().equals(f7);
321 
322         Iterator itr0 = layout.getColumn(0).iterator();
323 
324         itr0.next().equals(f5);
325         itr0.next().equals(f4);
326         itr0.next().equals(f6);
327         itr0.next().equals(f1);
328         itr0.next().equals(f2);
329         itr0.next().equals(f3);
330     }
331 
332     public void testInvalidOperations() throws Exception
333     {
334         // Create a mock that veridies events are NOT being fired on invalid operations
335         Mock listenerMock = mock(LayoutEventListener.class);
336         layout.addLayoutEventListener((LayoutEventListener) listenerMock.proxy());
337         listenerMock.expects(never()).method("handleEvent").withAnyArguments();
338         
339         layout.moveUp(f1); // Nothing at all should happen, not even exceptions
340 
341         assertEquals(f1, layout.getFragmentAt(new LayoutCoordinate(0, 0)));
342         assertEquals(f2, layout.getFragmentAt(new LayoutCoordinate(0, 1)));
343         assertEquals(f3, layout.getFragmentAt(new LayoutCoordinate(0, 2)));
344         assertEquals(f4, layout.getFragmentAt(new LayoutCoordinate(1, 0)));
345         assertEquals(f5, layout.getFragmentAt(new LayoutCoordinate(1, 1)));
346         assertEquals(f6, layout.getFragmentAt(new LayoutCoordinate(1, 2)));
347 
348         layout.moveDown(f3); // Nothing at all should happen, not even
349                                 // exceptions
350 
351         assertEquals(f1, layout.getFragmentAt(new LayoutCoordinate(0, 0)));
352         assertEquals(f2, layout.getFragmentAt(new LayoutCoordinate(0, 1)));
353         assertEquals(f3, layout.getFragmentAt(new LayoutCoordinate(0, 2)));
354         assertEquals(f4, layout.getFragmentAt(new LayoutCoordinate(1, 0)));
355         assertEquals(f5, layout.getFragmentAt(new LayoutCoordinate(1, 1)));
356         assertEquals(f6, layout.getFragmentAt(new LayoutCoordinate(1, 2)));
357 
358         layout.moveLeft(f1); // Nothing at all should happen, not even
359         // exceptions
360 
361         assertEquals(f1, layout.getFragmentAt(new LayoutCoordinate(0, 0)));
362         assertEquals(f2, layout.getFragmentAt(new LayoutCoordinate(0, 1)));
363         assertEquals(f3, layout.getFragmentAt(new LayoutCoordinate(0, 2)));
364         assertEquals(f4, layout.getFragmentAt(new LayoutCoordinate(1, 0)));
365         assertEquals(f5, layout.getFragmentAt(new LayoutCoordinate(1, 1)));
366         assertEquals(f6, layout.getFragmentAt(new LayoutCoordinate(1, 2)));
367     }
368 
369     public void testMoveDown() throws Exception
370     {
371         Mock listenerMock = mock(LayoutEventListener.class);
372         layout.addLayoutEventListener((LayoutEventListener) listenerMock.proxy());
373         listenerMock.expects(once()).method("handleEvent").with(eq(createEvent(f1, layout, LayoutEvent.MOVED_DOWN)));
374         listenerMock.expects(once()).method("handleEvent").with(eq(createEvent(f2, layout, LayoutEvent.MOVED_UP)));
375 
376         layout.moveDown(f1);
377 
378         assertEquals(f1, layout.getFragmentAt(new LayoutCoordinate(0, 1)));
379         assertEquals(f2, layout.getFragmentAt(new LayoutCoordinate(0, 0)));
380         assertEquals(f3, layout.getFragmentAt(new LayoutCoordinate(0, 2)));
381         assertEquals(f4, layout.getFragmentAt(new LayoutCoordinate(1, 0)));
382         assertEquals(f5, layout.getFragmentAt(new LayoutCoordinate(1, 1)));
383         assertEquals(f6, layout.getFragmentAt(new LayoutCoordinate(1, 2)));
384         
385         listenerMock.expects(once()).method("handleEvent").with(eq(createEvent(f1, layout, LayoutEvent.MOVED_DOWN)));
386         listenerMock.expects(once()).method("handleEvent").with(eq(createEvent(f3, layout, LayoutEvent.MOVED_UP)));
387 
388         layout.moveDown(f1);
389 
390         assertEquals(f1, layout.getFragmentAt(new LayoutCoordinate(0, 2)));
391         assertEquals(f2, layout.getFragmentAt(new LayoutCoordinate(0, 0)));
392         assertEquals(f3, layout.getFragmentAt(new LayoutCoordinate(0, 1)));
393         assertEquals(f4, layout.getFragmentAt(new LayoutCoordinate(1, 0)));
394         assertEquals(f5, layout.getFragmentAt(new LayoutCoordinate(1, 1)));
395         assertEquals(f6, layout.getFragmentAt(new LayoutCoordinate(1, 2)));
396         
397         //try moving a fragment below the bottom-most row.
398         listenerMock.expects(never()).method("handleEvent").withAnyArguments();
399         layout.moveDown(f6);
400         assertEquals(f6, layout.getFragmentAt(new LayoutCoordinate(1, 2)));
401 
402     }
403 
404     public void testMoveUp() throws Exception
405     {
406 
407         Mock listenerMock = mock(LayoutEventListener.class);
408         layout.addLayoutEventListener((LayoutEventListener) listenerMock.proxy());
409         listenerMock.expects(once()).method("handleEvent").with(eq(createEvent(f3, layout, LayoutEvent.MOVED_UP)));
410         listenerMock.expects(once()).method("handleEvent").with(eq(createEvent(f2, layout, LayoutEvent.MOVED_DOWN)));
411         layout.moveUp(f3);
412 
413         assertEquals(f1, layout.getFragmentAt(new LayoutCoordinate(0, 0)));
414         assertEquals(f2, layout.getFragmentAt(new LayoutCoordinate(0, 2)));
415         assertEquals(f3, layout.getFragmentAt(new LayoutCoordinate(0, 1)));
416         assertEquals(f4, layout.getFragmentAt(new LayoutCoordinate(1, 0)));
417         assertEquals(f5, layout.getFragmentAt(new LayoutCoordinate(1, 1)));
418         assertEquals(f6, layout.getFragmentAt(new LayoutCoordinate(1, 2)));
419     }
420 
421     protected void setUp() throws Exception
422     {
423         f1 = new FragmentImpl();
424         f1.setId("f1");
425         f1.setName("test");
426         f1.setLayoutRow(0);
427         f1.setLayoutColumn(0);
428 
429         f2 = new FragmentImpl();
430         f2.setId("f2");
431         f2.setName("test");
432         f2.setLayoutRow(1);
433         f2.setLayoutColumn(0);
434 
435         f3 = new FragmentImpl();
436         f3.setId("f3");
437         f3.setName("test");
438         f3.setLayoutRow(2);
439         f3.setLayoutColumn(0);
440         
441         f4 = new FragmentImpl();
442         f4.setId("f4");
443         f4.setName("test");
444         f4.setLayoutRow(0);
445         f4.setLayoutColumn(1);
446         
447         f5 = new FragmentImpl();
448         f5.setId("f5");
449         f5.setName("test");
450         f5.setLayoutRow(1);
451         f5.setLayoutColumn(1);
452 
453         f6 = new FragmentImpl();
454         f6.setId("f6");
455         f6.setName("test");
456         f6.setLayoutRow(2);
457         f6.setLayoutColumn(1);
458         
459         f8 = new FragmentImpl();
460         f8.setId("f8");
461         f8.setName("test");
462         f8.setLayoutRow(1);
463         f8.setLayoutColumn(2);
464 
465         layout = new ColumnLayout(3, "test", widths);
466         layout.addFragment(f1);
467         layout.addFragment(f2);
468         layout.addFragment(f3);
469         layout.addFragment(f4);
470         layout.addFragment(f5);
471         layout.addFragment(f6);
472         layout.addFragment(f8);
473     }
474 
475     protected LayoutEvent createEvent(Fragment fragment, ColumnLayout layout, int eventType) throws Exception
476     {
477         LayoutCoordinate fragmentOriginal = layout.getCoordinate(fragment);
478         LayoutCoordinate fragmentNew;
479 
480         switch (eventType)
481         {
482         case LayoutEvent.MOVED_UP:
483             fragmentNew = new LayoutCoordinate(fragmentOriginal.getX(), fragmentOriginal.getY() - 1);
484             break;
485         case LayoutEvent.MOVED_DOWN:
486             fragmentNew = new LayoutCoordinate(fragmentOriginal.getX(), fragmentOriginal.getY() + 1);
487             break;
488         case LayoutEvent.MOVED_LEFT:
489             fragmentNew = new LayoutCoordinate(fragmentOriginal.getX() - 1, fragmentOriginal.getY());
490             break;
491         case LayoutEvent.MOVED_RIGHT:
492             fragmentNew = new LayoutCoordinate(fragmentOriginal.getX() + 1, fragmentOriginal.getY());
493             break;
494         default:
495             fragmentNew = new LayoutCoordinate(fragmentOriginal.getX(), fragmentOriginal.getY());
496             break;
497         }
498 
499         return new LayoutEvent(eventType, fragment, fragmentOriginal, fragmentNew);
500 
501     }
502 
503 }