]> git.basschouten.com Git - openhab-addons.git/blob
680f057d3920a776abf5ff7779a9589aab7a7c3d
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2021 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
7  * This program and the accompanying materials are made available under the
8  * terms of the Eclipse Public License 2.0 which is available at
9  * http://www.eclipse.org/legal/epl-2.0
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.icalendar.internal.logic;
14
15 import static org.junit.jupiter.api.Assertions.*;
16
17 import java.io.FileInputStream;
18 import java.io.IOException;
19 import java.time.Instant;
20 import java.time.LocalDate;
21 import java.time.ZoneId;
22 import java.util.List;
23
24 import org.junit.jupiter.api.BeforeEach;
25 import org.junit.jupiter.api.Test;
26 import org.openhab.core.library.types.HSBType;
27 import org.openhab.core.library.types.OnOffType;
28 import org.openhab.core.library.types.OpenClosedType;
29 import org.openhab.core.library.types.PercentType;
30 import org.openhab.core.library.types.PlayPauseType;
31 import org.openhab.core.library.types.QuantityType;
32 import org.openhab.core.library.types.RewindFastforwardType;
33 import org.openhab.core.library.types.StringType;
34 import org.openhab.core.library.types.UpDownType;
35 import org.openhab.core.types.Command;
36
37 /**
38  * Tests for presentable calendar.
39  *
40  * @author Michael Wodniok - Initial contribution.
41  * @author Andrew Fiddian-Green - Tests for Command Tag code
42  * @author Michael Wodniok - Extended Tests for filtered Events
43  *
44  */
45 public class BiweeklyPresentableCalendarTest {
46     private AbstractPresentableCalendar calendar;
47     private AbstractPresentableCalendar calendar2;
48     private AbstractPresentableCalendar calendar3;
49     private AbstractPresentableCalendar calendar_issue9647;
50
51     @BeforeEach
52     public void setUp() throws IOException, CalendarException {
53         calendar = new BiweeklyPresentableCalendar(new FileInputStream("src/test/resources/test.ics"));
54         calendar2 = new BiweeklyPresentableCalendar(new FileInputStream("src/test/resources/test2.ics"));
55         calendar3 = new BiweeklyPresentableCalendar(new FileInputStream("src/test/resources/test3.ics"));
56         calendar_issue9647 = new BiweeklyPresentableCalendar(
57                 new FileInputStream("src/test/resources/test-issue9647.ics"));
58     }
59
60     /**
61      * Tests recurrence and whether TimeZone is interpolated in a right way.
62      */
63     @Test
64     public void testIsEventPresent() {
65         // Test series
66         assertFalse(calendar.isEventPresent(Instant.parse("2019-09-08T09:04:00Z")));
67         assertTrue(calendar.isEventPresent(Instant.parse("2019-09-08T09:08:00Z")));
68         assertFalse(calendar.isEventPresent(Instant.parse("2019-09-08T09:11:00Z")));
69
70         assertFalse(calendar.isEventPresent(Instant.parse("2019-09-09T09:04:00Z")));
71         assertFalse(calendar.isEventPresent(Instant.parse("2019-09-09T09:08:00Z")));
72         assertFalse(calendar.isEventPresent(Instant.parse("2019-09-09T09:11:00Z")));
73
74         assertFalse(calendar.isEventPresent(Instant.parse("2019-09-10T09:04:00Z")));
75         assertTrue(calendar.isEventPresent(Instant.parse("2019-09-10T09:08:00Z")));
76         assertFalse(calendar.isEventPresent(Instant.parse("2019-09-10T09:11:00Z")));
77
78         assertFalse(calendar.isEventPresent(Instant.parse("2019-09-11T09:04:00Z")));
79         assertTrue(calendar.isEventPresent(Instant.parse("2019-09-11T09:08:00Z")));
80         assertFalse(calendar.isEventPresent(Instant.parse("2019-09-11T09:11:00Z")));
81
82         assertFalse(calendar.isEventPresent(Instant.parse("2019-09-12T09:04:00Z")));
83         assertTrue(calendar.isEventPresent(Instant.parse("2019-09-12T09:08:00Z")));
84         assertFalse(calendar.isEventPresent(Instant.parse("2019-09-12T09:11:00Z")));
85
86         assertFalse(calendar.isEventPresent(Instant.parse("2019-09-13T09:04:00Z")));
87         assertFalse(calendar.isEventPresent(Instant.parse("2019-09-13T09:08:00Z")));
88         assertFalse(calendar.isEventPresent(Instant.parse("2019-09-13T09:11:00Z")));
89
90         // Test in CEST (UTC+2)
91         assertFalse(calendar.isEventPresent(Instant.parse("2019-09-14T07:59:00Z")));
92         assertTrue(calendar.isEventPresent(Instant.parse("2019-09-14T08:03:00Z")));
93         assertFalse(calendar.isEventPresent(Instant.parse("2019-09-14T09:01:00Z")));
94
95         // Test Series with cancelled event by Davdroid
96         assertFalse(calendar2.isEventPresent(Instant.parse("2019-11-03T09:55:00Z")));
97         assertTrue(calendar2.isEventPresent(Instant.parse("2019-11-03T10:01:00Z")));
98         assertFalse(calendar2.isEventPresent(Instant.parse("2019-11-03T13:00:00Z")));
99
100         assertFalse(calendar2.isEventPresent(Instant.parse("2019-11-24T09:55:00Z")));
101         assertFalse(calendar2.isEventPresent(Instant.parse("2019-11-24T10:01:00Z")));
102         assertFalse(calendar2.isEventPresent(Instant.parse("2019-11-24T13:00:00Z")));
103     }
104
105     /**
106      * This test relies on a working isEventPresent and assumes the calculation
107      * of recurrence is done the same way.
108      */
109     @Test
110     public void testGetCurrentEvent() {
111         Event currentEvent = calendar.getCurrentEvent(Instant.parse("2019-09-10T09:07:00Z"));
112         assertNotNull(currentEvent);
113         assertTrue("Test Series in UTC".contentEquals(currentEvent.title));
114         assertEquals(0, Instant.parse("2019-09-10T09:05:00Z").compareTo(currentEvent.start));
115         assertEquals(0, Instant.parse("2019-09-10T09:10:00Z").compareTo(currentEvent.end));
116
117         Event nonExistingEvent = calendar.getCurrentEvent(Instant.parse("2019-09-09T09:07:00Z"));
118         assertNull(nonExistingEvent);
119     }
120
121     /**
122      * This test relies on a working isEventPresent and assumes the calculation
123      * of recurrence is done the same way.
124      */
125     @Test
126     public void testGetNextEvent() {
127         // positive case: next event of series
128         Event nextEventOfSeries = calendar.getNextEvent(Instant.parse("2019-09-10T09:07:00Z"));
129         assertNotNull(nextEventOfSeries);
130         assertTrue("Test Series in UTC".contentEquals(nextEventOfSeries.title));
131         assertEquals(0, Instant.parse("2019-09-11T09:05:00Z").compareTo(nextEventOfSeries.start));
132         assertEquals(0, Instant.parse("2019-09-11T09:10:00Z").compareTo(nextEventOfSeries.end));
133
134         // positive case: next event after series
135         Event nextEventOutsideSeries = calendar.getNextEvent(Instant.parse("2019-09-12T09:07:00Z"));
136         assertNotNull(nextEventOutsideSeries);
137         assertTrue("Test Event in UTC+2".contentEquals(nextEventOutsideSeries.title));
138         assertEquals(0, Instant.parse("2019-09-14T08:00:00Z").compareTo(nextEventOutsideSeries.start));
139         assertEquals(0, Instant.parse("2019-09-14T09:00:00Z").compareTo(nextEventOutsideSeries.end));
140
141         // positive case: next event should be also set if currently none is present
142         Event nextEventIndependent = calendar.getNextEvent(Instant.parse("2019-09-13T09:07:00Z"));
143         assertTrue(nextEventOutsideSeries.equals(nextEventIndependent));
144
145         // negative case: after last event there is no next
146         Event nonExistingEvent = calendar.getNextEvent(Instant.parse("2019-09-14T12:00:00Z"));
147         assertNull(nonExistingEvent);
148
149         // mixed case: cancelled events also not show up as next
150         Event nextEventAfterCancelled = calendar2.getNextEvent(Instant.parse("2019-11-24T09:55:00Z"));
151         assertNotNull(nextEventAfterCancelled);
152         assertEquals(0, Instant.parse("2019-12-01T10:00:00Z").compareTo(nextEventAfterCancelled.start));
153     }
154
155     /**
156      * This test checks for Events that have just begun or ended, and if so it checks for Command Tags
157      * and checks if these tags are valid
158      */
159     @SuppressWarnings("null")
160     @Test
161     public void testCommandTagCode() {
162         List<Event> events = null;
163         int eventCount = 2;
164         int tagsPerEvent = 8;
165
166         // test just begun events: first in the series
167         events = calendar3.getJustBegunEvents(Instant.parse("2020-01-28T15:55:00Z"),
168                 Instant.parse("2020-01-28T16:05:00Z"));
169         assertNotNull(events);
170         assertEquals(eventCount, events.size());
171         for (Event event : events) {
172             List<CommandTag> cmdTags = event.commandTags;
173             assertEquals(tagsPerEvent, cmdTags.size());
174             int beginTags = 0;
175             for (CommandTag cmdTag : cmdTags) {
176                 if (cmdTag.getTagType() == CommandTagType.BEGIN) {
177                     assertTrue(cmdTag.isAuthorized("abc"));
178                     assertTrue(cmdTag.getItemName().matches("^\\w+$"));
179                     assertTrue(cmdTag.getCommand() != null);
180                     beginTags++;
181                 }
182             }
183             assertEquals(tagsPerEvent / 2, beginTags);
184         }
185
186         // test just begun events: third in the series
187         events = calendar3.getJustBegunEvents(Instant.parse("2020-01-30T15:55:00Z"),
188                 Instant.parse("2020-01-30T16:05:00Z"));
189         assertNotNull(events);
190         assertEquals(eventCount, events.size());
191         for (Event event : events) {
192             List<CommandTag> cmdTags = event.commandTags;
193             assertEquals(tagsPerEvent, cmdTags.size());
194             int beginTags = 0;
195             for (CommandTag cmdTag : cmdTags) {
196                 if (cmdTag.getTagType() == CommandTagType.BEGIN) {
197                     assertTrue(cmdTag.isAuthorized("abc"));
198                     assertTrue(cmdTag.getItemName().matches("^\\w+$"));
199                     assertTrue(cmdTag.getCommand() != null);
200                     beginTags++;
201                 }
202             }
203             assertEquals(tagsPerEvent / 2, beginTags);
204         }
205
206         // test outside of window: begun events, too early
207         events = calendar3.getJustBegunEvents(Instant.parse("2020-01-28T15:50:00Z"),
208                 Instant.parse("2020-01-28T15:55:00Z"));
209         assertNotNull(events);
210         assertEquals(0, events.size());
211
212         // test outside of window: begun events, too late
213         events = calendar3.getJustBegunEvents(Instant.parse("2020-01-28T16:05:00Z"),
214                 Instant.parse("2020-01-28T16:10:00Z"));
215         assertNotNull(events);
216         assertEquals(0, events.size());
217
218         // test just ended events: first in the series
219         events = calendar3.getJustEndedEvents(Instant.parse("2020-01-28T16:25:00Z"),
220                 Instant.parse("2020-01-28T16:35:00Z"));
221         assertNotNull(events);
222         assertEquals(eventCount, events.size());
223         for (Event event : events) {
224             List<CommandTag> cmdTags = event.commandTags;
225             assertEquals(tagsPerEvent, cmdTags.size());
226             int endTags = 0;
227             for (CommandTag cmdTag : cmdTags) {
228                 if (cmdTag.getTagType() == CommandTagType.END) {
229                     assertTrue(cmdTag.isAuthorized("abc"));
230                     assertTrue(cmdTag.getItemName().matches("^\\w+$"));
231                     assertTrue(cmdTag.getCommand() != null);
232                     endTags++;
233                 }
234             }
235             assertEquals(tagsPerEvent / 2, endTags);
236         }
237
238         // test outside of window: ended events, too early
239         events = calendar3.getJustEndedEvents(Instant.parse("2020-01-28T16:20:00Z"),
240                 Instant.parse("2020-01-28T16:25:00Z"));
241         assertNotNull(events);
242         assertEquals(0, events.size());
243
244         // test outside of window: ended events, too late
245         events = calendar3.getJustEndedEvents(Instant.parse("2020-01-28T16:35:00Z"),
246                 Instant.parse("2020-01-28T16:40:00Z"));
247         assertNotNull(events);
248         assertEquals(0, events.size());
249
250         // test a valid just begun event with both good and bad authorization codes
251         events = calendar3.getJustBegunEvents(Instant.parse("2020-01-28T15:55:00Z"),
252                 Instant.parse("2020-01-28T16:05:00Z"));
253         assertNotNull(events);
254         assertTrue(events.size() > 0);
255         List<CommandTag> cmdTags = events.get(0).commandTags;
256         assertTrue(cmdTags.size() > 0);
257         CommandTag cmd = cmdTags.get(0);
258         // accept correct, empty or null configuration codes
259         assertTrue(cmd.isAuthorized("abc"));
260         assertTrue(cmd.isAuthorized(""));
261         assertTrue(cmd.isAuthorized(null));
262         // reject incorrect configuration code
263         assertFalse(cmd.isAuthorized("123"));
264
265         // test tag syntax: Test Series #1
266         events = calendar3.getJustBegunEvents(Instant.parse("2020-01-28T19:25:00Z"),
267                 Instant.parse("2020-01-28T19:35:00Z"));
268         assertNotNull(events);
269         assertEquals(1, events.size());
270         cmdTags = events.get(0).commandTags;
271         assertEquals(11, cmdTags.size());
272
273         // BEGIN:Calendar_Test_Color:ON:abc
274         assertEquals("Calendar_Test_Color", cmdTags.get(0).getItemName());
275         assertTrue(cmdTags.get(0).isAuthorized("abc"));
276         Command cmd0 = cmdTags.get(0).getCommand();
277         assertNotNull(cmd0);
278         assertEquals(OnOffType.class, cmd0.getClass());
279
280         // BEGIN:Calendar_Test_Contact:OPEN:abc
281         Command cmd1 = cmdTags.get(1).getCommand();
282         assertNotNull(cmd1);
283         assertEquals(OpenClosedType.class, cmd1.getClass());
284
285         // BEGIN:Calendar_Test_Dimmer:ON:abc
286         Command cmd2 = cmdTags.get(2).getCommand();
287         assertNotNull(cmd2);
288         assertEquals(OnOffType.class, cmd2.getClass());
289
290         // BEGIN:Calendar_Test_Number:12.3:abc
291         Command cmd3 = cmdTags.get(3).getCommand();
292         assertNotNull(cmd3);
293         assertEquals(QuantityType.class, cmd3.getClass());
294
295         // BEGIN:Calendar_Test_Temperature:12.3°C:abc
296         Command cmd4 = cmdTags.get(4).getCommand();
297         assertNotNull(cmd4);
298         assertEquals(QuantityType.class, cmd4.getClass());
299
300         // BEGIN:Calendar_Test_Pressure:12.3hPa:abc
301         Command cmd5 = cmdTags.get(5).getCommand();
302         assertNotNull(cmd5);
303         assertEquals(QuantityType.class, cmd5.getClass());
304
305         // BEGIN:Calendar_Test_Speed:12.3m/s:abc
306         Command cmd6 = cmdTags.get(6).getCommand();
307         assertNotNull(cmd6);
308         assertEquals(QuantityType.class, cmd6.getClass());
309
310         // BEGIN:Calendar_Test_Player:PLAY:abc
311         Command cmd7 = cmdTags.get(7).getCommand();
312         assertNotNull(cmd7);
313         assertEquals(PlayPauseType.class, cmd7.getClass());
314
315         // BEGIN:Calendar_Test_RollerShutter:UP:abc
316         Command cmd8 = cmdTags.get(8).getCommand();
317         assertNotNull(cmd8);
318         assertEquals(UpDownType.class, cmd8.getClass());
319
320         // BEGIN:Calendar_Test_String:Test Series #1:abc
321         Command cmd9 = cmdTags.get(9).getCommand();
322         assertNotNull(cmd9);
323         assertEquals(StringType.class, cmd9.getClass());
324
325         // BEGIN:Calendar_Test_Switch:ON:abc
326         Command cmd10 = cmdTags.get(10).getCommand();
327         assertNotNull(cmd10);
328         assertEquals(OnOffType.class, cmd10.getClass());
329
330         // test tag syntax: Test Series #4
331         events = calendar3.getJustBegunEvents(Instant.parse("2020-01-28T20:10:00Z"),
332                 Instant.parse("2020-01-28T20:20:00Z"));
333         assertNotNull(events);
334         assertEquals(1, events.size());
335         cmdTags = events.get(0).commandTags;
336         assertEquals(11, cmdTags.size());
337
338         // BEGIN:Calendar_Test_Color:0%:abc
339         cmd0 = cmdTags.get(0).getCommand();
340         assertNotNull(cmd0);
341         assertEquals(PercentType.class, cmd0.getClass());
342
343         // BEGIN:Calendar_Test_Contact:CLOSED:abc
344         cmd1 = cmdTags.get(1).getCommand();
345         assertNotNull(cmd1);
346         assertEquals(OpenClosedType.class, cmd1.getClass());
347
348         // BEGIN:Calendar_Test_Dimmer:0%:abc
349         cmd2 = cmdTags.get(2).getCommand();
350         assertNotNull(cmd2);
351         assertEquals(PercentType.class, cmd2.getClass());
352
353         // BEGIN:Calendar_Test_Number:-12.3:abc
354         cmd3 = cmdTags.get(3).getCommand();
355         assertNotNull(cmd3);
356         assertEquals(QuantityType.class, cmd3.getClass());
357
358         // BEGIN:Calendar_Test_Temperature:-12.3°C:abc
359         cmd4 = cmdTags.get(4).getCommand();
360         assertNotNull(cmd4);
361         assertEquals(QuantityType.class, cmd4.getClass());
362
363         // BEGIN:Calendar_Test_Pressure:500mmHg:abc
364         cmd5 = cmdTags.get(5).getCommand();
365         assertNotNull(cmd5);
366         assertEquals(QuantityType.class, cmd5.getClass());
367
368         // BEGIN:Calendar_Test_Speed:12300000mm/h:abc
369         cmd6 = cmdTags.get(6).getCommand();
370         assertNotNull(cmd6);
371         assertEquals(QuantityType.class, cmd6.getClass());
372
373         // BEGIN:Calendar_Test_Player:REWIND:abc
374         cmd7 = cmdTags.get(7).getCommand();
375         assertNotNull(cmd7);
376         assertEquals(RewindFastforwardType.class, cmd7.getClass());
377
378         // BEGIN:Calendar_Test_RollerShutter:100%:abc
379         cmd8 = cmdTags.get(8).getCommand();
380         assertNotNull(cmd8);
381         assertEquals(PercentType.class, cmd8.getClass());
382
383         // BEGIN:Calendar_Test_String:Test Series #4:abc
384         cmd9 = cmdTags.get(9).getCommand();
385         assertNotNull(cmd9);
386         assertEquals(StringType.class, cmd9.getClass());
387
388         // BEGIN:Calendar_Test_Switch:OFF:abc
389         cmd10 = cmdTags.get(10).getCommand();
390         assertNotNull(cmd10);
391         assertEquals(OnOffType.class, cmd10.getClass());
392
393         // test tag syntax: Test Series #5
394         events = calendar3.getJustBegunEvents(Instant.parse("2020-01-28T20:25:00Z"),
395                 Instant.parse("2020-01-28T20:35:00Z"));
396         assertNotNull(events);
397         assertEquals(1, events.size());
398         cmdTags = events.get(0).commandTags;
399         assertEquals(11, cmdTags.size());
400
401         // BEGIN:Calendar_Test_Color:240,100,100:abc
402         cmd0 = cmdTags.get(0).getCommand();
403         assertNotNull(cmd0);
404         assertEquals(HSBType.class, cmd0.getClass());
405
406         // BEGIN:Calendar_Test_Contact:OPEN:abc
407         cmd1 = cmdTags.get(1).getCommand();
408         assertNotNull(cmd1);
409         assertEquals(OpenClosedType.class, cmd1.getClass());
410
411         // BEGIN:Calendar_Test_Dimmer:50%:abc
412         cmd2 = cmdTags.get(2).getCommand();
413         assertNotNull(cmd2);
414         assertEquals(PercentType.class, cmd2.getClass());
415
416         // BEGIN:Calendar_Test_Number:-0:abc
417         cmd3 = cmdTags.get(3).getCommand();
418         assertNotNull(cmd3);
419         assertEquals(QuantityType.class, cmd3.getClass());
420
421         // BEGIN:Calendar_Test_Temperature:0K:abc
422         cmd4 = cmdTags.get(4).getCommand();
423         assertNotNull(cmd4);
424         assertEquals(QuantityType.class, cmd4.getClass());
425
426         // BEGIN:Calendar_Test_Pressure:12.3hPa:abc
427         cmd5 = cmdTags.get(5).getCommand();
428         assertNotNull(cmd5);
429         assertEquals(QuantityType.class, cmd5.getClass());
430
431         // BEGIN:Calendar_Test_Speed:12.3km/h:abc
432         cmd6 = cmdTags.get(6).getCommand();
433         assertNotNull(cmd6);
434         assertEquals(QuantityType.class, cmd6.getClass());
435
436         // BEGIN:Calendar_Test_Player:PLAY:abc
437         cmd7 = cmdTags.get(7).getCommand();
438         assertNotNull(cmd7);
439         assertEquals(PlayPauseType.class, cmd7.getClass());
440
441         // BEGIN:Calendar_Test_RollerShutter:50%:abc
442         cmd8 = cmdTags.get(8).getCommand();
443         assertNotNull(cmd8);
444         assertEquals(PercentType.class, cmd8.getClass());
445
446         // BEGIN:Calendar_Test_String:Test Series #5:abc
447         cmd9 = cmdTags.get(9).getCommand();
448         assertNotNull(cmd9);
449         assertEquals(StringType.class, cmd9.getClass());
450
451         // BEGIN:Calendar_Test_Switch:ON:abc
452         cmd10 = cmdTags.get(10).getCommand();
453         assertNotNull(cmd10);
454         assertEquals(OnOffType.class, cmd10.getClass());
455
456         // test bad command tag syntax: Test Series #6
457         events = calendar3.getJustBegunEvents(Instant.parse("2020-01-28T20:40:00Z"),
458                 Instant.parse("2020-01-28T20:50:00Z"));
459         assertNotNull(events);
460         assertEquals(1, events.size());
461         cmdTags = events.get(0).commandTags;
462         // Test Series #6 contains only "bad" command tags as follows..
463
464         // tags with wrong case prefix..
465         // begin
466         // Begin
467         // BEGIn
468
469         // tags that are missing ":" field delimiters..
470         // BEGIN
471
472         // tags with too few field delimiters..
473         // BEGIN:www
474
475         // tags with too many field delimiters..
476         // BEGIN:www:xxx:yyy:zzz
477
478         // tags with an invalid prefix..
479         // BEGINX:xxx:yyy:zzz
480         // ENDX:xxx:yyy:zzz
481         // BEGIN :xxx:yyy:zzz
482         // BEGIN :xxx:yyy:zzz
483
484         // tags with an empty Item Name
485         // BEGIN::yyy:zzz
486         // BEGIN: :yyy:zzz
487         // BEGIN: :yyy:zzz
488
489         // tags with bad Item Name
490         // BEGIN:!:yyy:zzz
491         // BEGIN:@:yyy:zzz
492         // BEGIN:£:yyy:zzz
493
494         // tags with an empty Target State value
495         // BEGIN:xxx::zzz
496         // BEGIN:xxx: :zzz
497         // BEGIN:xxx: :zzz
498
499         // Note: All of the above tags must be rejected! => Assert cmdTags.size() == 0 !
500
501         assertEquals(0, cmdTags.size());
502
503         // test HTML command tag syntax: Test Series #7
504         events = calendar3.getJustBegunEvents(Instant.parse("2020-01-28T20:55:00Z"),
505                 Instant.parse("2020-01-28T21:05:00Z"));
506         assertNotNull(events);
507         assertEquals(1, events.size());
508         cmdTags = events.get(0).commandTags;
509         assertEquals(8, cmdTags.size());
510
511         // <p>BEGIN:Calendar_Test_Temperature:12.3°C:abc</p>
512         cmd0 = cmdTags.get(0).getCommand();
513         assertNotNull(cmd0);
514         assertEquals(QuantityType.class, cmd0.getClass());
515
516         // <p>END:Calendar_Test_Temperature:23.4°C:abc</p>
517         cmd1 = cmdTags.get(1).getCommand();
518         assertNotNull(cmd1);
519         assertEquals(QuantityType.class, cmd1.getClass());
520
521         // <p>BEGIN:Calendar_Test_Switch:ON:abc</p>
522         cmd2 = cmdTags.get(2).getCommand();
523         assertNotNull(cmd2);
524         assertEquals(OnOffType.class, cmd2.getClass());
525
526         // <p>END:Calendar_Test_Switch:OFF:abc</p>
527         cmd3 = cmdTags.get(3).getCommand();
528         assertNotNull(cmd3);
529         assertEquals(OnOffType.class, cmd3.getClass());
530
531         // <p>BEGIN:Calendar_Test_String:the quick:abc</p>
532         cmd4 = cmdTags.get(4).getCommand();
533         assertNotNull(cmd4);
534         assertEquals(StringType.class, cmd4.getClass());
535
536         // <p>END:Calendar_Test_String:brown fox:abc</p>
537         cmd5 = cmdTags.get(5).getCommand();
538         assertNotNull(cmd5);
539         assertEquals(StringType.class, cmd5.getClass());
540
541         // </p><p>BEGIN:Calendar_Test_Number:12.3:abc</p>
542         cmd6 = cmdTags.get(6).getCommand();
543         assertNotNull(cmd6);
544         assertEquals(QuantityType.class, cmd6.getClass());
545
546         // <p>END:Calendar_Test_Number:23.4:abc</p>
547         cmd7 = cmdTags.get(7).getCommand();
548         assertNotNull(cmd7);
549         assertEquals(QuantityType.class, cmd7.getClass());
550     }
551
552     @SuppressWarnings("null")
553     @Test
554     public void testGetFilteredEventsBetween() {
555         Event[] expectedFilteredEvents1 = new Event[] {
556                 new Event("Test Series in UTC", Instant.parse("2019-09-12T09:05:00Z"),
557                         Instant.parse("2019-09-12T09:10:00Z"), ""),
558                 new Event("Test Event in UTC+2", Instant.parse("2019-09-14T08:00:00Z"),
559                         Instant.parse("2019-09-14T09:00:00Z"), "") };
560         List<Event> realFilteredEvents1 = calendar.getFilteredEventsBetween(Instant.parse("2019-09-12T06:00:00Z"),
561                 Instant.parse("2019-09-15T06:00:00Z"), null, 3);
562         assertArrayEquals(expectedFilteredEvents1, realFilteredEvents1.toArray(new Event[0]));
563
564         Event[] expectedFilteredEvents2 = new Event[] {
565                 new Event("Evt", Instant.parse("2019-11-10T10:00:00Z"), Instant.parse("2019-11-10T11:45:00Z"), ""),
566                 new Event("Evt", Instant.parse("2019-11-17T10:00:00Z"), Instant.parse("2019-11-17T11:45:00Z"), ""),
567                 new Event("Evt", Instant.parse("2019-12-01T10:00:00Z"), Instant.parse("2019-12-01T11:45:00Z"), "") };
568         List<Event> realFilteredEvents2 = calendar2.getFilteredEventsBetween(Instant.parse("2019-11-08T06:00:00Z"),
569                 Instant.parse("2019-12-31T06:00:00Z"), null, 3);
570         assertArrayEquals(expectedFilteredEvents2, realFilteredEvents2.toArray(new Event[] {}));
571
572         Event[] expectedFilteredEvents3 = new Event[] { new Event("Test Event in UTC+2",
573                 Instant.parse("2019-09-14T08:00:00Z"), Instant.parse("2019-09-14T09:00:00Z"), "") };
574         List<Event> realFilteredEvents3 = calendar.getFilteredEventsBetween(Instant.parse("2019-09-12T06:00:00Z"),
575                 Instant.parse("2019-09-15T06:00:00Z"),
576                 new EventTextFilter(EventTextFilter.Field.SUMMARY, "utc+2", EventTextFilter.Type.TEXT), 3);
577         assertArrayEquals(expectedFilteredEvents3, realFilteredEvents3.toArray(new Event[] {}));
578
579         Event[] expectedFilteredEvents4 = new Event[] { new Event("Test Series in UTC",
580                 Instant.parse("2019-09-12T09:05:00Z"), Instant.parse("2019-09-12T09:10:00Z"), "") };
581         List<Event> realFilteredEvents4 = calendar.getFilteredEventsBetween(Instant.parse("2019-09-12T06:00:00Z"),
582                 Instant.parse("2019-09-15T06:00:00Z"),
583                 new EventTextFilter(EventTextFilter.Field.SUMMARY, ".*UTC$", EventTextFilter.Type.REGEX), 3);
584         assertArrayEquals(expectedFilteredEvents4, realFilteredEvents4.toArray(new Event[] {}));
585
586         List<Event> realFilteredEvents5 = calendar.getFilteredEventsBetween(Instant.parse("2019-09-15T06:00:00Z"),
587                 Instant.parse("2019-09-12T06:00:00Z"), null, 3);
588         assertEquals(0, realFilteredEvents5.size());
589
590         List<Event> realFilteredEvents6 = calendar.getFilteredEventsBetween(Instant.parse("2019-09-15T06:00:00Z"),
591                 Instant.parse("2019-12-31T00:00:00Z"), null, 3);
592         assertEquals(0, realFilteredEvents6.size());
593
594         List<Event> realFilteredEvents7 = calendar_issue9647.getFilteredEventsBetween(
595                 LocalDate.parse("2021-01-01").atStartOfDay(ZoneId.systemDefault()).toInstant(),
596                 LocalDate.parse("2021-01-02").atStartOfDay(ZoneId.systemDefault()).toInstant(), null, 3);
597         assertEquals(0, realFilteredEvents7.size());
598
599         Event[] expectedFilteredEvents8 = new Event[] {
600                 new Event("Restabfall", LocalDate.parse("2021-01-04").atStartOfDay(ZoneId.systemDefault()).toInstant(),
601                         LocalDate.parse("2021-01-05").atStartOfDay(ZoneId.systemDefault()).toInstant(), ""),
602                 new Event("Gelbe Tonne", LocalDate.parse("2021-01-04").atStartOfDay(ZoneId.systemDefault()).toInstant(),
603                         LocalDate.parse("2021-01-05").atStartOfDay(ZoneId.systemDefault()).toInstant(), "") };
604         List<Event> realFilteredEvents8 = calendar_issue9647.getFilteredEventsBetween(
605                 LocalDate.parse("2021-01-04").atStartOfDay(ZoneId.systemDefault()).toInstant(),
606                 LocalDate.parse("2021-01-05").atStartOfDay(ZoneId.systemDefault()).toInstant(), null, 3);
607         assertArrayEquals(expectedFilteredEvents8, realFilteredEvents8.toArray(new Event[] {}));
608     }
609 }