package calendar
import (
"strings"
"testing"
"github.com/google/uuid"
)
const propfindHead = `
`
func TestParsePropfindTrenntUnsereEigenschaftenAb(t *testing.T) {
body := []byte(propfindHead + ``)
want, rewritten := parsePropfind(body)
if !want.ctag || !want.color {
t.Fatalf("beide Eigenschaften sollten erkannt werden, bekam %+v", want)
}
out := string(rewritten)
if !strings.Contains(out, "") {
t.Errorf("die übrigen Eigenschaften müssen erhalten bleiben: %s", out)
}
// Der Kern: go-webdav darf sie nicht zu sehen bekommen, sonst meldet es
// sie als 404 und dieselbe Eigenschaft stünde zweimal in der Antwort.
if strings.Contains(out, "getctag") || strings.Contains(out, "calendar-color") {
t.Errorf("unsere Eigenschaften müssen entfernt sein: %s", out)
}
}
func TestParsePropfindLaesstFremdeAnfragenInRuhe(t *testing.T) {
body := []byte(propfindHead + ``)
want, rewritten := parsePropfind(body)
if want.any() {
t.Errorf("nichts von uns gefragt, trotzdem %+v", want)
}
if string(rewritten) != string(body) {
t.Errorf("Rumpf muss unverändert durchgereicht werden")
}
}
func TestParsePropfindNurUnsereEigenschaftHinterlaesstKeinLeeresProp(t *testing.T) {
// Ein leeres weist go-webdav ab – dann käme auf eine gültige
// Anfrage ein Fehler statt einer Antwort.
body := []byte(propfindHead + ``)
_, rewritten := parsePropfind(body)
if !strings.Contains(string(rewritten), "") {
t.Errorf("Platzhalter fehlt: %s", rewritten)
}
}
func TestParsePropfindAllpropUndLeererRumpf(t *testing.T) {
for _, tc := range []struct {
name string
body []byte
}{
{"allprop", []byte(propfindHead + ``)},
{"leerer Rumpf", nil}, // RFC 4918, 9.1: leer bedeutet allprop
} {
want, rewritten := parsePropfind(tc.body)
if !want.ctag || !want.color {
t.Errorf("%s: sollte alles liefern, bekam %+v", tc.name, want)
}
if string(rewritten) != string(tc.body) {
t.Errorf("%s: Rumpf darf nicht umgebaut werden", tc.name)
}
}
}
func TestCalendarOfResponseTrifftNurKalender(t *testing.T) {
id := uuid.New()
cal := &Calendar{ID: id, Color: "#a142f4", CTag: 7}
byID := map[uuid.UUID]*Calendar{id: cal}
tests := []struct {
name string
href string
will *Calendar
}{
{"Kalender", "/caldav/calendars/max/" + id.String() + "/", cal},
{"Home-Set", "/caldav/calendars/max/", nil},
{"Principal", "/caldav/principals-max/", nil},
{"einzelner Termin", "/caldav/calendars/max/" + id.String() + "/abc.ics", nil},
{"fremder Kalender", "/caldav/calendars/max/" + uuid.New().String() + "/", nil},
}
for _, tc := range tests {
part := `` + tc.href + ``
if got := calendarOfResponse(part, byID); got != tc.will {
t.Errorf("%s: bekam %v, erwartet %v", tc.name, got, tc.will)
}
}
}
func TestExtrasPropstat(t *testing.T) {
cal := &Calendar{Color: "#a142f4", CTag: 12}
got := extrasPropstat(cal, wantedExtras{ctag: true, color: true})
if !strings.Contains(got, ">12") {
t.Errorf("ctag fehlt: %s", got)
}
// Apple-Clients und DAVx5 erwarten den Alpha-Anteil.
if !strings.Contains(got, ">#A142F4FF") {
t.Errorf("Farbe nicht in Apple-Schreibweise: %s", got)
}
if !strings.Contains(got, "HTTP/1.1 200 OK") {
t.Errorf("Status fehlt: %s", got)
}
// Ohne Farbe bleibt die Eigenschaft weg – lieber gar nicht melden als
// leer, sonst färbt der Client den Kalender schwarz.
if got := extrasPropstat(&Calendar{CTag: 1}, wantedExtras{color: true}); got != "" {
t.Errorf("ohne Farbe sollte nichts entstehen, bekam %s", got)
}
}