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  
17  package org.kuali.rice.krms.test;
18  
19  import org.apache.commons.lang.StringUtils;
20  import org.junit.Before;
21  import org.junit.Test;
22  import org.kuali.rice.core.api.criteria.QueryByCriteria;
23  import org.kuali.rice.core.api.exception.RiceIllegalArgumentException;
24  import org.kuali.rice.krms.api.repository.LogicalOperator;
25  import org.kuali.rice.krms.api.repository.proposition.PropositionDefinition;
26  import org.kuali.rice.krms.api.repository.proposition.PropositionParameter;
27  import org.kuali.rice.krms.api.repository.proposition.PropositionType;
28  import org.kuali.rice.krms.api.repository.rule.RuleDefinition;
29  
30  import java.util.ArrayList;
31  import java.util.Arrays;
32  import java.util.List;
33  import java.util.Set;
34  
35  import static org.junit.Assert.*;
36  import static org.kuali.rice.core.api.criteria.PredicateFactory.equal;
37  
38  /**
39   *   RuleManagementPropositionDefinitionTest is to test the methods of ruleManagementServiceImpl relating to PropositionDefinitions
40   *
41   *   Each test focuses on one of the methods.
42   */
43  public class RuleManagementPropositionDefinitionTest extends RuleManagementBaseTest {
44      @Override
45      @Before
46      public void setClassDiscriminator() {
47          // set a unique class discriminator for test objects of this class
48          CLASS_DISCRIMINATOR = "RMPDT";
49      }
50  
51      /**
52       *  Test testCreateProposition()
53       *
54       *  This test focuses specifically on the RuleManagementServiceImpl .createProposition(PropositionDefinition) method
55       */
56      @Test
57      public void testCreateProposition() {
58          // get a set of unique object names for use by this test (discriminator passed can be any unique value within this class)
59          RuleManagementBaseTestObjectNames t0 =  new RuleManagementBaseTestObjectNames( CLASS_DISCRIMINATOR, "t0");
60  
61          PropositionDefinition propositionDefinition = createTestSimpleProposition(
62                  t0.namespaceName, t0.proposition_0_Id, "campusCode", "BL", "=", "java.lang.String", t0.rule_0_Id, "Campus Code");
63  
64          assertEquals("created Proposition not found", t0.rule_0_Id, propositionDefinition.getRuleId());
65  
66          try {
67              // returnPropositionDefinition has existing propositionId
68              ruleManagementService.createProposition(propositionDefinition);
69              fail("should throw exception if trying to create and already exists");
70          } catch (RiceIllegalArgumentException e) {
71              //  throw new RiceIllegalArgumentException(propositionDefinition.getId());
72          }
73      }
74  
75      /**
76       *  Test testCompoundCreateProposition()
77       *
78       *  This test focuses specifically on the RuleManagementServiceImpl .createProposition(PropositionDefinition) method
79       */
80      @Test
81      public void testCompoundCreateProposition() {
82          // get a set of unique object names for use by this test (discriminator passed can be any unique value within this class)
83          RuleManagementBaseTestObjectNames t1 =  new RuleManagementBaseTestObjectNames( CLASS_DISCRIMINATOR, "t1");
84  
85          // **************************
86          // Create a complex Compound Proposition (True if Account is 54321 and Occasion is either a Conference or Training)
87          // ***************************
88          //  C1_compound_proposition            "COMPOUND" "S1_simple_proposition"  "C2_compound_proposition" "&"
89          //      S1_simple_proposition          "SIMPLE"   "Account"                "54321"                   "="
90          //      C2_compound_proposition        "COMPOUND" "S2_simple_proposition"  "S2_simple_proposition"   "|"
91          //          S2_simple_proposition      "SIMPLE"   "Occasion"               "Conference"              "="
92          //          S3_simple_proposition      "SIMPLE"   "Occasion"               "Training"                "="
93  
94          PropositionDefinition propS3 = createTestSimpleProposition(
95                  t1.namespaceName, "S3", "Occasion", "Training", "=", "java.lang.String", t1.rule_0_Id, "Special Event");
96          PropositionDefinition.Builder propBuilderS3 = PropositionDefinition.Builder.create(propS3);
97  
98          PropositionDefinition propS2 = createTestSimpleProposition(
99                  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 }