Added handling of empty multistatus responses

This commit is contained in:
Andreas Schneider 2018-04-04 09:32:20 +02:00
parent b370513d15
commit fd0f4bf3c3
2 changed files with 44 additions and 4 deletions

View File

@ -4,7 +4,6 @@ import (
"bufio" "bufio"
"bytes" "bytes"
"encoding/xml" "encoding/xml"
"errors"
"fmt" "fmt"
"io" "io"
"log" "log"
@ -29,6 +28,10 @@ type ICal struct {
eventData []string // sub slice eventData []string // sub slice
} }
func (i ICal) Valid() bool {
return len(i.eventData) > 0
}
// Retrieve the summary (aka title) of the event. // Retrieve the summary (aka title) of the event.
func (i ICal) Summary() string { func (i ICal) Summary() string {
for _, s := range i.eventData { for _, s := range i.eventData {
@ -195,7 +198,11 @@ func ParseICal(r io.Reader) (*ICal, error) {
// If we didn't find a start or an end, abort. // If we didn't find a start or an end, abort.
if eventStart < 0 || eventEnd <= eventStart { if eventStart < 0 || eventEnd <= eventStart {
return nil, errors.New("calendar item without event") log.Println("Encountered calendar item without event")
return &ICal{
data: data,
eventData: make([]string, 0),
}, err
} }
return &ICal{ return &ICal{
@ -288,8 +295,10 @@ func (c *CalDAV) GetEvents() ([]CalDAVItem, error) {
result := make([]CalDAVItem, 0, len(ms.Response)) result := make([]CalDAVItem, 0, len(ms.Response))
for _, p := range ms.Response { for _, p := range ms.Response {
ical := p.PropStat.Prop.CalendarData ical := p.PropStat.Prop.CalendarData
item := CalDAVItem{p.HRef, &ical} if ical.Valid() {
result = append(result, item) item := CalDAVItem{p.HRef, &ical}
result = append(result, item)
}
} }
return result, nil return result, nil

View File

@ -1,6 +1,7 @@
package main package main
import ( import (
"encoding/xml"
"strings" "strings"
"testing" "testing"
"time" "time"
@ -174,6 +175,36 @@ END:VCALENDAR` {
}) })
} }
func TestXMLUnmarshal(t *testing.T) {
response := `<d:multistatus xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns" xmlns:card="urn:ietf:params:xml:ns:carddav" xmlns:cal="urn:ietf:params:xml:ns:caldav" xmlns:cs="http://calendarserver.org/ns/"><d:response><d:href>/calendar/</d:href><d:propstat><d:prop><cal:calendar-data/></d:prop><d:status>HTTP/1.1 404 Not Found</d:status></d:propstat></d:response><d:response><d:href>/calendar/f10545b91c12a44ef7ed2ee3aa250df4-z2QSIWY.ics</d:href><d:propstat><d:prop><cal:calendar-data>BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//some//NONSGML Calendar//EN
X-WR-Timezone: Europe/London
BEGIN:VEVENT
DTSTART:20180404T080000Z
DTEND:20180404T081500Z
DTSTAMP:20180404T070805Z
SEQUENCE:1522825685
SUMMARY:Test
UID:f10545b91c12a44ef7ed2ee3aa250df4-z2QSIWY
END:VEVENT
END:VCALENDAR</cal:calendar-data></d:prop><d:status>HTTP/1.1 200 OK</d:status></d:propstat></d:response></d:multistatus>`
ms := &MultiStatus{}
err := xml.Unmarshal([]byte(response), ms)
if err != nil {
t.Fatal("Decoding should have worked")
}
if len(ms.Response) != 2 {
t.Fatal("Invalid number of results.")
}
if ms.Response[0].PropStat.Prop.CalendarData.Valid() {
t.Error("CalendarData 0 should not be valid")
}
if !ms.Response[1].PropStat.Prop.CalendarData.Valid() {
t.Error("CalendarData 1 should be valid")
}
}
const icsWithTZ = `BEGIN:VCALENDAR const icsWithTZ = `BEGIN:VCALENDAR
PRODID:-//Ximian//NONSGML Evolution Calendar//EN PRODID:-//Ximian//NONSGML Evolution Calendar//EN
VERSION:2.0 VERSION:2.0