001: /*
002: * Copyright 2005-2007 The Kuali Foundation.
003: *
004: * Licensed under the Educational Community License, Version 1.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/ecl1.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.core.util;
017:
018: import java.util.Arrays;
019: import java.util.HashSet;
020: import java.util.Iterator;
021: import java.util.Map;
022: import java.util.Set;
023:
024: import org.kuali.kfs.KFSConstants;
025: import org.kuali.kfs.KFSKeyConstants;
026: import org.kuali.kfs.context.KualiTestBase;
027: import org.kuali.module.chart.bo.Account;
028:
029: /**
030: * This class tests the ErrorMap methods.
031: */
032: public class ErrorMapTest extends KualiTestBase {
033:
034: /**
035: * ErrorMap should only allow String keys and values.
036: */
037: public final void testPut() {
038: ErrorMap testMap = new ErrorMap();
039:
040: // should be ok putting strings
041: try {
042: testMap.putError("accountNbr",
043: KFSKeyConstants.ERROR_INACTIVE);
044: } catch (RuntimeException e) {
045: fail("ErrorMap threw exception adding string pair");
046: }
047:
048: // should fail putting other objects
049: try {
050: testMap.put(new Account(), KFSKeyConstants.ERROR_INACTIVE);
051: testMap.put("accountNbr", new Account());
052: fail("ErrorMap allowed put of non Strin type");
053: } catch (RuntimeException e) {
054: }
055: }
056:
057: /**
058: * Test all errors are getting added and counted correctly.
059: */
060: public final void testErrorCount() {
061: ErrorMap testMap = new ErrorMap();
062:
063: testMap.putError("accountNbr", KFSKeyConstants.ERROR_INACTIVE);
064: assertTrue(testMap.getErrorCount() == 1);
065:
066: testMap.putError("accountNbr",
067: KFSKeyConstants.ERROR_INVALID_FORMAT);
068: assertTrue(testMap.getErrorCount() == 2);
069:
070: testMap.putError("chartCode",
071: KFSKeyConstants.ERROR_INVALID_FORMAT);
072: testMap.putError("projectCode",
073: KFSKeyConstants.ERROR_INVALID_FORMAT);
074: testMap.putError("objectCode",
075: KFSKeyConstants.ERROR_INVALID_FORMAT);
076: assertTrue(testMap.getErrorCount() == 5);
077:
078: testMap.remove("accountNbr");
079: assertTrue(testMap.getErrorCount() == 3);
080: }
081:
082: /**
083: * Test messages are getting accumulated correctly for a property.
084: */
085: public final void testFieldMessages() {
086: ErrorMap testMap = new ErrorMap();
087:
088: testMap.putError("accountNbr", KFSKeyConstants.ERROR_INACTIVE);
089: testMap.putError("accountNbr",
090: KFSKeyConstants.ERROR_INVALID_FORMAT);
091: testMap.putError("accountNbr",
092: KFSKeyConstants.ERROR_PHONE_NUMBER);
093: assertEquals(3, testMap.countFieldMessages("accountNbr"));
094: assertTrue(testMap.fieldHasMessage("accountNbr",
095: KFSKeyConstants.ERROR_INACTIVE));
096: assertTrue(testMap.fieldHasMessage("accountNbr",
097: KFSKeyConstants.ERROR_INVALID_FORMAT));
098: assertTrue(testMap.fieldHasMessage("accountNbr",
099: KFSKeyConstants.ERROR_PHONE_NUMBER));
100: }
101:
102: /**
103: * Test the error path is being prepended.
104: */
105: public final void testErrorPath() {
106: ErrorMap testMap = new ErrorMap();
107:
108: assertTrue(testMap.getKeyPath("accountNbr", true).equals(
109: "accountNbr"));
110: testMap.addToErrorPath("document");
111: assertTrue(testMap.getKeyPath("accountNbr", true).equals(
112: "document.accountNbr"));
113: assertTrue(testMap.getKeyPath("accountNbr", false).equals(
114: "accountNbr"));
115: testMap.removeFromErrorPath("document");
116: assertTrue(testMap.getKeyPath("accountNbr", true).equals(
117: "accountNbr"));
118: assertTrue(testMap.getKeyPath("accountNbr", false).equals(
119: "accountNbr"));
120: testMap.addToErrorPath("document");
121: testMap.addToErrorPath("newAccountingLine");
122: assertTrue(testMap.getKeyPath("accountNbr", true).equals(
123: "document.newAccountingLine.accountNbr"));
124: assertTrue(testMap.getKeyPath("accountNbr", false).equals(
125: "accountNbr"));
126:
127: testMap.putError("accountNbr", KFSKeyConstants.ERROR_INACTIVE);
128: assertEquals(
129: 1,
130: testMap
131: .countFieldMessages("document.newAccountingLine.accountNbr"));
132: assertTrue(testMap.fieldHasMessage(
133: "document.newAccountingLine.accountNbr",
134: KFSKeyConstants.ERROR_INACTIVE));
135:
136: // global key should not be prepended with key path
137: assertTrue(testMap.getKeyPath(KFSConstants.GLOBAL_ERRORS, true)
138: .equals(KFSConstants.GLOBAL_ERRORS));
139:
140: assertTrue(testMap.getKeyPath("projectCode.code", true).equals(
141: "document.newAccountingLine.projectCode.code"));
142: testMap.removeFromErrorPath("newAccountingLine");
143: assertTrue(testMap.getKeyPath("accountNbr", true).equals(
144: "document.accountNbr"));
145: testMap.removeFromErrorPath("document");
146: assertTrue(testMap.getKeyPath("accountNbr", true).equals(
147: "accountNbr"));
148: }
149:
150: /**
151: * Test that properties added with errors are being kept.
152: */
153: public final void testPropertiesWithErrors() {
154: ErrorMap testMap = new ErrorMap();
155:
156: testMap.putError("accountNbr", KFSKeyConstants.ERROR_INACTIVE);
157: testMap.putError("projectCode", KFSKeyConstants.ERROR_INACTIVE);
158: testMap.putError("chartCode", KFSKeyConstants.ERROR_INACTIVE);
159: testMap.putError("objectCode", KFSKeyConstants.ERROR_INACTIVE);
160: testMap.putError("subAccountNbr",
161: KFSKeyConstants.ERROR_INACTIVE);
162:
163: assertTrue(testMap.getPropertiesWithErrors().contains(
164: "accountNbr"));
165: assertTrue(testMap.getPropertiesWithErrors().contains(
166: "projectCode"));
167: assertTrue(testMap.getPropertiesWithErrors().contains(
168: "chartCode"));
169: assertTrue(testMap.getPropertiesWithErrors().contains(
170: "objectCode"));
171: assertTrue(testMap.getPropertiesWithErrors().contains(
172: "subAccountNbr"));
173: }
174:
175: /**
176: * Test message parameters are being correctly added and associated with an error message.
177: */
178: public final void testMessageParameters() {
179: ErrorMap testMap = new ErrorMap();
180:
181: testMap.putError("accountNbr", KFSKeyConstants.ERROR_INACTIVE,
182: "Account Number");
183: testMap.putError("accountNbr", KFSKeyConstants.ERROR_REQUIRED,
184: "Account Number");
185: // check duplicate message doesn't get added
186: testMap.putError("accountNbr", KFSKeyConstants.ERROR_INACTIVE,
187: "Account Number");
188: testMap.putError("chartCode", KFSKeyConstants.ERROR_REQUIRED,
189: "Chart Code");
190:
191: assertEquals(3, testMap.getErrorCount());
192:
193: TypedArrayList errorMessages = testMap
194: .getMessages("accountNbr");
195: assertEquals(2, errorMessages.size());
196: checkMessageParemeters(errorMessages, 0,
197: KFSKeyConstants.ERROR_INACTIVE,
198: new String[] { "Account Number" });
199: checkMessageParemeters(errorMessages, 1,
200: KFSKeyConstants.ERROR_REQUIRED,
201: new String[] { "Account Number" });
202:
203: errorMessages = testMap.getMessages("chartCode");
204: assertEquals(1, errorMessages.size());
205: checkMessageParemeters(errorMessages, 0,
206: KFSKeyConstants.ERROR_REQUIRED,
207: new String[] { "Chart Code" });
208: }
209:
210: private void checkMessageParemeters(TypedArrayList errorMessages,
211: int messageIndex, String expectedKeyConstant,
212: String[] expectedParameters) {
213: ErrorMessage message1 = (ErrorMessage) errorMessages
214: .get(messageIndex);
215: assertEquals(expectedKeyConstant, message1.getErrorKey());
216: assertTrue(Arrays.equals(message1.getMessageParameters(),
217: expectedParameters));
218: }
219:
220: /**
221: * Verify that using the same error message multiple times correctly stores different parameters each time. (Reproduces bug
222: * KULNRVSYS-943).
223: */
224: public final void testMessageCollisions() {
225: final String PROPERTY_NAME = "document.sourceAccounting*,document.targetAccounting*,newSourceLine*,newTargetLine*";
226: ErrorMap testMap = new ErrorMap();
227:
228: testMap.putError(PROPERTY_NAME, "error.inactive", "Chart Code");
229: testMap
230: .putError(PROPERTY_NAME,
231: "error.document.subAccountClosed",
232: "Sub-Account Number");
233: testMap
234: .putError(PROPERTY_NAME, "error.inactive",
235: "Object Code");
236: testMap.putError(PROPERTY_NAME, "error.inactive",
237: "SubObject Code");
238: testMap.putError(PROPERTY_NAME, "error.inactive",
239: "Project Code");
240:
241: assertEquals(5, testMap.getErrorCount());
242:
243: // retrieve error messages for the one known key
244: Object thing = testMap.get(PROPERTY_NAME);
245:
246: Set usedParams = new HashSet();
247: for (Iterator i = testMap.entrySet().iterator(); i.hasNext();) {
248: Map.Entry entry = (Map.Entry) i.next();
249:
250: String propertyKey = (String) entry.getKey();
251: TypedArrayList messageList = (TypedArrayList) entry
252: .getValue();
253: for (Iterator j = messageList.iterator(); j.hasNext();) {
254: ErrorMessage message = (ErrorMessage) j.next();
255:
256: String[] params = message.getMessageParameters();
257: if (usedParams.contains(params)) {
258: fail("usedParams contains duplicate parameters object '"
259: + params + "'");
260: }
261: usedParams.add(params);
262: }
263: }
264: }
265:
266: private final static String MIXED_LIST_PATTERN = "document.sourceAccounting*,document.targetAccounting*,foo,bar,newSourceLine*,newTargetLine*";
267:
268: public final void testContainsKeyMatchingPattern_mixedList_empty() {
269: assertEquals(false, new ErrorMap()
270: .containsKeyMatchingPattern(MIXED_LIST_PATTERN));
271: }
272:
273: public final void testContainsKeyMatchingPattern_mixedList_simpleNoMatch() {
274: ErrorMap testMap = new ErrorMap();
275: testMap.putError("xxx", "error.inactive", "Chart Code");
276: testMap.putError("yyy", "error.inactive", "Chart Code");
277: assertEquals(false, testMap
278: .containsKeyMatchingPattern(MIXED_LIST_PATTERN));
279: }
280:
281: public final void testContainsKeyMatchingPattern_mixedList_simpleMatch() {
282: ErrorMap testMap = new ErrorMap();
283: testMap.putError("xxx", "error.inactive", "Chart Code");
284: testMap.putError("foo", "error.inactive", "Chart Code");
285: testMap.putError("yyy", "error.inactive", "Chart Code");
286: assertEquals(true, testMap
287: .containsKeyMatchingPattern(MIXED_LIST_PATTERN));
288: }
289:
290: public final void testContainsKeyMatchingPattern_mixedList_wildcardMatch() {
291: ErrorMap testMap = new ErrorMap();
292: testMap.putError("xxx", "error.inactive", "Chart Code");
293: testMap.putError("document.targetAccountingLine.something",
294: "error.inactive", "Chart Code");
295: testMap.putError("yyy", "error.inactive", "Chart Code");
296: assertEquals(true, testMap
297: .containsKeyMatchingPattern(MIXED_LIST_PATTERN));
298: }
299:
300: public final void testReplace_testEquals() {
301: final ErrorMap constantMap = buildReplaceErrorMap();
302: ErrorMap replaceMap = buildReplaceErrorMap();
303:
304: assertEquals(replaceMap, replaceMap);
305: assertEquals(replaceMap, constantMap);
306: assertEquals(constantMap, replaceMap);
307:
308: replaceMap.putError("somethingElse",
309: KFSKeyConstants.ERROR_INACTIVE, "Account Number");
310:
311: assertFalse(replaceMap.equals(constantMap));
312: }
313:
314: public final void testReplace_noMatchingProperty() {
315: final ErrorMap constantMap = buildReplaceErrorMap();
316: ErrorMap replaceMap = buildReplaceErrorMap();
317:
318: assertTrue(replaceMap.equals(constantMap));
319: assertFalse(replaceMap.containsMessageKey("fooKey"));
320:
321: boolean replaced = replaceMap.replaceError("fooName", "fooKey",
322: "fooReplaceKey");
323: assertFalse(replaced);
324:
325: assertTrue(replaceMap.equals(constantMap));
326: assertFalse(replaceMap.containsMessageKey("fooKey"));
327: }
328:
329: public final void testReplace_matchingProperty_noMatchingKey() {
330: final ErrorMap constantMap = buildReplaceErrorMap();
331: ErrorMap replaceMap = buildReplaceErrorMap();
332:
333: assertTrue(replaceMap.equals(constantMap));
334: assertFalse(replaceMap.containsMessageKey("fooKey"));
335:
336: boolean replaced = replaceMap.replaceError("accountNbr",
337: "fooKey", "fooReplaceKey");
338: assertFalse(replaced);
339:
340: assertTrue(replaceMap.equals(constantMap));
341: assertFalse(replaceMap.containsMessageKey("fooKey"));
342: }
343:
344: public final void testReplace_matchingProperty_matchingKey_noParams() {
345: final ErrorMap constantMap = buildReplaceErrorMap();
346: ErrorMap replaceMap = buildReplaceErrorMap();
347:
348: assertTrue(replaceMap.equals(constantMap));
349: assertTrue(replaceMap
350: .containsMessageKey(KFSKeyConstants.ERROR_INACTIVE));
351: assertFalse(replaceMap
352: .containsMessageKey(KFSKeyConstants.ERROR_NOT_AMONG));
353:
354: TypedArrayList preMessages = replaceMap
355: .getMessages("accountNbr");
356: assertEquals(2, preMessages.size());
357:
358: boolean replaced = replaceMap.replaceError("accountNbr",
359: KFSKeyConstants.ERROR_INACTIVE,
360: KFSKeyConstants.ERROR_NOT_AMONG);
361: assertTrue(replaced);
362:
363: assertFalse(replaceMap.equals(constantMap));
364: assertFalse(replaceMap
365: .containsMessageKey(KFSKeyConstants.ERROR_INACTIVE));
366: assertTrue(replaceMap
367: .containsMessageKey(KFSKeyConstants.ERROR_NOT_AMONG));
368:
369: TypedArrayList postMessages = replaceMap
370: .getMessages("accountNbr");
371: assertEquals(2, postMessages.size());
372:
373: int replacedCount = 0;
374: for (Iterator i = postMessages.iterator(); i.hasNext();) {
375: ErrorMessage em = (ErrorMessage) i.next();
376: if (em.getErrorKey()
377: .equals(KFSKeyConstants.ERROR_NOT_AMONG)) {
378: String[] params = em.getMessageParameters();
379: assertEquals(0, params.length);
380:
381: ++replacedCount;
382: }
383: }
384: assertEquals(1, replacedCount);
385: }
386:
387: public final void testReplace_matchingProperty_matchingKey_withParams() {
388: final ErrorMap constantMap = buildReplaceErrorMap();
389: ErrorMap replaceMap = buildReplaceErrorMap();
390:
391: assertTrue(replaceMap.equals(constantMap));
392: assertTrue(replaceMap
393: .containsMessageKey(KFSKeyConstants.ERROR_INACTIVE));
394: assertFalse(replaceMap
395: .containsMessageKey(KFSKeyConstants.ERROR_NOT_AMONG));
396:
397: TypedArrayList preMessages = replaceMap
398: .getMessages("accountNbr");
399: assertEquals(2, preMessages.size());
400:
401: boolean replaced = replaceMap.replaceError("accountNbr",
402: KFSKeyConstants.ERROR_INACTIVE,
403: KFSKeyConstants.ERROR_NOT_AMONG, "zero", "one");
404: assertTrue(replaced);
405:
406: assertFalse(replaceMap.equals(constantMap));
407: assertFalse(replaceMap
408: .containsMessageKey(KFSKeyConstants.ERROR_INACTIVE));
409: assertTrue(replaceMap
410: .containsMessageKey(KFSKeyConstants.ERROR_NOT_AMONG));
411:
412: TypedArrayList postMessages = replaceMap
413: .getMessages("accountNbr");
414: assertEquals(2, postMessages.size());
415:
416: int replacedCount = 0;
417: for (Iterator i = postMessages.iterator(); i.hasNext();) {
418: ErrorMessage em = (ErrorMessage) i.next();
419: if (em.getErrorKey()
420: .equals(KFSKeyConstants.ERROR_NOT_AMONG)) {
421: String[] params = em.getMessageParameters();
422: assertEquals(2, params.length);
423: assertEquals("zero", params[0]);
424: assertEquals("one", params[1]);
425:
426: ++replacedCount;
427: }
428: }
429: assertEquals(1, replacedCount);
430: }
431:
432: private ErrorMap buildReplaceErrorMap() {
433: ErrorMap testMap = new ErrorMap();
434:
435: testMap.putError("accountNbr", KFSKeyConstants.ERROR_INACTIVE,
436: "Account Number");
437: testMap.putError("accountNbr", KFSKeyConstants.ERROR_REQUIRED,
438: "Account Number");
439: testMap.putError("chartCode", KFSKeyConstants.ERROR_REQUIRED,
440: "Chart Code");
441:
442: return testMap;
443: }
444: }
|