001: /*
002: * Copyright 2006-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.module.gl.web.lookupable;
017:
018: import java.util.ArrayList;
019: import java.util.Iterator;
020: import java.util.List;
021: import java.util.Map;
022:
023: import org.kuali.core.util.KualiDecimal;
024: import org.kuali.kfs.KFSPropertyConstants;
025: import org.kuali.kfs.bo.GeneralLedgerPendingEntry;
026: import org.kuali.kfs.context.SpringContext;
027: import org.kuali.kfs.lookup.LookupableSpringContext;
028: import org.kuali.module.gl.bo.Balance;
029: import org.kuali.module.gl.service.BalanceService;
030: import org.kuali.module.gl.util.BusinessObjectFieldConverter;
031: import org.kuali.module.gl.web.Constant;
032: import org.kuali.test.ConfigureContext;
033:
034: /**
035: * This class contains the test cases that can be applied to the method in BalanceLookupableImpl class.
036: */
037: @ConfigureContext
038: public class BalanceLookupableHelperServiceTest extends
039: AbstractGLLookupableHelperServiceTestBase {
040:
041: private BalanceService balanceService;
042:
043: /**
044: * Sets up the services needed to test balance lookups
045: * @see org.kuali.module.gl.web.lookupable.AbstractGLLookupableHelperServiceTestBase#setUp()
046: */
047: @Override
048: protected void setUp() throws Exception {
049: super .setUp();
050:
051: setBalanceService(SpringContext.getBean(BalanceService.class));
052: lookupableHelperServiceImpl = LookupableSpringContext
053: .getLookupableHelperService("glBalanceLookupableHelperService");
054: lookupableHelperServiceImpl
055: .setBusinessObjectClass(Balance.class);
056: }
057:
058: /**
059: * Covers the search results returned by BalanceLookupableHelperService
060: * @throws Exception thrown if an exception is encountered for any reason
061: * @see org.kuali.module.gl.web.lookupable.AbstractGLLookupableTestBase#testGetSearchResults()
062: */
063: public void testGetSearchResults() throws Exception {
064: testDataGenerator.generateTransactionData(pendingEntry);
065: Balance balance = new Balance(pendingEntry);
066:
067: // test the search results before the specified entry is inserted into the database
068: Map fieldValues = getLookupFieldValues(balance, true);
069: List searchResults = lookupableHelperServiceImpl
070: .getSearchResults(fieldValues);
071: assertTrue(testDataGenerator.getMessageValue("noSuchRecord"),
072: !contains(searchResults, balance));
073:
074: // add a new entry into database
075: this .insertNewRecord(balance);
076:
077: // the new record can meet the search criteria.
078: fieldValues = getLookupFieldValues(balance, true);
079: searchResults = lookupableHelperServiceImpl
080: .getSearchResults(fieldValues);
081: assertTrue(
082: testDataGenerator.getMessageValue("wrongRecordSize"),
083: searchResults.size() == 1);
084: assertTrue(testDataGenerator
085: .getMessageValue("failToFindRecord"), contains(
086: searchResults, balance));
087:
088: // add another entry into database
089: Balance anotherBalance = new Balance(pendingEntry);
090: anotherBalance.setAccountNumber(testDataGenerator
091: .getPropertyValue("genericAccountNumber"));
092: this .insertNewRecord(anotherBalance);
093:
094: // the new record cannot meet the search criteria.
095: fieldValues = getLookupFieldValues(balance, true);
096: searchResults = lookupableHelperServiceImpl
097: .getSearchResults(fieldValues);
098: assertTrue(
099: testDataGenerator.getMessageValue("wrongRecordSize"),
100: searchResults.size() == 1);
101: assertTrue(testDataGenerator
102: .getMessageValue("failToFindRecord"), !contains(
103: searchResults, anotherBalance));
104:
105: // the new record cannot meet the search criteria.
106: fieldValues = getLookupFieldValues(balance, false);
107: searchResults = lookupableHelperServiceImpl
108: .getSearchResults(fieldValues);
109: assertTrue(
110: testDataGenerator.getMessageValue("wrongRecordSize"),
111: searchResults.size() >= 1);
112: assertTrue(testDataGenerator
113: .getMessageValue("failToFindRecord"), !contains(
114: searchResults, anotherBalance));
115: }
116:
117: /**
118: * This method includes the test cases applied to the pending entry option: Approved and All
119: *
120: * @throws Exception thrown if an exception is encountered for any reason
121: */
122: public void testPendingEntryOption() throws Exception {
123: testDataGenerator.generateTransactionData(pendingEntry);
124: pendingEntry.setUniversityFiscalPeriodCode("CB");
125: KualiDecimal pendingAmount = pendingEntry
126: .getTransactionLedgerEntryAmount().abs();
127: Balance balance = new Balance(pendingEntry);
128:
129: // prepare the test data for the pending option: approved
130: insertNewPendingEntry(pendingEntry);
131: this .insertNewRecord(balance);
132:
133: // test if the approved pending entry has been combined with cash balance
134: Map fieldValues = getLookupFieldValues(balance, true);
135: fieldValues.put(Constant.PENDING_ENTRY_OPTION,
136: Constant.APPROVED_PENDING_ENTRY);
137: fieldValues.put(Constant.CONSOLIDATION_OPTION,
138: Constant.CONSOLIDATION);
139: List searchResults = lookupableHelperServiceImpl
140: .getSearchResults(fieldValues);
141: assertTrue(
142: testDataGenerator.getMessageValue("wrongRecordSize"),
143: searchResults.size() >= 1);
144:
145: Balance result = (Balance) searchResults.get(0);
146: KualiDecimal approvedCGBeginningBalance = result
147: .getContractsGrantsBeginningBalanceAmount().abs();
148: // assertTrue(testDataGenerator.getMessageValue("incorrectAmount"), approvedCGBeginningBalance.equals(pendingAmount));
149:
150: // prepare the test data for the pending option: All
151: GeneralLedgerPendingEntry nonapprovedPendingEntry = new GeneralLedgerPendingEntry();
152: testDataGenerator
153: .generateTransactionData(nonapprovedPendingEntry);
154: nonapprovedPendingEntry.setUniversityFiscalPeriodCode("CB");
155: nonapprovedPendingEntry.setFinancialDocumentApprovedCode(" ");
156:
157: String sequenceNumber = testDataGenerator.getProperties()
158: .getProperty("genericSquenceNumber");
159: nonapprovedPendingEntry
160: .setTransactionLedgerEntrySequenceNumber(new Integer(
161: sequenceNumber));
162:
163: insertNewPendingEntry(nonapprovedPendingEntry);
164:
165: // test if the all pending entries have been combined with cash balance
166: fieldValues = getLookupFieldValues(balance, true);
167: fieldValues.put(Constant.PENDING_ENTRY_OPTION,
168: Constant.ALL_PENDING_ENTRY);
169: fieldValues.put(Constant.CONSOLIDATION_OPTION,
170: Constant.CONSOLIDATION);
171:
172: searchResults = lookupableHelperServiceImpl
173: .getSearchResults(fieldValues);
174: assertTrue(
175: testDataGenerator.getMessageValue("wrongRecordSize"),
176: searchResults.size() == 1);
177:
178: Balance newResult = (Balance) searchResults.get(0);
179: KualiDecimal allCGBeginningBalance = newResult
180: .getContractsGrantsBeginningBalanceAmount().abs();
181: // assertTrue(testDataGenerator.getMessageValue("incorrectAmount"),
182: // !approvedCGBeginningBalance.equals(allCGBeginningBalance));
183: }
184:
185: /**
186: * This method tests if the orphan pending entries can be included in the search results
187: *
188: * @throws Exception thrown if an exception is encountered for any reason
189: */
190: public void testOrphanPendingEntry() throws Exception {
191: testDataGenerator.generateTransactionData(pendingEntry);
192: Balance balance = new Balance(pendingEntry);
193:
194: // test if the all pending entries have been combined into a balance record
195: // TODO the pending entry cannot be retrived. It took one day to find the reason, but I didn't sovle that.
196: getPendingEntryService().save(pendingEntry);
197: insertNewRecord(balance);
198:
199: Map fieldValues = getLookupFieldValues(balance, true);
200: fieldValues.put(Constant.PENDING_ENTRY_OPTION,
201: Constant.ALL_PENDING_ENTRY);
202:
203: Map pendingEntryFieldValues = BusinessObjectFieldConverter
204: .convertToTransactionFieldValues(fieldValues);
205: pendingEntryFieldValues.remove(Constant.CONSOLIDATION_OPTION);
206: pendingEntryFieldValues.remove(Constant.PENDING_ENTRY_OPTION);
207: pendingEntryFieldValues.remove(Constant.AMOUNT_VIEW_OPTION);
208: Iterator iterator = getPendingEntryService()
209: .findPendingLedgerEntriesForBalance(
210: pendingEntryFieldValues, true);
211:
212: List searchResults = lookupableHelperServiceImpl
213: .getSearchResults(fieldValues);
214: assertTrue(testDataGenerator
215: .getMessageValue("failToFindRecord"), contains(
216: searchResults, balance));
217: assertTrue(
218: testDataGenerator.getMessageValue("wrongRecordSize"),
219: searchResults.size() >= 1);
220: }
221:
222: /**
223: * This method includes the test cases applied to the consolidation option: Consolidate and Detail
224: *
225: * @throws Exception thrown if an exception is encountered for any reason
226: */
227: public void testConsolidationOption() throws Exception {
228: // ensure the transaction data does not exist in enty table. Otherwise, execption may be raised
229: testDataGenerator.generateTransactionData(pendingEntry);
230: Balance balanceOne = new Balance(pendingEntry);
231: this .insertNewRecord(balanceOne);
232:
233: // get the number of the search results before adding the second record into database
234: Map fieldValues = getLookupFieldValues(balanceOne, true);
235: fieldValues.put(Constant.CONSOLIDATION_OPTION,
236: Constant.CONSOLIDATION);
237:
238: List searchResults = lookupableHelperServiceImpl
239: .getSearchResults(fieldValues);
240: int numOfFirstResults = searchResults.size();
241:
242: String subAccountNumber = testDataGenerator
243: .getPropertyValue("genericSubAccountNumber");
244: pendingEntry.setSubAccountNumber(subAccountNumber);
245: Balance balanceTwo = new Balance(pendingEntry);
246: this .insertNewRecord(balanceTwo);
247:
248: // test if the second record is consolidated with others
249: fieldValues = getLookupFieldValues(balanceOne, true);
250: fieldValues.put(Constant.CONSOLIDATION_OPTION,
251: Constant.CONSOLIDATION);
252:
253: searchResults = lookupableHelperServiceImpl
254: .getSearchResults(fieldValues);
255: int numOfSecondResults = searchResults.size();
256:
257: // test if the search results appear in details
258: fieldValues = getLookupFieldValues(balanceOne, false);
259: fieldValues.put(Constant.CONSOLIDATION_OPTION, Constant.DETAIL);
260:
261: searchResults = lookupableHelperServiceImpl
262: .getSearchResults(fieldValues);
263: int numOfThirdResults = searchResults.size();
264: assertTrue(
265: testDataGenerator.getMessageValue("wrongRecordSize"),
266: numOfSecondResults < numOfThirdResults);
267: }
268:
269: /**
270: * This method includes the test cases applied to the amount view option: Monthly and Accumulate
271: *
272: * @throws Exception thrown if an exception is encountered for any reason
273: */
274: public void testAmountViewOption() throws Exception {
275: try {
276: testDataGenerator.generateTransactionData(pendingEntry);
277: Balance balanceOne = new Balance(pendingEntry);
278:
279: this .insertNewRecord(balanceOne);
280:
281: // get the amount of the second month
282: Map fieldValues = getLookupFieldValues(balanceOne, true);
283: fieldValues.put(Constant.AMOUNT_VIEW_OPTION,
284: Constant.MONTHLY);
285:
286: List searchResults = lookupableHelperServiceImpl
287: .getSearchResults(fieldValues);
288: assertTrue(testDataGenerator
289: .getMessageValue("wrongRecordSize"), searchResults
290: .size() == 1);
291: assertTrue(testDataGenerator
292: .getMessageValue("failToFindRecord"), contains(
293: searchResults, balanceOne));
294:
295: KualiDecimal month2Amount = ((Balance) searchResults.get(0))
296: .getMonth2Amount();
297: assertTrue(testDataGenerator
298: .getMessageValue("incorrectAmount"), month2Amount
299: .equals(KualiDecimal.ZERO));
300:
301: // get the acculated amount of the second month
302: fieldValues = getLookupFieldValues(balanceOne, true);
303: fieldValues.put(Constant.AMOUNT_VIEW_OPTION,
304: Constant.ACCUMULATE);
305:
306: searchResults = lookupableHelperServiceImpl
307: .getSearchResults(fieldValues);
308: assertTrue(testDataGenerator
309: .getMessageValue("wrongRecordSize"), searchResults
310: .size() == 1);
311: assertTrue(testDataGenerator
312: .getMessageValue("failToFindRecord"), contains(
313: searchResults, balanceOne));
314:
315: KualiDecimal accumulatedMonth2Amount = ((Balance) searchResults
316: .get(0)).getMonth2Amount();
317:
318: // test if the acculated amount is greater than or equal to the monthly amount
319: assertTrue(testDataGenerator
320: .getMessageValue("incorrectAmount"),
321: accumulatedMonth2Amount
322: .isGreaterEqual(month2Amount));
323: } catch (Exception e) {
324: e.printStackTrace();
325: }
326: }
327:
328: /**
329: * This method includes the test cases applied to the consolidation option: Consolidate and Detail
330: *
331: * @throws Exception thrown if an exception is encountered for any reason
332: */
333: public void testPerformance() throws Exception {
334: long threshlod = 60000;
335:
336: // get the number of the search results before adding the second record into database
337: Balance balance = new Balance();
338: balance.setAccountNumber("1031400");
339: balance.setUniversityFiscalYear(2007);
340: balance.setChartOfAccountsCode("BL");
341:
342: Map fieldValues = getLookupFieldValues(balance, true);
343: fieldValues.put(Constant.CONSOLIDATION_OPTION,
344: Constant.CONSOLIDATION);
345:
346: long startTime = System.currentTimeMillis();
347: List searchResults = lookupableHelperServiceImpl
348: .getSearchResults(fieldValues);
349: long endTime = System.currentTimeMillis();
350: long duration = endTime - startTime;
351:
352: System.out.println(duration + "ms");
353: assertTrue("Too slow", duration < threshlod);
354:
355: // test if the search results appear in details
356: fieldValues = getLookupFieldValues(balance, false);
357: fieldValues.put(Constant.CONSOLIDATION_OPTION, Constant.DETAIL);
358:
359: startTime = System.currentTimeMillis();
360: searchResults = lookupableHelperServiceImpl
361: .getSearchResults(fieldValues);
362: endTime = System.currentTimeMillis();
363: duration = endTime - startTime;
364:
365: System.out.println(duration + "ms");
366: assertTrue("Too slow", duration < threshlod);
367: }
368:
369: /**
370: * Returns the lookup fields to test in the search results
371: * @param isExtended true if extended fields should be included, false if they should not be included
372: * @return a List of field names to check
373: * @see org.kuali.module.gl.web.lookupable.AbstractGLLookupableTestBase#getLookupFields(boolean)
374: */
375: public List getLookupFields(boolean isExtended) {
376: List lookupFields = new ArrayList();
377:
378: lookupFields.add(KFSPropertyConstants.UNIVERSITY_FISCAL_YEAR);
379: lookupFields.add(KFSPropertyConstants.CHART_OF_ACCOUNTS_CODE);
380: lookupFields.add(KFSPropertyConstants.ACCOUNT_NUMBER);
381: lookupFields.add(KFSPropertyConstants.BALANCE_TYPE_CODE);
382:
383: lookupFields.add(Constant.CONSOLIDATION_OPTION);
384: lookupFields.add(Constant.PENDING_ENTRY_OPTION);
385: lookupFields.add(Constant.AMOUNT_VIEW_OPTION);
386:
387: // include the extended fields
388: if (isExtended) {
389: lookupFields.add(KFSPropertyConstants.SUB_ACCOUNT_NUMBER);
390: lookupFields.add(KFSPropertyConstants.OBJECT_CODE);
391: lookupFields.add(KFSPropertyConstants.SUB_OBJECT_CODE);
392: lookupFields.add(KFSPropertyConstants.OBJECT_TYPE_CODE);
393: }
394: return lookupFields;
395: }
396:
397: /**
398: * This method inserts a new balance record into database
399: *
400: * @param balance the given balance
401: */
402: protected void insertNewRecord(Balance balance) {
403: try {
404: balanceService.save(balance);
405: } catch (Exception e) {
406: e.printStackTrace();
407: }
408: }
409:
410: /**
411: * Gets the balanceService attribute.
412: *
413: * @return Returns the balanceService.
414: */
415: public BalanceService getBalanceService() {
416: return balanceService;
417: }
418:
419: /**
420: * Sets the balanceService attribute value.
421: *
422: * @param balanceService The balanceService to set.
423: */
424: public void setBalanceService(BalanceService balanceService) {
425: this.balanceService = balanceService;
426: }
427: }
|