diff --git a/backend/service/ical/icalFileGeneration.go b/backend/service/ical/icalFileGeneration.go index f39e618..02f3c01 100644 --- a/backend/service/ical/icalFileGeneration.go +++ b/backend/service/ical/icalFileGeneration.go @@ -3,6 +3,7 @@ package ical import ( "htwkalender/model" "htwkalender/service/functions" + clock "htwkalender/service/functions/time" "htwkalender/service/names" "time" @@ -18,6 +19,12 @@ type IcalModel struct { // EmitICal implements the interface for goics func (icalModel IcalModel) EmitICal() goics.Componenter { + internalClock := clock.RealClock{} + c := generateIcalEmit(icalModel, internalClock) + return c +} + +func generateIcalEmit(icalModel IcalModel, internalClock clock.Clock) *goics.Component { europeTime, _ := time.LoadLocation("Europe/Berlin") c := goics.NewComponent() c.SetType("VCALENDAR") @@ -38,7 +45,7 @@ func (icalModel IcalModel) EmitICal() goics.Componenter { s := goics.NewComponent() s.SetType("VEVENT") - s.AddProperty(goics.FormatDateTime("DTSTAMP", time.Now().Local().In(europeTime))) + s.AddProperty(goics.FormatDateTime("DTSTAMP", internalClock.Now().Local().In(europeTime))) // create a unique id for the event by hashing the event start, end, course and name var eventHash = functions.HashString(event.Start.String() + event.End.String() + event.Course + event.Name + event.Rooms) @@ -49,7 +56,7 @@ func (icalModel IcalModel) EmitICal() goics.Componenter { if mappingFound { addPropertyIfNotEmpty(s, "SUMMARY", replaceNameIfUserDefined(&event, mapEntry)) - addAlarmIfSpecified(s, event, mapEntry) + addAlarmIfSpecified(s, event, mapEntry, internalClock) } else { addPropertyIfNotEmpty(s, "SUMMARY", event.Name) } @@ -99,10 +106,10 @@ func (icalModel IcalModel) daylight(tz *goics.Component) { } // if reminder is specified in the configuration for this event, an alarm will be added to the event -func addAlarmIfSpecified(s *goics.Component, event model.Event, mapping model.FeedCollection) { +func addAlarmIfSpecified(s *goics.Component, event model.Event, mapping model.FeedCollection, clock clock.Clock) { // if event.Start > now // then add alarm - if event.Start.Time().Local().After(time.Now().Local()) && mapping.Reminder { + if event.Start.Time().Local().After(clock.Now().Local()) && mapping.Reminder { a := goics.NewComponent() a.SetType("VALARM") a.AddProperty("TRIGGER", "-P0DT0H15M0S") diff --git a/backend/service/ical/icalFileGeneration_test.go b/backend/service/ical/icalFileGeneration_test.go new file mode 100644 index 0000000..4eccc99 --- /dev/null +++ b/backend/service/ical/icalFileGeneration_test.go @@ -0,0 +1,123 @@ +package ical + +import ( + "github.com/jordic/goics" + "htwkalender/model" + mockTime "htwkalender/service/functions/time" + "reflect" + "testing" + "time" +) + +func TestIcalModel_EmitICal(t *testing.T) { + type fields struct { + Events model.Events + Mapping map[string]model.FeedCollection + } + tests := []struct { + name string + fields fields + want *goics.Component + }{ + { + name: "Test EmitICal", + fields: fields{ + Events: model.Events{ + { + UUID: "123", + Name: "Test", + EventType: "Test", + Notes: "Test", + Prof: "Test", + Rooms: "Test", + BookedAt: "Test", + }, + }, + Mapping: map[string]model.FeedCollection{ + "123": { + UUID: "123", + Name: "Test", + Course: "Test", + UserDefinedName: "Test", + }, + }, + }, + want: &goics.Component{ + Tipo: "VCALENDAR", + Elements: []goics.Componenter{ + &goics.Component{ + Tipo: "VTIMEZONE", + Elements: []goics.Componenter{ + &HtwkalenderComponent{ + Component: &goics.Component{ + Tipo: "STANDARD", + Elements: []goics.Componenter{}, + Properties: map[string][]string{ + "DTSTART": {"19701025T030000"}, + "RRULE": {"FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU"}, + "TZOFFSETFROM": {"+0200"}, + "TZOFFSETTO": {"+0100"}, + "TZNAME": {"CET"}, + }, + }, + }, + &HtwkalenderComponent{ + Component: &goics.Component{ + Tipo: "DAYLIGHT", + Elements: []goics.Componenter{}, + Properties: map[string][]string{ + "DTSTART": {"19700329T020000"}, + "TZOFFSETFROM": {"+0100"}, + "TZOFFSETTO": {"+0200"}, + "TZNAME": {"CEST"}, + "RRULE": {"FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU"}, + }, + }, + }, + }, + Properties: map[string][]string{ + "TZID": {"EUROPE/BERLIN"}, + }, + }, + &goics.Component{ + Tipo: "VEVENT", + Elements: []goics.Componenter{}, + Properties: map[string][]string{ + "DTSTAMP": {"20231201T000000Z"}, + "UID": {"a8d627d93f518e9096b6f40e36d27b7660fa26d318ef1adc43da750e49ebe4be@htwkalender.de"}, + "DTEND": {"00010101T000000Z"}, + "DTSTART": {"00010101T000000Z"}, + "SUMMARY": {"Test"}, + "DESCRIPTION": {"Notizen: Test\nProf: Test\nTyp: Test\n"}, + "LOCATION": {"Test"}, + }, + }, + }, + Properties: map[string][]string{ + "PRODID": {"-//HTWK Kalender//htwkalender.de//DE"}, + "VERSION": {"2.0"}, + "CALSCALE": {"GREGORIAN"}, + "TZID": {"EUROPE/BERLIN"}, + "X-WR-CALNAME": {"HTWK Kalender"}, + "X-WR-TIMEZONE": {"EUROPE/BERLIN"}, + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + icalModel := IcalModel{ + Events: tt.fields.Events, + Mapping: tt.fields.Mapping, + } + + mockClock := mockTime.MockClock{ + NowTime: time.Date(2023, 12, 1, 0, 0, 0, 0, time.UTC), + } + + if got := generateIcalEmit(icalModel, mockClock); !reflect.DeepEqual(got, tt.want) { + t.Errorf("EmitICal() = %v, want %v", got, tt.want) + } + }) + } +}