View Javadoc
1   /*
2    * The Kuali Financial System, a comprehensive financial management system for higher education.
3    * 
4    * Copyright 2005-2014 The Kuali Foundation
5    * 
6    * This program is free software: you can redistribute it and/or modify
7    * it under the terms of the GNU Affero General Public License as
8    * published by the Free Software Foundation, either version 3 of the
9    * License, or (at your option) any later version.
10   * 
11   * This program is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   * GNU Affero General Public License for more details.
15   * 
16   * You should have received a copy of the GNU Affero General Public License
17   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18   */
19  package org.kuali.kfs.sys.document.validation;
20  
21  import groovy.util.logging.Log;
22  
23  import java.util.List;
24  
25  import org.apache.log4j.Logger;
26  import org.kuali.kfs.sys.ConfigureContext;
27  import org.kuali.kfs.sys.KFSConstants;
28  import org.kuali.kfs.sys.KFSKeyConstants;
29  import org.kuali.kfs.sys.context.KualiTestBase;
30  import org.kuali.kfs.sys.context.SpringContext;
31  import org.kuali.rice.kew.api.exception.WorkflowException;
32  import org.kuali.rice.kns.document.MaintenanceDocument;
33  import org.kuali.rice.kns.maintenance.KualiMaintainableImpl;
34  import org.kuali.rice.kns.maintenance.rules.MaintenanceDocumentRuleBase;
35  import org.kuali.rice.kns.rules.MaintenanceDocumentRule;
36  import org.kuali.rice.kns.service.DictionaryValidationService;
37  import org.kuali.rice.kns.service.MaintenanceDocumentDictionaryService;
38  import org.kuali.rice.krad.bo.PersistableBusinessObject;
39  import org.kuali.rice.krad.service.DocumentService;
40  import org.kuali.rice.krad.util.ErrorMessage;
41  import org.kuali.rice.krad.util.GlobalVariables;
42  
43  @ConfigureContext
44  public abstract class MaintenanceRuleTestBase extends KualiTestBase {
45      /**
46       * This method creates a minimal MaintenanceDocument instance, and populates it with the provided businessObject for the
47       * newMaintainable, and null for the oldMaintainable.
48       * 
49       * @param newSubAccount - populated subAccount for the newMaintainable
50       * @return a populated MaintenanceDocument instance
51       */
52      protected MaintenanceDocument newMaintDoc(PersistableBusinessObject newBo) {
53          return newMaintDoc(null, newBo);
54      }
55  
56      /**
57       * This method creates a minimal MaintenanceDocument instance, and populates it with the provided businessObjects for the
58       * newMaintainable and oldMaintainable.
59       * 
60       * @param oldSubAccount - populated subAccount for the oldMaintainable
61       * @param newSubAccount - populated subAccount for the newMaintainable
62       * @return a populated MaintenanceDocument instance
63       */
64      protected MaintenanceDocument newMaintDoc(PersistableBusinessObject oldBo, PersistableBusinessObject newBo) {
65  
66          // disallow null value for newBo
67          if (null == newBo) {
68              throw new IllegalArgumentException("Invalid value (null) for newBo.  " + "This must always be a valid, populated BusinessObject instance.");
69          }
70  
71          // get a new MaintenanceDocument from Spring
72          MaintenanceDocument document = null;
73          try {
74              document = (MaintenanceDocument) SpringContext.getBean(DocumentService.class).getNewDocument(SpringContext.getBean(MaintenanceDocumentDictionaryService.class).getDocumentTypeName(newBo.getClass()));
75          }
76          catch (WorkflowException e) {
77              throw new RuntimeException(e);
78          }
79  
80          // add all the pieces
81          document.getDocumentHeader().setDocumentDescription("test");
82          if (null == oldBo) {
83              document.setOldMaintainableObject(new KualiMaintainableImpl());
84          }
85          else {
86              document.setOldMaintainableObject(new KualiMaintainableImpl(oldBo));
87              document.getOldMaintainableObject().setBoClass(oldBo.getClass());
88          }
89          document.setNewMaintainableObject(new KualiMaintainableImpl(newBo));
90          document.getNewMaintainableObject().setBoClass(newBo.getClass());
91          return document;
92      }
93  
94      /**
95       * This method creates a new instance of the specified ruleClass, injects the businessObject(s). With this method, the
96       * oldMaintainable will be set to null.
97       * 
98       * @param newBo - the populated businessObject for the newMaintainble
99       * @param ruleClass - the class of rule to instantiate
100      * @return a populated and ready-to-test rule, of the specified class
101      */
102     protected MaintenanceDocumentRule setupMaintDocRule(PersistableBusinessObject newBo, Class ruleClass) {
103         MaintenanceDocument maintDoc = newMaintDoc(newBo);
104         return setupMaintDocRule(maintDoc, ruleClass);
105     }
106 
107     /**
108      * This method first creates a new MaintenanceDocument with the BusinessObject(s) passed in. Note that the maintDoc is created
109      * and destroyed internally, and is never returned. This method then creates a new instance of the specified ruleClass, injects
110      * the businessObject(s).
111      * 
112      * @param oldBo - the populated businessObject for the oldMaintainable
113      * @param newBo - the populated businessObject for the newMaintainable
114      * @param ruleClass - the class of rule to instantiate
115      * @return a populated and ready-to-test rule, of the specified class
116      */
117     protected MaintenanceDocumentRule setupMaintDocRule(PersistableBusinessObject oldBo, PersistableBusinessObject newBo, Class ruleClass) {
118 
119         MaintenanceDocument maintDoc = newMaintDoc(oldBo, newBo);
120 
121         return setupMaintDocRule(maintDoc, ruleClass);
122     }
123 
124     /**
125      * This method creates a new instance of the specified ruleClass, and then injects the maintenanceDocument and associated
126      * business objects.
127      * 
128      * @param maintDoc - the populated MaintenanceDocument instance
129      * @param ruleClass - the class of rule to instantiate
130      * @return a populated and ready-to-test rule, of the specified class
131      */
132     protected MaintenanceDocumentRule setupMaintDocRule(MaintenanceDocument maintDoc, Class ruleClass) {
133 
134         MaintenanceDocumentRule rule;
135         try {
136             rule = (MaintenanceDocumentRule) ruleClass.newInstance();
137         }
138         catch (InstantiationException e) {
139             throw new RuntimeException(e);
140         }
141         catch (IllegalAccessException e) {
142             throw new RuntimeException(e);
143         }
144 
145         rule.setupBaseConvenienceObjects(maintDoc);
146 
147         // confirm that we're starting with no errors
148         assertEquals(0, GlobalVariables.getMessageMap().getNumberOfPropertiesWithErrors());
149 
150         return rule;
151     }
152 
153     protected void testDefaultExistenceCheck(PersistableBusinessObject bo, String fieldName, boolean shouldFail) {
154 
155         // init the error path
156         GlobalVariables.getMessageMap().addToErrorPath("document.newMaintainableObject");
157 
158         // run the dataDictionary validation
159         SpringContext.getBean(DictionaryValidationService.class).validateDefaultExistenceChecks(bo);
160 
161         // clear the error path
162         GlobalVariables.getMessageMap().removeFromErrorPath("document.newMaintainableObject");
163 
164         // assert that the existence of the error is what is expected
165         assertFieldErrorExistence(fieldName, KFSKeyConstants.ERROR_EXISTENCE, shouldFail);
166 
167     }
168 
169     /**
170      * This method tests whether the expected number of errors exists in the errorMap. The assert will fail if this expected number
171      * isnt what is returned.
172      * 
173      * @param expectedErrorCount - the number of errors expected
174      */
175     protected void assertErrorCount(int expectedErrorCount) {
176         assertEquals(expectedErrorCount, GlobalVariables.getMessageMap().getErrorCount());
177     }
178 
179     /**
180      * This method tests whether the field error exists and returns the result of this test.
181      * 
182      * @param fieldName
183      * @param errorKey
184      * @return True if the error exists in the GlobalErrors, false if not.
185      */
186     protected boolean doesFieldErrorExist(String fieldName, String errorKey) {
187         return GlobalVariables.getMessageMap().fieldHasMessage(MaintenanceDocumentRuleBase.MAINTAINABLE_ERROR_PREFIX + fieldName, errorKey);
188     }
189 
190     /**
191      * This method tests whether the existence check on the error matches what is expected by what is passed into expectedResult.
192      * This method will fail the assertion if the presence of the error is not what is expected.
193      * 
194      * @param fieldName
195      * @param errorKey
196      * @param expectedResult - True if the error is expected, False if it is not.
197      */
198     protected void assertFieldErrorExistence(String fieldName, String errorKey, boolean expectedResult) {
199         boolean result = doesFieldErrorExist(fieldName, errorKey);
200         assertEquals("Existence check for Error on fieldName/errorKey: " + fieldName + "/" + errorKey + ". " + GlobalVariables.getMessageMap(), expectedResult, result);
201     }
202 
203     /**
204      * This method tests whether a given combination of fieldName and errorKey does NOT exist in the GlobalVariables.getMessageMap().
205      * The assert will fail if the fieldName & errorKey combination DOES exist. NOTE that fieldName should NOT include the prefix
206      * errorPath.
207      * 
208      * @param fieldName - fieldName as it would be provided when adding the error
209      * @param errorKey - errorKey as it would be provided when adding the error
210      */
211     protected void assertFieldErrorDoesNotExist(String fieldName, String errorKey) {
212         boolean result = doesFieldErrorExist(fieldName, errorKey);
213         assertTrue("FieldName (" + fieldName + ") should NOT contain errorKey: " + errorKey, !result);
214     }
215 
216     /**
217      * This method tests whether a given combination of fieldName and errorKey exists in the GlobalVariables.getMessageMap(). The
218      * assert will fail if the fieldName & errorKey combination doesnt exist. NOTE that fieldName should NOT include the prefix
219      * errorPath.
220      * 
221      * @param fieldName - fieldName as it would be provided when adding the error
222      * @param errorKey - errorKey as it would be provided when adding the error
223      */
224     protected void assertFieldErrorExists(String fieldName, String errorKey) {
225         boolean result = GlobalVariables.getMessageMap().fieldHasMessage(MaintenanceDocumentRuleBase.MAINTAINABLE_ERROR_PREFIX + fieldName, errorKey);
226         if ( !result ) {
227             Logger.getLogger(getClass()).info("Messages in MessageMap: " + GlobalVariables.getMessageMap());
228         }
229         assertTrue("FieldName (" + fieldName + ") should contain errorKey: " + errorKey, result);
230     }
231 
232     /**
233      * This method tests whether a given errorKey exists on the document itself (ie, not tied to a specific field). The assert will
234      * fail if the errorKey already exists on the document.
235      * 
236      * @param errorKey - errorKey as it would be provided when adding the error
237      */
238     protected void assertGlobalErrorExists(String errorKey) {
239         boolean result = GlobalVariables.getMessageMap().fieldHasMessage(KFSConstants.DOCUMENT_ERRORS, errorKey);
240         assertTrue("Document should contain errorKey: " + errorKey, result);
241     }
242 }