View Javadoc

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