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
017 package org.kuali.rice.krms.test;
018
019 import org.apache.commons.lang.StringUtils;
020 import org.junit.Before;
021 import org.junit.Test;
022 import org.kuali.rice.core.api.criteria.QueryByCriteria;
023 import org.kuali.rice.core.api.exception.RiceIllegalArgumentException;
024 import org.kuali.rice.krms.api.repository.LogicalOperator;
025 import org.kuali.rice.krms.api.repository.proposition.PropositionDefinition;
026 import org.kuali.rice.krms.api.repository.proposition.PropositionParameter;
027 import org.kuali.rice.krms.api.repository.proposition.PropositionType;
028 import org.kuali.rice.krms.api.repository.rule.RuleDefinition;
029
030 import java.util.ArrayList;
031 import java.util.Arrays;
032 import java.util.List;
033 import java.util.Set;
034
035 import static org.junit.Assert.*;
036 import static org.kuali.rice.core.api.criteria.PredicateFactory.equal;
037
038 /**
039 * RuleManagementPropositionDefinitionTest is to test the methods of ruleManagementServiceImpl relating to PropositionDefinitions
040 *
041 * Each test focuses on one of the methods.
042 */
043 public class RuleManagementPropositionDefinitionTest extends RuleManagementBaseTest {
044 @Override
045 @Before
046 public void setClassDiscriminator() {
047 // set a unique class discriminator for test objects of this class
048 CLASS_DISCRIMINATOR = "RMPDT";
049 }
050
051 /**
052 * Test testCreateProposition()
053 *
054 * This test focuses specifically on the RuleManagementServiceImpl .createProposition(PropositionDefinition) method
055 */
056 @Test
057 public void testCreateProposition() {
058 // get a set of unique object names for use by this test (discriminator passed can be any unique value within this class)
059 RuleManagementBaseTestObjectNames t0 = new RuleManagementBaseTestObjectNames( CLASS_DISCRIMINATOR, "t0");
060
061 PropositionDefinition propositionDefinition = createTestSimpleProposition(
062 t0.namespaceName, t0.proposition_0_Id, "campusCode", "BL", "=", "java.lang.String", t0.rule_0_Id, "Campus Code");
063
064 assertEquals("created Proposition not found", t0.rule_0_Id, propositionDefinition.getRuleId());
065
066 try {
067 // returnPropositionDefinition has existing propositionId
068 ruleManagementService.createProposition(propositionDefinition);
069 fail("should throw exception if trying to create and already exists");
070 } catch (RiceIllegalArgumentException e) {
071 // throw new RiceIllegalArgumentException(propositionDefinition.getId());
072 }
073 }
074
075 /**
076 * Test testCompoundCreateProposition()
077 *
078 * This test focuses specifically on the RuleManagementServiceImpl .createProposition(PropositionDefinition) method
079 */
080 @Test
081 public void testCompoundCreateProposition() {
082 // get a set of unique object names for use by this test (discriminator passed can be any unique value within this class)
083 RuleManagementBaseTestObjectNames t1 = new RuleManagementBaseTestObjectNames( CLASS_DISCRIMINATOR, "t1");
084
085 // **************************
086 // Create a complex Compound Proposition (True if Account is 54321 and Occasion is either a Conference or Training)
087 // ***************************
088 // C1_compound_proposition "COMPOUND" "S1_simple_proposition" "C2_compound_proposition" "&"
089 // S1_simple_proposition "SIMPLE" "Account" "54321" "="
090 // C2_compound_proposition "COMPOUND" "S2_simple_proposition" "S2_simple_proposition" "|"
091 // S2_simple_proposition "SIMPLE" "Occasion" "Conference" "="
092 // S3_simple_proposition "SIMPLE" "Occasion" "Training" "="
093
094 PropositionDefinition propS3 = createTestSimpleProposition(
095 t1.namespaceName, "S3", "Occasion", "Training", "=", "java.lang.String", t1.rule_0_Id, "Special Event");
096 PropositionDefinition.Builder propBuilderS3 = PropositionDefinition.Builder.create(propS3);
097
098 PropositionDefinition propS2 = createTestSimpleProposition(
099 t1.namespaceName, "S2", "Occasion", "Conference", "=", "java.lang.String", t1.rule_0_Id, "Special Event");
100 PropositionDefinition.Builder propBuilderS2 = PropositionDefinition.Builder.create(propS2);
101
102 PropositionDefinition propS1 = createTestSimpleProposition(
103 t1.namespaceName, "S1", "Account", "54321", "=", "java.lang.String", t1.rule_0_Id, "Charged To Account");
104 PropositionDefinition.Builder propBuilderS1 = PropositionDefinition.Builder.create(propS1);
105
106 PropositionDefinition.Builder propBuilderC2 = PropositionDefinition.Builder.create(
107 null,PropositionType.COMPOUND.getCode(),t1.rule_0_Id,null,new ArrayList<PropositionParameter.Builder>());
108
109 propBuilderC2.compoundOpCode(LogicalOperator.OR.getCode());
110 List<PropositionDefinition.Builder> compoundComponentsC2 = new ArrayList<PropositionDefinition.Builder>();
111 compoundComponentsC2.add(propBuilderS2);
112 compoundComponentsC2.add(propBuilderS3);
113 propBuilderC2.setCompoundComponents(compoundComponentsC2);
114 propBuilderC2.setDescription("C2_compound_proposition");
115
116 PropositionDefinition.Builder propBuilderC1 = PropositionDefinition.Builder.create(
117 null,PropositionType.COMPOUND.getCode(),t1.rule_0_Id,null,new ArrayList<PropositionParameter.Builder>());
118
119 propBuilderC1.compoundOpCode(LogicalOperator.AND.getCode());
120 List<PropositionDefinition.Builder> compoundComponentsC1 = new ArrayList<PropositionDefinition.Builder>();
121 compoundComponentsC1.add(propBuilderS1);
122 compoundComponentsC1.add(propBuilderC2);
123 propBuilderC1.setCompoundComponents(compoundComponentsC1);
124 propBuilderC1.setDescription("C1_compound_proposition");
125 PropositionDefinition propC1 = ruleManagementService.createProposition(propBuilderC1.build());
126
127 propC1 = ruleManagementService.getProposition(propC1.getId());
128 assertEquals("proposition not in database","C1_compound_proposition",propC1.getDescription());
129
130 List<String> propositionDescrs = Arrays.asList("C1_compound_proposition", "C2_compound_proposition",
131 "S1_simple_proposition", "S2_simple_proposition", "S3_simple_proposition");
132
133 Set<PropositionDefinition> propsFound = ruleManagementService.getPropositionsByRule(t1.rule_0_Id);
134 for (PropositionDefinition propTemp : propsFound) {
135 assertTrue(propositionDescrs.contains(propTemp.getDescription()));
136 }
137
138 assertEquals("invalid number of propositions found for ruleId", 5, propsFound.size());
139 }
140
141 /**
142 * Test testGetProposition()
143 *
144 * This test focuses specifically on the RuleManagementServiceImpl .getProposition("proposition id") method
145 */
146 @Test
147 public void testGetProposition() {
148 // get a set of unique object names for use by this test (discriminator passed can be any unique value within this class)
149 RuleManagementBaseTestObjectNames t2 = new RuleManagementBaseTestObjectNames( CLASS_DISCRIMINATOR, "t2");
150
151 PropositionDefinition propositionDefinition = createTestPropositionForRule(t2.object0);
152
153 PropositionDefinition returnPropositionDefinition = ruleManagementService.getProposition(propositionDefinition.getId());
154
155 // match ruleIds from returned proposition returned by get by propositionId
156 assertEquals("", propositionDefinition.getRuleId(), returnPropositionDefinition.getRuleId());
157
158 try {
159 ruleManagementService.getProposition(null);
160 fail("should throw RiceIllegalArgumentException");
161 } catch (RiceIllegalArgumentException e) {
162 // throw new RiceIllegalArgumentException (id);
163 }
164 }
165
166 /**
167 * Test testGetPropositionsByType()
168 *
169 * This test focuses specifically on the RuleManagementServiceImpl .getPropositionsByType("proposition type id") method
170 */
171 @Test
172 public void testGetPropositionsByType() {
173 // get a set of unique object names for use by this test (discriminator passed can be any unique value within this class)
174 RuleManagementBaseTestObjectNames t3 = new RuleManagementBaseTestObjectNames( CLASS_DISCRIMINATOR, "t3");
175
176 PropositionDefinition propositionDefinition = createTestPropositionForRule(t3.object0);
177
178 Set<PropositionDefinition> propositionDefinitionSet = ruleManagementService.getPropositionsByType(propositionDefinition.getTypeId());
179
180 boolean propositionFound = false;
181 for ( PropositionDefinition pd : propositionDefinitionSet ) {
182 if (pd.getId().equals(propositionDefinition.getId())){
183 assertEquals("unexpected PropositionTypeId returned",propositionDefinition.getTypeId(),pd.getTypeId());
184 propositionFound = true;
185 }
186 }
187
188 assertTrue("proposition not found by PropositionTypeId",propositionFound);
189 }
190
191 /**
192 * Test testGetPropositionsByRule()
193 *
194 * This test focuses specifically on the RuleManagementServiceImpl .getPropositionsByRule("rule id") method
195 */
196 @Test
197 public void testGetPropositionsByRule() {
198 // get a set of unique object names for use by this test (discriminator passed can be any unique value within this class)
199 RuleManagementBaseTestObjectNames t4 = new RuleManagementBaseTestObjectNames( CLASS_DISCRIMINATOR, "t4");
200
201 PropositionDefinition propositionDefinition = createTestPropositionForRule(t4.object0);
202
203 Set<PropositionDefinition> propositionDefinitionSet = ruleManagementService.getPropositionsByRule(
204 propositionDefinition.getRuleId());
205
206 boolean propositionFound = false;
207 for ( PropositionDefinition pd : propositionDefinitionSet ) {
208 if (pd.getId().equals(propositionDefinition.getId())){
209 propositionFound = true;
210 }
211 }
212
213 assertTrue("proposition not found by RuleId",propositionFound);
214 }
215
216 /**
217 * Test testUpdateProposition()
218 *
219 * This test focuses specifically on the RuleManagementServiceImpl .updateProposition(PropositionDefinition) method
220 */
221 @Test
222 public void testUpdateProposition() {
223 // get a set of unique object names for use by this test (discriminator passed can be any unique value within this class)
224 RuleManagementBaseTestObjectNames t5 = new RuleManagementBaseTestObjectNames( CLASS_DISCRIMINATOR, "t5");
225
226 PropositionDefinition propositionDefinition = createTestPropositionForRule(t5.object0);
227 PropositionDefinition.Builder builder = PropositionDefinition.Builder.create(propositionDefinition);
228 builder.setDescription("UpdatedDescription");
229 builder.setPropositionTypeCode(PropositionType.COMPOUND.getCode());
230
231 // focus of test is on this instruction
232 ruleManagementService.updateProposition(builder.build());
233
234 PropositionDefinition returnPropositionDefinition = ruleManagementService.getProposition(propositionDefinition.getId());
235
236 assertEquals("description was not updated", "UpdatedDescription", returnPropositionDefinition.getDescription());
237 assertEquals("propositionType was not updated", PropositionType.COMPOUND.getCode(), returnPropositionDefinition.getPropositionTypeCode());
238 }
239
240 /**
241 * Test testDeleteProposition()
242 *
243 * This test focuses specifically on the RuleManagementServiceImpl .deleteProposition("proposition id") method
244 */
245 @Test
246 public void testDeleteProposition() {
247 // get a set of unique object names for use by this test (discriminator passed can be any unique value within this class)
248 RuleManagementBaseTestObjectNames t6 = new RuleManagementBaseTestObjectNames( CLASS_DISCRIMINATOR, "t6");
249
250 PropositionDefinition propositionDefinition = createTestPropositionForRule(t6.object0);
251
252 ruleManagementService.deleteProposition(propositionDefinition.getId());
253
254 assertTrue("proposition should have been deleted", ruleManagementService.getPropositionsByRule(propositionDefinition.getRuleId()).isEmpty());
255
256 try {
257 ruleManagementService.deleteProposition(propositionDefinition.getId());
258 fail("should fail with IllegalStateException: the Proposition to delete does not exists");
259 } catch (IllegalStateException e) {
260 // IllegalStateException: the Proposition to delete does not exists
261 }
262 }
263
264 /**
265 * Test testFindPropositionIds()
266 *
267 * This test focuses specifically on the RuleManagementServiceImpl .findPropositionIds(QueryByCriteria) method
268 */
269 @Test
270 public void testFindPropositionIds() {
271 // get a set of unique object names for use by this test (discriminator passed can be any unique value within this class)
272 RuleManagementBaseTestObjectNames t6 = new RuleManagementBaseTestObjectNames( CLASS_DISCRIMINATOR, "t6");
273
274 List<String> propositionIds = Arrays.asList(
275 createTestPropositionForRule(t6.object0).getId(),
276 createTestPropositionForRule(t6.object1).getId(),
277 createTestPropositionForRule(t6.object2).getId(),
278 createTestPropositionForRule(t6.object3).getId());
279
280 for (String propositionId : propositionIds) {
281 PropositionDefinition.Builder builder = PropositionDefinition.Builder.create(
282 ruleManagementService.getProposition(propositionId));
283 builder.setDescription("targetOfQuery");
284 ruleManagementService.updateProposition(builder.build());
285 }
286
287 QueryByCriteria.Builder query = QueryByCriteria.Builder.create();
288 query.setPredicates(equal("description", "targetOfQuery"));
289
290 List<String> returnedPropositionIds = ruleManagementService.findPropositionIds(query.build());
291
292 for (String returnedPropositionId : returnedPropositionIds ) {
293 assertTrue(propositionIds.contains(returnedPropositionId));
294 }
295
296 assertEquals("incorrect number of Propositions found", 4, returnedPropositionIds.size());
297 }
298
299 /**
300 * Tests whether the {@code PropositionDefinition} cache is being evicted properly by checking the status the
301 * dependent objects before and after creating an {@code PropositionDefinition} (and consequently emptying the cache).
302 *
303 * <p>
304 * The following object caches are affected:
305 * {@code PropositionDefinition}, {@code RuleDefinition}
306 * </p>
307 */
308 @Test
309 public void testPropositionCacheEvict() {
310 // get a set of unique object names for use by this test (discriminator passed can be any unique value within this class)
311 RuleManagementBaseTestObjectNames t7 = new RuleManagementBaseTestObjectNames( CLASS_DISCRIMINATOR, "t7");
312
313 verifyEmptyProposition(t7);
314
315 // Proposition is built as part of a Rule
316 buildTestRuleDefinition(t7.namespaceName, t7.object0);
317
318 verifyFullProposition(t7);
319 }
320
321 private void verifyEmptyProposition(RuleManagementBaseTestObjectNames t) {
322 Set<PropositionDefinition> propositions = ruleManagementService.getPropositionsByRule(t.rule_Id);
323 assertFalse("Proposition is not null", propositions != null && !propositions.isEmpty());
324
325 RuleDefinition rule = ruleManagementService.getRule(t.rule_Id);
326 assertFalse("Proposition in Rule found", rule != null);
327 }
328
329 private void verifyFullProposition(RuleManagementBaseTestObjectNames t) {
330 Set<PropositionDefinition> propositions = ruleManagementService.getPropositionsByRule(t.rule_Id);
331 assertTrue("Proposition is not null", propositions != null && !propositions.isEmpty());
332
333 String propositionId = new ArrayList<PropositionDefinition>(propositions).get(0).getId();
334
335 RuleDefinition rule = ruleManagementService.getRule(t.rule_Id);
336 assertTrue("Proposition in Rule not found", rule != null);
337 assertTrue("Proposition in Rule not found", StringUtils.equals(propositionId, rule.getPropId()));
338 }
339 }