1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.kuali.rice.kew.rule.xmlrouting;
18
19 import java.io.BufferedReader;
20 import java.io.StringReader;
21 import java.util.ArrayList;
22 import java.util.HashMap;
23 import java.util.Iterator;
24 import java.util.List;
25 import java.util.Map;
26
27 import javax.xml.parsers.DocumentBuilderFactory;
28 import javax.xml.xpath.XPath;
29 import javax.xml.xpath.XPathConstants;
30 import javax.xml.xpath.XPathFactory;
31
32 import org.junit.Test;
33 import org.kuali.rice.kew.dto.NetworkIdDTO;
34 import org.kuali.rice.kew.dto.WorkflowAttributeDefinitionDTO;
35 import org.kuali.rice.kew.exception.WorkflowException;
36 import org.kuali.rice.kns.web.ui.Field;
37 import org.kuali.rice.kns.web.ui.Row;
38 import org.kuali.rice.kew.routeheader.DocumentContent;
39 import org.kuali.rice.kew.routeheader.StandardDocumentContent;
40 import org.kuali.rice.kew.rule.RuleExtension;
41 import org.kuali.rice.kew.rule.RuleExtensionValue;
42 import org.kuali.rice.kew.rule.bo.RuleAttribute;
43 import org.kuali.rice.kew.rule.bo.RuleTemplateAttribute;
44 import org.kuali.rice.kew.rule.xmlrouting.StandardGenericXMLRuleAttribute;
45 import org.kuali.rice.kew.service.WorkflowDocument;
46 import org.kuali.rice.kew.test.KEWTestCase;
47 import org.w3c.dom.Element;
48 import org.xml.sax.InputSource;
49
50
51 public class StandardGenericXMLRuleAttributeTest extends KEWTestCase {
52
53 private DocumentContent docContent;
54 private StandardGenericXMLRuleAttribute attribute;
55 private List extensions;
56
57 public void setUp() throws Exception {
58 super.setUp();
59 attribute = new StandardGenericXMLRuleAttribute();
60 String documentcontent =
61 "<documentContent>" +
62 "<attributeContent>"+
63 "<xmlContent>"+
64 "<fieldDef name=\"givenname\">"+
65 "<value>Dave</value>"+
66 "</fieldDef>"+
67 "<fieldDef name=\"gender\">"+
68 "<value>female</value>"+
69 "</fieldDef>"+
70 "<fieldDef name=\"color\">"+
71 "<value>green</value>"+
72 "</fieldDef>"+
73 "<fieldDef name=\"totalDollar\">"+
74 "<value>500</value>"+
75 "</fieldDef>"+
76 "</xmlContent>"+
77 "<xmlContent>"+
78 "<fieldDef name=\"givenname\">"+
79 "<value>Jane</value>"+
80 "</fieldDef>"+
81 "<fieldDef name=\"gender\">"+
82 "<value>female</value>"+
83 "</fieldDef>"+
84 "<fieldDef name=\"color\">"+
85 "<value>blue</value>"+
86 "</fieldDef>"+
87 "<fieldDef name=\"totalDollar\">"+
88 "<value>400</value>"+
89 "</fieldDef>"+
90 "</xmlContent>"+
91 "</attributeContent>"+
92 "</documentContent>";
93
94 String routingConfig =
95 "<routingConfig>"+
96 "<globalEvaluations>" +
97 "<xpathexpression>//fieldDef/value != 'Nothing'</xpathexpression>" +
98 "</globalEvaluations>"+
99
100 "<fieldDef name=\"givenname\" title=\"First name\" workflowType=\"ALL\">"+
101 "<value>Joe</value>"+
102 "<display>"+
103 "<type>text</type>"+
104 "<meta><name>size</name><value>20</value></meta>"+
105 "</display>" +
106 "<validation required=\"true\">"+
107 "<regex>^[a-zA-Z ]+$</regex>"+
108 "<message>Invalid first name</message>"+
109 "</validation>"+
110 "<fieldEvaluation><xpathexpression>//xmlContent/fieldDef[@name='givenname']/value = wf:ruledata('givenname')</xpathexpression></fieldEvaluation>"+
111 "</fieldDef>"+
112 "<fieldDef name=\"gender\" title=\"Gender\" workflowType=\"ALL\">"+
113 "<value>male</value>"+
114 "<display>"+
115 "<type>radio</type>"+
116 "<values title=\"Male\">male</values>"+
117 "<values title=\"Female\">female</values>"+
118 "</display>"+
119 "<validation required=\"true\">" +
120 "<regex>(male|female)</regex>"+
121 "<message>Invalid gender</message>"+
122 "</validation>"+
123 "<fieldEvaluation><xpathexpression>//xmlContent/fieldDef[@name='gender']/value = wf:ruledata('gender')</xpathexpression></fieldEvaluation>"+
124 "</fieldDef>"+
125 "<fieldDef name=\"color\" title=\"Color\" workflowType=\"ALL\">" +
126 "<value>blue</value>" +
127 "<display>" +
128 "<type>select</type>" +
129 "<values title=\"Red\">red</values>" +
130 "<values title=\"Green\">green</values>" +
131 "<values title=\"Blue\" selected=\"true\">blue</values>" +
132 "</display>" +
133 "<validation required=\"true\">"+
134 "<regex>(red|green|blue|)</regex>"+
135 "<message>Invalid color</message>"+
136 "</validation>"+
137 "<fieldEvaluation><xpathexpression>//xmlContent/fieldDef[@name='color']/value = wf:ruledata('color')</xpathexpression></fieldEvaluation>"+
138 "</fieldDef>"+
139 "<fieldDef name=\"maxDollar\" title=\"Max dollar\" workflowType=\"RULE\">" +
140 "<display>" +
141 "<type>text</type>" +
142 "</display>" +
143 "<fieldEvaluation><xpathexpression>//xmlContent/fieldDef[@name='totalDollar']/value <= wf:ruledata('maxDollar')</xpathexpression></fieldEvaluation>"+
144 "</fieldDef>"+
145 "<fieldDef name=\"minDollar\" title=\"Min dollar\" workflowType=\"RULE\">" +
146 "<display>" +
147 "<type>text</type>" +
148 "</display>" +
149 "<fieldEvaluation><xpathexpression>//xmlContent/fieldDef[@name='totalDollar']/value >= wf:ruledata('minDollar')</xpathexpression></fieldEvaluation>"+
150 "</fieldDef>"+
151 "<fieldDef name=\"totalDollar\" title=\"Total dollar\" workflowType=\"REPORT\">" +
152 "<display>" +
153 "<type>text</type>" +
154 "</display>" +
155 "</fieldDef>" +
156 "</routingConfig>";
157
158 docContent = new StandardDocumentContent(documentcontent);
159 RuleAttribute ruleAttribute = new RuleAttribute();
160 ruleAttribute.setXmlConfigData(routingConfig);
161 ruleAttribute.setName("MyUniqueRuleAttribute1");
162 attribute.setRuleAttribute(ruleAttribute);
163 }
164
165 @Test public void testValidateRoutingData(){
166 Map paramMap = new HashMap();
167 paramMap.put("givenname", "Dave");
168 paramMap.put("gender", "female");
169 paramMap.put("color", "green");
170 paramMap.put("totalDollar", "500");
171
172 assertTrue("Errors found", attribute.validateRoutingData(paramMap).isEmpty());
173 }
174
175 @Test public void testValidateRuleData(){
176 Map paramMap = new HashMap();
177 paramMap.put("givenname", "Dave");
178 paramMap.put("gender", "female");
179 paramMap.put("color", "green");
180 paramMap.put("totalDollar", "500");
181
182 assertTrue("Errors found", attribute.validateRuleData(paramMap).isEmpty());
183
184 paramMap = new HashMap();
185 paramMap.put("givenname", "4444");
186 paramMap.put("gender", "crap");
187 paramMap.put("color", "green");
188 paramMap.put("totalDollar", "500");
189
190 assertFalse("Error list should contain at least one error.", attribute.validateRuleData(paramMap).isEmpty());
191
192 paramMap = new HashMap();
193 paramMap.put("givenname", "");
194 paramMap.put("gender", "female");
195 paramMap.put("color", "green");
196 paramMap.put("totalDollar", "500");
197
198 assertFalse("givenname should be required.", attribute.validateRuleData(paramMap).isEmpty());
199 }
200
201
202
203
204
205 @Test public void testNonMatchingExtensionKey() throws WorkflowException {
206 loadXmlFile("TestExtensionValueMatching.xml");
207 WorkflowDocument doc = new WorkflowDocument(new NetworkIdDTO("arh14"), "TestDocument");
208
209 WorkflowAttributeDefinitionDTO attr = new WorkflowAttributeDefinitionDTO(StandardGenericXMLRuleAttribute.class.getName());
210 attr.setAttributeName("Attr1");
211
212 attr.addProperty("attr1", "2");
213 doc.addAttributeDefinition(attr);
214
215 doc.routeDocument("");
216
217 Long id = doc.getRouteHeaderId();
218
219 doc = new WorkflowDocument(new NetworkIdDTO("user1"), id);
220 assertTrue("Request should have been generated to user1", doc.isApprovalRequested());
221
222 doc = new WorkflowDocument(new NetworkIdDTO("user2"), id);
223 assertTrue("Expected approval request to user2", doc.isApprovalRequested());
224 }
225
226
227
228
229 @Test public void testIsMatch() {
230 RuleExtension extension = new RuleExtension();
231
232 List values = new ArrayList();
233 RuleExtensionValue value = new RuleExtensionValue();
234 value.setKey("givenname");
235 value.setValue("Dave");
236 values.add(value);
237
238 RuleExtensionValue value2 = new RuleExtensionValue();
239 value2.setKey("gender");
240 value2.setValue("female");
241 values.add(value2);
242
243 RuleExtensionValue value3 = new RuleExtensionValue();
244 value3.setKey("color");
245 value3.setValue("green");
246 values.add(value3);
247
248 extension.setExtensionValues(values);
249 RuleTemplateAttribute ruleTemplateAttribute = new RuleTemplateAttribute();
250
251 RuleAttribute ruleAttribute = new RuleAttribute();
252 ruleAttribute.setName("MyUniqueRuleAttribute1");
253
254 ruleTemplateAttribute.setRuleAttribute(ruleAttribute);
255 extension.setRuleTemplateAttribute(ruleTemplateAttribute);
256 RuleExtension extension2 = new RuleExtension();
257
258 List values2 = new ArrayList();
259 RuleExtensionValue valueNew = new RuleExtensionValue();
260 valueNew.setKey("givenname");
261 valueNew.setValue("Jack");
262
263 RuleExtensionValue minDollar = new RuleExtensionValue();
264 minDollar.setKey("minDollar");
265 minDollar.setValue("300");
266 RuleExtensionValue maxDollar = new RuleExtensionValue();
267 maxDollar.setKey("maxDollar");
268 maxDollar.setValue("600");
269
270
271 values2.add(valueNew);
272 values2.add(minDollar);
273 values2.add(maxDollar);
274 extension2.setExtensionValues(values2);
275 RuleTemplateAttribute ruleTemplateAttribute2 = new RuleTemplateAttribute();
276
277 RuleAttribute ruleAttribute2 = new RuleAttribute();
278 ruleAttribute2.setName("MyUniqueRuleAttribute2");
279
280 ruleTemplateAttribute2.setRuleAttribute(ruleAttribute2);
281 extension2.setRuleTemplateAttribute(ruleTemplateAttribute2);
282
283 extensions = new ArrayList();
284 extensions.add(extension);
285 extensions.add(extension2);
286
287 assertTrue("Givenname did not match Dave, gender did not match female, or color did not match green", attribute.isMatch(docContent, extensions));
288
289 extension = new RuleExtension();
290 values = new ArrayList();
291 RuleExtensionValue value4 = new RuleExtensionValue();
292 value4.setKey("givenname");
293 value4.setValue("Dave");
294 values.add(value4);
295
296 RuleExtensionValue value5 = new RuleExtensionValue();
297 value5.setKey("gender");
298 value5.setValue("male");
299 values.add(value5);
300
301 RuleExtensionValue value6 = new RuleExtensionValue();
302 value6.setKey("color");
303 value6.setValue("green");
304 values.add(value6);
305
306 extension.setExtensionValues(values);
307 ruleTemplateAttribute = new RuleTemplateAttribute();
308
309 ruleAttribute = new RuleAttribute();
310 ruleAttribute.setName("MyUniqueRuleAttribute1");
311
312 ruleTemplateAttribute.setRuleAttribute(ruleAttribute);
313 extension.setRuleTemplateAttribute(ruleTemplateAttribute);
314
315
316 values2 = new ArrayList();
317 valueNew = new RuleExtensionValue();
318 valueNew.setKey("givenname");
319 valueNew.setValue("Jack");
320
321 values2.add(valueNew);
322 extension2.setExtensionValues(values2);
323 ruleTemplateAttribute2 = new RuleTemplateAttribute();
324
325 ruleAttribute2 = new RuleAttribute();
326 ruleAttribute2.setName("MyUniqueRuleAttribute2");
327
328 ruleTemplateAttribute2.setRuleAttribute(ruleAttribute2);
329 extension2.setRuleTemplateAttribute(ruleTemplateAttribute2);
330
331 extensions = new ArrayList();
332 extensions.add(extension);
333 extensions.add(extension2);
334 assertFalse("Gender female != male.", attribute.isMatch(docContent, extensions));
335
336
337
338 extension = new RuleExtension();
339 values = new ArrayList();
340
341 RuleExtensionValue value7 = new RuleExtensionValue();
342 value7.setKey("maxDollar");
343 value7.setValue("500");
344
345
346 RuleExtensionValue value8 = new RuleExtensionValue();
347 value8.setKey("minDollar");
348 value8.setValue("100");
349
350 values.add(value7);
351 values.add(value8);
352 extension.setExtensionValues(values);
353 ruleTemplateAttribute = new RuleTemplateAttribute();
354 ruleAttribute = new RuleAttribute();
355 ruleAttribute.setName("MyUniqueRuleAttribute1");
356 ruleTemplateAttribute.setRuleAttribute(ruleAttribute);
357 extension.setRuleTemplateAttribute(ruleTemplateAttribute);
358
359 values2 = new ArrayList();
360
361 valueNew = new RuleExtensionValue();
362 valueNew.setKey("givenname");
363 valueNew.setValue("Jack");
364 values2.add(valueNew);
365
366 extension2.setExtensionValues(values2);
367 ruleTemplateAttribute2 = new RuleTemplateAttribute();
368
369 ruleAttribute2 = new RuleAttribute();
370 ruleAttribute2.setName("MyUniqueRuleAttribute2");
371
372 ruleTemplateAttribute2.setRuleAttribute(ruleAttribute2);
373 extension2.setRuleTemplateAttribute(ruleTemplateAttribute2);
374
375 extensions = new ArrayList();
376 extensions.add(extension);
377 extensions.add(extension2);
378 assertTrue("Total dollar is greater than the max or less than the min.", attribute.isMatch(docContent, extensions));
379 }
380
381
382
383
384 @Test public void testGetRuleRows() {
385 assertTrue("Invalid number of rule rows", attribute.getRuleRows().size() == 5);
386
387 String routingConfigWithQuickfinders =
388 "<routingConfig>"+
389 "<globalEvaluations>" +
390 "<xpathexpression>//field/value != 'Nothing'</xpathexpression>" +
391 "</globalEvaluations>"+
392
393 "<fieldDef name=\"chart\" title=\"Chart\" workflowType=\"ALL\">"+
394 "<value>BL</value>"+
395 "<display>"+
396 "<type>text</type>"+
397 "<meta><name>size</name><value>20</value></meta>"+
398 "</display>" +
399 "<fieldEvaluation><xpathexpression>//xmlContent/field[@name='chart']/value = wf:ruledata('chart')</xpathexpression></fieldEvaluation>"+
400 "</fieldDef>"+
401 "<fieldDef name=\"org\" title=\"Org\" workflowType=\"ALL\">"+
402 "<display>"+
403 "<type>text</type>"+
404 "</display>" +
405 "<lookup businessObjectClass=\"ChartOrgLookupableImplService\">" +
406 "<fieldConversions>" +
407 "<fieldConversion lookupFieldName=\"fin_coa_cd\" localFieldName=\"chart\"/>" +
408 "<fieldConversion lookupFieldName=\"org_cd\" localFieldName=\"org\"/>" +
409 "</fieldConversions>" +
410 "</lookup>" +
411 "<fieldEvaluation><xpathexpression>//xmlContent/field[@name='gender']/value = wf:ruledata('gender')</xpathexpression></fieldEvaluation>"+
412 "</fieldDef>" +
413 "</routingConfig>";
414
415 RuleAttribute ruleAttribute = new RuleAttribute();
416 ruleAttribute.setXmlConfigData(routingConfigWithQuickfinders);
417 ruleAttribute.setName("MyUniqueRuleAttribute3");
418 StandardGenericXMLRuleAttribute myAttribute = new StandardGenericXMLRuleAttribute();
419 myAttribute.setRuleAttribute(ruleAttribute);
420
421 for (Iterator iter = myAttribute.getRuleRows().iterator(); iter.hasNext();) {
422 Row row = (Row) iter.next();
423 for (Iterator iterator = row.getFields().iterator(); iterator.hasNext();) {
424 Field field = (Field) iterator.next();
425 if(field.getFieldType().equals(Field.QUICKFINDER)){
426 assertTrue("Did not find quickfinder.", true);
427 }
428 }
429 }
430 assertTrue("Should have 2 rows and 3 fields: chart, org, and quickfinder.", myAttribute.getRuleRows().size() == 2);
431 }
432
433 @Test public void testGetRoutingDataRows() {
434 assertTrue("Invalid number of routing data rows",attribute.getRoutingDataRows().size() == 4);
435 }
436
437 @Test public void testGetDocContent() {
438
439 Map paramMap = new HashMap();
440 paramMap.put("givenname", "Dave");
441 paramMap.put("gender", "female");
442 paramMap.put("color", "green");
443 paramMap.put("totalDollar", "500");
444
445 attribute.setParamMap(paramMap);
446 try{
447 XPath xpath = XPathFactory.newInstance().newXPath();
448 Element element = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new InputSource(new BufferedReader(new StringReader(attribute.getDocContent())))).getDocumentElement();
449
450 String findStuff = "//xmlRouting/field[@name='givenname']/value";
451 assertTrue("Document content does not contain field givenname with value of Dave.", "Dave".equals(xpath.evaluate(findStuff, element, XPathConstants.STRING)));
452
453 findStuff = "//xmlRouting/field[@name='gender']/value";
454 assertTrue("Document content does not contain field gender with value of female.", "female".equals(xpath.evaluate(findStuff, element, XPathConstants.STRING)));
455
456 findStuff = "//xmlRouting/field[@name='color']/value";
457 assertTrue("Document content does not contain field color with value of green.", "green".equals(xpath.evaluate(findStuff, element, XPathConstants.STRING)));
458
459 findStuff = "//xmlRouting/field[@name='totalDollar']/value";
460 assertTrue("Document content does not contain field totalDollar with value of 500.", "500".equals(xpath.evaluate(findStuff, element, XPathConstants.STRING)));
461 } catch (Exception e){
462 e.printStackTrace();
463 }
464
465
466 String routingConfig =
467 "<routingConfig>" +
468 "<fieldDef name=\"myname\" title=\"First name\" workflowType=\"ALL\">"+
469 "<value>Joe</value>"+
470 "<display>"+
471 "<type>text</type>"+
472 "<meta><name>size</name><value>20</value></meta>"+
473 "</display>"+
474 "<fieldEvaluation><xpathexpression>//putWhateverWordsIwantInsideThisTag/myname/value = wf:ruledata('myname')</xpathexpression></fieldEvaluation>"+
475 "</fieldDef>"+
476 "<fieldDef name=\"theGender\" title=\"Gender\" workflowType=\"ALL\">"+
477 "<value>male</value>"+
478 "<display>"+
479 "<type>radio</type>"+
480 "<values title=\"Male\">male</values>"+
481 "<values title=\"Female\">female</values>"+
482 "</display>"+
483 "<fieldEvaluation><xpathexpression>//putWhateverWordsIwantInsideThisTag/theGender/value = wf:ruledata('theGender')</xpathexpression></fieldEvaluation>"+
484 "</fieldDef>"+
485 "<fieldDef name=\"myFavoriteColor\" title=\"Color\" workflowType=\"ALL\">" +
486 "<value>blue</value>" +
487 "<display>" +
488 "<type>select</type>" +
489 "<values title=\"Red\">red</values>" +
490 "<values title=\"Green\">green</values>" +
491 "<values title=\"Blue\" selected=\"true\">blue</values>" +
492 "</display>" +
493 "<fieldEvaluation><xpathexpression>//putWhateverWordsIwantInsideThisTag/myFavoriteColor/value = wf:ruledata('myFavoriteColor')</xpathexpression></fieldEvaluation>"+
494 "</fieldDef>"+
495 "<fieldDef name=\"maxDollar\" title=\"Max dollar\" workflowType=\"RULE\">" +
496 "<display>" +
497 "<type>text</type>" +
498 "</display>" +
499 "<fieldEvaluation><xpathexpression>//putWhateverWordsIwantInsideThisTag/myMoney/value <= wf:ruledata('maxDollar')</xpathexpression></fieldEvaluation>"+
500 "</fieldDef>"+
501 "<fieldDef name=\"minDollar\" title=\"Min dollar\" workflowType=\"RULE\">" +
502 "<display>" +
503 "<type>text</type>" +
504 "</display>" +
505 "<fieldEvaluation><xpathexpression>//putWhateverWordsIwantInsideThisTag/myMoney/value >= wf:ruledata('minDollar')</xpathexpression></fieldEvaluation>"+
506 "</fieldDef>"+
507 "<fieldDef name=\"myMoney\" title=\"Total dollar\" workflowType=\"REPORT\">" +
508 "<display>" +
509 "<type>text</type>" +
510 "</display>" +
511 "</fieldDef>"+
512
513 "<xmlDocumentContent>"+
514 "<putWhateverWordsIwantInsideThisTag>"+
515 "<myname>"+
516 "<value>%myname%</value>"+
517 "</myname>"+
518 "<theGender>"+
519 "<value>%theGender%</value>"+
520 "</theGender>"+
521 "<myFavoriteColor>"+
522 "<value>%myFavoriteColor%</value>"+
523 "</myFavoriteColor>"+
524 "<myMoney>"+
525 "<value>%myMoney%</value>"+
526 "</myMoney>"+
527 "</putWhateverWordsIwantInsideThisTag>"+
528 "</xmlDocumentContent>"+
529 "</routingConfig>";
530 try {
531 paramMap = new HashMap();
532 paramMap.put("myname", "jack");
533 paramMap.put("theGender", "male");
534 paramMap.put("myFavoriteColor", "blue");
535 paramMap.put("myMoney", "10");
536
537 attribute.setParamMap(paramMap);
538
539 RuleAttribute ruleAttribute = new RuleAttribute();
540 ruleAttribute.setXmlConfigData(routingConfig);
541 ruleAttribute.setName("MyUniqueRuleAttribute2");
542 attribute.setRuleAttribute(ruleAttribute);
543
544 String docContent = attribute.getDocContent();
545 assertTrue("DocContent was not found.", docContent != null && docContent.length() > 0);
546
547
548 XPath xpath = XPathFactory.newInstance().newXPath();
549 Element foundDocContent = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new InputSource(new BufferedReader(new StringReader(docContent)))).getDocumentElement();
550
551 String findStuff = "//putWhateverWordsIwantInsideThisTag/myMoney/value";
552 assertTrue("Document content does not contain field myMoney with a value of 10.", "10".equals(xpath.evaluate(findStuff, foundDocContent, XPathConstants.STRING)));
553
554 findStuff = "//putWhateverWordsIwantInsideThisTag/myFavoriteColor/value";
555 assertTrue("Document content does not contain field myFavoriteColor with value of blue.", "blue".equals(xpath.evaluate(findStuff, foundDocContent, XPathConstants.STRING)));
556
557 findStuff = "//putWhateverWordsIwantInsideThisTag/theGender/value";
558 assertTrue("Document content does not contain field theGender with value of male.", "male".equals(xpath.evaluate(findStuff, foundDocContent, XPathConstants.STRING)));
559
560 findStuff = "//putWhateverWordsIwantInsideThisTag/myname/value";
561 assertTrue("Document content does not contain field myname with value of jack.", "jack".equals(xpath.evaluate(findStuff, foundDocContent, XPathConstants.STRING)));
562
563 } catch(Exception e){
564 e.printStackTrace();
565 }
566 }
567 }