@@ -3,6 +3,7 @@ package caldav
33import (
44 "context"
55 "fmt"
6+ "github.com/stretchr/testify/assert"
67 "io"
78 "io/ioutil"
89 "net/http/httptest"
@@ -33,7 +34,7 @@ func TestPropFindSupportedCalendarComponent(t *testing.T) {
3334 req .Body = io .NopCloser (strings .NewReader (propFindSupportedCalendarComponentRequest ))
3435 req .Header .Set ("Content-Type" , "application/xml" )
3536 w := httptest .NewRecorder ()
36- handler := Handler {Backend : testBackend {calendars : []Calendar {* calendar }}}
37+ handler := Handler {Backend : & testBackend {calendars : []Calendar {* calendar }}}
3738 handler .ServeHTTP (w , req )
3839
3940 res := w .Result ()
@@ -68,7 +69,7 @@ func TestPropFindRoot(t *testing.T) {
6869 req .Header .Set ("Content-Type" , "application/xml" )
6970 w := httptest .NewRecorder ()
7071 calendar := & Calendar {}
71- handler := Handler {Backend : testBackend {calendars : []Calendar {* calendar }}}
72+ handler := Handler {Backend : & testBackend {calendars : []Calendar {* calendar }}}
7273 handler .ServeHTTP (w , req )
7374
7475 res := w .Result ()
@@ -118,7 +119,7 @@ func TestMultiCalendarBackend(t *testing.T) {
118119 req := httptest .NewRequest ("PROPFIND" , "/user/calendars/" , strings .NewReader (propFindUserPrincipal ))
119120 req .Header .Set ("Content-Type" , "application/xml" )
120121 w := httptest .NewRecorder ()
121- handler := Handler {Backend : testBackend {
122+ handler := Handler {Backend : & testBackend {
122123 calendars : calendars ,
123124 objectMap : map [string ][]CalendarObject {
124125 calendarB .Path : []CalendarObject {object },
@@ -177,12 +178,216 @@ func TestMultiCalendarBackend(t *testing.T) {
177178 }
178179}
179180
181+ var mkcolRequestData = `
182+ <?xml version='1.0' encoding='UTF-8' ?>
183+ <mkcol
184+ xmlns="DAV:"
185+ xmlns:CAL="urn:ietf:params:xml:ns:caldav"
186+ xmlns:CARD="urn:ietf:params:xml:ns:carddav">
187+ <set>
188+ <prop>
189+ <resourcetype>
190+ <collection />
191+ <CAL:calendar />
192+ </resourcetype>
193+ <displayname>Test calendar</displayname>
194+ <CAL:calendar-description>A calendar for testing</CAL:calendar-description>
195+ <n0:calendar-color
196+ xmlns:n0="http://apple.com/ns/ical/">#009688FF
197+ </n0:calendar-color>
198+ <CAL:calendar-timezone>
199+ <![CDATA[BEGIN:VCALENDAR
200+ BEGIN:VTIMEZONE
201+ TZID:Europe/Berlin
202+ LAST-MODIFIED:20230104T023643Z
203+ TZURL:https://www.tzurl.org/zoneinfo/Europe/Berlin
204+ X-LIC-LOCATION:Europe/Berlin
205+ X-PROLEPTIC-TZNAME:LMT
206+ BEGIN:STANDARD
207+ TZNAME:CET
208+ TZOFFSETFROM:+005328
209+ TZOFFSETTO:+0100
210+ DTSTART:18930401T000632
211+ END:STANDARD
212+ BEGIN:DAYLIGHT
213+ TZNAME:CEST
214+ TZOFFSETFROM:+0100
215+ TZOFFSETTO:+0200
216+ DTSTART:19160430T230000
217+ RDATE:19400401T020000
218+ RDATE:19430329T020000
219+ RDATE:19460414T020000
220+ RDATE:19470406T030000
221+ RDATE:19480418T020000
222+ RDATE:19490410T020000
223+ RDATE:19800406T020000
224+ END:DAYLIGHT
225+ BEGIN:STANDARD
226+ TZNAME:CET
227+ TZOFFSETFROM:+0200
228+ TZOFFSETTO:+0100
229+ DTSTART:19161001T010000
230+ RDATE:19421102T030000
231+ RDATE:19431004T030000
232+ RDATE:19441002T030000
233+ RDATE:19451118T030000
234+ RDATE:19461007T030000
235+ END:STANDARD
236+ BEGIN:DAYLIGHT
237+ TZNAME:CEST
238+ TZOFFSETFROM:+0100
239+ TZOFFSETTO:+0200
240+ DTSTART:19170416T020000
241+ RRULE:FREQ=YEARLY;UNTIL=19180415T010000Z;BYMONTH=4;BYDAY=3MO
242+ END:DAYLIGHT
243+ BEGIN:STANDARD
244+ TZNAME:CET
245+ TZOFFSETFROM:+0200
246+ TZOFFSETTO:+0100
247+ DTSTART:19170917T030000
248+ RRULE:FREQ=YEARLY;UNTIL=19180916T010000Z;BYMONTH=9;BYDAY=3MO
249+ END:STANDARD
250+ BEGIN:DAYLIGHT
251+ TZNAME:CEST
252+ TZOFFSETFROM:+0100
253+ TZOFFSETTO:+0200
254+ DTSTART:19440403T020000
255+ RRULE:FREQ=YEARLY;UNTIL=19450402T010000Z;BYMONTH=4;BYDAY=1MO
256+ END:DAYLIGHT
257+ BEGIN:DAYLIGHT
258+ TZNAME:CEMT
259+ TZOFFSETFROM:+0200
260+ TZOFFSETTO:+0300
261+ DTSTART:19450524T010000
262+ RDATE:19470511T020000
263+ END:DAYLIGHT
264+ BEGIN:DAYLIGHT
265+ TZNAME:CEST
266+ TZOFFSETFROM:+0300
267+ TZOFFSETTO:+0200
268+ DTSTART:19450924T030000
269+ RDATE:19470629T030000
270+ END:DAYLIGHT
271+ BEGIN:STANDARD
272+ TZNAME:CET
273+ TZOFFSETFROM:+0100
274+ TZOFFSETTO:+0100
275+ DTSTART:19460101T000000
276+ RDATE:19800101T000000
277+ END:STANDARD
278+ BEGIN:STANDARD
279+ TZNAME:CET
280+ TZOFFSETFROM:+0200
281+ TZOFFSETTO:+0100
282+ DTSTART:19471005T030000
283+ RRULE:FREQ=YEARLY;UNTIL=19491002T010000Z;BYMONTH=10;BYDAY=1SU
284+ END:STANDARD
285+ BEGIN:STANDARD
286+ TZNAME:CET
287+ TZOFFSETFROM:+0200
288+ TZOFFSETTO:+0100
289+ DTSTART:19800928T030000
290+ RRULE:FREQ=YEARLY;UNTIL=19950924T010000Z;BYMONTH=9;BYDAY=-1SU
291+ END:STANDARD
292+ BEGIN:DAYLIGHT
293+ TZNAME:CEST
294+ TZOFFSETFROM:+0100
295+ TZOFFSETTO:+0200
296+ DTSTART:19810329T020000
297+ RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU
298+ END:DAYLIGHT
299+ BEGIN:STANDARD
300+ TZNAME:CET
301+ TZOFFSETFROM:+0200
302+ TZOFFSETTO:+0100
303+ DTSTART:19961027T030000
304+ RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU
305+ END:STANDARD
306+ END:VTIMEZONE
307+ END:VCALENDAR
308+ ]]>
309+ </CAL:calendar-timezone>
310+ <CAL:supported-calendar-component-set>
311+ <CAL:comp name="VEVENT" />
312+ <CAL:comp name="VTODO" />
313+ <CAL:comp name="VJOURNAL" />
314+ </CAL:supported-calendar-component-set>
315+ </prop>
316+ </set>
317+ </mkcol>`
318+
319+ func TestCreateCalendar (t * testing.T ) {
320+ tb := testBackend {
321+ calendars : nil ,
322+ objectMap : nil ,
323+ }
324+ b := backend {
325+ Backend : & tb ,
326+ Prefix : "/dav" ,
327+ }
328+ req := httptest .NewRequest ("MKCOL" , "/dav/calendars/user0/test-calendar" , strings .NewReader (mkcolRequestData ))
329+ req .Header .Set ("Content-Type" , "application/xml" )
330+
331+ err := b .Mkcol (req )
332+ assert .NoError (t , err )
333+ assert .Len (t , tb .calendars , 1 )
334+ c := tb .calendars [0 ]
335+ assert .Equal (t , "Test calendar" , c .Name )
336+ assert .Equal (t , "/dav/calendars/user0/test-calendar" , c .Path )
337+ assert .Equal (t , "A calendar for testing" , c .Description )
338+ assert .Equal (t , "#009688FF" , c .Color )
339+ assert .Equal (t , []string {"VEVENT" , "VTODO" , "VJOURNAL" }, c .SupportedComponentSet )
340+ assert .Contains (t , c .TimeZone , "BEGIN:VCALENDAR" )
341+ }
342+
343+ var mkcolRequestDataMinimalBody = `
344+ <?xml version='1.0' encoding='UTF-8' ?>
345+ <mkcol
346+ xmlns="DAV:"
347+ xmlns:CAL="urn:ietf:params:xml:ns:caldav"
348+ xmlns:CARD="urn:ietf:params:xml:ns:carddav">
349+ <set>
350+ <prop>
351+ <resourcetype>
352+ <collection />
353+ <CAL:calendar />
354+ </resourcetype>
355+ <displayname>Test calendar</displayname>
356+ </prop>
357+ </set>
358+ </mkcol>`
359+
360+ func TestCreateCalendarMinimalBody (t * testing.T ) {
361+ tb := testBackend {
362+ calendars : nil ,
363+ objectMap : nil ,
364+ }
365+ b := backend {
366+ Backend : & tb ,
367+ Prefix : "/dav" ,
368+ }
369+ req := httptest .NewRequest ("MKCOL" , "/dav/calendars/user0/test-calendar" , strings .NewReader (mkcolRequestDataMinimalBody ))
370+ req .Header .Set ("Content-Type" , "application/xml" )
371+
372+ err := b .Mkcol (req )
373+ assert .NoError (t , err )
374+ assert .Len (t , tb .calendars , 1 )
375+ c := tb .calendars [0 ]
376+ assert .Equal (t , "Test calendar" , c .Name )
377+ assert .Equal (t , "/dav/calendars/user0/test-calendar" , c .Path )
378+ assert .Equal (t , "" , c .Description )
379+ assert .Equal (t , "" , c .Color )
380+ assert .Equal (t , []string {}, c .SupportedComponentSet )
381+ assert .Equal (t , "" , c .TimeZone )
382+ }
383+
180384type testBackend struct {
181385 calendars []Calendar
182386 objectMap map [string ][]CalendarObject
183387}
184388
185- func (t testBackend ) CreateCalendar (ctx context.Context , calendar * Calendar ) error {
389+ func (t * testBackend ) CreateCalendar (ctx context.Context , calendar * Calendar ) error {
390+ t .calendars = append (t .calendars , * calendar )
186391 return nil
187392}
188393
0 commit comments