@@ -8,7 +8,9 @@ package at.bitfire.synctools.icalendar
88
99import at.bitfire.synctools.icalendar.validation.ICalPreprocessor
1010import net.fortuna.ical4j.data.CalendarBuilder
11+ import net.fortuna.ical4j.data.CalendarOutputter
1112import net.fortuna.ical4j.data.ParserException
13+ import net.fortuna.ical4j.model.Calendar
1214import net.fortuna.ical4j.model.Component
1315import net.fortuna.ical4j.model.DateTime
1416import net.fortuna.ical4j.model.Parameter
@@ -20,18 +22,20 @@ import net.fortuna.ical4j.model.component.VEvent
2022import net.fortuna.ical4j.model.component.VTimeZone
2123import net.fortuna.ical4j.model.parameter.Email
2224import net.fortuna.ical4j.model.property.Attendee
25+ import net.fortuna.ical4j.model.property.ProdId
2326import org.junit.Assert.assertEquals
2427import org.junit.Assert.assertNotEquals
2528import org.junit.Test
2629import java.io.StringReader
30+ import java.io.StringWriter
2731import java.time.Period
2832
2933class Ical4jTest {
3034
31- val tzReg = TimeZoneRegistryFactory .getInstance().createRegistry()
35+ private val tzReg = TimeZoneRegistryFactory .getInstance().createRegistry()
3236
3337 @Test
34- fun testEmailParameter () {
38+ fun `ATTENDEE with EMAIL parameter` () {
3539 // https://github.com/ical4j/ical4j/issues/418
3640 val event = ICalendarParser ().parse(
3741 StringReader (
@@ -50,27 +54,77 @@ class Ical4jTest {
5054 }
5155
5256 @Test
53- fun testTemporalAmountAdapter_durationToString_DropsMinutes () {
57+ fun `DTSTART in America_Asuncion from KOrganizer` () {
58+ // See https://github.com/bitfireAT/synctools/issues/113
59+ val vtzFromKOrganizer = " BEGIN:VCALENDAR\n " +
60+ " CALSCALE:GREGORIAN\n " +
61+ " VERSION:2.0\n " +
62+ " PRODID:-//K Desktop Environment//NONSGML KOrganizer 6.5.0 (25.08.0)//EN\n " +
63+ " BEGIN:VTIMEZONE\n " +
64+ " TZID:America/Asuncion\n " +
65+ " BEGIN:STANDARD\n " +
66+ " TZNAME:-03\n " +
67+ " TZOFFSETFROM:-0300\n " +
68+ " TZOFFSETTO:-0300\n " +
69+ " DTSTART:19700101T000000\n " +
70+ " END:STANDARD\n " +
71+ " END:VTIMEZONE\n " +
72+ " BEGIN:VEVENT\n " +
73+ " DTSTAMP:20250828T233827Z\n " +
74+ " CREATED:20250828T233750Z\n " +
75+ " UID:e5d424b9-d3f6-4ee0-bf95-da7537fca1fe\n " +
76+ " LAST-MODIFIED:20250828T233827Z\n " +
77+ " SUMMARY:Test Timezones\n " +
78+ " RRULE:FREQ=WEEKLY;COUNT=3;BYDAY=TH\n " +
79+ " DTSTART;TZID=America/Asuncion:20250828T130000\n " +
80+ " DTEND;TZID=America/Asuncion:20250828T133000\n " +
81+ " TRANSP:OPAQUE\n " +
82+ " END:VEVENT\n " +
83+ " END:VCALENDAR"
84+ val iCalFromKOrganizer = CalendarBuilder ().build(StringReader (vtzFromKOrganizer))
85+ ICalPreprocessor ().preprocessCalendar(iCalFromKOrganizer)
86+ val vEvent = iCalFromKOrganizer.getComponent<VEvent >(Component .VEVENT )
87+ val dtStart = vEvent.startDate
88+ // SHOULD BE UTC -3:
89+ // assertEquals(1756396800000, dtStart.date.time)
90+ // However is one hour later: 1756400400000
91+ }
92+
93+ @Test
94+ fun `PRODID is folded when exactly max line length` () {
95+ val calendar = Calendar ().apply {
96+ properties + = ProdId (" 01234567890123456789012345678901234567890123456789012345678901234567" )
97+ }
98+ val writer = StringWriter ()
99+ CalendarOutputter ().output(calendar, writer)
100+ assertEquals(" BEGIN:VCALENDAR\r\n " +
101+ " PRODID:01234567890123456789012345678901234567890123456789012345678901234567\r\n " +
102+ " \r\n " +
103+ " END:VCALENDAR\r\n " , writer.toString())
104+ }
105+
106+ @Test
107+ fun `TemporalAmountAdapter durationToString drops minutes` () {
54108 // https://github.com/ical4j/ical4j/issues/420
55109 assertEquals(" P1DT1H4M" , TemporalAmountAdapter .parse(" P1DT1H4M" ).toString())
56110 }
57111
58112 @Test(expected = AssertionError ::class )
59- fun testTemporalAmountAdapter_Months () {
113+ fun `TemporalAmountAdapter months` () {
60114 // https://github.com/ical4j/ical4j/issues/419
61115 // A month usually doesn't have 4 weeks = 4*7 days = 28 days (except February in non-leap years).
62116 assertNotEquals(" P4W" , TemporalAmountAdapter (Period .ofMonths(1 )).toString())
63117 }
64118
65119 @Test(expected = AssertionError ::class )
66- fun testTemporalAmountAdapter_Year () {
120+ fun `TemporalAmountAdapter year` () {
67121 // https://github.com/ical4j/ical4j/issues/419
68122 // A year has 365 or 366 days, but never 52 weeks = 52*7 days = 364 days.
69123 assertNotEquals(" P52W" , TemporalAmountAdapter (Period .ofYears(1 )).toString())
70124 }
71125
72126 @Test(expected = AssertionError ::class )
73- fun testTzDarwin () {
127+ fun `TZ Darwin` () {
74128 val darwin = tzReg.getTimeZone(" Australia/Darwin" )
75129
76130 val ts1 = 1616720400000
@@ -81,7 +135,7 @@ class Ical4jTest {
81135 }
82136
83137 @Test
84- fun testTzDublin_negativeDst () {
138+ fun `TZ Dublin with negative DST` () {
85139 // https://github.com/ical4j/ical4j/issues/493
86140 // fixed by enabling net.fortuna.ical4j.timezone.offset.negative_dst_supported in ical4j.properties
87141 val vtzFromGoogle = " BEGIN:VCALENDAR\n " +
@@ -113,44 +167,7 @@ class Ical4jTest {
113167 }
114168
115169 @Test
116- fun `DTSTART in America_Asuncion from KOrganizer` () {
117- // See https://github.com/bitfireAT/synctools/issues/113
118- val vtzFromKOrganizer = " BEGIN:VCALENDAR\n " +
119- " CALSCALE:GREGORIAN\n " +
120- " VERSION:2.0\n " +
121- " PRODID:-//K Desktop Environment//NONSGML KOrganizer 6.5.0 (25.08.0)//EN\n " +
122- " BEGIN:VTIMEZONE\n " +
123- " TZID:America/Asuncion\n " +
124- " BEGIN:STANDARD\n " +
125- " TZNAME:-03\n " +
126- " TZOFFSETFROM:-0300\n " +
127- " TZOFFSETTO:-0300\n " +
128- " DTSTART:19700101T000000\n " +
129- " END:STANDARD\n " +
130- " END:VTIMEZONE\n " +
131- " BEGIN:VEVENT\n " +
132- " DTSTAMP:20250828T233827Z\n " +
133- " CREATED:20250828T233750Z\n " +
134- " UID:e5d424b9-d3f6-4ee0-bf95-da7537fca1fe\n " +
135- " LAST-MODIFIED:20250828T233827Z\n " +
136- " SUMMARY:Test Timezones\n " +
137- " RRULE:FREQ=WEEKLY;COUNT=3;BYDAY=TH\n " +
138- " DTSTART;TZID=America/Asuncion:20250828T130000\n " +
139- " DTEND;TZID=America/Asuncion:20250828T133000\n " +
140- " TRANSP:OPAQUE\n " +
141- " END:VEVENT\n " +
142- " END:VCALENDAR"
143- val iCalFromKOrganizer = CalendarBuilder ().build(StringReader (vtzFromKOrganizer))
144- ICalPreprocessor ().preprocessCalendar(iCalFromKOrganizer)
145- val vEvent = iCalFromKOrganizer.getComponent<VEvent >(Component .VEVENT )
146- val dtStart = vEvent.startDate
147- // SHOULD BE UTC -3:
148- // assertEquals(1756396800000, dtStart.date.time)
149- // However is one hour later: 1756400400000
150- }
151-
152- @Test
153- fun testTzKarachi () {
170+ fun `TZ Karachi` () {
154171 // https://github.com/ical4j/ical4j/issues/491
155172 val karachi = tzReg.getTimeZone(" Asia/Karachi" )
156173
0 commit comments