/* * 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.calendar; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertThat; import org.joda.time.DateTime; import org.junit.Test; public class CalendarUtilsTest { @Test public void shouldRollDateForwardByOneDay() { DateTime firstOfNextMonth = new DateTime().plusMonths(1).withDayOfMonth(1).toDateMidnight().toDateTime(); // exercise test DateTime adjustedDate = CalendarUtils.getNextDateForDay(firstOfNextMonth, 1); assertThat(adjustedDate, is(firstOfNextMonth.plusDays(1))); } @Test public void shouldRollDateForwardByTwoDay() { DateTime firstOfNextMonth = new DateTime().plusMonths(1).withDayOfMonth(1).toDateMidnight().toDateTime(); // exercise test DateTime adjustedDate = CalendarUtils.getNextDateForDay(firstOfNextMonth, 2); assertThat(adjustedDate, is(firstOfNextMonth.plusDays(2))); } @Test public void shouldRollDateForwardToNearestDayOfWeek() { DateTime firstOfNextMonth = new DateTime().plusMonths(1).withDayOfMonth(1).toDateMidnight().toDateTime(); DateTime firstTuesdayOfNextMonth = firstOfNextMonth.withDayOfWeek(DayOfWeek.tuesday()); // exercise test DateTime adjustedDate = CalendarUtils.getFirstDateForWeek(firstTuesdayOfNextMonth, DayOfWeek.wednesday()); assertThat(adjustedDate, is(firstTuesdayOfNextMonth.plusDays(1))); } @Test public void shouldRollDateForwardToNearestDayOfWeek2() { DateTime firstOfNextMonth = new DateTime().plusMonths(1).withDayOfMonth(1).toDateMidnight().toDateTime(); DateTime firstThursdayOfNextMonth = firstOfNextMonth.withDayOfWeek(DayOfWeek.thursday()); // exercise test DateTime adjustedDate = CalendarUtils.getFirstDateForWeek(firstThursdayOfNextMonth, DayOfWeek.wednesday()); assertThat(adjustedDate, is(firstThursdayOfNextMonth.plusDays(6))); } @Test public void shouldNotRollDateForwardWhenItMatchesDayOfWeek() { DateTime firstOfNextMonth = new DateTime().plusMonths(1).withDayOfMonth(1).toDateMidnight().toDateTime(); DateTime firstThursdayOfNextMonth = firstOfNextMonth.withDayOfWeek(DayOfWeek.thursday()); // exercise test DateTime adjustedDate = CalendarUtils.getFirstDateForWeek(firstThursdayOfNextMonth, DayOfWeek.thursday()); assertThat(adjustedDate, is(firstThursdayOfNextMonth)); } @Test public void shouldRollDateForwardToNearestMonthAndDayOfMonth() { DateTime firstOfNextMonth = new DateTime().plusMonths(1).withDayOfMonth(1).toDateMidnight().toDateTime(); // exercise test DateTime adjustedDate = CalendarUtils.getFirstDateForMonthOnDate(firstOfNextMonth, 15); assertThat(adjustedDate, is(firstOfNextMonth.plusDays(14))); } @Test public void shouldRollDateForwardToNearestMonthAndDayOfMonthWhenDayOfMonthHasBeenPassed() { DateTime twentiethOfNextMonth = new DateTime().plusMonths(1).withDayOfMonth(20).toDateMidnight().toDateTime(); // exercise test DateTime adjustedDate = CalendarUtils.getFirstDateForMonthOnDate(twentiethOfNextMonth, 15); assertThat(adjustedDate, is(twentiethOfNextMonth.plusMonths(1).withDayOfMonth(15))); } @Test public void shouldNotRollForwardDateIfStartingDateMatchesDayOfMonth() { DateTime secondLastDayOfJune = new DateTime().withMonthOfYear(6).withDayOfMonth(29).toDateMidnight() .toDateTime(); // exercise test DateTime adjustedDate = CalendarUtils.getFirstDateForMonthOnDate(secondLastDayOfJune, 29); assertThat(adjustedDate, is(secondLastDayOfJune)); } @Test public void shouldRollDateForwardToNearestMonthGivenWeekAndWeekDay() { DateTime thursdayFirstOfApril2010 = new DateTime().withDayOfMonth(1).withMonthOfYear(4).withYear(2010).toDateMidnight().toDateTime(); // exercise test DateTime adjustedDate = CalendarUtils.getFirstDayForMonthUsingWeekRankAndWeekday(thursdayFirstOfApril2010, 1, DayOfWeek.friday()); assertThat(adjustedDate, is(thursdayFirstOfApril2010.plusDays(1))); } @Test public void shouldRollDateForwardToNearestMonthGivenWeekAndWeekDayHaveBeenPassedInCurrentMonth() { DateTime firstOfMarch2010 = new DateTime().withYear(2010).withMonthOfYear(3).withDayOfMonth(1).toDateMidnight().toDateTime(); DateTime startingFromfirstThursdayOfNextMonth = firstOfMarch2010.withDayOfWeek(DayOfWeek.thursday()); // exercise test DateTime adjustedDate = CalendarUtils.getFirstDayForMonthUsingWeekRankAndWeekday(startingFromfirstThursdayOfNextMonth, 1, DayOfWeek.wednesday()); DateTime expectedAdjustedDate = new DateTime().withYear(2010).withMonthOfYear(4).withDayOfMonth(7).toDateMidnight().toDateTime(); assertThat(adjustedDate, is(expectedAdjustedDate)); } @Test public void shouldRollDateForwardToNearestMonthGivenWeekAndWeekDayForMonthWithFiveWeekdaysInMonth() { DateTime monday29thOfMarch2010 = new DateTime().withMonthOfYear(3).withDayOfMonth(29).withYear(2010).toDateMidnight().toDateTime(); // exercise test DateTime adjustedDate = CalendarUtils.getFirstDayForMonthUsingWeekRankAndWeekday(monday29thOfMarch2010, 5, DayOfWeek.tuesday()); assertThat(adjustedDate, is(monday29thOfMarch2010.plusDays(1))); } @Test public void shouldRollDateForwardToNextMonthAndDayOfMonthThatMatches() { DateTime firstOfNextMonth = new DateTime().plusMonths(1).withDayOfMonth(1).toDateMidnight().toDateTime(); // exercise test DateTime adjustedDate = CalendarUtils.getNextDateForMonthOnDate(firstOfNextMonth, 1, 1); assertThat(adjustedDate, is(firstOfNextMonth.plusMonths(1))); } @Test public void shouldRollDateForwardToNextMonthAndDayOfMonthThatMatchesGivenMonthDoesNotHaveThatDayNumber() { DateTime lastDayInAugust = new DateTime().withMonthOfYear(8).withDayOfMonth(31).toDateMidnight().toDateTime(); // exercise test DateTime adjustedDate = CalendarUtils.getNextDateForMonthOnDate(lastDayInAugust, 31, 1); assertThat(adjustedDate, is(lastDayInAugust.plusMonths(1))); assertThat(adjustedDate.getDayOfMonth(), is(30)); } @Test public void shouldRollDateForwardToNextDateThatMatchesGivenWeekAndWeekDayHaveBeenPassedInCurrentMonth() { DateTime wednesday7thOfApril2010 = new DateTime().withDayOfMonth(7).withMonthOfYear(4).withYear(2010).toDateMidnight().toDateTime(); DateTime thursday = wednesday7thOfApril2010.plusDays(1); // exercise test DateTime adjustedDate = CalendarUtils.getNextDayForMonthUsingWeekRankAndWeekday(thursday, 1, DayOfWeek.wednesday(), 1); DateTime wednesday5thOfMay2010 = new DateTime().withDayOfMonth(5).withMonthOfYear(5).withYear(2010).toDateMidnight().toDateTime(); assertThat(adjustedDate, is(wednesday5thOfMay2010)); } @Test public void shouldRollDateForwardToNextDateThatMatchesGivenWeekAndWeekDayForMonthWithFiveWeekdaysInMonth() { DateTime monday29thOfMarch2010 = new DateTime().withMonthOfYear(3).withDayOfMonth(29).withYear(2010).toDateMidnight().toDateTime(); // exercise test DateTime adjustedDate = CalendarUtils.getFirstDayForMonthUsingWeekRankAndWeekday(monday29thOfMarch2010, 5, DayOfWeek.tuesday()); assertThat(adjustedDate, is(monday29thOfMarch2010.plusDays(1))); } /* * !!! This is unexpected behavior of CalendarUtils.getNextDateForMonthOnDate * shown while investigating MIFOS-3584. */ @Test public void shouldPlaceNextMonthDateInTheSameMonth() { DateTime adjustedInstallementDate = new DateTime(2010, 11, 1, 0, 0, 0, 0); DateTime next = CalendarUtils.getNextDateForMonthOnDate(adjustedInstallementDate, 30, 1); assertThat(next, is(new DateTime(2010, 12, 30, 0, 0, 0, 0))); } // The same unexpected behavior but with next day in new year @Test public void shouldPlaceNextMonthDateInTheSameMonth2() { DateTime adjustedInstallementDate = new DateTime(2010, 12, 1, 0, 0, 0, 0); DateTime next = CalendarUtils.getNextDateForMonthOnDate(adjustedInstallementDate, 30, 1); assertThat(next, is(new DateTime(2011, 1, 30, 0, 0, 0, 0))); } // The same behavior with 'every' months set to 2 @Test public void shouldPlaceNextMonthDateInTheSameMonthEvery2Months() { DateTime adjustedInstallementDate = new DateTime(2010, 6, 1, 0, 0, 0, 0); DateTime next = CalendarUtils.getNextDateForMonthOnDate(adjustedInstallementDate, 30, 2); assertThat(next, is(new DateTime(2010, 8, 30, 0, 0, 0, 0))); } @Test public void shouldSelectMarchFor28February() { DateTime lastDayOfFebruary = new DateTime(2006, 2, 28, 0, 0, 0, 0); DateTime next = CalendarUtils.getNextDateForMonthOnDate(lastDayOfFebruary, 31, 1); assertThat(next, is(new DateTime(2006, 3, 31, 0, 0, 0, 0))); } @Test public void shouldSelectAugustFor28June() { DateTime lastDayOfJune = new DateTime(2006, 6, 30, 0, 0, 0, 0); DateTime next = CalendarUtils.getNextDateForMonthOnDate(lastDayOfJune, 31, 3); assertThat(next, is(new DateTime(2006, 9, 30, 0, 0, 0, 0))); } @Test public void shouldSelectNextMonth() { DateTime lastDayOfJune = new DateTime(2006, 6, 30, 0, 0, 0, 0); DateTime next = CalendarUtils.getNextDateForMonthOnDate(lastDayOfJune, 31, 1); assertThat(next, is(new DateTime(2006, 7, 31, 0, 0, 0, 0))); } private DateTime firstWednesdayOfTwoMonthsAway() { DateTime firstOfTwoMonthsAway = new DateTime().plusMonths(2).withDayOfMonth(1).toDateMidnight().toDateTime(); DateTime firstWednesdayOfTwoMonthsAway = firstOfTwoMonthsAway.withDayOfWeek(DayOfWeek.wednesday()); if (firstWednesdayOfTwoMonthsAway.getMonthOfYear() != firstOfTwoMonthsAway.getMonthOfYear()) { return firstWednesdayOfTwoMonthsAway.plusWeeks(1); } return firstWednesdayOfTwoMonthsAway; } }