View Javadoc

1   /*
2    * Copyright 2006-2012 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  
17  package org.kuali.rice.krms.test;
18  
19  import com.google.common.collect.Sets;
20  import org.apache.commons.lang.StringUtils;
21  import org.junit.Test;
22  import org.kuali.rice.core.api.exception.RiceIllegalArgumentException;
23  import org.kuali.rice.core.api.exception.RiceRuntimeException;
24  import org.kuali.rice.krms.api.repository.agenda.AgendaDefinition;
25  import org.kuali.rice.krms.api.repository.agenda.AgendaItemDefinition;
26  import org.kuali.rice.krms.api.repository.context.ContextDefinition;
27  import org.kuali.rice.krms.api.repository.type.KrmsTypeDefinition;
28  import org.kuali.rice.krms.impl.repository.AgendaBo;
29  import org.kuali.rice.krms.impl.repository.AgendaItemBo;
30  import org.kuali.rice.test.BaselineTestCase;
31  import org.springframework.util.CollectionUtils;
32  
33  import java.util.ArrayList;
34  import java.util.Arrays;
35  import java.util.Collections;
36  import java.util.HashMap;
37  import java.util.HashSet;
38  import java.util.List;
39  import java.util.Map;
40  import java.util.Set;
41  
42  import static org.junit.Assert.*;
43  
44  /**
45   * Integration test for the AgendaBoService.  Note that we inherit the test data created by AbstractAgendaBoTest, and
46   * test the service against that data.
47   */
48  @BaselineTestCase.BaselineMode(BaselineTestCase.Mode.CLEAR_DB)
49  public class AgendaBoServiceTest extends AbstractAgendaBoTest {
50  
51      private static final String NULL = new String("null"); // null String.  Hah. Using it as a "null object".
52  
53      private static <A> A nullConvertingGet(List<A> list, int index) {
54          // being lazy, no input checks here
55          A result = list.get(index);
56          if (result == NULL) result = null;
57          return result;
58      }
59  
60      @Test public void testGetByContextId() {
61  
62          assertTrue(CollectionUtils.isEmpty(getAgendaBoService().getAgendasByContextId("#$^$ BogusContextId !@#$")));
63          assertTrue(CollectionUtils.isEmpty(getAgendaBoService().getAgendaItemsByContext("#$^$ BogusContextId !@#$")));
64  
65          for (String contextName : Arrays.asList(CONTEXT1, CONTEXT2, CONTEXT3)) {
66  
67              String contextId = getContextRepository().getContextByNameAndNamespace(contextName,
68                      getNamespaceByContextName(contextName))
69                      .getId();
70  
71              List<AgendaDefinition> agendas = getAgendaBoService().getAgendasByContextId(contextId);
72              List<AgendaItemDefinition> agendaItems = getAgendaBoService().getAgendaItemsByContext(contextId);
73  
74              assertEquals("agenda count doesn't match our tally for context " + contextName, agendas.size(),
75                      getBoService().countMatching(AgendaBo.class, Collections.singletonMap("contextId", contextId)));
76  
77              int totalAgendaItems = 0; // count agenda items in the context for verification purposes
78  
79              Set<String> agendaIds = new HashSet<String>(); // build set of agenda ids, also for verification purposes
80  
81              for (AgendaDefinition agenda : agendas) {
82                  assertEquals("agenda w/ ID "+ agenda.getId() +" has a context ID that doesn't match",
83                          agenda.getContextId(), contextId);
84  
85                  totalAgendaItems += getBoService().countMatching(
86                          AgendaItemBo.class, Collections.singletonMap("agendaId", agenda.getId())
87                  );
88  
89                  agendaIds.add(agenda.getId());
90              }
91  
92              for (AgendaItemDefinition agendaItem : agendaItems) {
93                  assertTrue("agenda item is not part of any agendas in " + contextName,
94                          agendaIds.contains(agendaItem.getAgendaId()));
95              }
96  
97              assertEquals("number of agenda items doesn't match our tally", agendaItems.size(), totalAgendaItems);
98          }
99  
100     }
101 
102     @Test public void testGetAgendasByContextId_nullOrBlank() {
103 
104         for (String contextId : Arrays.asList(null, "", " ")) {
105             try {
106                 getAgendaBoService().getAgendasByContextId(contextId);
107                 fail("getAgendasByContextId should have thrown "+ RiceIllegalArgumentException.class.getSimpleName() +
108                         " for invalid contextId=" + contextId +".");
109             } catch (RiceIllegalArgumentException e) {
110                 // good, that's what it should do
111             }
112         }
113     }
114 
115     @Test public void testGetAgendaItemsByContextId_nullOrBlank() {
116 
117         for (String contextId : Arrays.asList(null, "", " ")) {
118             try {
119                 getAgendaBoService().getAgendaItemsByContext(contextId);
120                 fail("getAgendaItemsByContext should have thrown "+ RiceIllegalArgumentException.class.getSimpleName() +
121                         " for invalid contextId=" + contextId +".");
122             } catch (RiceIllegalArgumentException e) {
123                 // good, that's what it should do
124             }
125         }
126     }
127 
128     @Test
129     public void testGetByType() {
130 
131         assertTrue(CollectionUtils.isEmpty(getAgendaBoService().getAgendasByType("#$^$ BogusTypeId !@#$")));
132         assertTrue(CollectionUtils.isEmpty(getAgendaBoService().getAgendaItemsByType("#$^$ BogusTypeId !@#$")));
133 
134         List<KrmsTypeDefinition> agendaTypes =  getAgendaTypesForContexts(Arrays.asList(CONTEXT1, CONTEXT2, CONTEXT3));
135 
136         assertTrue("We must have some types to test with or we prove nothing", agendaTypes.size() > 0);
137 
138         for (KrmsTypeDefinition agendaType : agendaTypes) {
139             String typeName = agendaType.getName();
140             String typeNamespace = agendaType.getNamespace();
141 
142             KrmsTypeDefinition type = getKrmsTypeRepository().getTypeByName(typeNamespace, typeName);
143 
144             List<AgendaDefinition> agendas = getAgendaBoService().getAgendasByType(type.getId());
145             List<AgendaItemDefinition> agendaItems = getAgendaBoService().getAgendaItemsByType(type.getId());
146 
147 
148             assertEquals("agenda count doesn't match our tally for type " + typeNamespace+":"+typeName,
149                     agendas.size(), getBoService().countMatching(
150                     AgendaBo.class, Collections.singletonMap("typeId", type.getId()))
151             );
152 
153             int totalAgendaItems = 0; // count agenda items in the type for verification purposes
154 
155             Set<String> agendaIds = new HashSet<String>(); // build set of agenda ids, also for verification purposes
156 
157             for (AgendaDefinition agenda : agendas) {
158                 assertEquals("agenda w/ ID "+ agenda.getTypeId() +" has a type ID that doesn't match",
159                         agenda.getTypeId(), type.getId());
160 
161                 totalAgendaItems += getBoService().countMatching(
162                         AgendaItemBo.class, Collections.singletonMap("agendaId", agenda.getId())
163                 );
164 
165                 agendaIds.add(agenda.getId());
166             }
167 
168             for (AgendaItemDefinition agendaItem : agendaItems) {
169                 assertTrue("agenda item is not part of any agendas in type " + typeNamespace+":"+typeName,
170                         agendaIds.contains(agendaItem.getAgendaId()));
171             }
172 
173             assertEquals("number of agenda items doesn't match our tally", agendaItems.size(), totalAgendaItems);
174 
175         }
176     }
177 
178     private List<KrmsTypeDefinition> getAgendaTypesForContexts(List<String> contextNames) {
179         List<KrmsTypeDefinition> results = new ArrayList<KrmsTypeDefinition>();
180 
181         // collect all the types used for the agendas in our contexts
182         for (String contextName : contextNames) {
183             String namespace = getNamespaceByContextName(contextName);
184             if (StringUtils.isBlank(namespace)) {
185                 throw new RiceRuntimeException("namespace is " + namespace + " for context with name " + contextName);
186             }
187             String contextId = getContextRepository().getContextByNameAndNamespace(contextName, namespace).getId();
188 
189             // depending on good behavior of getAgendasByContextId which is tested elsewhere
190             List<AgendaDefinition> agendas = getAgendaBoService().getAgendasByContextId(contextId);
191 
192             // stacked filters here
193             if (!CollectionUtils.isEmpty(agendas)) {
194                 for (AgendaDefinition agenda : agendas) {
195                     if (agenda.getTypeId() != null) {
196                         KrmsTypeDefinition type = getKrmsTypeRepository().getTypeById(agenda.getTypeId());
197 
198                         // we depend on working hashcode & equals for KrmsTypeDefinition here
199                         if (!results.contains(type)) {
200                             results.add(type);
201                         }
202                     }
203                 }
204             }
205         }
206         return results;
207     }
208 
209     @Test public void testGetAgendasByType_nullOrBlank() {
210 
211         for (String contextId : Arrays.asList(null, "", " ")) {
212             try {
213                 getAgendaBoService().getAgendasByType(contextId);
214                 fail("getAgendasByType should have thrown "+ RiceIllegalArgumentException.class.getSimpleName() +
215                         " for invalid contextId=" + contextId +".");
216             } catch (RiceIllegalArgumentException e) {
217                 // good, that's what it should do
218             }
219         }
220     }
221 
222     @Test public void testGetAgendaItemsByType_nullOrBlank() {
223 
224         for (String contextId : Arrays.asList(null, "", " ")) {
225             try {
226                 getAgendaBoService().getAgendaItemsByType(contextId);
227                 fail("getAgendaItemsByType should have thrown "+ RiceIllegalArgumentException.class.getSimpleName() +
228                         " for invalid contextId=" + contextId +".");
229             } catch (RiceIllegalArgumentException e) {
230                 // good, that's what it should do
231             }
232         }
233     }
234 
235     @Test public void testGetByTypeAndContext() {
236 
237         boolean testedSomeTypes = false;
238 
239         for (String contextName : Arrays.asList(CONTEXT1, CONTEXT2, CONTEXT3)) {
240 
241             List<KrmsTypeDefinition> agendaTypes =  getAgendaTypesForContexts(Collections.singletonList(contextName));
242 
243             ContextDefinition context = getContextRepository().getContextByNameAndNamespace(contextName,
244                     getNamespaceByContextName(contextName));
245 
246             for (KrmsTypeDefinition agendaType : agendaTypes) {
247 
248                 testedSomeTypes = true; // prove we got to the inner loop
249 
250                 assertTrue(CollectionUtils.isEmpty(getAgendaBoService().getAgendasByTypeAndContext("#$^$ BogusTypeId !@#$", context.getId())));
251                 assertTrue(CollectionUtils.isEmpty(getAgendaBoService().getAgendaItemsByTypeAndContext("#$^$ BogusTypeId !@#$", context.getId())));
252                 assertTrue(CollectionUtils.isEmpty(getAgendaBoService().getAgendasByTypeAndContext(agendaType.getId(), "#$^$ BogusContextId !@#$")));
253                 assertTrue(CollectionUtils.isEmpty(getAgendaBoService().getAgendaItemsByTypeAndContext(
254                         agendaType.getId(), "#$^$ BogusContextId !@#$")));
255 
256                 List<AgendaDefinition> agendas = getAgendaBoService().getAgendasByTypeAndContext(agendaType.getId(), context.getId());
257                 List<AgendaItemDefinition> agendaItems = getAgendaBoService().getAgendaItemsByTypeAndContext(agendaType.getId(), context.getId());
258 
259                 Map<String, String> agendaCountCrit = new HashMap<String, String>();
260                 agendaCountCrit.put("typeId", agendaType.getId());
261                 agendaCountCrit.put("contextId", context.getId());
262                 assertEquals(
263                         "agenda count doesn't match our tally for type " + agendaType.getNamespace() + ":" + agendaType
264                                 .getName(), agendas.size(), getBoService().countMatching(AgendaBo.class,
265                         agendaCountCrit));
266 
267                 int totalAgendaItems = 0; // count agenda items in the type for verification purposes
268 
269                 Set<String> agendaIds = new HashSet<String>(); // build set of agenda ids, also for verification purposes
270 
271                 for (AgendaDefinition agenda : agendas) {
272                     assertEquals("agenda w/ ID "+ agenda.getTypeId() +" has a type ID that doesn't match",
273                             agenda.getTypeId(), agendaType.getId());
274 
275                     totalAgendaItems += getBoService().countMatching(
276                             AgendaItemBo.class, Collections.singletonMap("agendaId", agenda.getId())
277                     );
278 
279                     agendaIds.add(agenda.getId());
280                 }
281 
282                 for (AgendaItemDefinition agendaItem : agendaItems) {
283                     String assertionString = "agenda item is not part of any agendas in type " +
284                             agendaType.getNamespace()+":"+agendaType.getName() +
285                             " and context " + context.getNamespace()+":"+context.getName();
286 
287                     assertTrue(assertionString, agendaIds.contains(agendaItem.getAgendaId())
288                     );
289                 }
290 
291                 assertEquals("number of agenda items doesn't match our tally", agendaItems.size(), totalAgendaItems);
292             }
293 
294             assertTrue("We have to test some types or we prove nothing", testedSomeTypes);
295 
296         }
297     }
298 
299     @Test public void testGetAgendaItemsByTypeAndContext_nullOrBlank() {
300 
301 
302         Set<String> emptyValues = new HashSet<String>();
303         emptyValues.addAll(Arrays.asList(NULL, "", " "));
304 
305         Set<String> oneNonBlank = Sets.union(emptyValues, Collections.singleton("fakeId"));
306         Set<List<String>> testIds = Sets.union(Sets.cartesianProduct(emptyValues, oneNonBlank),
307                 Sets.cartesianProduct(oneNonBlank, emptyValues));
308 
309         for (List<String> ids : testIds) {
310             try {
311                 getAgendaBoService().getAgendaItemsByTypeAndContext(nullConvertingGet(ids, 0), nullConvertingGet(ids, 1));
312                 fail("getAgendaItemsByType should have thrown "+ RiceIllegalArgumentException.class.getSimpleName() +
313                         " for invalid combo of contextId=" + ids +".");
314             } catch (RiceIllegalArgumentException e) {
315                 // good, that's what it should do
316             }
317         }
318     }
319 
320     // TODO:
321 
322     // methods left to test:
323     //
324     // deleteAgendaItem
325     // updateAgendaItem
326     // updateAgenda
327     // deleteAgenda
328     // createAgendaItem
329     @Test
330     public void testAgendaCrud() {
331 
332         ContextDefinition context = getContextRepository().getContextByNameAndNamespace(CONTEXT1,
333                 getNamespaceByContextName(CONTEXT1));
334 
335         // Get an agenda to use as a template for agenda creation
336         List<AgendaDefinition> agendas = getAgendaBoService().getAgendasByContextId(context.getId());
337         AgendaDefinition templateAgenda = agendas.get(0);
338 
339 //        AgendaBo templateAgendaBo = getBoService().findBySinglePrimaryKey(AgendaBo.class, templateAgenda.getId());
340 //        AgendaBo.to(templateAgendaBo.copyAgenda("newTestAgenda", "FooTime"));
341 
342 
343         AgendaDefinition.Builder agendaBuilder = AgendaDefinition.Builder.create(templateAgenda);
344 
345         agendaBuilder.setFirstItemId(null);
346         agendaBuilder.setId(null);
347         agendaBuilder.setVersionNumber(null);
348         agendaBuilder.setName("testAgendaCrud-agenda");
349 
350         // create agenda
351         AgendaDefinition newAgenda = getAgendaBoService().createAgenda(agendaBuilder.build());
352 
353         // verify the agenda is there and
354         assertNotNull(newAgenda);
355         // we depend on working equals for AgendaDefinition here
356         assertEquals(newAgenda, getAgendaBoService().getAgendaByAgendaId(newAgenda.getId()));
357 
358 //        List<AgendaItemDefinition> templateAgendaItems = getAgendaBoService().getAgendaItemsByAgendaId(templateAgenda.getId());
359 //        List<AgendaItemDefinition.Builder> agendaItemBuilders = new ArrayList<AgendaItemDefinition.Builder>();
360 //
361 //        for (AgendaItemDefinition templateAgendaItem : templateAgendaItems) {
362 //            AgendaItemDefinition.Builder agendaItemBuilder = AgendaItemDefinition.Builder.create(templateAgendaItem);
363 //            agendaItemBuilder.setAlwaysId(null);
364 //            agendaItemBuilder.setWhenFalseId(null);
365 //            agendaItemBuilder.setWhenTrueId(null);
366 //            agendaItemBuilder.setAgendaId(newAgenda.getId());
367 //            agendaItemBuilder.set
368 //        }
369 
370     }
371 
372 }