/*
* Copyright (c) 2005-2011 Grameen Foundation USA
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
* implied. See the License for the specific language governing
* permissions and limitations under the License.
*
* See also http://www.apache.org/licenses/LICENSE-2.0.html for an
* explanation of the license and how it is applied.
*/
package org.mifos.application.holiday.persistence;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.junit.matchers.JUnitMatchers.hasItem;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import org.joda.time.DateTime;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import org.mifos.application.holiday.business.Holiday;
import org.mifos.application.holiday.business.HolidayBO;
import org.mifos.application.master.business.MifosCurrency;
import org.mifos.config.Localization;
import org.mifos.customers.office.business.OfficeBO;
import org.mifos.customers.office.util.helpers.OfficeConstants;
import org.mifos.domain.builders.HolidayBuilder;
import org.mifos.domain.builders.OfficeBuilder;
import org.mifos.dto.domain.HolidayDetails;
import org.mifos.framework.MifosIntegrationTestCase;
import org.mifos.framework.TestUtils;
import org.mifos.framework.components.audit.util.helpers.AuditConfiguration;
import org.mifos.framework.exceptions.ApplicationException;
import org.mifos.framework.hibernate.helper.StaticHibernateUtil;
import org.mifos.framework.util.StandardTestingService;
import org.mifos.framework.util.helpers.IntegrationTestObjectMother;
import org.mifos.framework.util.helpers.Money;
import org.mifos.service.test.TestMode;
import org.mifos.test.framework.util.DatabaseCleaner;
import org.springframework.beans.factory.annotation.Autowired;
public class HolidayDaoHibernateIntegrationTest extends MifosIntegrationTestCase {
@Autowired
private HolidayDao holidayDao;
@Autowired
private DatabaseCleaner databaseCleaner;
private OfficeBO areaOffice1;
private OfficeBO branch1;
private OfficeBO areaOffice2;
private static MifosCurrency oldDefaultCurrency;
@BeforeClass
public static void initialiseHibernateUtil() {
Locale locale = Localization.getInstance().getConfiguredLocale();
AuditConfiguration.init(locale);
oldDefaultCurrency = Money.getDefaultCurrency();
Money.setDefaultCurrency(TestUtils.RUPEE);
new StandardTestingService().setTestMode(TestMode.INTEGRATION);
}
@AfterClass
public static void resetCurrency() {
Money.setDefaultCurrency(oldDefaultCurrency);
}
@After
public void cleanDatabaseTablesAfterTest() {
// NOTE: - only added to stop older integration tests failing due to brittleness
databaseCleaner.clean();
}
@Before
public void cleanDatabaseTables() {
databaseCleaner.clean();
}
@Test
public void isNotFutureRepaymentHolidayWhenHolidayDoesNotExist() {
DateTime secondLastDayOfYear = new DateTime().withMonthOfYear(12).withDayOfMonth(30).toDateMidnight().toDateTime();
Assert.assertFalse(holidayDao.isFutureRepaymentHoliday((short) 1, secondLastDayOfYear.toLocalDate().toString()));
}
@Test
@Ignore
public void sameDayHolidayIsNotFutureRepaymentHoliday() {
DateTime secondLastDayOfYear = new DateTime().withMonthOfYear(12).withDayOfMonth(30).toDateMidnight().toDateTime();
Holiday sameDayRepaymentHoliday = new HolidayBuilder().from(secondLastDayOfYear).to(secondLastDayOfYear).withSameDayAsRule().build();
insertHoliday(sameDayRepaymentHoliday);
Assert.assertFalse(holidayDao.isFutureRepaymentHoliday((short) 1, secondLastDayOfYear.toLocalDate().toString()));
}
@Test
@Ignore
public void nextDayRepaymentIsFutureRepaymentHoliday() {
DateTime secondLastDayOfYear = new DateTime().withMonthOfYear(12).withDayOfMonth(30).toDateMidnight().toDateTime();
Holiday nextDayRepaymentHoliday = new HolidayBuilder().from(secondLastDayOfYear).to(secondLastDayOfYear).withNextMeetingRule().build();
insertHoliday(nextDayRepaymentHoliday);
Assert.assertTrue(holidayDao.isFutureRepaymentHoliday((short) 1, secondLastDayOfYear.toLocalDate().toString()));
}
@Test
public void shouldSaveFutureHoliday() throws Exception {
List<Holiday> holidays = holidayDao.findAllHolidaysThisYearAndNext((short) 1);
int initialCount = holidays.size();
OfficeBO headOffice = IntegrationTestObjectMother.findOfficeById(Short.valueOf("1"));
Holiday futureHoliday = new HolidayBuilder().from(new DateTime()).to(new DateTime().plusDays(1)).appliesTo(
headOffice).build();
StaticHibernateUtil.startTransaction();
holidayDao.save(futureHoliday);
StaticHibernateUtil.flushSession();
holidays = holidayDao.findAllHolidaysThisYearAndNext(headOffice.getOfficeId());
assertFalse(holidays.isEmpty());
assertThat(holidays.size() - initialCount, is(1));
}
@Ignore
@Test
public void shouldFindAllHolidaysOrderedByFromDateAscending() throws Exception {
DateTime secondlastDayOfYear = new DateTime().withMonthOfYear(12).withDayOfMonth(30).toDateMidnight()
.toDateTime();
DateTime lastDayOfYear = secondlastDayOfYear.plusDays(1);
DateTime secondOfJanNextYear = new DateTime().plusYears(1).withMonthOfYear(1).withDayOfMonth(2)
.toDateMidnight().toDateTime();
DateTime thirdOfJanNextYear = new DateTime().plusYears(1).withMonthOfYear(1).withDayOfMonth(3).toDateMidnight()
.toDateTime();
List<Holiday> holidays = holidayDao.findAllHolidaysThisYearAndNext(new Short("1"));
int initialCountOfHolidays = holidays.size();
List<Holiday> futureHolidays = holidayDao.findAllHolidaysFromDateAndNext(new Short("1"), secondOfJanNextYear.toLocalDate().toString());
int initialCountOfFutureHolidays = futureHolidays.size();
Holiday holiday1 = new HolidayBuilder().from(secondlastDayOfYear).to(secondlastDayOfYear).build();
Holiday holiday2 = new HolidayBuilder().from(secondOfJanNextYear).to(secondOfJanNextYear).build();
Holiday holiday3 = new HolidayBuilder().from(thirdOfJanNextYear).to(thirdOfJanNextYear).build();
Holiday holiday4 = new HolidayBuilder().from(lastDayOfYear).to(lastDayOfYear).build();
insertHoliday(holiday2);
insertHoliday(holiday3);
insertHoliday(holiday1);
insertHoliday(holiday4);
holidays = holidayDao.findAllHolidaysThisYearAndNext(new Short("1"));
assertThat(holidays.size() - initialCountOfHolidays, is(4));
assertTrue(holidays.get(0).encloses(secondlastDayOfYear.toDate()));
assertTrue(holidays.get(1).encloses(lastDayOfYear.toDate()));
assertTrue(holidays.get(2).encloses(secondOfJanNextYear.toDate()));
assertTrue(holidays.get(3).encloses(thirdOfJanNextYear.toDate()));
futureHolidays = holidayDao.findAllHolidaysFromDateAndNext(new Short("1"), secondOfJanNextYear.toLocalDate().toString());
assertThat(futureHolidays.size() - initialCountOfFutureHolidays, is(2));
assertTrue(futureHolidays.get(0).encloses(secondOfJanNextYear.toDate()));
assertTrue(futureHolidays.get(1).encloses(thirdOfJanNextYear.toDate()));
}
@Ignore
@Test
public void shouldFindWhetherGivenDateIsAHoliday() {
Short officeId = Short.valueOf("1");
DateTime secondlastDayOfYear = new DateTime().withMonthOfYear(12).withDayOfMonth(30).toDateMidnight().toDateTime();
insertHoliday(new HolidayBuilder().from(secondlastDayOfYear).to(secondlastDayOfYear).build());
assertThat(holidayDao.isHoliday(officeId, secondlastDayOfYear.toLocalDate().toString()), is(true));
DateTime thirdOfJanNextYear = new DateTime().plusYears(1).withMonthOfYear(1).withDayOfMonth(3).toDateMidnight().toDateTime();
DateTime sixthOfJanNextYear = new DateTime().plusYears(1).withMonthOfYear(1).withDayOfMonth(6).toDateMidnight().toDateTime();
DateTime tenthOfJanNextYear = new DateTime().plusYears(1).withMonthOfYear(1).withDayOfMonth(10).toDateMidnight().toDateTime();
DateTime eleventhOfJanNextYear = new DateTime().plusYears(1).withMonthOfYear(1).withDayOfMonth(11).toDateMidnight().toDateTime();
insertHoliday(new HolidayBuilder().from(thirdOfJanNextYear).to(tenthOfJanNextYear).build());
assertThat(holidayDao.isHoliday(officeId, thirdOfJanNextYear.toLocalDate().toString()), is(true));
assertThat(holidayDao.isHoliday(officeId, sixthOfJanNextYear.toLocalDate().toString()), is(true));
assertThat(holidayDao.isHoliday(officeId, tenthOfJanNextYear.toLocalDate().toString()), is(true));
assertThat(holidayDao.isHoliday(officeId, eleventhOfJanNextYear.toLocalDate().toString()), is(false));
}
@Test
public void shouldfindCurrentAndFutureOfficeHolidaysEarliestFirst() throws Exception {
DateTime yesterday = new DateTime().minusDays(1);
Set<HolidayBO> holidays;
OfficeBO headOffice = IntegrationTestObjectMother.findOfficeById(Short.valueOf("1"));
holidays = new HashSet<HolidayBO>();
holidays.add((HolidayBO) new HolidayBuilder().withName("Fourth").from(yesterday.plusWeeks(4)).to(
yesterday.plusWeeks(5)).build());
holidays.add((HolidayBO) new HolidayBuilder().withName("Second").from(yesterday.plusDays(1)).to(
yesterday.plusWeeks(7)).build());
headOffice.setHolidays(holidays);
IntegrationTestObjectMother.createOffice(headOffice);
// builder not setting searchId correctly due to not going thru office.save (which uses HierarchyManager)
String headOfficeSearchId = headOffice.getSearchId();
OfficeBO areaOffice = new OfficeBuilder().withName("Area Office").withSearchId(headOfficeSearchId + "25.")
.withParentOffice(headOffice).withGlobalOfficeNum("area56").build();
holidays = new HashSet<HolidayBO>();
holidays.add((HolidayBO) new HolidayBuilder().withName("Fifth").from(yesterday.plusWeeks(8)).to(
yesterday.plusWeeks(9)).build());
areaOffice.setHolidays(holidays);
IntegrationTestObjectMother.createOffice(areaOffice);
OfficeBO myOffice = new OfficeBuilder().withName("My Office").withSearchId(headOfficeSearchId + "25.1.")
.withParentOffice(areaOffice).withGlobalOfficeNum("my001").build();
holidays = new HashSet<HolidayBO>();
holidays.add((HolidayBO) new HolidayBuilder().withName("Third").from(yesterday.plusWeeks(3)).to(
yesterday.plusWeeks(4)).build());
holidays.add((HolidayBO) new HolidayBuilder().withName("First").from(yesterday).to(yesterday.plusWeeks(2))
.build());
myOffice.setHolidays(holidays);
IntegrationTestObjectMother.createOffice(myOffice);
OfficeBO anotherOffice = new OfficeBuilder().withName("Another Unconnected Office").withSearchId(
headOfficeSearchId + "26.").withParentOffice(headOffice).withGlobalOfficeNum("n/a001").build();
holidays = new HashSet<HolidayBO>();
holidays.add((HolidayBO) new HolidayBuilder().withName("N/A").from(yesterday.minusWeeks(3)).to(
yesterday.plusWeeks(4)).build());
anotherOffice.setHolidays(holidays);
IntegrationTestObjectMother.createOffice(anotherOffice);
List<Holiday> myHolidays = holidayDao.findCurrentAndFutureOfficeHolidaysEarliestFirst(myOffice.getOfficeId());
assertThat(myHolidays.size(), is(5));
assertThat(myHolidays.get(0).getName(), is("First"));
assertThat(myHolidays.get(1).getName(), is("Second"));
assertThat(myHolidays.get(2).getName(), is("Third"));
assertThat(myHolidays.get(3).getName(), is("Fourth"));
assertThat(myHolidays.get(4).getName(), is("Fifth"));
}
@Test
public void shouldThrowExceptionWhenFutureHolidaysApplicableToNewParentOfficeDifferFromPreviousParentOffice() throws Exception {
OfficeBO headOffice = IntegrationTestObjectMother.findOfficeById(Short.valueOf("1"));
// setup
createOfficeHierarchyUnderHeadOffice(headOffice);
DateTime tomorrow = new DateTime().plusDays(1);
HolidayDetails holidayDetails = new HolidayBuilder().withName("areaOffice2Holiday").from(tomorrow).to(tomorrow).buildDto();
IntegrationTestObjectMother.createHoliday(holidayDetails, Arrays.asList(areaOffice2.getOfficeId()));
HolidayDetails branchOnlyHolidayDetails = new HolidayBuilder().withName("branchOnlyHoliday").from(tomorrow).to(tomorrow).buildDto();
IntegrationTestObjectMother.createHoliday(branchOnlyHolidayDetails, Arrays.asList(branch1.getOfficeId()));
// refetch
branch1 = IntegrationTestObjectMother.findOfficeById(branch1.getOfficeId());
// exercise test
try {
holidayDao.validateNoExtraFutureHolidaysApplicableOnParentOffice(branch1.getParentOffice().getOfficeId(), areaOffice2.getOfficeId());
fail("shouldThrowExceptionWhenFutureHolidaysApplicableToNewParentOfficeDifferFromPreviousParentOffice");
} catch (ApplicationException e) {
assertThat(e.getKey(), is(OfficeConstants.ERROR_REPARENT_NOT_ALLOWED_AS_FUTURE_APPLICABLE_HOLIDAYS_ARE_DIFFERENT_ON_PREVIOUS_AND_NEW_PARENT));
}
}
@Test
public void shouldNotThrowExceptionWhenFutureHolidaysApplicableToNewParentOfficeDoNotDifferFromPreviousParentOffice() throws Exception {
OfficeBO headOffice = IntegrationTestObjectMother.findOfficeById(Short.valueOf("1"));
// setup
createOfficeHierarchyUnderHeadOffice(headOffice);
DateTime tomorrow = new DateTime().plusDays(1);
HolidayDetails holidayDetails = new HolidayBuilder().withName("areaOffice2Holiday").from(tomorrow).to(tomorrow).buildDto();
IntegrationTestObjectMother.createHoliday(holidayDetails, Arrays.asList(areaOffice2.getOfficeId(), areaOffice1.getOfficeId()));
HolidayDetails branchOnlyHolidayDetails = new HolidayBuilder().withName("branchOnlyHoliday").from(tomorrow).to(tomorrow).buildDto();
IntegrationTestObjectMother.createHoliday(branchOnlyHolidayDetails, Arrays.asList(branch1.getOfficeId()));
// refetch
branch1 = IntegrationTestObjectMother.findOfficeById(branch1.getOfficeId());
// exercise test
holidayDao.validateNoExtraFutureHolidaysApplicableOnParentOffice(branch1.getParentOffice().getOfficeId(), areaOffice2.getOfficeId());
}
@Test
public void shouldRetrieveOfficeNames() throws Exception {
OfficeBO headOffice = IntegrationTestObjectMother.findOfficeById(Short.valueOf("1"));
// setup
createOfficeHierarchyUnderHeadOffice(headOffice);
List<Short> officeIds = Arrays.asList(branch1.getOfficeId());
// exercise test
List<String> officeNames = holidayDao.retrieveApplicableOfficeNames(officeIds);
// verification
assertThat(officeNames, hasItem(branch1.getOfficeName()));
}
private void insertHoliday(final Holiday holiday) {
OfficeBO headOffice = IntegrationTestObjectMother.findOfficeById(Short.valueOf("1"));
HolidayDetails holidayDetails = new HolidayDetails("HolidayDaoTest", holiday.getFromDate().toDate(), holiday
.getThruDate().toDate(), holiday.getRepaymentRuleType().getValue());
List<Short> officeIds = Arrays.asList(headOffice.getOfficeId());
IntegrationTestObjectMother.createHoliday(holidayDetails, officeIds);
}
private void createOfficeHierarchyUnderHeadOffice(OfficeBO headOffice) {
areaOffice1 = new OfficeBuilder().areaOffice()
.withParentOffice(headOffice)
.withName("areaOffice1")
.withGlobalOfficeNum("x002")
.withSearchId("1.1.2")
.build();
IntegrationTestObjectMother.createOffice(areaOffice1);
branch1 = new OfficeBuilder().branchOffice()
.withParentOffice(areaOffice1)
.withName("branch1")
.withGlobalOfficeNum("x005")
.withSearchId("1.1.2.1")
.build();
IntegrationTestObjectMother.createOffice(branch1);
areaOffice2 = new OfficeBuilder().areaOffice()
.withParentOffice(headOffice)
.withName("areaOffice2")
.withGlobalOfficeNum("x003")
.withSearchId("1.1.3")
.build();
IntegrationTestObjectMother.createOffice(areaOffice2);
}
}