001/* 002 * Copyright 2006-2013 The Kuali Foundation 003 * 004 * Licensed under the Educational Community License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/ecl2.php 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.kuali.rice.krms.test; 018 019import org.apache.commons.lang.StringUtils; 020import org.junit.Before; 021import org.junit.Test; 022import org.kuali.rice.core.api.criteria.QueryByCriteria; 023import org.kuali.rice.core.api.exception.RiceIllegalArgumentException; 024import org.kuali.rice.krms.api.repository.action.ActionDefinition; 025import org.kuali.rice.krms.api.repository.agenda.AgendaItemDefinition; 026import org.kuali.rice.krms.api.repository.proposition.PropositionDefinition; 027import org.kuali.rice.krms.api.repository.rule.RuleDefinition; 028import org.kuali.rice.krms.api.repository.type.KrmsTypeDefinition; 029import org.kuali.rice.krms.impl.repository.ActionAttributeBo; 030 031import java.util.ArrayList; 032import java.util.Arrays; 033import java.util.Collection; 034import java.util.HashMap; 035import java.util.List; 036import java.util.Map; 037import java.util.Set; 038 039import static org.junit.Assert.*; 040import static org.junit.Assert.assertEquals; 041import static org.kuali.rice.core.api.criteria.PredicateFactory.equal; 042import static org.kuali.rice.core.api.criteria.PredicateFactory.in; 043 044 045/** 046 * RuleManagementRuleDefinitionTest is to test the methods of ruleManagementServiceImpl relating to RuleDefinitions 047 * 048 * Each test focuses on one of the methods. 049 */ 050public class RuleManagementRuleDefinitionTest extends RuleManagementBaseTest{ 051 @Override 052 @Before 053 public void setClassDiscriminator() { 054 // set a unique discriminator for test objects of this class 055 CLASS_DISCRIMINATOR = "RMRDT"; 056 } 057 058 /** 059 * Test testGetRuleByNameAndNamespace() 060 * 061 * This test focuses specifically on the RuleManagementServiceImpl .getRuleByNameAndNamespace("rule name", "namespace") method 062 */ 063 @Test 064 public void testGetRuleByNameAndNamespace() { 065 // get a set of unique object names for use by this test (discriminator passed can be any unique value within this class) 066 RuleManagementBaseTestObjectNames t0 = new RuleManagementBaseTestObjectNames( CLASS_DISCRIMINATOR, "t0"); 067 068 RuleDefinition ruleDefinition = buildTestRuleDefinition(t0.namespaceName, t0.object0); 069 070 RuleDefinition returnRuleDefinition = ruleManagementService.getRuleByNameAndNamespace( 071 ruleDefinition.getName(), ruleDefinition.getNamespace()); 072 073 assertEquals("rule not found", ruleDefinition.getId(), returnRuleDefinition.getId()); 074 075 // try getRuleByNameAndNamespace with null Name parameter 076 try { 077 ruleManagementService.getRuleByNameAndNamespace(null, t0.namespaceName); 078 fail("Should have thrown IllegalArgumentException: name is null or blank"); 079 } catch (IllegalArgumentException e) { 080 // throws IllegalArgumentException: name is null or blank 081 } 082 083 // try getRuleByNameAndNamespace with null Name parameter 084 try { 085 ruleManagementService.getRuleByNameAndNamespace(" ", t0.namespaceName); 086 fail("Should have thrown IllegalArgumentException: name is null or blank"); 087 } catch (IllegalArgumentException e) { 088 // throws IllegalArgumentException: name is null or blank 089 } 090 091 // try getRuleByNameAndNamespace with null namespace parameter 092 try { 093 ruleManagementService.getRuleByNameAndNamespace(ruleDefinition.getName(),null); 094 fail("should throw IllegalArgumentException: namespace is null or blank"); 095 } catch (IllegalArgumentException e) { 096 // IllegalArgumentException: namespace is null or blank 097 } 098 099 // try getRuleByNameAndNamespace with blank namespace parameter 100 try { 101 ruleManagementService.getRuleByNameAndNamespace(ruleDefinition.getName()," "); 102 fail("should throw IllegalArgumentException: namespace is null or blank"); 103 } catch (IllegalArgumentException e) { 104 // IllegalArgumentException: namespace is null or blank 105 } 106 107 108 } 109 110 /** 111 * Test testCreateRule() 112 * 113 * This test focuses specifically on the RuleManagementServiceImpl .createRule(RuleDefinition) method 114 */ 115 @Test 116 public void testCreateRule() { 117 // get a set of unique object names for use by this test (discriminator passed can be any unique value within this class) 118 RuleManagementBaseTestObjectNames t1 = new RuleManagementBaseTestObjectNames( CLASS_DISCRIMINATOR, "t1"); 119 120 // create a Rule 121 RuleDefinition ruleFirstCreate = buildTestRuleDefinition(t1.namespaceName, t1.object0); 122 assertTrue("created Rule not found", ruleManagementService.getRule(ruleFirstCreate.getId()).getId().contains(t1.rule_0_Id)); 123 124 // try to create a duplicate Rule 125 try { 126 RuleDefinition ruleSecondCreate = ruleManagementService.createRule(ruleFirstCreate); 127 fail("should have thrown RiceIllegalArgumentException"); 128 } catch (RiceIllegalArgumentException e) { 129 // throw new RiceIllegalArgumentException(ruleDefinition.getId()); 130 } 131 132 // try to create a malformed Rule 133 RuleDefinition malformedRule = buildTestRuleDefinition(t1.namespaceName, t1.object1); 134 RuleDefinition.Builder builder = RuleDefinition.Builder.create(malformedRule); 135 builder.setPropId("invalidValue"); 136 malformedRule = builder.build(); 137 try { 138 ruleManagementService.createRule(malformedRule); 139 fail("should have thrown RiceIllegalArgumentException"); 140 } catch (RiceIllegalArgumentException e) { 141 // throw new RiceIllegalArgumentException("propId does not match proposition.getId" 142 } 143 } 144 145 /** 146 * Test testUpdateRule() 147 * 148 * This test focuses specifically on the RuleManagementServiceImpl .updateRule(RuleDefinition) method 149 */ 150 @Test 151 public void testUpdateRule() { 152 // get a set of unique object names for use by this test (discriminator passed can be any unique value within this class) 153 RuleManagementBaseTestObjectNames t2 = new RuleManagementBaseTestObjectNames( CLASS_DISCRIMINATOR, "t2"); 154 155 // build a rule to test with 156 RuleDefinition.Builder ruleBuilder0 = RuleDefinition.Builder.create(buildTestRuleDefinition(t2.namespaceName, 157 t2.object0)); 158 159 // update the rule's Name 160 ruleBuilder0.setName("updatedName"); 161 ruleManagementService.updateRule(ruleBuilder0.build()); 162 163 // verify update 164 RuleDefinition rule0 = ruleManagementService.getRule(t2.rule_0_Id); 165 assertNotEquals("Rule Name Not Updated", t2.rule_0_Name, rule0.getName()); 166 assertEquals("Rule Name Not Updated", "updatedName", rule0.getName()); 167 168 // build new rule for test 169 RuleDefinition.Builder ruleBuilder1 = RuleDefinition.Builder.create(buildTestRuleDefinition(t2.namespaceName, 170 t2.object1)); 171 assertEquals("Expected Proposition not found in Rule",t2.proposition_1_Descr,ruleBuilder1.getProposition().getDescription()); 172 173 // create new proposition to update rule with 174 String newPropId = "PropNewId"; 175 PropositionDefinition prop = createTestSimpleProposition(t2.namespaceName, newPropId, "TSI_"+newPropId, 176 "ABC", "=", "java.lang.String", t2.rule_0_Id, "TSI_" + newPropId + "_Descr"); 177 PropositionDefinition.Builder propBuilder = PropositionDefinition.Builder.create(prop); 178 ruleBuilder1.setPropId(newPropId); 179 ruleBuilder1.setProposition(propBuilder); 180 181 // Update Proposition in rule 182 ruleManagementService.updateRule(ruleBuilder1.build()); 183 rule0 = ruleManagementService.getRule(ruleBuilder1.getId()); 184 assertEquals("Expected Proposition not found in Rule","PropNewId_simple_proposition",rule0.getProposition().getDescription()); 185 186 // build new rule for test 187 RuleDefinition.Builder ruleBuilder2 = RuleDefinition.Builder.create(buildTestRuleDefinition(t2.namespaceName,t2.object7)); 188 createTestKrmsAttribute(t2.actionAttribute, t2.actionAttribute_Key, t2.namespaceName); 189 Map<String, String> attributes = new HashMap<String, String>(); 190 attributes.put(t2.actionAttribute_Key, t2.actionAttribute_Value); 191 List<ActionDefinition.Builder> actionBuilders = new ArrayList<ActionDefinition.Builder>(); 192 KrmsTypeDefinition krmsTypeDefinition = createKrmsActionTypeDefinition(t2.namespaceName); 193 ActionDefinition.Builder actionBuilder = ActionDefinition.Builder.create(t2.action_Id, t2.action_Name, 194 t2.namespaceName, krmsTypeDefinition.getId(), rule0.getId(), 1); 195 actionBuilder.setDescription(t2.action_Descr); 196 actionBuilder.setAttributes(attributes); 197 actionBuilders.add(actionBuilder); 198 ruleBuilder2.setActions(actionBuilders); 199 ruleManagementService.updateRule(ruleBuilder2.build()); 200 201 // Update Action in rule 202 ruleBuilder2 = RuleDefinition.Builder.create(ruleManagementService.getRule(t2.rule_7_Id)); 203 Map<String, String> newAttributes = new HashMap<String, String>(); 204 newAttributes.put(t2.actionAttribute_Key, t2.actionAttribute1_Value); 205 for (ActionDefinition.Builder ruleActionBuilder : ruleBuilder2.getActions()) { 206 ruleActionBuilder.setAttributes(newAttributes); 207 } 208 ruleManagementService.updateRule(ruleBuilder2.build()); 209 rule0 = ruleManagementService.getRule(t2.rule_7_Id); 210 assertEquals("Invalid AgendaItem Rule Actions count",1,rule0.getActions().size()); 211 for (ActionDefinition action : rule0.getActions()) { 212 Map<String, Object> map = new HashMap<String, Object>(); 213 map.put("actionId", action.getId()); 214 Collection<ActionAttributeBo> actionAttributes = businessObjectService.findMatching(ActionAttributeBo.class, map); 215 assertEquals("Invalid AgendaItem Rule Actions attribute count",1,actionAttributes.size()); 216 for (ActionAttributeBo actionAttribute : actionAttributes) { 217 String expectedAttribute = t2.actionAttribute1_Value; 218 String actualAttribute = actionAttribute.getValue(); 219 assertEquals("Invalid AgendaItem Rule Actions attribute",expectedAttribute,actualAttribute); 220 } 221 } 222 } 223 224 /** 225 * Test testDeleteRule() 226 * 227 * This test focuses specifically on the RuleManagementServiceImpl .deleteRule("rule id") method 228 */ 229 @Test 230 public void testDeleteRule() { 231 // get a set of unique object names for use by this test (discriminator passed can be any unique value within this class) 232 RuleManagementBaseTestObjectNames t3 = new RuleManagementBaseTestObjectNames( CLASS_DISCRIMINATOR, "t3"); 233 234 // create a Rule 235 RuleDefinition rule = buildTestRuleDefinition(t3.namespaceName, t3.object0); 236 assertTrue("created Rule not found", ruleManagementService.getRule(rule.getId()).getId().contains(t3.rule_0_Id)); 237 String propositionId = rule.getPropId(); 238 assertEquals("Proposition for Rule not found", t3.proposition_0_Descr, 239 ruleManagementService.getProposition(propositionId).getDescription()); 240 241 242 ruleManagementService.deleteRule(rule.getId()); 243 244 assertNull("Rule was not deleted", ruleManagementService.getRule(rule.getId())); 245 246 // make sure proposition was cleaned up when rule was deleted 247 try { 248 ruleManagementService.deleteProposition(propositionId); 249 fail("should fail with IllegalStateException: the Proposition to delete does not exists"); 250 } catch (IllegalStateException e) { 251 // IllegalStateException: the Proposition to delete does not exists 252 } 253 } 254 255 /** 256 * Test testFindRuleIds() 257 * 258 * This test focuses specifically on the RuleManagementServiceImpl .findRuleIds( QueryByCriteria) method 259 */ 260 @Test 261 public void testFindRuleIds() { 262 // get a set of unique object names for use by this test (discriminator passed can be any unique value within this class) 263 RuleManagementBaseTestObjectNames t4 = new RuleManagementBaseTestObjectNames( CLASS_DISCRIMINATOR, "t4"); 264 265 RuleDefinition rule0 = buildTestRuleDefinition(t4.namespaceName, t4.object0); 266 RuleDefinition rule1 = buildTestRuleDefinition(t4.namespaceName, t4.object1); 267 RuleDefinition rule2 = buildTestRuleDefinition(t4.namespaceName, t4.object2); 268 RuleDefinition rule3 = buildTestRuleDefinition(t4.namespaceName, t4.object3); 269 String ruleNameSpace = rule0.getNamespace(); 270 List<String> ruleNames = new ArrayList<String>(); 271 ruleNames.add(rule0.getName()); 272 ruleNames.add(rule1.getName()); 273 ruleNames.add(rule2.getName()); 274 ruleNames.add(rule3.getName()); 275 276 QueryByCriteria.Builder builder = QueryByCriteria.Builder.create(); 277 278 builder.setPredicates(equal("namespace", ruleNameSpace), in("name", ruleNames.toArray(new String[]{}))); 279 280 List<String> ruleIds = ruleManagementService.findRuleIds(builder.build()); 281 assertEquals("Wrong number of RuleIds returned", 4, ruleIds.size()); 282 283 if(!ruleIds.contains(rule0.getId())){ 284 fail("RuleId not found in results"); 285 } 286 } 287 288 /** 289 * Test testGetRule() 290 * 291 * This test focuses specifically on the RuleManagementServiceImpl .getRule("rule id") method 292 */ 293 @Test 294 public void testGetRule() { 295 // get a set of unique object names for use by this test (discriminator passed can be any unique value within this class) 296 RuleManagementBaseTestObjectNames t5 = new RuleManagementBaseTestObjectNames( CLASS_DISCRIMINATOR, "t5"); 297 298 // create a rule to test with 299 RuleDefinition ruleDefinition = buildTestRuleDefinition(t5.namespaceName, t5.object0); 300 301 assertNotNull(ruleManagementService.getRule(ruleDefinition.getId())); 302 303 assertNull("Should have returned null", ruleManagementService.getRule(null)); 304 assertNull("Should have returned null", ruleManagementService.getRule(" ")); 305 assertNull("Should have returned null", ruleManagementService.getRule("badValueId")); 306 } 307 308 /** 309 * Test testGetRules() 310 * 311 * This test focuses specifically on the RuleManagementServiceImpl .getRules(List<String> ruleIds) method 312 */ 313 @Test 314 public void testGetRules() { 315 // get a set of unique object names for use by this test (discriminator passed can be any unique value within this class) 316 RuleManagementBaseTestObjectNames t6 = new RuleManagementBaseTestObjectNames( CLASS_DISCRIMINATOR, "t6"); 317 318 // build two rules for testing 319 buildTestRuleDefinition(t6.namespaceName, t6.object0); 320 buildTestRuleDefinition(t6.namespaceName, t6.object1); 321 322 // build List rule ids for the rules created 323 List<String> ruleIds = new ArrayList<String>(); 324 ruleIds.add(t6.rule_0_Id); 325 ruleIds.add(t6.rule_1_Id); 326 327 // get test rules by List of rule ids 328 List<RuleDefinition> ruleDefinitions = ruleManagementService.getRules(ruleIds); 329 assertEquals("Two RuleDefintions should have been returned",2,ruleDefinitions.size()); 330 331 for(RuleDefinition ruleDefinition : ruleDefinitions) { 332 if (!ruleIds.contains(ruleDefinition.getId())) { 333 fail("Invalid RuleDefinition returned"); 334 } 335 } 336 337 try { 338 ruleManagementService.getRules(null); 339 fail("Should have failed with RiceIllegalArgumentException: ruleIds must not be null"); 340 } catch (RiceIllegalArgumentException e) { 341 // throws RiceIllegalArgumentException: ruleIds must not be null 342 } 343 344 assertEquals("No RuleDefinitions should have been returned",0, 345 ruleManagementService.getRules(new ArrayList<String>()).size()); 346 347 ruleIds = Arrays.asList("badValueId"); 348 assertEquals("No RuleDefinitions should have been returned",0, ruleManagementService.getRules(ruleIds).size()); 349 } 350 351 /** 352 * Tests whether the {@code RuleDefinition} cache is being evicted properly by checking the status the dependent 353 * objects before and after creating an {@code RuleDefinition} (and consequently emptying the cache). 354 * 355 * <p> 356 * The following object caches are affected: 357 * {@code RuleDefinition}, {@code PropositionDefinition}, {@code ActionDefinition}, {@code AgendaItemDefinition} 358 * </p> 359 */ 360 @Test 361 public void testRuleCacheEvict() { 362 // get a set of unique object names for use by this test (discriminator passed can be any unique value within this class) 363 RuleManagementBaseTestObjectNames t7 = new RuleManagementBaseTestObjectNames( CLASS_DISCRIMINATOR, "t7"); 364 365 verifyEmptyRule(t7); 366 367 String ruleId = buildTestRuleDefinition(t7.namespaceName, t7.object0).getId(); 368 buildTestActionDefinition(t7.action_Id, t7.action_Name, t7.action_Descr, 1, ruleId, t7.namespaceName); 369 String agendaId = createTestAgenda(t7.object0).getId(); 370 buildTestAgendaItemDefinition(t7.agendaItem_Id, agendaId, ruleId); 371 372 verifyFullRule(t7); 373 } 374 375 private void verifyEmptyRule(RuleManagementBaseTestObjectNames t) { 376 RuleDefinition rule = ruleManagementService.getRule(t.rule_Id); 377 assertNull("Rule is not null", rule); 378 379 Set<PropositionDefinition> propositions = ruleManagementService.getPropositionsByRule(t.rule_Id); 380 assertFalse("Rule in Proposition found", propositions != null && !propositions.isEmpty()); 381 382 ActionDefinition action = ruleManagementService.getAction(t.action_Id); 383 assertFalse("Rule in Action found", action != null); 384 385 AgendaItemDefinition agendaItem = ruleManagementService.getAgendaItem(t.agendaItem_Id); 386 assertFalse("Rule in AgendaItem found", agendaItem != null); 387 } 388 389 private void verifyFullRule(RuleManagementBaseTestObjectNames t) { 390 RuleDefinition rule = ruleManagementService.getRule(t.rule_Id); 391 assertNotNull("Rule is null", rule); 392 393 boolean foundRule = false; 394 Set<PropositionDefinition> propositions = ruleManagementService.getPropositionsByRule(t.rule_Id); 395 if (propositions != null) { 396 for (PropositionDefinition proposition : propositions) { 397 if (StringUtils.equals(t.rule_Id, proposition.getRuleId())) { 398 foundRule = true; 399 break; 400 } 401 } 402 } 403 assertTrue("Rule in Proposition not found", foundRule); 404 405 ActionDefinition action = ruleManagementService.getAction(t.action_Id); 406 assertTrue("Rule in Action not found", action != null); 407 assertTrue("Rule in Action not found", StringUtils.equals(t.rule_Id, action.getRuleId())); 408 409 AgendaItemDefinition agendaItem = ruleManagementService.getAgendaItem(t.agendaItem_Id); 410 assertTrue("Rule in AgendaItem not found", agendaItem != null); 411 assertTrue("Rule in AgendaItem not found", StringUtils.equals(t.rule_Id, agendaItem.getRuleId())); 412 } 413}