eintopf.info@v0.13.16/service/revent/revent_test.go (about) 1 // Copyright (C) 2022 The Eintopf authors 2 // 3 // This program is free software: you can redistribute it and/or modify 4 // it under the terms of the GNU Affero General Public License as 5 // published by the Free Software Foundation, either version 3 of the 6 // License, or (at your option) any later version. 7 // 8 // This program is distributed in the hope that it will be useful, 9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 // GNU Affero General Public License for more details. 12 // 13 // You should have received a copy of the GNU Affero General Public License 14 // along with this program. If not, see <https://www.gnu.org/licenses/>. 15 16 package revent_test 17 18 import ( 19 "context" 20 "fmt" 21 "testing" 22 "time" 23 24 "github.com/google/go-cmp/cmp" 25 "github.com/google/go-cmp/cmp/cmpopts" 26 27 "eintopf.info/service/auth" 28 "eintopf.info/service/event" 29 "eintopf.info/service/revent" 30 "eintopf.info/test" 31 ) 32 33 func tptr(t time.Time) *time.Time { 34 return &t 35 } 36 37 func TestIntervalGenerateDates(t *testing.T) { 38 tests := []struct { 39 name string 40 interval *revent.Interval 41 start time.Time 42 end time.Time 43 wantDates []time.Time 44 }{ 45 { 46 name: "daily", 47 interval: &revent.Interval{ 48 Type: revent.IntervalDay, 49 Interval: 1, 50 }, 51 start: time.Date(2021, 8, 10, 16, 0, 0, 0, time.UTC), 52 end: time.Date(2021, 8, 15, 16, 0, 0, 0, time.UTC), 53 wantDates: []time.Time{ 54 time.Date(2021, 8, 10, 16, 0, 0, 0, time.UTC), 55 time.Date(2021, 8, 11, 16, 0, 0, 0, time.UTC), 56 time.Date(2021, 8, 12, 16, 0, 0, 0, time.UTC), 57 time.Date(2021, 8, 13, 16, 0, 0, 0, time.UTC), 58 time.Date(2021, 8, 14, 16, 0, 0, 0, time.UTC), 59 time.Date(2021, 8, 15, 16, 0, 0, 0, time.UTC), 60 }, 61 }, 62 { 63 name: "every second day", 64 interval: &revent.Interval{ 65 Type: revent.IntervalDay, 66 Interval: 2, 67 }, 68 start: time.Date(2021, 8, 10, 16, 0, 0, 0, time.UTC), 69 end: time.Date(2021, 8, 15, 16, 0, 0, 0, time.UTC), 70 wantDates: []time.Time{ 71 time.Date(2021, 8, 10, 16, 0, 0, 0, time.UTC), 72 time.Date(2021, 8, 12, 16, 0, 0, 0, time.UTC), 73 time.Date(2021, 8, 14, 16, 0, 0, 0, time.UTC), 74 }, 75 }, 76 { 77 name: "every monday", 78 interval: &revent.Interval{ 79 Type: revent.IntervalWeek, 80 Interval: 1, 81 WeekDay: time.Monday, 82 }, 83 start: time.Date(2021, 8, 1, 16, 0, 0, 0, time.UTC), 84 end: time.Date(2021, 9, 1, 16, 0, 0, 0, time.UTC), 85 wantDates: []time.Time{ 86 time.Date(2021, 8, 2, 16, 0, 0, 0, time.UTC), 87 time.Date(2021, 8, 9, 16, 0, 0, 0, time.UTC), 88 time.Date(2021, 8, 16, 16, 0, 0, 0, time.UTC), 89 time.Date(2021, 8, 23, 16, 0, 0, 0, time.UTC), 90 time.Date(2021, 8, 30, 16, 0, 0, 0, time.UTC), 91 }, 92 }, 93 { 94 name: "every second thursday", 95 interval: &revent.Interval{ 96 Type: revent.IntervalWeek, 97 Interval: 2, 98 WeekDay: time.Thursday, 99 }, 100 start: time.Date(2021, 8, 1, 16, 0, 0, 0, time.UTC), 101 end: time.Date(2021, 9, 1, 16, 0, 0, 0, time.UTC), 102 wantDates: []time.Time{ 103 time.Date(2021, 8, 5, 16, 0, 0, 0, time.UTC), 104 time.Date(2021, 8, 19, 16, 0, 0, 0, time.UTC), 105 }, 106 }, 107 { 108 name: "every first friday per month", 109 interval: &revent.Interval{ 110 Type: revent.IntervalMonth, 111 Interval: 1, 112 WeekDay: time.Friday, 113 }, 114 start: time.Date(2021, 8, 1, 18, 30, 0, 0, time.UTC), 115 end: time.Date(2021, 11, 1, 18, 30, 0, 0, time.UTC), 116 wantDates: []time.Time{ 117 time.Date(2021, 8, 6, 18, 30, 0, 0, time.UTC), 118 time.Date(2021, 9, 3, 18, 30, 0, 0, time.UTC), 119 time.Date(2021, 10, 1, 18, 30, 0, 0, time.UTC), 120 }, 121 }, 122 { 123 name: "every second sunday per month", 124 interval: &revent.Interval{ 125 Type: revent.IntervalMonth, 126 Interval: 2, 127 WeekDay: time.Sunday, 128 }, 129 start: time.Date(2021, 8, 1, 18, 30, 0, 0, time.UTC), 130 end: time.Date(2021, 11, 1, 18, 30, 0, 0, time.UTC), 131 wantDates: []time.Time{ 132 time.Date(2021, 8, 8, 18, 30, 0, 0, time.UTC), 133 time.Date(2021, 9, 12, 18, 30, 0, 0, time.UTC), 134 time.Date(2021, 10, 10, 18, 30, 0, 0, time.UTC), 135 }, 136 }, 137 } 138 139 for _, test := range tests { 140 t.Run(test.name, func(tt *testing.T) { 141 dates, err := test.interval.GenerateDates(test.start, test.end) 142 if err != nil { 143 tt.Error(err) 144 } 145 if diff := cmp.Diff(test.wantDates, dates); diff != "" { 146 tt.Errorf("dates mismatch (-want +got):\n%s", diff) 147 } 148 }) 149 } 150 } 151 152 func TestServiceGenerateEvents(t *testing.T) { 153 tests := []struct { 154 name string 155 newRepeatingEvent *revent.NewRepeatingEvent 156 wantErr error 157 wantFirstEvent *event.Event 158 wantEventsCount int 159 }{ 160 { 161 name: "it works", 162 newRepeatingEvent: &revent.NewRepeatingEvent{ 163 Name: "foo", 164 Organizers: []string{"a", "b"}, 165 Location: "c", 166 Location2: "d", 167 Description: "e", 168 Intervals: []revent.Interval{ 169 { 170 Type: revent.IntervalDay, 171 Interval: 1, 172 }, 173 }, 174 Start: time.Date(2021, 8, 1, 16, 0, 0, 0, time.UTC), 175 End: time.Date(2021, 8, 1, 18, 0, 0, 0, time.UTC), 176 Tags: []string{"x", "y", "z"}, 177 Image: "i", 178 OwnedBy: []string{"user1", "user2"}, 179 }, 180 wantEventsCount: 31, 181 wantFirstEvent: &event.Event{ 182 Published: true, 183 Name: "foo", 184 Organizers: []string{"a", "b"}, 185 Location: "c", 186 Location2: "d", 187 Description: "e", 188 Start: time.Date(2021, 8, 1, 16, 0, 0, 0, time.UTC), 189 End: tptr(time.Date(2021, 8, 1, 18, 0, 0, 0, time.UTC)), 190 Tags: []string{"x", "y", "z"}, 191 Image: "i", 192 OwnedBy: []string{"user1", "user2", "1"}, 193 }, 194 }, 195 } 196 197 for _, testCase := range tests { 198 t.Run(testCase.name, func(tt *testing.T) { 199 reventStore := revent.NewMemoryStore() 200 eventStore := event.NewMemoryStore() 201 202 service := revent.NewService(reventStore, event.NewService(eventStore, nil)) 203 204 ctx := auth.ContextWithID(context.Background(), "1") 205 206 repeatingEvent, err := service.Create(ctx, testCase.newRepeatingEvent) 207 if err != nil { 208 tt.Fatal(err) 209 } 210 211 events, err := service.GenerateEvents(ctx, repeatingEvent.ID, 212 time.Date(2021, 8, 1, 0, 0, 0, 0, time.UTC), 213 time.Date(2021, 8, 31, 0, 0, 0, 0, time.UTC), 214 ) 215 if !test.EqualError(testCase.wantErr, err) { 216 tt.Errorf("err: want != got: %s, %s", testCase.wantErr, err) 217 } 218 if len(events) != testCase.wantEventsCount { 219 tt.Errorf("events len: want != got: %d, %d", testCase.wantEventsCount, len(events)) 220 } 221 if len(events) > 0 && testCase.wantFirstEvent != nil { 222 testCase.wantFirstEvent.Parent = revent.ID(repeatingEvent.ID) 223 if diff := cmp.Diff(testCase.wantFirstEvent, events[0], cmpopts.IgnoreFields(event.Event{}, "ID")); diff != "" { 224 tt.Errorf("first event mismatch mismatch (-want +got):\n%s", diff) 225 } 226 } 227 }) 228 } 229 } 230 231 func TestGenerateEvents(t *testing.T) { 232 tests := []struct { 233 name string 234 repeatingEvent *revent.RepeatingEvent 235 existingEvents []*event.Event 236 wantErr error 237 wantFirstNewEvent *event.NewEvent 238 wantNewEventsCount int 239 }{ 240 { 241 name: "no intervals error", 242 repeatingEvent: &revent.RepeatingEvent{ 243 ID: "1", 244 Name: "foo", 245 Organizers: []string{"a"}, 246 Location: "c", 247 Location2: "d", 248 Description: "e", 249 Intervals: []revent.Interval{}, 250 Start: time.Date(2021, 8, 1, 16, 0, 0, 0, time.UTC), 251 End: time.Date(2021, 8, 1, 18, 0, 0, 0, time.UTC), 252 Tags: []string{"x", "y", "z"}, 253 Image: "i", 254 OwnedBy: []string{"user1", "user2"}, 255 }, 256 wantErr: fmt.Errorf("repeating event has no intervals"), 257 }, 258 { 259 name: "generate with IntervalDay", 260 repeatingEvent: &revent.RepeatingEvent{ 261 ID: "2", 262 Name: "foo", 263 Organizers: []string{"a"}, 264 Location: "c", 265 Location2: "d", 266 Description: "e", 267 Intervals: []revent.Interval{ 268 { 269 Type: revent.IntervalDay, 270 Interval: 1, 271 }, 272 }, 273 Start: time.Date(2021, 8, 1, 16, 0, 0, 0, time.UTC), 274 End: time.Date(2021, 8, 1, 18, 0, 0, 0, time.UTC), 275 Tags: []string{"x", "y", "z"}, 276 Image: "i", 277 OwnedBy: []string{"user1", "user2"}, 278 }, 279 wantNewEventsCount: 31, 280 wantFirstNewEvent: &event.NewEvent{ 281 Published: true, 282 Name: "foo", 283 Organizers: []string{"a"}, 284 Location: "c", 285 Location2: "d", 286 Description: "e", 287 Start: time.Date(2021, 8, 1, 16, 0, 0, 0, time.UTC), 288 End: tptr(time.Date(2021, 8, 1, 18, 0, 0, 0, time.UTC)), 289 Tags: []string{"x", "y", "z"}, 290 Image: "i", 291 OwnedBy: []string{"user1", "user2"}, 292 }, 293 }, 294 { 295 name: "has existingEvents", 296 repeatingEvent: &revent.RepeatingEvent{ 297 ID: "2", 298 Name: "foo", 299 Organizers: []string{"a", "b"}, 300 Location: "c", 301 Location2: "d", 302 Description: "e", 303 Intervals: []revent.Interval{ 304 { 305 Type: revent.IntervalDay, 306 Interval: 1, 307 }, 308 }, 309 Start: time.Date(2021, 8, 1, 16, 0, 0, 0, time.UTC), 310 End: time.Date(2021, 8, 1, 18, 0, 0, 0, time.UTC), 311 Tags: []string{"x", "y", "z"}, 312 Image: "i", 313 OwnedBy: []string{"user1", "user2"}, 314 }, 315 existingEvents: []*event.Event{ 316 { 317 Published: true, 318 Name: "foo", 319 Organizers: []string{"a", "b"}, 320 Location: "c", 321 Location2: "d", 322 Description: "e", 323 Start: time.Date(2021, 8, 1, 16, 0, 0, 0, time.UTC), 324 End: tptr(time.Date(2021, 8, 1, 18, 0, 0, 0, time.UTC)), 325 Tags: []string{"x", "y", "z"}, 326 Image: "i", 327 OwnedBy: []string{"user1", "user2"}, 328 }, 329 }, 330 wantNewEventsCount: 30, 331 wantFirstNewEvent: &event.NewEvent{ 332 Published: true, 333 Name: "foo", 334 Organizers: []string{"a", "b"}, 335 Location: "c", 336 Location2: "d", 337 Description: "e", 338 Start: time.Date(2021, 8, 2, 16, 0, 0, 0, time.UTC), 339 End: tptr(time.Date(2021, 8, 2, 18, 0, 0, 0, time.UTC)), 340 Tags: []string{"x", "y", "z"}, 341 Image: "i", 342 OwnedBy: []string{"user1", "user2"}, 343 }, 344 }, 345 } 346 347 for _, testCase := range tests { 348 t.Run(testCase.name, func(tt *testing.T) { 349 events, err := revent.GenerateEvents( 350 testCase.repeatingEvent, 351 testCase.existingEvents, 352 time.Date(2021, 8, 1, 0, 0, 0, 0, time.UTC), 353 time.Date(2021, 8, 31, 0, 0, 0, 0, time.UTC), 354 ) 355 if !test.EqualError(testCase.wantErr, err) { 356 tt.Errorf("err: want != got: %s, %s", testCase.wantErr, err) 357 } 358 if len(events) != testCase.wantNewEventsCount { 359 tt.Errorf("new events len: want != got: %d, %d", testCase.wantNewEventsCount, len(events)) 360 } 361 if len(events) > 0 && testCase.wantFirstNewEvent != nil { 362 testCase.wantFirstNewEvent.Parent = revent.ID(testCase.repeatingEvent.ID) 363 if diff := cmp.Diff(testCase.wantFirstNewEvent, events[0], cmpopts.IgnoreFields(event.Event{}, "ID")); diff != "" { 364 tt.Errorf("first event mismatch mismatch (-want +got):\n%s", diff) 365 } 366 } 367 }) 368 } 369 }