001    /**
002     * Copyright 2005-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    package org.kuali.rice.kew.rule;
017    
018    import org.junit.Test;
019    import org.kuali.rice.core.api.util.KeyValue;
020    import org.kuali.rice.kew.actionrequest.bo.RuleMaintenanceActionRequestCodeValuesFinder;
021    import org.kuali.rice.kew.api.KEWPropertyConstants;
022    import org.kuali.rice.kew.document.RoutingRuleMaintainable;
023    import org.kuali.rice.kew.service.KEWServiceLocator;
024    import org.kuali.rice.kew.test.KEWTestCase;
025    import org.kuali.rice.kew.api.KewApiConstants;
026    import org.kuali.rice.kns.document.MaintenanceDocument;
027    import org.kuali.rice.kns.document.MaintenanceDocumentBase;
028    import org.kuali.rice.kns.maintenance.Maintainable;
029    import org.kuali.rice.kns.util.KNSGlobalVariables;
030    import org.kuali.rice.kns.web.struts.form.KualiForm;
031    import org.kuali.rice.kns.web.struts.form.KualiMaintenanceForm;
032    
033    import java.util.HashSet;
034    import java.util.Iterator;
035    import java.util.List;
036    import java.util.Set;
037    
038    import static org.junit.Assert.*;
039    
040    /**
041     * This class tests the code that handles the default values for the rule templates.
042     * 
043     * @author Kuali Rice Team (rice.collab@kuali.org)
044     */
045    public class RuleTemplateDefaultsTest extends KEWTestCase {
046    
047            /**
048             * Creates a KualiMaintenanceForm with the given rule template inside of its RuleBaseValues instance.
049             * 
050             * @param rtName The rule template to use.
051             */
052            private void createNewKualiMaintenanceForm(String rtName) {
053                    // Initialize the required variables.
054                    final KualiMaintenanceForm kmForm = new KualiMaintenanceForm();
055                    final MaintenanceDocument maintDoc = new MaintenanceDocumentBase();
056                    final Maintainable oldMaint = new RoutingRuleMaintainable();
057                    final Maintainable newMaint = new RoutingRuleMaintainable();
058                    final RuleBaseValues rbValues = new RuleBaseValues();
059                    // Setup the rule base and the maintainables.
060                    rbValues.setRuleTemplate(KEWServiceLocator.getRuleTemplateService().findByRuleTemplateName(rtName));
061                    oldMaint.setBusinessObject(rbValues);
062                    oldMaint.setBoClass(rbValues.getClass());
063                    newMaint.setBusinessObject(rbValues);
064                    newMaint.setBoClass(rbValues.getClass());
065                    // Setup the maintenance document and the maintenance form.
066                    maintDoc.setOldMaintainableObject(oldMaint);
067                    maintDoc.setNewMaintainableObject(newMaint);
068                    maintDoc.getDocumentHeader().setDocumentDescription("This is a rule template test");
069                    kmForm.setDocument(maintDoc);
070                    KNSGlobalVariables.setKualiForm(kmForm);
071            }
072            
073            /**
074             * A convenience method for creating a set of expected key label pairs.
075             * 
076             * @param hasAcknowledge Indicates that a KeyValue for "acknowledge" options should exist.
077             * @param hasComplete Indicates that a KeyValue for "complete" options should exist.
078             * @param hasApprove Indicates that a KeyValue for "approve" options should exist.
079             * @param hasFyi Indicates that a KeyValue for "fyi" options should exist.
080             * @return A Set containing the desired expected KeyValue keys.
081             */
082            private Set<String> createExpectedKeysSet(boolean hasAcknowledge, boolean hasComplete, boolean hasApprove, boolean hasFyi) {
083                    final Set<String> expectedKeys = new HashSet<String>();
084                    // Insert the desired expected options into the set.
085                    if (hasAcknowledge) { expectedKeys.add(KewApiConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ); }
086                    if (hasComplete) { expectedKeys.add(KewApiConstants.ACTION_REQUEST_COMPLETE_REQ); }
087                    if (hasApprove) { expectedKeys.add(KewApiConstants.ACTION_REQUEST_APPROVE_REQ); }
088                    if (hasFyi) { expectedKeys.add(KewApiConstants.ACTION_REQUEST_FYI_REQ); }
089                    return expectedKeys;
090            }
091            
092            /**
093             * A convenience method for placing the keys from a KeyValue list into a set.
094             * 
095             * @param kValues The KeyValues to process.
096             * @return A Set containing the keys of each KeyValue.
097             */
098            private Set<String> createSetOfKeyValueKeys(List<KeyValue> klpList) {
099                    final Set<String> actualKeys = new HashSet<String>();
100                    for (Iterator<KeyValue> iterator = klpList.iterator(); iterator.hasNext();) {
101                            actualKeys.add((String) iterator.next().getKey());
102                    }
103                    return actualKeys;
104            }
105            
106            /**
107             * Tests to ensure that the "TestRuleTemplate" in DefaultTestData.xml has the four action request options defined as "true",
108             * either explicitly or by default.
109             */
110            @Test public void testAllTrueOptionsInTestRuleTemplate() throws Exception {
111                    createNewKualiMaintenanceForm("TestRuleTemplate");
112                    assertRuleTemplateHasExpectedKeyValues(
113                                    createExpectedKeysSet(true, true, true, true),
114                                    createSetOfKeyValueKeys((new RuleMaintenanceActionRequestCodeValuesFinder()).getKeyValues()));
115            }
116    
117            /**
118             * Tests to ensure that the proper key values are returned based upon the class type of the currently-set Kuali form.
119             * 
120             * @throws Exception
121             */
122            @Test public void testCorrectKeyValuesReturnedBasedOnKualiFormInstance() throws Exception {
123                    // First, check that the proper values are returned when the Kuali form is *not* a KualiMaintenanceForm.
124                    KNSGlobalVariables.setKualiForm(new KualiForm());
125                    assertRuleTemplateHasExpectedKeyValues(
126                                    createExpectedKeysSet(true, true, true, true),
127                                    createSetOfKeyValueKeys((new RuleMaintenanceActionRequestCodeValuesFinder()).getKeyValues()));
128                    // Next, check that the proper values are returned when the Kuali form is a KualiMaintenanceForm containing a given rule template.
129                    loadXmlFile("RT_ValidRuleTemplatesWithVaryingDefaults.xml");
130                    createNewKualiMaintenanceForm("Test_Rule_Template2");
131                    assertRuleTemplateHasExpectedKeyValues(
132                                    createExpectedKeysSet(false, false, false, true),
133                                    createSetOfKeyValueKeys((new RuleMaintenanceActionRequestCodeValuesFinder()).getKeyValues()));
134            }
135            
136            /**
137             * Tests to ensure that the rule template in RT_ValidRuleTemplateWithFullDefaults.xml has the expected action request options.
138             * 
139             * @throws Exception
140             */
141            @Test public void testOptionsInRT_ValidRuleTemplatesWithVaryingDefaults() throws Exception {
142                    loadXmlFile("RT_ValidRuleTemplatesWithVaryingDefaults.xml");
143                    final String[] ruleTemplates = {"RuleTemplate_With_Valid_Defaults", "RuleTemplate_With_More_Valid_Defaults"};
144                    final boolean[][] kSetBools = { {false, false, true, false}, {true, true, false, false} };
145                    final String[][] defaultActions = {
146                            {KewApiConstants.ACTION_REQUEST_APPROVE_REQ,KewApiConstants.ACTION_REQUEST_APPROVE_REQ,KewApiConstants.ACTION_REQUEST_APPROVE_REQ},
147                            {KewApiConstants.ACTION_REQUEST_COMPLETE_REQ,KewApiConstants.ACTION_REQUEST_COMPLETE_REQ,KewApiConstants.ACTION_REQUEST_COMPLETE_REQ}};
148                    // Test each rule template from the given file.
149                    for (int i = 0; i < ruleTemplates.length; i++) {
150                            createNewKualiMaintenanceForm(ruleTemplates[i]);
151                            assertRuleTemplateHasExpectedKeyValues(
152                                            createExpectedKeysSet(kSetBools[i][0], kSetBools[i][1], kSetBools[i][2], kSetBools[i][3]),
153                                            createSetOfKeyValueKeys((new RuleMaintenanceActionRequestCodeValuesFinder()).getKeyValues()));
154                            assertRuleTemplateHasExpectedDefaultActions(defaultActions[i]);
155                    }
156            }
157            
158            /**
159             * A convenience method for performing KeyValue existence/nonexistence tests.
160             * 
161             * @param expectedKeys The expected KeyValue keys.
162             * @param actualKeys The actual KeyValue keys.
163             * @throws Exception
164             */
165            private void assertRuleTemplateHasExpectedKeyValues(Set<String> expectedKeys, Set<String> actualKeys) throws Exception {
166                    // Check to see if all required keys are in the set.
167                    for (Iterator<String> iterator = expectedKeys.iterator(); iterator.hasNext();) {
168                            final String expKey = iterator.next();
169                            assertTrue("The key label pair with a key of '" + expKey + "' should have been true.", actualKeys.contains(expKey));
170                            actualKeys.remove(expKey);
171                    }
172                    // If any keys are still in the list, then fail the test because we expected their equivalent rule template options to
173                    // have a non-true value.
174                    if (!actualKeys.isEmpty()) {
175                            // Construct the error message.
176                            final String pluralStr = (actualKeys.size() != 1) ? "s" : "";
177                            final StringBuilder errMsg = new StringBuilder();
178                            errMsg.append("The key label pair").append(pluralStr).append(" with the key").append(pluralStr).append(" of ");
179                            for (Iterator<String> iterator = actualKeys.iterator(); iterator.hasNext();) {
180                                    errMsg.append("'").append(iterator.next()).append(iterator.hasNext() ? "', " : "' ");
181                            }
182                            errMsg.append("should have been false.");
183                            // Fail the test.
184                            fail(errMsg.toString());
185                    }
186            }
187            
188            /**
189             * A convenience method for verifying that a rule template contains the expected default action.
190             * 
191             * @param expectedDefActions The default actions expected by each responsibility (person, then group, then role).
192             * @throws Exception
193             */
194            private void assertRuleTemplateHasExpectedDefaultActions(String[] expectedDefActions) throws Exception {
195                    // Acquire the Maintainable and the responsibility constants.
196                    final RoutingRuleMaintainable rrMaint = (RoutingRuleMaintainable) ((MaintenanceDocument) ((KualiMaintenanceForm)
197                                    KNSGlobalVariables.getKualiForm()).getDocument()).getNewMaintainableObject();
198                    final String[] respSectionConsts = { KEWPropertyConstants.PERSON_RESP_SECTION, KEWPropertyConstants.GROUP_RESP_SECTION,
199                                    KEWPropertyConstants.ROLE_RESP_SECTION };
200                    // Check each responsibility's default action.
201                    for (int i = 0; i < respSectionConsts.length; i++) {
202                            final String actualDefAction =
203                                            ((RuleResponsibilityBo) rrMaint.initNewCollectionLine(respSectionConsts[i])).getActionRequestedCd();
204                            assertEquals("The rule template does not have the expected default approve action.", expectedDefActions[i], actualDefAction);
205                    }
206            }
207    }