diff --git a/pkg/caldav/caldav.go b/pkg/caldav/caldav.go index 3431fb1ad..bcde52aa2 100644 --- a/pkg/caldav/caldav.go +++ b/pkg/caldav/caldav.go @@ -58,7 +58,7 @@ type Todo struct { Priority int64 // 0-9, 1 is highest RelatedToUID string Color string - + Categories []string Start time.Time End time.Time DueDate time.Time @@ -239,6 +239,11 @@ RRULE:FREQ=SECONDLY;INTERVAL=` + strconv.FormatInt(t.RepeatAfter, 10) } } + if len(t.Categories) > 0 { + caldavtodos += ` +CATEGORIES:` + strings.Join(t.Categories, ",") + } + caldavtodos += ` LAST-MODIFIED:` + makeCalDavTimeFromTimeStamp(t.Updated) diff --git a/pkg/caldav/caldav_test.go b/pkg/caldav/caldav_test.go index f5e3ab13f..fea80080f 100644 --- a/pkg/caldav/caldav_test.go +++ b/pkg/caldav/caldav_test.go @@ -481,6 +481,45 @@ DUE:20181201T011204Z RRULE:FREQ=SECONDLY;INTERVAL=435 LAST-MODIFIED:00010101T000000Z END:VTODO +END:VCALENDAR`, + }, + { + name: "with categories", + args: args{ + config: &Config{ + Name: "test", + ProdID: "RandomProdID which is not random", + Color: "ffffff", + }, + todos: []*Todo{ + { + Summary: "Todo #1", + UID: "randommduid", + Timestamp: time.Unix(1543626724, 0).In(config.GetTimeZone()), + Color: "affffe", + Categories: []string{"label1", "label2"}, + }, + }, + }, + wantCaldavtasks: `BEGIN:VCALENDAR +VERSION:2.0 +METHOD:PUBLISH +X-PUBLISHED-TTL:PT4H +X-WR-CALNAME:test +PRODID:-//RandomProdID which is not random//EN +X-APPLE-CALENDAR-COLOR:#ffffffFF +X-OUTLOOK-COLOR:#ffffffFF +X-FUNAMBOL-COLOR:#ffffffFF +BEGIN:VTODO +UID:randommduid +DTSTAMP:20181201T011204Z +SUMMARY:Todo #1 +X-APPLE-CALENDAR-COLOR:#affffeFF +X-OUTLOOK-COLOR:#affffeFF +X-FUNAMBOL-COLOR:#affffeFF +CATEGORIES:label1,label2 +LAST-MODIFIED:00010101T000000Z +END:VTODO END:VCALENDAR`, }, } diff --git a/pkg/caldav/parsing.go b/pkg/caldav/parsing.go index d9c419086..f66fdcb1a 100644 --- a/pkg/caldav/parsing.go +++ b/pkg/caldav/parsing.go @@ -34,6 +34,10 @@ func GetCaldavTodosForTasks(list *models.ListWithTasksAndBuckets, listTasks []*m for _, t := range listTasks { duration := t.EndDate.Sub(t.StartDate) + var categories []string + for _, label := range t.Labels { + categories = append(categories, label.Title) + } caldavtodos = append(caldavtodos, &Todo{ Timestamp: t.Updated, @@ -42,6 +46,7 @@ func GetCaldavTodosForTasks(list *models.ListWithTasksAndBuckets, listTasks []*m Description: t.Description, Completed: t.DoneAt, // Organizer: &t.CreatedBy, // Disabled until we figure out how this works + Categories: categories, Priority: t.Priority, Start: t.StartDate, End: t.EndDate, diff --git a/pkg/caldav/parsing_test.go b/pkg/caldav/parsing_test.go index 99bb61a62..8d170fd69 100644 --- a/pkg/caldav/parsing_test.go +++ b/pkg/caldav/parsing_test.go @@ -99,3 +99,85 @@ END:VCALENDAR`, }) } } + +func TestFormatTaskAsVTODO(t *testing.T) { + type args struct { + list *models.ListWithTasksAndBuckets + tasks []*models.TaskWithComments + } + tests := []struct { + name string + args args + wantCaldav string + }{ + { + name: "Format single Task as Caldav", + args: args{ + list: &models.ListWithTasksAndBuckets{ + List: models.List{ + Title: "List title", + }, + }, + tasks: []*models.TaskWithComments{ + { + Task: models.Task{ + Title: "Task 1", + UID: "randomuid", + Description: "Description", + Priority: 3, + Created: time.Unix(1543626721, 0).In(config.GetTimeZone()), + DueDate: time.Unix(1543626722, 0).In(config.GetTimeZone()), + StartDate: time.Unix(1543626723, 0).In(config.GetTimeZone()), + EndDate: time.Unix(1543626724, 0).In(config.GetTimeZone()), + Updated: time.Unix(1543626725, 0).In(config.GetTimeZone()), + DoneAt: time.Unix(1543626726, 0).In(config.GetTimeZone()), + RepeatAfter: 86400, + Labels: []*models.Label{ + { + ID: 1, + Title: "label1", + }, + { + ID: 2, + Title: "label2", + }, + }, + + }, + }, + }, + }, + wantCaldav: `BEGIN:VCALENDAR +VERSION:2.0 +METHOD:PUBLISH +X-PUBLISHED-TTL:PT4H +X-WR-CALNAME:List title +PRODID:-//Vikunja Todo App//EN +BEGIN:VTODO +UID:randomuid +DTSTAMP:20181201T011205Z +SUMMARY:Task 1 +DTSTART:20181201T011203Z +DTEND:20181201T011204Z +DESCRIPTION:Description +COMPLETED:20181201T011206Z +STATUS:COMPLETED +DUE:20181201T011202Z +CREATED:20181201T011201Z +PRIORITY:3 +RRULE:FREQ=SECONDLY;INTERVAL=86400 +CATEGORIES:label1,label2 +LAST-MODIFIED:20181201T011205Z +END:VTODO +END:VCALENDAR`, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := GetCaldavTodosForTasks(tt.args.list, tt.args.tasks) + if diff, equal := messagediff.PrettyDiff(got, tt.wantCaldav); !equal { + t.Errorf("GetCaldavTodosForTasks() gotVTask = %v, want %v, diff = %s", got, tt.wantCaldav, diff) + } + }) + } +}