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 }