/*
* $Id: VEventTest.java [28/09/2004]
*
* Copyright (c) 2004, Ben Fortuna All rights reserved.
*/
package net.fortuna.ical4j.model.component;
import java.io.FileInputStream;
import java.io.IOException;
import java.text.ParseException;
import java.util.Calendar;
import java.util.Iterator;
import net.fortuna.ical4j.data.CalendarBuilder;
import net.fortuna.ical4j.data.ParserException;
import net.fortuna.ical4j.model.Component;
import net.fortuna.ical4j.model.ComponentTest;
import net.fortuna.ical4j.model.Date;
import net.fortuna.ical4j.model.DateTime;
import net.fortuna.ical4j.model.Dur;
import net.fortuna.ical4j.model.ParameterList;
import net.fortuna.ical4j.model.Period;
import net.fortuna.ical4j.model.PeriodList;
import net.fortuna.ical4j.model.Property;
import net.fortuna.ical4j.model.Recur;
import net.fortuna.ical4j.model.TimeZone;
import net.fortuna.ical4j.model.TimeZoneRegistry;
import net.fortuna.ical4j.model.TimeZoneRegistryFactory;
import net.fortuna.ical4j.model.ValidationException;
import net.fortuna.ical4j.model.WeekDay;
import net.fortuna.ical4j.model.parameter.TzId;
import net.fortuna.ical4j.model.parameter.Value;
import net.fortuna.ical4j.model.property.DtEnd;
import net.fortuna.ical4j.model.property.DtStamp;
import net.fortuna.ical4j.model.property.DtStart;
import net.fortuna.ical4j.model.property.ExDate;
import net.fortuna.ical4j.model.property.RRule;
import net.fortuna.ical4j.model.property.Summary;
import net.fortuna.ical4j.model.property.Uid;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* A test case for VEvents.
* @author Ben Fortuna
*/
public class VEventTest extends ComponentTest {
private static Log log = LogFactory.getLog(VEventTest.class);
private TimeZoneRegistry registry;
private VTimeZone tz;
private TzId tzParam;
private VEvent weekdayNineToFiveEvents = null;
private VEvent dailyWeekdayEvents = null;
private VEvent monthlyWeekdayEvents = null;
public void setUp() throws Exception {
super.setUp();
registry = TimeZoneRegistryFactory.getInstance().createRegistry();
// create timezone property..
tz = registry.getTimeZone("Australia/Melbourne").getVTimeZone();
// create tzid parameter..
tzParam = new TzId(tz.getProperty(Property.TZID).getValue());
Calendar weekday9AM = getCalendarInstance();
weekday9AM.set(2005, Calendar.MARCH, 7, 9, 0, 0);
weekday9AM.set(Calendar.MILLISECOND, 0);
Calendar weekday5PM = getCalendarInstance();
weekday5PM.set(2005, Calendar.MARCH, 7, 17, 0, 0);
weekday5PM.set(Calendar.MILLISECOND, 0);
// Do the recurrence until December 31st.
Calendar untilCal = getCalendarInstance();
untilCal.set(2005, Calendar.DECEMBER, 31);
untilCal.set(Calendar.MILLISECOND, 0);
Date until = new Date(untilCal.getTime().getTime());
// 9:00AM to 5:00PM Rule using weekly
Recur recurWeekly = new Recur(Recur.WEEKLY, until);
recurWeekly.getDayList().add(WeekDay.MO);
recurWeekly.getDayList().add(WeekDay.TU);
recurWeekly.getDayList().add(WeekDay.WE);
recurWeekly.getDayList().add(WeekDay.TH);
recurWeekly.getDayList().add(WeekDay.FR);
recurWeekly.setInterval(1);
recurWeekly.setWeekStartDay(WeekDay.MO.getDay());
RRule rruleWeekly = new RRule(recurWeekly);
// 9:00AM to 5:00PM Rule using daily frequency
Recur recurDaily = new Recur(Recur.DAILY, until);
recurDaily.getDayList().add(WeekDay.MO);
recurDaily.getDayList().add(WeekDay.TU);
recurDaily.getDayList().add(WeekDay.WE);
recurDaily.getDayList().add(WeekDay.TH);
recurDaily.getDayList().add(WeekDay.FR);
recurDaily.setInterval(1);
recurDaily.setWeekStartDay(WeekDay.MO.getDay());
RRule rruleDaily = new RRule(recurDaily);
// 9:00AM to 5:00PM Rule using monthly frequency
Recur recurMonthly = new Recur(Recur.MONTHLY, until);
recurMonthly.getDayList().add(WeekDay.MO);
recurMonthly.getDayList().add(WeekDay.TU);
recurMonthly.getDayList().add(WeekDay.WE);
recurMonthly.getDayList().add(WeekDay.TH);
recurMonthly.getDayList().add(WeekDay.FR);
recurMonthly.setInterval(1);
recurMonthly.setWeekStartDay(WeekDay.MO.getDay());
RRule rruleMonthly = new RRule(recurMonthly);
Summary summary = new Summary("TEST EVENTS THAT HAPPEN 9-5 MON-FRI DEFINED WEEKLY");
weekdayNineToFiveEvents = new VEvent();
weekdayNineToFiveEvents.getProperties().add(rruleWeekly);
weekdayNineToFiveEvents.getProperties().add(summary);
DtStart dtStart = new DtStart(new DateTime(weekday9AM.getTime().getTime()));
// dtStart.getParameters().add(Value.DATE);
weekdayNineToFiveEvents.getProperties().add(dtStart);
DtEnd dtEnd = new DtEnd(new DateTime(weekday5PM.getTime().getTime()));
// dtEnd.getParameters().add(Value.DATE);
weekdayNineToFiveEvents.getProperties().add(dtEnd);
weekdayNineToFiveEvents.getProperties().add(new Uid("000001@modularity.net.au"));
// ensure event is valid..
weekdayNineToFiveEvents.validate();
summary = new Summary("TEST EVENTS THAT HAPPEN 9-5 MON-FRI DEFINED DAILY");
dailyWeekdayEvents = new VEvent();
dailyWeekdayEvents.getProperties().add(rruleDaily);
dailyWeekdayEvents.getProperties().add(summary);
DtStart dtStart2 = new DtStart(new DateTime(weekday9AM.getTime().getTime()));
// dtStart2.getParameters().add(Value.DATE);
dailyWeekdayEvents.getProperties().add(dtStart2);
DtEnd dtEnd2 = new DtEnd(new DateTime(weekday5PM.getTime().getTime()));
// dtEnd2.getParameters().add(Value.DATE);
dailyWeekdayEvents.getProperties().add(dtEnd2);
dailyWeekdayEvents.getProperties().add(new Uid("000002@modularity.net.au"));
// ensure event is valid..
dailyWeekdayEvents.validate();
summary = new Summary("TEST EVENTS THAT HAPPEN 9-5 MON-FRI DEFINED MONTHLY");
monthlyWeekdayEvents = new VEvent();
monthlyWeekdayEvents.getProperties().add(rruleMonthly);
monthlyWeekdayEvents.getProperties().add(summary);
DtStart dtStart3 = new DtStart(new DateTime(weekday9AM.getTime().getTime()));
// dtStart3.getParameters().add(Value.DATE);
monthlyWeekdayEvents.getProperties().add(dtStart3);
DtEnd dtEnd3 = new DtEnd(new DateTime(weekday5PM.getTime().getTime()));
// dtEnd3.getParameters().add(Value.DATE);
monthlyWeekdayEvents.getProperties().add(dtEnd3);
monthlyWeekdayEvents.getProperties().add(new Uid("000003@modularity.net.au"));
// ensure event is valid..
monthlyWeekdayEvents.validate();
}
/**
* @return
*/
private Calendar getCalendarInstance() {
return Calendar.getInstance(); //java.util.TimeZone.getTimeZone(TimeZones.GMT_ID));
}
/**
*
*/
public final void testChristmas() {
// create event start date..
java.util.Calendar calendar = getCalendarInstance();
calendar.set(java.util.Calendar.MONTH, java.util.Calendar.DECEMBER);
calendar.set(java.util.Calendar.DAY_OF_MONTH, 25);
DtStart start = new DtStart(new Date(calendar.getTime()));
start.getParameters().add(tzParam);
start.getParameters().add(Value.DATE);
Summary summary = new Summary("Christmas Day; \n this is a, test\\");
VEvent christmas = new VEvent();
christmas.getProperties().add(start);
christmas.getProperties().add(summary);
log.info(christmas);
}
/**
* Test creating an event with an associated timezone.
*/
public final void testMelbourneCup() {
TimeZoneRegistry registry = TimeZoneRegistryFactory.getInstance().createRegistry();
TimeZone timezone = registry.getTimeZone("Australia/Melbourne");
java.util.Calendar cal = java.util.Calendar.getInstance(timezone);
cal.set(java.util.Calendar.YEAR, 2005);
cal.set(java.util.Calendar.MONTH, java.util.Calendar.NOVEMBER);
cal.set(java.util.Calendar.DAY_OF_MONTH, 1);
cal.set(java.util.Calendar.HOUR_OF_DAY, 15);
cal.clear(java.util.Calendar.MINUTE);
cal.clear(java.util.Calendar.SECOND);
DateTime dt = new DateTime(cal.getTime());
dt.setTimeZone(timezone);
VEvent melbourneCup = new VEvent(dt, "Melbourne Cup");
log.info(melbourneCup);
}
public final void test2() {
java.util.Calendar cal = getCalendarInstance();
cal.set(java.util.Calendar.MONTH, java.util.Calendar.DECEMBER);
cal.set(java.util.Calendar.DAY_OF_MONTH, 25);
VEvent christmas = new VEvent(new Date(cal.getTime()), "Christmas Day");
// initialise as an all-day event..
christmas.getProperty(Property.DTSTART).getParameters().add(Value.DATE);
// add timezone information..
christmas.getProperty(Property.DTSTART).getParameters().add(tzParam);
log.info(christmas);
}
public final void test3() {
java.util.Calendar cal = getCalendarInstance();
// tomorrow..
cal.add(java.util.Calendar.DAY_OF_MONTH, 1);
cal.set(java.util.Calendar.HOUR_OF_DAY, 9);
cal.set(java.util.Calendar.MINUTE, 30);
VEvent meeting = new VEvent(new DateTime(cal.getTime().getTime()), new Dur(0, 1, 0, 0), "Progress Meeting");
// add timezone information..
meeting.getProperty(Property.DTSTART).getParameters().add(tzParam);
log.info(meeting);
}
/**
* Test Null Dates
* Test Start today, End One month from now.
*
* @throws Exception
*/
public final void testGetConsumedTime() throws Exception {
// Test Null Dates
try {
weekdayNineToFiveEvents.getConsumedTime(null, null);
fail("Should've thrown an exception.");
} catch (RuntimeException re) {
log.info("Expecting an exception here.");
}
// Test Start 04/01/2005, End One month later.
// Query Calendar Start and End Dates.
Calendar queryStartDate = getCalendarInstance();
queryStartDate.set(2005, Calendar.APRIL, 1, 14, 47, 0);
queryStartDate.set(Calendar.MILLISECOND, 0);
DateTime queryStart = new DateTime(queryStartDate.getTime().getTime());
Calendar queryEndDate = getCalendarInstance();
queryEndDate.set(2005, Calendar.MAY, 1, 07, 15, 0);
queryEndDate.set(Calendar.MILLISECOND, 0);
DateTime queryEnd = new DateTime(queryEndDate.getTime().getTime());
Calendar week1EndDate = getCalendarInstance();
week1EndDate.set(2005, Calendar.APRIL, 8, 11, 15, 0);
week1EndDate.set(Calendar.MILLISECOND, 0);
Calendar week4StartDate = getCalendarInstance();
week4StartDate.set(2005, Calendar.APRIL, 24, 14, 47, 0);
week4StartDate.set(Calendar.MILLISECOND, 0);
DateTime week4Start = new DateTime(week4StartDate.getTime().getTime());
// This range is monday to friday every three weeks, starting from
// March 7th 2005, which means for our query dates we need
// April 18th through to the 22nd.
PeriodList weeklyPeriods = weekdayNineToFiveEvents.getConsumedTime(queryStart, queryEnd);
PeriodList dailyPeriods = dailyWeekdayEvents.getConsumedTime(queryStart, queryEnd);
// week1EndDate.getTime());
dailyPeriods.addAll(dailyWeekdayEvents.getConsumedTime(week4Start, queryEnd));
Calendar expectedCal = Calendar.getInstance(); //TimeZone.getTimeZone(TimeZones.GMT_ID));
expectedCal.set(2005, Calendar.APRIL, 1, 9, 0, 0);
expectedCal.set(Calendar.MILLISECOND, 0);
Date expectedStartOfFirstRange = new DateTime(expectedCal.getTime().getTime());
expectedCal.set(2005, Calendar.APRIL, 1, 17, 0, 0);
expectedCal.set(Calendar.MILLISECOND, 0);
Date expectedEndOfFirstRange = new DateTime(expectedCal.getTime().getTime());
assertNotNull(weeklyPeriods);
assertTrue(weeklyPeriods.size() > 0);
Period firstPeriod = (Period) weeklyPeriods.toArray()[0];
assertEquals(expectedStartOfFirstRange, firstPeriod.getStart());
assertEquals(expectedEndOfFirstRange, firstPeriod.getEnd());
assertEquals(dailyPeriods, weeklyPeriods);
}
/**
* Test whether you can select weekdays using a daily frequency.
* <p>
* This test really belongs in RecurTest, but the weekly range test
* in this VEventTest matches so perfectly with the daily range test
* that should produce the same results for some weeks that it was
* felt leveraging the existing test code was more important.
* <p>
* This addresses bug
* <a href="http://sourceforge.net/tracker/index.php?func=detail&aid=1203990&group_id=107024&atid=646395">1203990</a>
*
*/
public final void testGetConsumedTimeDaily() throws Exception {
// Test Starts 04/03/2005, Ends One week later.
// Query Calendar Start and End Dates.
Calendar queryStartDate = getCalendarInstance();
queryStartDate.set(2005, Calendar.APRIL, 3, 05, 12, 0);
queryStartDate.set(Calendar.MILLISECOND, 0);
Calendar queryEndDate = getCalendarInstance();
queryEndDate.set(2005, Calendar.APRIL, 10, 21, 55, 0);
queryEndDate.set(Calendar.MILLISECOND, 0);
// This range is Monday to Friday every day (which has a filtering
// effect), starting from March 7th 2005. Our query dates are
// April 3rd through to the 10th.
PeriodList weeklyPeriods =
weekdayNineToFiveEvents.getConsumedTime(new DateTime(queryStartDate.getTime()),
new DateTime(queryEndDate.getTime()));
PeriodList dailyPeriods =
dailyWeekdayEvents.getConsumedTime(new DateTime(queryStartDate.getTime()),
new DateTime(queryEndDate.getTime()));
Calendar expectedCal = getCalendarInstance();
expectedCal.set(2005, Calendar.APRIL, 4, 9, 0, 0);
expectedCal.set(Calendar.MILLISECOND, 0);
Date expectedStartOfFirstRange = new DateTime(expectedCal.getTime());
expectedCal.set(2005, Calendar.APRIL, 4, 17, 0, 0);
expectedCal.set(Calendar.MILLISECOND, 0);
Date expectedEndOfFirstRange = new DateTime(expectedCal.getTime());
assertNotNull(dailyPeriods);
assertTrue(dailyPeriods.size() > 0);
Period firstPeriod = (Period) dailyPeriods.toArray()[0];
assertEquals(expectedStartOfFirstRange, firstPeriod.getStart());
assertEquals(expectedEndOfFirstRange, firstPeriod.getEnd());
assertEquals(weeklyPeriods, dailyPeriods);
}
/**
* Test whether you can select weekdays using a monthly frequency.
* <p>
* This test really belongs in RecurTest, but the weekly range test
* in this VEventTest matches so perfectly with the daily range test
* that should produce the same results for some weeks that it was
* felt leveraging the existing test code was more important.
* <p>
* Section 4.3.10 of the iCalendar specification RFC 2445 reads:
* <pre>
* If an integer modifier is not present, it means all days of
* this type within the specified frequency.
* </pre>
* This test ensures compliance.
*/
public final void testGetConsumedTimeMonthly() throws Exception {
// Test Starts 04/03/2005, Ends two weeks later.
// Query Calendar Start and End Dates.
Calendar queryStartDate = getCalendarInstance();
queryStartDate.set(2005, Calendar.APRIL, 3, 05, 12, 0);
queryStartDate.set(Calendar.MILLISECOND, 0);
Calendar queryEndDate = getCalendarInstance();
queryEndDate.set(2005, Calendar.APRIL, 17, 21, 55, 0);
queryEndDate.set(Calendar.MILLISECOND, 0);
// This range is Monday to Friday every month (which has a multiplying
// effect), starting from March 7th 2005. Our query dates are
// April 3rd through to the 17th.
PeriodList monthlyPeriods =
monthlyWeekdayEvents.getConsumedTime(new DateTime(queryStartDate.getTime()),
new DateTime(queryEndDate.getTime()));
PeriodList dailyPeriods =
dailyWeekdayEvents.getConsumedTime(new DateTime(queryStartDate.getTime()),
new DateTime(queryEndDate.getTime()));
Calendar expectedCal = getCalendarInstance();
expectedCal.set(2005, Calendar.APRIL, 4, 9, 0, 0);
expectedCal.set(Calendar.MILLISECOND, 0);
Date expectedStartOfFirstRange = new DateTime(expectedCal.getTime());
expectedCal.set(2005, Calendar.APRIL, 4, 17, 0, 0);
expectedCal.set(Calendar.MILLISECOND, 0);
Date expectedEndOfFirstRange = new DateTime(expectedCal.getTime());
assertNotNull(monthlyPeriods);
assertTrue(monthlyPeriods.size() > 0);
Period firstPeriod = (Period) monthlyPeriods.toArray()[0];
assertEquals(expectedStartOfFirstRange, firstPeriod.getStart());
assertEquals(expectedEndOfFirstRange, firstPeriod.getEnd());
assertEquals(dailyPeriods, monthlyPeriods);
}
public final void testGetConsumedTime2() throws Exception {
String filename = "etc/samples/valid/derryn.ics";
FileInputStream fin = new FileInputStream(filename);
CalendarBuilder builder = new CalendarBuilder();
net.fortuna.ical4j.model.Calendar calendar = null;
try {
calendar = builder.build(fin);
} catch (IOException e) {
log.warn("File: " + filename, e);
} catch (ParserException e) {
log.warn("File: " + filename, e);
}
assertNotNull(calendar);
try {
calendar.validate();
} catch (ValidationException e) {
assertTrue("Calendar file " + filename + " isn't valid:\n" + e.getMessage(), false);
}
log.info("File: " + filename);
if (log.isDebugEnabled()) {
log.debug("Calendar:\n=========\n" + calendar.toString());
}
Date start = new Date();
Calendar endCal = getCalendarInstance();
endCal.setTime(start);
endCal.add(Calendar.WEEK_OF_YEAR, 4);
// Date end = new Date(start.getTime() + (1000 * 60 * 60 * 24 * 7 * 4));
for (Iterator i = calendar.getComponents().iterator(); i.hasNext();) {
Component c = (Component) i.next();
if (c instanceof VEvent) {
PeriodList consumed = ((VEvent) c).getConsumedTime(start, new Date(endCal.getTime().getTime()));
log.debug("Event [" + c + "]");
log.debug("Consumed time [" + consumed + "]");
}
}
}
/**
* Test COUNT rules.
*/
public void testGetConsumeTimeByCount() {
Recur recur = new Recur(Recur.WEEKLY, 3);
recur.setInterval(1);
recur.getDayList().add(WeekDay.SU);
log.info(recur);
Calendar cal = getCalendarInstance();
cal.set(Calendar.DAY_OF_MONTH, 8);
Date start = new DateTime(cal.getTime());
// cal.add(Calendar.DAY_OF_WEEK_IN_MONTH, 10);
cal.add(Calendar.HOUR_OF_DAY, 1);
Date end = new DateTime(cal.getTime());
// log.info(recur.getDates(start, end, Value.DATE_TIME));
RRule rrule = new RRule(recur);
VEvent event = new VEvent(start, end, "Test recurrence COUNT");
event.getProperties().add(rrule);
log.info(event);
Calendar rangeCal = getCalendarInstance();
Date rangeStart = new DateTime(rangeCal.getTime());
rangeCal.add(Calendar.WEEK_OF_YEAR, 4);
Date rangeEnd = new DateTime(rangeCal.getTime());
log.info(event.getConsumedTime(rangeStart, rangeEnd));
}
/**
* A test to confirm that the end date is calculated correctly
* from a given start date and duration.
*/
public final void testEventEndDate() {
Calendar cal = getCalendarInstance();
Date startDate = new Date(cal.getTime());
log.info("Start date: " + startDate);
VEvent event = new VEvent(startDate, new Dur(3, 0, 0, 0), "3 day event");
Date endDate = event.getEndDate().getDate();
log.info("End date: " + endDate);
cal.add(Calendar.DAY_OF_YEAR, 3);
assertEquals(new Date(cal.getTime()), endDate);
}
/**
* Test to ensure that EXDATE properties are correctly applied.
* @throws ParseException
*/
public void testGetConsumedTimeWithExDate() throws ParseException {
VEvent event1 = new VEvent(new DateTime("20050103T080000"),
new Dur(0, 0, 15, 0),
"Event 1");
Recur rRuleRecur = new Recur("FREQ=WEEKLY;INTERVAL=1;BYDAY=MO,TU,WE,TH,FR");
RRule rRule = new RRule(rRuleRecur);
event1.getProperties().add(rRule);
ParameterList parameterList = new ParameterList();
parameterList.add(Value.DATE);
ExDate exDate = new ExDate(parameterList, "20050106");
event1.getProperties().add(exDate);
Date start = new Date("20050106");
Date end = new Date("20050107");
PeriodList list = event1.getConsumedTime(start, end);
assertTrue(list.isEmpty());
}
/**
* Test to ensure that EXDATE properties are correctly applied.
* @throws ParseException
*/
public void testGetConsumedTimeWithExDate2() throws IOException, ParserException {
FileInputStream fin = new FileInputStream("etc/samples/valid/friday13.ics");
net.fortuna.ical4j.model.Calendar calendar = new CalendarBuilder().build(fin);
VEvent event = (VEvent) calendar.getComponent(Component.VEVENT);
Calendar cal = Calendar.getInstance();
cal.set(1997, 8, 2);
Date start = new Date(cal.getTime());
cal.set(1997, 8, 4);
Date end = new Date(cal.getTime());
PeriodList periods = event.getConsumedTime(start, end);
assertTrue(periods.isEmpty());
}
/* (non-Javadoc)
* @see net.fortuna.ical4j.model.ComponentTest#testIsCalendarComponent()
*/
public void testIsCalendarComponent() {
assertIsCalendarComponent(new VEvent());
}
}