View Javadoc
1   /**
2    * Copyright 2005-2014 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.rice.coreservice.impl.component;
17  
18  import org.apache.commons.lang.StringUtils;
19  import org.hamcrest.BaseMatcher;
20  import org.hamcrest.Description;
21  import org.junit.Test;
22  import org.junit.runner.RunWith;
23  import org.kuali.rice.core.api.criteria.GenericQueryResults;
24  import org.kuali.rice.core.api.criteria.QueryByCriteria;
25  import org.kuali.rice.coreservice.api.component.Component;
26  import org.kuali.rice.coreservice.api.component.ComponentService;
27  import org.kuali.rice.coreservice.api.namespace.Namespace;
28  import org.kuali.rice.coreservice.api.namespace.NamespaceService;
29  import org.kuali.rice.krad.data.DataObjectService;
30  import org.mockito.ArgumentCaptor;
31  import org.mockito.InjectMocks;
32  import org.mockito.Matchers;
33  import org.mockito.Mock;
34  import org.mockito.runners.MockitoJUnitRunner;
35  
36  import java.sql.Timestamp;
37  import java.util.ArrayList;
38  import java.util.Arrays;
39  import java.util.List;
40  
41  import static org.junit.Assert.assertTrue;
42  import static org.junit.Assert.fail;
43  import static org.mockito.Matchers.any;
44  import static org.mockito.Matchers.anyObject;
45  import static org.mockito.Mockito.*;
46  
47  /**
48   * Unit test for {@link org.kuali.rice.coreservice.impl.component.ComponentServiceImpl}.
49   *
50   * @author Kuali Rice Team (rice.collab@kuali.org)
51   */
52  @RunWith(MockitoJUnitRunner.class)
53  public class ComponentServiceImplTest {
54      @Mock private DataObjectService dataObjectService;
55      @Mock private NamespaceService namespaceService;
56      @Mock private ComponentSetDaoJpa componentSetDao;
57  
58      @InjectMocks private ComponentServiceImpl componentService = new ComponentServiceImpl();
59  
60  
61      private static final String NAMESPACE_CODE = "MyNamespaceCode";
62      private static final String CODE = "MyComponentCode";
63      private static final String NAME = "This is my component!";
64  
65  
66      private static final String DERIVED_CODE = "MyDerivedComponentCode";
67      private static final String DERIVED_NAME = "This is my derived component!";
68      private static final String DERIVED_COMPONENT_SET_ID = "derivedComponentSetId";
69  
70      private static final String COMPONENT_SET_ID = "componentSetId";
71  
72      final Component component = createComponent();
73      final org.kuali.rice.coreservice.impl.component.ComponentBo componentBo = convertComponent(component);
74  
75      private ComponentService compService = componentService;
76      final Component derivedComponent = createDerivedComponent();
77      final DerivedComponentBo derivedComponentBo = DerivedComponentBo.from(derivedComponent);
78  
79      final ComponentSetBo componentSetBo = createComponentSet();
80  
81      private Component createDerivedComponent() {
82          Component.Builder builder = Component.Builder.create(NAMESPACE_CODE, DERIVED_CODE, DERIVED_NAME);
83          builder.setComponentSetId(DERIVED_COMPONENT_SET_ID);
84  
85          return builder.build();
86      }
87  
88      private ComponentSetBo createComponentSet(){
89          ComponentSetBo compSetBo = new ComponentSetBo();
90          compSetBo.setComponentSetId(COMPONENT_SET_ID);
91          compSetBo.setLastUpdateTimestamp(new Timestamp(System.currentTimeMillis()));
92          compSetBo.setChecksum("test");
93  
94          return compSetBo;
95      }
96  
97      public void setComponentService(ComponentService componentService){
98           this.compService = componentService;
99      }
100 
101     public ComponentService getComponentService(){
102         return compService;
103     }
104 
105     private Component createComponent() {
106         Component.Builder builder = Component.Builder.create(NAMESPACE_CODE, CODE, NAME);
107         return builder.build();
108     }
109 
110     private ComponentBo convertComponent(Component component) {
111         Namespace namespace = Namespace.Builder.create(NAMESPACE_CODE).build();
112 
113         NamespaceService nmService = mock(NamespaceService.class);
114         when(nmService.getNamespace(NAMESPACE_CODE)).thenReturn(namespace);
115         ComponentBo.setNamespaceService(nmService);
116         return ComponentBo.from(component);
117     }
118 
119     @Test(expected = IllegalArgumentException.class)
120     public void test_getComponentByCode_null_namespaceCode() throws Exception{
121         getComponentService().getComponentByCode(null, "myComponentCode");
122     }
123 
124     @Test(expected = IllegalArgumentException.class)
125     public void test_getComponentByCode_empty_namespaceCode() throws Exception{
126         getComponentService().getComponentByCode("", "myComponentCode");
127     }
128 
129     @Test(expected = IllegalArgumentException.class)
130     public void test_getComponentByCode_blank_namespaceCode() throws Exception{
131         getComponentService().getComponentByCode("  ", "myComponentCode");
132     }
133 
134     @Test(expected = IllegalArgumentException.class)
135     public void test_getComponentByCode_null_componentCode() throws Exception{
136         getComponentService().getComponentByCode("myNamespaceCode", null);
137     }
138 
139     @Test(expected = IllegalArgumentException.class)
140     public void test_getComponentByCode_empty_componentCode() throws Exception{
141         getComponentService().getComponentByCode("myNamespaceCode", "");
142     }
143 
144     @Test(expected = IllegalArgumentException.class)
145     public void test_getComponentByCode_blank_componentCode() throws Exception{
146         getComponentService().getComponentByCode("myNamespaceCode", "  ");
147     }
148 
149     @Test
150     public void test_getComponentByCode_exists() throws Exception{
151         when(dataObjectService.find(any(Class.class),anyObject())).thenReturn(componentBo);
152         assertTrue("Component was returned", StringUtils.equals(component.getCode(),
153                 getComponentService().getComponentByCode(NAMESPACE_CODE, CODE).getCode()));
154     }
155 
156     @Test
157     public void test_getComponentsByCode_not_exists() throws Exception{
158         when(dataObjectService.find(any(Class.class),anyObject())).thenReturn(null);
159         assertTrue("Component was returned",getComponentService().getComponentByCode("blah", "blah")==null);
160     }
161 
162     @Test(expected = IllegalArgumentException.class)
163     public void test_getAllComponentsByNamespaceCode_null_namespaceCode() throws Exception {
164         getComponentService().getAllComponentsByNamespaceCode(null);
165     }
166 
167     @Test(expected = IllegalArgumentException.class)
168     public void test_getAllComponentsByNamespaceCode_empty_namespaceCode() throws Exception{
169         getComponentService().getAllComponentsByNamespaceCode("");
170     }
171 
172     @Test(expected = IllegalArgumentException.class)
173     public void test_getAllComponentsByNamespaceCode_blank_namespaceCode() throws Exception{
174         getComponentService().getAllComponentsByNamespaceCode("  ");
175     }
176 
177     @Test
178     public void test_getAllComponentsByNamespaceCode_exists() throws Exception{
179         setupDataObjectServiceFetchComponent();
180         when(dataObjectService.findMatching(Matchers.argThat(
181                 new ClassOrSubclassMatcher<DerivedComponentBo>(DerivedComponentBo.class)),
182                 any(QueryByCriteria.class))).thenReturn(null);
183         List<Component> components = getComponentService().getAllComponentsByNamespaceCode(NAMESPACE_CODE);
184         assertTrue("getAllComponentsByNamespaceCode retrieved correctly", components != null && components.size() == 1);
185         assertTrue("Component was returned", StringUtils.equals(component.getCode(), components.get(0).getCode()));
186         assertImmutableList(components);
187         verify(dataObjectService,times(1)).findMatching(Matchers.argThat(
188                 new ClassOrSubclassMatcher<ComponentBo>(ComponentBo.class)), any(QueryByCriteria.class));
189         verify(dataObjectService,times(1)).findMatching(Matchers.argThat(
190                 new ClassOrSubclassMatcher<DerivedComponentBo>(DerivedComponentBo.class)), any(QueryByCriteria.class));
191     }
192 
193     @Test
194     public void test_getAllComponentsByNamespaceCode_not_exists() throws Exception{
195         when(dataObjectService.findMatching(Matchers.argThat(
196                 new ClassOrSubclassMatcher<ComponentBo>(ComponentBo.class)),
197                 any(QueryByCriteria.class))).thenReturn(null);
198         when(dataObjectService.findMatching(Matchers.argThat(
199                 new ClassOrSubclassMatcher<DerivedComponentBo>(DerivedComponentBo.class)),
200                 any(QueryByCriteria.class))).thenReturn(null);
201         List<Component> components = getComponentService().getAllComponentsByNamespaceCode("blah");
202         assertTrue("getAllComponentsByNamespaceCode not retrieved", components != null && components.isEmpty());
203         verify(dataObjectService,times(1)).findMatching(Matchers.argThat(
204                 new ClassOrSubclassMatcher<ComponentBo>(ComponentBo.class)), any(QueryByCriteria.class));
205         verify(dataObjectService,times(1)).findMatching(Matchers.argThat(
206                 new ClassOrSubclassMatcher<DerivedComponentBo>(DerivedComponentBo.class)), any(QueryByCriteria.class));
207     }
208 
209     @Test
210     public void test_getAllComponentsByNamespaceCode_with_derived() throws Exception{
211         setupDataObjectServiceFetchComponent();
212         setupDataObjectServiceFetchDerivedComponent();
213 
214         List<Component> components = getComponentService().getAllComponentsByNamespaceCode(NAMESPACE_CODE);
215         assertTrue("getAllComponentsByNamespaceCode retrieved correctly",
216                                     components != null && components.size() == 2);
217         assertTrue("Component was returned", StringUtils.equals(component.getCode(), components.get(0).getCode()));
218         assertTrue("Component was returned", StringUtils.equals(derivedComponent.getCode(),
219                                 components.get(1).getCode()));
220         assertImmutableList(components);
221     }
222 
223     @Test(expected = IllegalArgumentException.class)
224     public void test_getActiveComponentsByNamespaceCode_null_namespaceCode() throws Exception{
225         getComponentService().getActiveComponentsByNamespaceCode(null);
226     }
227 
228     @Test(expected = IllegalArgumentException.class)
229     public void test_getActiveComponentsByNamespaceCode_empty_namespaceCode() throws Exception{
230         getComponentService().getActiveComponentsByNamespaceCode("");
231     }
232 
233     @Test(expected = IllegalArgumentException.class)
234     public void test_getActiveComponentsByNamespaceCode_blank_namespaceCode() throws Exception{
235         getComponentService().getActiveComponentsByNamespaceCode("  ");
236     }
237 
238     @Test
239     public void test_getActiveComponentsByNamespaceCode_exists() throws Exception{
240         ArgumentCaptor<QueryByCriteria> argument = setupDataObjectServiceFetchComponent();
241         List <Component> components = getComponentService().getActiveComponentsByNamespaceCode(NAMESPACE_CODE);
242         QueryByCriteria queryByCriteria = argument.getValue();
243         assertTrue("Active passed as criteria for findMatching",StringUtils.contains(queryByCriteria.toString(),
244                 "active, true"));
245         assertTrue("getActiveComponentsByNamespaceCode retrieved correctly", components != null && components.size() == 1);
246         assertTrue("Component was returned", StringUtils.equals(component.getCode(), components.get(0).getCode()));
247         assertImmutableList(components);
248         verify(dataObjectService,times(1)).findMatching(Matchers.argThat(
249                 new ClassOrSubclassMatcher<ComponentBo>(ComponentBo.class)), any(QueryByCriteria.class));
250     }
251 
252     @Test
253     public void test_getActiveComponentsByNamespaceCode_not_exists() throws Exception{
254         GenericQueryResults.Builder builder = GenericQueryResults.Builder.create();
255         when(dataObjectService.findMatching(Matchers.argThat(
256                 new ClassOrSubclassMatcher<ComponentBo>(ComponentBo.class)), any(QueryByCriteria.class))).thenReturn(
257                 builder.build());
258         List<Component> components = getComponentService().getActiveComponentsByNamespaceCode("blah");
259         assertTrue("getActiveComponentsByNamespaceCode retrieved correctly",
260                                     components != null && components.size() == 0);
261         assertImmutableList(components);
262     }
263 
264     @Test
265     public void test_getActiveComponentsByNamespaceCode_with_derived() throws Exception{
266         ArgumentCaptor<QueryByCriteria> argument = setupDataObjectServiceFetchComponent();
267         setupDataObjectServiceFetchDerivedComponent();
268 
269         List<Component> components = getComponentService().getActiveComponentsByNamespaceCode(NAMESPACE_CODE);
270         QueryByCriteria queryByCriteria = argument.getValue();
271         assertTrue("Active passed as criteria for findMatching",StringUtils.contains(
272                 queryByCriteria.toString(),"active, true"));
273         assertTrue("getAllComponentsByNamespaceCode retrieved correctly",
274                 components != null && components.size() == 2);
275         assertTrue("Component was returned", StringUtils.equals(component.getCode(), components.get(0).getCode()));
276         assertTrue("Component was returned", StringUtils.equals(derivedComponent.getCode(),
277                 components.get(1).getCode()));
278         assertImmutableList(components);
279     }
280 
281     @Test(expected = IllegalArgumentException.class)
282     public void test_getDerivedComponentSet_null_componentSetId() throws Exception{
283         getComponentService().getDerivedComponentSet(null);
284     }
285 
286     @Test(expected = IllegalArgumentException.class)
287     public void test_getDerivedComponentSet_empty_componentSetId() throws Exception{
288         getComponentService().getDerivedComponentSet("");
289     }
290 
291     @Test(expected = IllegalArgumentException.class)
292     public void test_getDerivedComponentSet_blank_componentSetId() throws Exception{
293         getComponentService().getDerivedComponentSet("  ");
294     }
295 
296     @Test
297     public void test_getDerivedComponentSet_not_exists() throws Exception{
298         when(dataObjectService.findMatching(Matchers.argThat(
299                 new ClassOrSubclassMatcher<DerivedComponentBo>(DerivedComponentBo.class)),
300                 any(QueryByCriteria.class))).thenReturn(null);
301         List<Component> components = getComponentService().getDerivedComponentSet("blah");
302         assertTrue("getDerivedComponentSet is empty",components != null && components.isEmpty());
303         assertImmutableList(components);
304     }
305 
306     @Test(expected = IllegalArgumentException.class)
307     public void test_publishDerivedComponents_null_componentSetId() throws Exception{
308         List<Component> components = new ArrayList<Component>();
309         components.add(component);
310         getComponentService().publishDerivedComponents(null, components);
311     }
312 
313     @Test(expected = IllegalArgumentException.class)
314     public void test_publishDerivedComponents_empty_componentSetId() throws Exception{
315         List<Component> components = new ArrayList<Component>();
316         components.add(derivedComponent);
317         getComponentService().publishDerivedComponents("", components);
318     }
319 
320     @Test(expected = IllegalArgumentException.class)
321     public void test_publishDerivedComponents_blank_componentSetId() throws Exception{
322         List<Component> components = new ArrayList<Component>();
323         components.add(derivedComponent);
324         getComponentService().publishDerivedComponents("  ", components);
325     }
326 
327     @Test(expected = IllegalArgumentException.class)
328     public void test_publishDerivedComponents_invalidComponentSetId_onComponents() throws Exception{
329         Component.Builder builder = Component.Builder.create(component);
330         builder.setComponentSetId("myComponentSet");
331         List<Component> components = new ArrayList<Component>();
332         components.add(builder.build());
333         getComponentService().publishDerivedComponents("blah", components);
334     }
335 
336     @Test
337     public void test_publishDerivedComponents_null_components() throws Exception{
338         when(dataObjectService.find(Matchers.argThat(new ClassOrSubclassMatcher<ComponentSetBo>(
339                 ComponentSetBo.class)), any(Object.class))).thenReturn(null);
340         ArgumentCaptor<ComponentSetBo> boArgumentCaptor = ArgumentCaptor.forClass(ComponentSetBo.class);
341         when(componentSetDao.saveIgnoreLockingFailure(boArgumentCaptor.capture())).thenReturn(true);
342 
343         when(dataObjectService.findMatching(Matchers.argThat(
344                 new ClassOrSubclassMatcher<ComponentBo>(ComponentBo.class)),
345                 any(QueryByCriteria.class))).thenReturn(null);
346 
347         getComponentService().publishDerivedComponents("myComponentSet", null);
348         getComponentService().getDerivedComponentSet("myComponentSet").isEmpty();
349 
350         ArgumentCaptor<QueryByCriteria> argument = ArgumentCaptor.forClass(QueryByCriteria.class);
351         verify(dataObjectService).deleteMatching(Matchers.argThat(
352                 new ClassOrSubclassMatcher<DerivedComponentBo>(DerivedComponentBo.class)),
353                 argument.capture());
354         ComponentSetBo compSetCaptured = boArgumentCaptor.getValue();
355         QueryByCriteria queryByCriteria = argument.getValue();
356         assertTrue("QueryByCriteria contained componentSetId",queryByCriteria!= null &&
357                 StringUtils.contains(queryByCriteria.getPredicate().toString(),"componentSetId"));
358         assertTrue(compSetCaptured != null);
359         assertTrue(compSetCaptured.getChecksum() != null);
360         assertTrue(StringUtils.equals(compSetCaptured.getComponentSetId(),"myComponentSet"));
361         assertTrue(compSetCaptured.getLastUpdateTimestamp() != null);
362     }
363 
364     /**
365      * Tests attempting to publish an empty list of components in a situation where there are already components for
366      * the component set.
367      */
368     @Test
369     public void test_publishDerivedComponents_empty_components_withExisting_componentSet() throws Exception{
370         ComponentSetBo componentSetBo = new ComponentSetBo();
371         componentSetBo.setComponentSetId("myComponentSet");
372         componentSetBo.setChecksum("blah");
373         componentSetBo.setLastUpdateTimestamp(new Timestamp(System.currentTimeMillis()));
374         componentSetBo.setVersionNumber(500L);
375 
376         ComponentSetBo savedComponentSet = null;
377         when(dataObjectService.find(Matchers.argThat(new ClassOrSubclassMatcher<ComponentSetBo>(ComponentSetBo.class))
378                 ,any(Object.class))).thenReturn(componentSetBo);
379 
380         ArgumentCaptor<ComponentSetBo> boArgumentCaptor = ArgumentCaptor.forClass(ComponentSetBo.class);
381         when(componentSetDao.saveIgnoreLockingFailure(boArgumentCaptor.capture())).thenReturn(true);
382         when(dataObjectService.findMatching(Matchers.argThat(new ClassOrSubclassMatcher<ComponentSetBo>(
383                 ComponentSetBo.class)), any(QueryByCriteria.class))).thenReturn(null);
384 
385         getComponentService().publishDerivedComponents("myComponentSet", new ArrayList<Component>());
386         assertTrue(getComponentService().getDerivedComponentSet("myComponentSet").isEmpty());
387 
388         ArgumentCaptor<QueryByCriteria> argument = ArgumentCaptor.forClass(QueryByCriteria.class);
389         verify(dataObjectService).deleteMatching(Matchers.argThat(
390                 new ClassOrSubclassMatcher<DerivedComponentBo>(DerivedComponentBo.class)),
391                 argument.capture());
392         ComponentSetBo compSetCaptured = boArgumentCaptor.getValue();
393         QueryByCriteria queryByCriteria = argument.getValue();
394         assertTrue("QueryByCriteria contained componentSetId",queryByCriteria!= null &&
395                 StringUtils.contains(queryByCriteria.getPredicate().toString(),"componentSetId"));
396         assertTrue(compSetCaptured != null);
397         assertTrue(!StringUtils.equals(compSetCaptured.getChecksum(),"blah"));
398     }
399 
400     @Test
401     public void test_publishDerivedComponents() throws Exception{
402 
403         List<ComponentBo> publishedComponentBos = new ArrayList<ComponentBo>();
404         ComponentSetBo componentSet = null;
405 
406 
407         setupDataObjectServiceFetchComponentSetEmptyList();
408 
409         when(dataObjectService.find(Matchers.argThat(new ClassOrSubclassMatcher<ComponentSetBo>(ComponentSetBo.class)),
410                 any(Object.class))).thenReturn(null);
411 
412         ArgumentCaptor<ComponentSetBo> boArgumentCaptor = ArgumentCaptor.forClass(ComponentSetBo.class);
413         when(componentSetDao.saveIgnoreLockingFailure(boArgumentCaptor.capture())).thenReturn(true);
414 
415         List<Component> components = getComponentService().getDerivedComponentSet("myComponentSet");
416         assertTrue(components.isEmpty());
417 
418 
419         getComponentService().publishDerivedComponents("myComponentSet", Arrays.asList(component));
420         verify(dataObjectService, times(1)).save(any(ComponentBo.class));
421         derivedComponentBo.setComponentSetId("myComponentSet");
422         setupDataObjectServiceFetchDerivedComponent();
423         components = getComponentService().getDerivedComponentSet("myComponentSet");
424         assertTrue(components.size() == 1);
425         assertTrue(StringUtils.equals(derivedComponent.getNamespaceCode(),components.get(0).getNamespaceCode()));
426         assertTrue(StringUtils.equals(derivedComponent.getCode(),components.get(0).getCode()));
427     }
428 
429 
430     private void assertImmutableList(List<Component> components){
431         try{
432             components.add(null);
433             fail("Should not be able to add to immutable list");
434         } catch(UnsupportedOperationException e){
435 
436         }
437     }
438 
439     private ArgumentCaptor<QueryByCriteria> setupDataObjectServiceFetchComponent(){
440         List<ComponentBo> componentBoList = new ArrayList<ComponentBo>();
441         componentBoList.add(componentBo);
442         GenericQueryResults.Builder builder = GenericQueryResults.Builder.create();
443 
444         builder.setResults(componentBoList);
445         ArgumentCaptor<QueryByCriteria> argument = ArgumentCaptor.forClass(QueryByCriteria.class);
446         when(dataObjectService.findMatching(Matchers.argThat(
447                 new ClassOrSubclassMatcher<ComponentBo>(ComponentBo.class)), argument.capture())).thenReturn(
448                 builder.build());
449         return argument;
450     }
451 
452     private void setupDataObjectServiceFetchDerivedComponent(){
453         List<DerivedComponentBo> derivedComponentBoList = new ArrayList<DerivedComponentBo>();
454         derivedComponentBoList.add(derivedComponentBo);
455         GenericQueryResults.Builder builder = GenericQueryResults.Builder.create();
456         builder.setResults(derivedComponentBoList);
457 
458         when(dataObjectService.findMatching(Matchers.argThat(new ClassOrSubclassMatcher<DerivedComponentBo>(
459                 DerivedComponentBo.class)), any(QueryByCriteria.class))).thenReturn(builder.build());
460     }
461 
462     private void setupDataObjectServiceFetchComponentSet(){
463         List<ComponentSetBo> componentSetBoList = new ArrayList<ComponentSetBo>();
464         componentSetBoList.add(componentSetBo);
465         GenericQueryResults.Builder builder = GenericQueryResults.Builder.create();
466         builder.setResults(componentSetBoList);
467 
468         when(dataObjectService.findMatching(Matchers.argThat(new ClassOrSubclassMatcher<ComponentSetBo>(
469                 ComponentSetBo.class)), any(QueryByCriteria.class))).thenReturn(builder.build());
470     }
471 
472     private void setupDataObjectServiceFetchComponentSetEmptyList(){
473         List<ComponentSetBo> componentSetBoList = new ArrayList<ComponentSetBo>();
474         GenericQueryResults.Builder builder = GenericQueryResults.Builder.create();
475         builder.setResults(componentSetBoList);
476 
477         when(dataObjectService.findMatching(Matchers.argThat(new ClassOrSubclassMatcher<ComponentSetBo>(
478                 ComponentSetBo.class)), any(QueryByCriteria.class))).thenReturn(builder.build());
479     }
480 
481 
482     /**
483      * Tests that the calculateChecksum method returns the same checksum regardless of the order of the elements given
484      * to it.
485      */
486     @Test
487     public void test_calculateChecksum_orderIndependent() throws Exception{
488         Component component2 = Component.Builder.create("a", "b", "name2").build();
489         Component component3 = Component.Builder.create("b", "a", "name3").build();
490         Component component4 = Component.Builder.create("c", "c", "name4").build();
491 
492         List<Component> components1 = new ArrayList<Component>();
493         components1.add(component);
494         components1.add(component2);
495         components1.add(component3);
496         components1.add(component4);
497 
498         String checksum1 = componentService.calculateChecksum(components1);
499         assert checksum1 != null;
500 
501 
502         List<Component> components2 = new ArrayList<Component>();
503         components2.add(component3);
504         components2.add(component2);
505         components2.add(component);
506         components2.add(component4);
507 
508         String checksum2 = componentService.calculateChecksum(components2);
509         assert checksum2 != null;
510 
511         assertTrue("Checksums match",StringUtils.equals(checksum1,checksum2));
512     }
513 
514     @Test
515     public void test_calculateChecksum_emptyList() throws Exception{
516         String checksum1 = componentService.calculateChecksum(new ArrayList<Component>());
517         String checksum2 = componentService.calculateChecksum(new ArrayList<Component>());
518         assert checksum1 != null;
519         assert checksum2 != null;
520         assertTrue("Checksums match",StringUtils.equals(checksum1,checksum2));
521     }
522 
523     @Test
524     public void test_translateCollections_nullList() throws Exception{
525         List<Component> components = componentService.translateCollections(null, null);
526         assert components != null;
527         assert components.isEmpty();
528         assertImmutableList(components);
529     }
530 
531     @Test
532     public void test_translateCollections_emptyList() throws Exception{
533         GenericQueryResults.Builder builder = GenericQueryResults.Builder.create();
534         GenericQueryResults.Builder builder2 = GenericQueryResults.Builder.create();
535         List<Component> components = componentService.translateCollections(builder.build(), builder2.build());
536         assert components != null;
537         assert components.isEmpty();
538         assertImmutableList(components);
539     }
540 
541     @Test
542     public void test_translateCollections_components() throws Exception{
543         GenericQueryResults.Builder builder = GenericQueryResults.Builder.create();
544         List<ComponentBo> results = new ArrayList<ComponentBo>();
545         results.add(componentBo);
546         builder.setResults(results);
547         List<Component> components = componentService.translateCollections(builder.build(), null);
548         assert components != null;
549         assert components.size() == 1;
550         assertTrue("Component fetched correctly",
551                 StringUtils.equals(components.get(0).getCode(),component.getCode()));
552         assertImmutableList(components);
553     }
554 
555     @Test
556     public void test_translateCollections_derivedComponents() throws Exception{
557         GenericQueryResults.Builder builder = GenericQueryResults.Builder.create();
558         List<DerivedComponentBo> results = new ArrayList<DerivedComponentBo>();
559         results.add(derivedComponentBo);
560         builder.setResults(results);
561         List<Component> components = componentService.translateCollections(null, builder.build());
562         assert components != null;
563         assert components.size() == 1;
564         assertTrue("Component fetched correctly",
565                 StringUtils.equals(components.get(0).getCode(),derivedComponent.getCode()));
566         assertImmutableList(components);
567     }
568 
569     @Test
570     public void test_translateCollections_both() throws Exception{
571         GenericQueryResults.Builder builder = GenericQueryResults.Builder.create();
572         GenericQueryResults.Builder builder2 = GenericQueryResults.Builder.create();
573 
574         List<DerivedComponentBo> derivedComponentBoList = new ArrayList<DerivedComponentBo>();
575         derivedComponentBoList.add(derivedComponentBo);
576         builder2.setResults(derivedComponentBoList);
577 
578         List<ComponentBo> componentBoList = new ArrayList<ComponentBo>();
579         componentBoList.add(componentBo);
580         builder.setResults(componentBoList);
581 
582         List<Component> components = componentService.translateCollections(builder.build(), builder2.build());
583         assert components != null;
584         assert components.size() == 2;
585         assertTrue("Component fetched correctly",
586                 StringUtils.equals(components.get(0).getCode(),component.getCode()));
587         assertTrue("Component fetched correctly",
588                 StringUtils.equals(components.get(1).getCode(),derivedComponent.getCode()));
589         assertImmutableList(components);
590     }
591 
592     class ClassOrSubclassMatcher<T> extends BaseMatcher<Class<T>> {
593 
594         private final Class<T> targetClass;
595 
596         public ClassOrSubclassMatcher(Class<T> targetClass) {
597             this.targetClass = targetClass;
598         }
599 
600         @SuppressWarnings("unchecked")
601         public boolean matches(Object obj) {
602             if (obj != null) {
603                 if (obj instanceof Class) {
604                     return targetClass.isAssignableFrom((Class<T>) obj);
605                 }
606             }
607             return false;
608         }
609 
610         public void describeTo(Description desc) {
611             desc.appendText("Matches a class or subclass");
612         }
613     }
614 
615 
616 
617 
618 
619 }