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