package jfxtras.icalendarfx.calendar;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.io.IOException;
import java.io.Reader;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Arrays;
import java.util.List;
import org.junit.Ignore;
import org.junit.Test;
import jfxtras.icalendarfx.ICalendarTestAbstract;
import jfxtras.icalendarfx.VCalendar;
import jfxtras.icalendarfx.components.VEvent;
import jfxtras.icalendarfx.properties.calendar.Version;
public class ParseCalendarTest extends ICalendarTestAbstract
{
@Test
public void canParseSimpleVCalendar()
{
String content =
"BEGIN:VCALENDAR" + System.lineSeparator() +
"VERSION:2.0" + System.lineSeparator() +
"PRODID:-//hacksw/handcal//NONSGML v1.0//EN" + System.lineSeparator() +
"BEGIN:VEVENT" + System.lineSeparator() +
"UID:19970610T172345Z-AF23B2@example.com" + System.lineSeparator() +
"DTSTAMP:19970610T172345Z" + System.lineSeparator() +
"DTSTART:19970714T170000Z" + System.lineSeparator() +
"DTEND:19970715T040000Z" + System.lineSeparator() +
"SUMMARY:Bastille Day Party" + System.lineSeparator() +
"END:VEVENT" + System.lineSeparator() +
"END:VCALENDAR";
VCalendar vCalendar = VCalendar.parse(content);
assertEquals(content, vCalendar.toString());
VCalendar vCalendar2 = new VCalendar()
.withVersion(new Version())
.withProductIdentifier("-//hacksw/handcal//NONSGML v1.0//EN")
.withVEvents(new VEvent()
.withUniqueIdentifier("UID:19970610T172345Z-AF23B2@example.com")
.withDateTimeStamp("DTSTAMP:19970610T172345Z")
.withDateTimeStart("19970714T170000Z")
.withDateTimeEnd(ZonedDateTime.of(LocalDateTime.of(1997, 7, 15, 4, 0), ZoneId.of("Z")))
.withSummary("Bastille Day Party")
);
assertEquals(vCalendar2, vCalendar);
}
@Test
public void canParseVCalendarWithNonStandard()
{
String content =
"BEGIN:VCALENDAR" + System.lineSeparator() +
"VERSION:2.0" + System.lineSeparator() +
"PRODID:-//hacksw/handcal//NONSGML v1.0//EN" + System.lineSeparator() +
"BEGIN:VEVENT" + System.lineSeparator() +
"UID:19970610T172345Z-AF23B2@example.com" + System.lineSeparator() +
"DTSTAMP:19970610T172345Z" + System.lineSeparator() +
"DTSTART:19970714T170000Z" + System.lineSeparator() +
"DTEND:19970715T040000Z" + System.lineSeparator() +
"SUMMARY:Bastille Day Party" + System.lineSeparator() +
"END:VEVENT" + System.lineSeparator() +
"BEGIN:VEVENT" + System.lineSeparator() +
"SUMMARY:New Event" + System.lineSeparator() +
"CLASS:PUBLIC" + System.lineSeparator() +
"DTSTART;TZID=Etc/GMT:20150902T133000Z" + System.lineSeparator() +
"DTEND;TZID=Etc/GMT:20150902T180000Z" + System.lineSeparator() +
"PRIORITY:0" + System.lineSeparator() +
"SEQUENCE:1" + System.lineSeparator() +
"STATUS:CANCELLED" + System.lineSeparator() +
"UID:dc654e79-cc85-449c-a1b2-71b2d20b80df" + System.lineSeparator() +
"RECURRENCE-ID;TZID=Etc/GMT:20150902T133000Z" + System.lineSeparator() +
"DTSTAMP:20150831T053218Z" + System.lineSeparator() +
"ORGANIZER;CN=David Bal;SENT-BY=\"mailto:ddbal1@yahoo.com\":mailto:ddbal1@yaho" + System.lineSeparator() +
" o.com" + System.lineSeparator() +
"X-YAHOO-YID:testuser" + System.lineSeparator() +
"TRANSP:OPAQUE" + System.lineSeparator() +
"X-YAHOO-USER-STATUS:BUSY" + System.lineSeparator() +
"X-YAHOO-EVENT-STATUS:BUSY" + System.lineSeparator() +
"BEGIN:VALARM" + System.lineSeparator() +
"ACTION:DISPLAY" + System.lineSeparator() +
"DESCRIPTION:" + System.lineSeparator() +
"TRIGGER;RELATED=START:-PT30M" + System.lineSeparator() +
"END:VALARM" + System.lineSeparator() +
"END:VEVENT" + System.lineSeparator() +
"END:VCALENDAR";
VCalendar vCalendar = VCalendar.parse(content);
assertEquals(content, vCalendar.toString());
}
@Test
public void canParseGoogleRepeatable()
{
String vEventString1 = "BEGIN:VEVENT" + System.lineSeparator()
+ "DTSTART;TZID=America/Los_Angeles:20160214T110000" + System.lineSeparator()
+ "DTEND;TZID=America/Los_Angeles:20160214T130000" + System.lineSeparator()
+ "RRULE:FREQ=DAILY;UNTIL=20160218T185959Z" + System.lineSeparator()
+ "DTSTAMP:20160214T213637Z" + System.lineSeparator()
+ "UID:mrrfvnj5acdcvn13273on9nrhs@google.com" + System.lineSeparator()
+ "CREATED:20160214T193703Z" + System.lineSeparator()
+ "DESCRIPTION:" + System.lineSeparator()
+ "LAST-MODIFIED:20160214T193717Z" + System.lineSeparator()
+ "LOCATION:" + System.lineSeparator()
+ "SEQUENCE:0" + System.lineSeparator()
+ "STATUS:CONFIRMED" + System.lineSeparator() // currently not supported
+ "SUMMARY:test4" + System.lineSeparator()
+ "TRANSP:OPAQUE" + System.lineSeparator() // currently not supported
+ "END:VEVENT";
String vEventString2 = "BEGIN:VEVENT" + System.lineSeparator()
+ "DTSTART;TZID=America/Los_Angeles:20160218T110000" + System.lineSeparator()
+ "DTEND;TZID=America/Los_Angeles:20160218T140000" + System.lineSeparator()
+ "RRULE:FREQ=DAILY;COUNT=6" + System.lineSeparator()
+ "DTSTAMP:20160214T213637Z" + System.lineSeparator()
+ "UID:mrrfvnj5acdcvn13273on9nrhs_R20160218T190000@google.com" + System.lineSeparator()
+ "CREATED:20160214T193703Z" + System.lineSeparator()
+ "DESCRIPTION:" + System.lineSeparator()
+ "LAST-MODIFIED:20160214T193717Z" + System.lineSeparator()
+ "LOCATION:" + System.lineSeparator()
+ "SEQUENCE:0" + System.lineSeparator()
+ "STATUS:CONFIRMED" + System.lineSeparator() // currently not supported
+ "SUMMARY:test5" + System.lineSeparator()
+ "TRANSP:OPAQUE" + System.lineSeparator() // currently not supported
+ "END:VEVENT";
String vEventString3 = "BEGIN:VEVENT" + System.lineSeparator()
+ "DTSTART;TZID=America/Los_Angeles:20160216T070000" + System.lineSeparator()
+ "DTEND;TZID=America/Los_Angeles:20160216T090000" + System.lineSeparator()
+ "DTSTAMP:20160214T213637Z" + System.lineSeparator()
+ "UID:mrrfvnj5acdcvn13273on9nrhs@google.com" + System.lineSeparator()
+ "CREATED:20160214T193703Z" + System.lineSeparator()
+ "DESCRIPTION:" + System.lineSeparator()
+ "LAST-MODIFIED:20160214T213226Z" + System.lineSeparator()
+ "LOCATION:" + System.lineSeparator()
+ "RECURRENCE-ID;TZID=America/Los_Angeles:20160216T110000" + System.lineSeparator()
+ "SEQUENCE:1" + System.lineSeparator()
+ "STATUS:CONFIRMED" + System.lineSeparator() // currently not supported
+ "SUMMARY:test6" + System.lineSeparator()
+ "TRANSP:OPAQUE" + System.lineSeparator() // currently not supported
+ "END:VEVENT";
VCalendar c = new VCalendar()
.withProductIdentifier("My ID")
.withVersion(new Version());
c.addChild(vEventString1);
c.addChild(vEventString2);
c.addChild(vEventString3);
assertEquals(3, c.getVEvents().size());
assertEquals(1, c.getVEvents().get(0).recurrenceChildren().size());
assertEquals(c.getVEvents().get(0), c.getVEvents().get(2).recurrenceParent());
assertTrue(c.isValid());
}
@Test (expected = NullPointerException.class)
public void canParseNullCalendar() throws IOException
{
VCalendar.parse((Reader) null);
}
@Test (expected = IllegalArgumentException.class)
public void canParseInvalidCalendar1()
{
VCalendar.parse("invalid calendar");
}
@Test
public void canIgnoreUnrecognizedLine()
{
String content =
"BEGIN:VCALENDAR" + System.lineSeparator() +
"Ignore this line" + System.lineSeparator() +
"END:VCALENDAR";
VCalendar v = VCalendar.parse(content);
VCalendar expected = new VCalendar();
assertEquals(expected, v);
assertEquals("BEGIN:VCALENDAR" + System.lineSeparator() +
"END:VCALENDAR", v.toString());
}
@Test (expected = IllegalArgumentException.class)
public void canParseBadVCalendar1()
{
String content =
"BEGIN:VCALENDAR" + System.lineSeparator() +
"VERSION:2.0" + System.lineSeparator() +
"PRODID:-//hacksw/handcal//NONSGML v1.0//EN" + System.lineSeparator() +
"BEGIN:VEVENT" + System.lineSeparator() +
"UID:19970610T172345Z-AF23B2@example.com" + System.lineSeparator() +
"DTSTAMP:19970610T172345Z" + System.lineSeparator() +
"DTSTART:19970714T170000Z" + System.lineSeparator() +
// "DTSTART:19970714T170000Z" + System.lineSeparator() +
"DTEND:19970715T040000Z" + System.lineSeparator() +
"SUMMARY:Bastille Day Party" + System.lineSeparator() +
"END:VEVENT" + System.lineSeparator() +
"BEGIN:VEVENT" + System.lineSeparator() +
"SUMMARY:New Event" + System.lineSeparator() +
"CLASS:PUBLIC" + System.lineSeparator() +
"DTSTART;TZID=Etc/GMT:20150902T133000Z" + System.lineSeparator() +
"DTEND;TZID=Etc/GMT:20150902T180000Z" + System.lineSeparator() +
"PRIORITY:0" + System.lineSeparator() +
"SEQUENCE:1" + System.lineSeparator() +
"STATUS:CANCELLED" + System.lineSeparator() +
"UID:dc654e79-cc85-449c-a1b2-71b2d20b80df" + System.lineSeparator() +
"RECURRENCE-ID;TZID=Etc/GMT:20150902T133000Z" + System.lineSeparator() +
"STATUS:CANCELLED" + System.lineSeparator() + // extra property to be ignored
"DTSTAMP:20150831T053218Z" + System.lineSeparator() +
"ORGANIZER;CN=David Bal;SENT-BY=\"mailto:ddbal1@yahoo.com\":mailto:ddbal1@yaho" + System.lineSeparator() +
" o.com" + System.lineSeparator() +
"X-YAHOO-YID:testuser" + System.lineSeparator() +
"TRANSP:OPAQUE" + System.lineSeparator() +
"X-YAHOO-USER-STATUS:BUSY" + System.lineSeparator() +
"X-YAHOO-EVENT-STATUS:BUSY" + System.lineSeparator() +
"BEGIN:VALARM" + System.lineSeparator() +
"ACTION:DISPLAY" + System.lineSeparator() +
"DESCRIPTION:" + System.lineSeparator() +
"TRIGGER;RELATED=START:-PT30M" + System.lineSeparator() +
"END:VALARM" + System.lineSeparator() +
"END:VEVENT" + System.lineSeparator() +
"END:VCALENDAR";
VCalendar.parse(content);
}
@Test
public void canIgnoreBadLine()
{
String content = "BEGIN:VCALENDAR" + System.lineSeparator() +
"X-CUSTOM-PROP:THE DATA" + System.lineSeparator() +
"IGNORE THIS LINE" + System.lineSeparator() +
"END:VCALENDAR";
VCalendar v = VCalendar.parse(content);
VCalendar expected = new VCalendar()
.withNonStandard("X-CUSTOM-PROP:THE DATA")
;
assertEquals(expected, v);
}
@Test (expected = IllegalArgumentException.class)
public void canHandleDuplicate()
{
String content = "BEGIN:VCALENDAR" + System.lineSeparator() +
"X-CUSTOM-PROP:THE DATA" + System.lineSeparator() +
"X-CUSTOM-PROP:THE DATA" + System.lineSeparator() +
"END:VCALENDAR";
VCalendar v = VCalendar.parse(content);
assertEquals(content, v.toString());
}
@Test
@Ignore // TODO - Consider ways to collect messages when parsing
public void canGetErrorMessageFromBadLine()
{
String content = "BEGIN:VCALENDAR" + System.lineSeparator() +
"X-CUSTOM-PROP:THE DATA" + System.lineSeparator() +
"IGNORE THIS LINE" + System.lineSeparator() +
"UNKNOWN-PROP:SOMETHING" + System.lineSeparator() +
"END:VCALENDAR";
VCalendar v = new VCalendar();
List<String> m = v.processITIPMessage(content);
v.addChild(content);
List<String> messages = null; // v.parseContent(content);
List<String> expectedMessages = Arrays.asList("VCALENDAR:Unknown line is ignored:IGNORE THIS LINE", "VCALENDAR:Unknown property is ignored:UNKNOWN-PROP:SOMETHING");
assertEquals(expectedMessages, messages);
}
@Test (expected = IllegalArgumentException.class)
public void canHandleInvalidCalendarProperty()
{
String content =
"BEGIN:VCALENDAR" + System.lineSeparator() +
"CALSCALE:INVALID" + System.lineSeparator() +
"END:VCALENDAR";
VCalendar v = VCalendar.parse(content);
}
}