1 import { differenceInDays, differenceInHours, differenceInMinutes, differenceInWeeks } from 'date-fns';
2 import { enUS } from 'date-fns/locale';
5 dedupeAlarmsWithNormalizedTriggers,
7 filterFutureNotifications,
9 sortNotificationsByAscendingTrigger,
10 } from '../../lib/calendar/alarms';
11 import { normalizeTrigger } from '../../lib/calendar/alarms/trigger';
12 import { NOTIFICATION_TYPE_API, NOTIFICATION_UNITS, NOTIFICATION_WHEN } from '../../lib/calendar/constants';
13 import { propertyToUTCDate } from '../../lib/calendar/vcalConverter';
14 import { DAY, HOUR, MINUTE, WEEK } from '../../lib/constants';
15 import { convertUTCDateTimeToZone, convertZonedDateTimeToUTC, toUTCDate } from '../../lib/date/timezone';
16 import { pick } from '../../lib/helpers/object';
22 VcalValarmRelativeComponent,
24 } from '../../lib/interfaces/calendar';
26 const formatOptions = { locale: enUS };
27 const tzidEurope = 'Europe/Zurich';
28 const tzidAsia = 'Asia/Seoul';
30 const getNow = (fakeZonedNow: DateTime, tzid = tzidEurope) => toUTCDate(convertZonedDateTimeToUTC(fakeZonedNow, tzid));
32 describe('getAlarmMessage', () => {
33 const testFakeZonedDate = { year: 2019, month: 10, day: 13, hours: 20, minutes: 0, seconds: 0 };
34 const testComponent = {
36 value: { ...testFakeZonedDate, isUTC: false },
37 parameters: { tzid: tzidEurope },
39 summary: { value: 'test alarm' },
40 } as VcalVeventComponent;
41 const testFulldayComponent = {
43 value: pick(testFakeZonedDate, ['year', 'month', 'day']),
44 parameters: { type: 'date' },
46 summary: { value: 'test alarm' },
47 } as VcalVeventComponent;
48 const start = toUTCDate(convertZonedDateTimeToUTC(testFakeZonedDate, tzidEurope));
50 it('treats the part day event as "starts now" when within 30 seconds of the beginning', () => {
52 component: testComponent,
61 now: getNow({ ...testFakeZonedDate, minutes: testFakeZonedDate.minutes - 1, seconds: 29 }),
63 ).toEqual('test alarm starts at 8:00 PM');
68 now: getNow({ ...testFakeZonedDate, seconds: 31 }),
70 ).toEqual('test alarm started at 8:00 PM');
75 now: getNow({ ...testFakeZonedDate, minutes: testFakeZonedDate.minutes - 1, seconds: 39 }),
77 ).toEqual('test alarm starts now');
82 now: getNow({ ...testFakeZonedDate, seconds: 30 }),
84 ).toEqual('test alarm starts now');
87 it('it should display the right notification for events happening today', () => {
88 const fakeZonedNow = { ...testFakeZonedDate, hours: 1 };
89 const now = toUTCDate(convertZonedDateTimeToUTC(fakeZonedNow, tzidEurope));
90 expect(getAlarmMessage({ component: testComponent, start, now, tzid: tzidEurope, formatOptions })).toEqual(
91 'test alarm starts at 8:00 PM'
95 it('it should display the right notification for full-day events happening today', () => {
96 const fakeZonedNow = { ...testFakeZonedDate, hours: 1 };
97 const now = toUTCDate(convertZonedDateTimeToUTC(fakeZonedNow, tzidEurope));
99 getAlarmMessage({ component: testFulldayComponent, start, now, tzid: tzidEurope, formatOptions })
100 ).toEqual('test alarm starts today');
103 it('it should display the right notification for events happening tomorrow', () => {
104 const fakeZonedNow = { ...testFakeZonedDate, day: 12 };
105 const now = toUTCDate(convertZonedDateTimeToUTC(fakeZonedNow, tzidEurope));
106 expect(getAlarmMessage({ component: testComponent, start, now, tzid: tzidEurope, formatOptions })).toEqual(
107 'test alarm starts tomorrow at 8:00 PM'
111 it('it should display the right notification for full-day events happening tomorrow', () => {
112 const fakeZonedNow = { ...testFakeZonedDate, day: 12 };
113 const now = toUTCDate(convertZonedDateTimeToUTC(fakeZonedNow, tzidEurope));
115 getAlarmMessage({ component: testFulldayComponent, start, now, tzid: tzidEurope, formatOptions })
116 ).toEqual('test alarm starts tomorrow');
119 it('it should display the right notification for full-day events happening yesterday', () => {
120 const fakeZonedNow = { ...testFakeZonedDate, day: 14 };
121 const now = toUTCDate(convertZonedDateTimeToUTC(fakeZonedNow, tzidEurope));
123 getAlarmMessage({ component: testFulldayComponent, start, now, tzid: tzidEurope, formatOptions })
124 ).toEqual('test alarm started yesterday');
127 it('it should display the right notification for events happening yesterday', () => {
128 const fakeZonedNow = { ...testFakeZonedDate, day: 14 };
129 const now = toUTCDate(convertZonedDateTimeToUTC(fakeZonedNow, tzidEurope));
130 expect(getAlarmMessage({ component: testComponent, start, now, tzid: tzidEurope, formatOptions })).toEqual(
131 'test alarm started yesterday at 8:00 PM'
135 it('it should display the right notification for events happening later this month', () => {
136 const fakeZonedNow = { ...testFakeZonedDate, day: 5 };
137 const now = toUTCDate(convertZonedDateTimeToUTC(fakeZonedNow, tzidEurope));
138 expect(getAlarmMessage({ component: testComponent, start, now, tzid: tzidEurope, formatOptions })).toEqual(
139 'test alarm starts on Sunday 13th at 8:00 PM'
143 it('it should display the right notification for full-day events happening later this month', () => {
144 const fakeZonedNow = { ...testFakeZonedDate, day: 5 };
145 const now = toUTCDate(convertZonedDateTimeToUTC(fakeZonedNow, tzidEurope));
147 getAlarmMessage({ component: testFulldayComponent, start, now, tzid: tzidEurope, formatOptions })
148 ).toEqual('test alarm starts on Sunday 13th');
151 it('it should display the right notification for events happening earlier this month', () => {
152 const fakeZonedNow = { ...testFakeZonedDate, day: 22 };
153 const now = toUTCDate(convertZonedDateTimeToUTC(fakeZonedNow, tzidEurope));
154 expect(getAlarmMessage({ component: testComponent, start, now, tzid: tzidEurope, formatOptions })).toEqual(
155 'test alarm started on Sunday 13th at 8:00 PM'
159 it('it should display the right notification for full-day events happening earlier this month', () => {
160 const fakeZonedNow = { ...testFakeZonedDate, day: 22 };
161 const now = toUTCDate(convertZonedDateTimeToUTC(fakeZonedNow, tzidEurope));
163 getAlarmMessage({ component: testFulldayComponent, start, now, tzid: tzidEurope, formatOptions })
164 ).toEqual('test alarm started on Sunday 13th');
167 it('it should display the right notification for events happening later this year', () => {
168 const fakeZonedNow = { ...testFakeZonedDate, month: 7 };
169 const now = toUTCDate(convertZonedDateTimeToUTC(fakeZonedNow, tzidEurope));
170 expect(getAlarmMessage({ component: testComponent, start, now, tzid: tzidEurope, formatOptions })).toEqual(
171 'test alarm starts on Sunday 13th October at 8:00 PM'
175 it('it should display the right notification for full-day events happening later this year', () => {
176 const fakeZonedNow = { ...testFakeZonedDate, month: 7 };
177 const now = toUTCDate(convertZonedDateTimeToUTC(fakeZonedNow, tzidEurope));
179 getAlarmMessage({ component: testFulldayComponent, start, now, tzid: tzidEurope, formatOptions })
180 ).toEqual('test alarm starts on Sunday 13th October');
183 it('it should display the right notification for events happening earlier this year', () => {
184 const fakeZonedNow = { ...testFakeZonedDate, month: 12 };
185 const now = toUTCDate(convertZonedDateTimeToUTC(fakeZonedNow, tzidEurope));
186 expect(getAlarmMessage({ component: testComponent, start, now, tzid: tzidEurope, formatOptions })).toEqual(
187 'test alarm started on Sunday 13th October at 8:00 PM'
191 it('it should display the right notification for full-day events happening earlier this year', () => {
192 const fakeZonedNow = { ...testFakeZonedDate, month: 12 };
193 const now = toUTCDate(convertZonedDateTimeToUTC(fakeZonedNow, tzidEurope));
195 getAlarmMessage({ component: testFulldayComponent, start, now, tzid: tzidEurope, formatOptions })
196 ).toEqual('test alarm started on Sunday 13th October');
199 it('it should display the right notification for events happening in future years', () => {
200 const fakeZonedNow = { ...testFakeZonedDate, year: 2002 };
201 const now = toUTCDate(convertZonedDateTimeToUTC(fakeZonedNow, tzidEurope));
202 expect(getAlarmMessage({ component: testComponent, start, now, tzid: tzidEurope, formatOptions })).toEqual(
203 'test alarm starts on Sunday, October 13th, 2019 at 8:00 PM'
207 it('it should display the right notification for full-day events happening in future years', () => {
208 const fakeZonedNow = { ...testFakeZonedDate, year: 2002 };
209 const now = toUTCDate(convertZonedDateTimeToUTC(fakeZonedNow, tzidEurope));
211 getAlarmMessage({ component: testFulldayComponent, start, now, tzid: tzidEurope, formatOptions })
212 ).toEqual('test alarm starts on Sunday, October 13th, 2019');
215 it('it should display the right notification for events happening in past years', () => {
216 const fakeZonedNow = { ...testFakeZonedDate, year: 2022 };
217 const now = toUTCDate(convertZonedDateTimeToUTC(fakeZonedNow, tzidEurope));
218 expect(getAlarmMessage({ component: testComponent, start, now, tzid: tzidEurope, formatOptions })).toEqual(
219 'test alarm started on Sunday, October 13th, 2019 at 8:00 PM'
223 it('it should display the right notification for full-day events happening in past years', () => {
224 const fakeZonedNow = { ...testFakeZonedDate, year: 2022 };
225 const now = toUTCDate(convertUTCDateTimeToZone(fakeZonedNow, tzidEurope));
227 getAlarmMessage({ component: testFulldayComponent, start, now, tzid: tzidEurope, formatOptions })
228 ).toEqual('test alarm started on Sunday, October 13th, 2019');
231 it('it should display the right notification for events happening both this month and next year', () => {
232 const fakeZonedNow = { ...testFakeZonedDate, day: 5 };
233 const now = toUTCDate(convertUTCDateTimeToZone(fakeZonedNow, tzidEurope));
234 expect(getAlarmMessage({ component: testComponent, start, now, tzid: tzidEurope, formatOptions })).toEqual(
235 'test alarm starts on Sunday 13th at 8:00 PM'
239 it('it should display the right notification for events happening both this month and next year', () => {
240 const fakeZonedNow = { ...testFakeZonedDate, day: 5 };
241 const now = toUTCDate(convertZonedDateTimeToUTC(fakeZonedNow, tzidEurope));
242 expect(getAlarmMessage({ component: testComponent, start, now, tzid: tzidEurope, formatOptions })).toEqual(
243 'test alarm starts on Sunday 13th at 8:00 PM'
247 it('it should take into account day changes due to timezone differences', () => {
248 const fakeZonedNow = { ...testFakeZonedDate, hours: 10 };
249 const now = toUTCDate(convertZonedDateTimeToUTC(fakeZonedNow, tzidEurope));
250 expect(getAlarmMessage({ component: testComponent, start, now, tzid: tzidEurope, formatOptions })).toEqual(
251 'test alarm starts at 8:00 PM'
253 expect(getAlarmMessage({ component: testComponent, start, now, tzid: tzidAsia, formatOptions })).toEqual(
254 'test alarm starts tomorrow at 3:00 AM'
259 describe('filterFutureNotifications', () => {
260 it('it should filter future part-day notifications', () => {
261 const isAllDay = false;
262 const atSameTimeNotifications = [
265 unit: NOTIFICATION_UNITS.MINUTE,
266 type: NOTIFICATION_TYPE_API.EMAIL,
267 when: NOTIFICATION_WHEN.AFTER,
273 unit: NOTIFICATION_UNITS.DAY,
274 type: NOTIFICATION_TYPE_API.DEVICE,
275 when: NOTIFICATION_WHEN.BEFORE,
281 unit: NOTIFICATION_UNITS.DAY,
282 type: NOTIFICATION_TYPE_API.EMAIL,
283 when: NOTIFICATION_WHEN.AFTER,
289 unit: NOTIFICATION_UNITS.WEEK,
290 type: NOTIFICATION_TYPE_API.DEVICE,
291 when: NOTIFICATION_WHEN.BEFORE,
296 const beforeNotifications = [
299 unit: NOTIFICATION_UNITS.MINUTE,
300 type: NOTIFICATION_TYPE_API.DEVICE,
301 when: NOTIFICATION_WHEN.BEFORE,
307 unit: NOTIFICATION_UNITS.DAY,
308 type: NOTIFICATION_TYPE_API.EMAIL,
309 when: NOTIFICATION_WHEN.BEFORE,
315 unit: NOTIFICATION_UNITS.WEEK,
316 type: NOTIFICATION_TYPE_API.DEVICE,
317 when: NOTIFICATION_WHEN.BEFORE,
322 const afterNotifications = [
325 unit: NOTIFICATION_UNITS.MINUTE,
326 type: NOTIFICATION_TYPE_API.DEVICE,
327 when: NOTIFICATION_WHEN.AFTER,
332 unit: NOTIFICATION_UNITS.MINUTE,
333 type: NOTIFICATION_TYPE_API.DEVICE,
334 when: NOTIFICATION_WHEN.AFTER,
340 unit: NOTIFICATION_UNITS.DAY,
341 type: NOTIFICATION_TYPE_API.EMAIL,
342 when: NOTIFICATION_WHEN.AFTER,
348 unit: NOTIFICATION_UNITS.WEEK,
349 type: NOTIFICATION_TYPE_API.DEVICE,
350 when: NOTIFICATION_WHEN.AFTER,
355 const notifications = [...beforeNotifications, ...atSameTimeNotifications, ...afterNotifications];
356 const expected = [...beforeNotifications, ...atSameTimeNotifications];
357 expect(filterFutureNotifications(notifications)).toEqual(expected);
360 it('it should filter future all-day notifications', () => {
361 const isAllDay = true;
362 const onSameDayNotifications = [
365 unit: NOTIFICATION_UNITS.DAY,
366 type: NOTIFICATION_TYPE_API.DEVICE,
367 when: NOTIFICATION_WHEN.AFTER,
373 unit: NOTIFICATION_UNITS.DAY,
374 type: NOTIFICATION_TYPE_API.EMAIL,
375 when: NOTIFICATION_WHEN.BEFORE,
381 unit: NOTIFICATION_UNITS.WEEK,
382 type: NOTIFICATION_TYPE_API.EMAIL,
383 when: NOTIFICATION_WHEN.AFTER,
389 unit: NOTIFICATION_UNITS.WEEK,
390 type: NOTIFICATION_TYPE_API.DEVICE,
391 when: NOTIFICATION_WHEN.BEFORE,
396 const beforeNotifications = [
399 unit: NOTIFICATION_UNITS.DAY,
400 type: NOTIFICATION_TYPE_API.DEVICE,
401 when: NOTIFICATION_WHEN.BEFORE,
407 unit: NOTIFICATION_UNITS.DAY,
408 type: NOTIFICATION_TYPE_API.EMAIL,
409 when: NOTIFICATION_WHEN.BEFORE,
415 unit: NOTIFICATION_UNITS.WEEK,
416 type: NOTIFICATION_TYPE_API.DEVICE,
417 when: NOTIFICATION_WHEN.BEFORE,
422 const afterNotifications = [
425 unit: NOTIFICATION_UNITS.DAY,
426 type: NOTIFICATION_TYPE_API.DEVICE,
427 when: NOTIFICATION_WHEN.AFTER,
432 unit: NOTIFICATION_UNITS.DAY,
433 type: NOTIFICATION_TYPE_API.DEVICE,
434 when: NOTIFICATION_WHEN.AFTER,
440 unit: NOTIFICATION_UNITS.WEEK,
441 type: NOTIFICATION_TYPE_API.EMAIL,
442 when: NOTIFICATION_WHEN.AFTER,
448 unit: NOTIFICATION_UNITS.WEEK,
449 type: NOTIFICATION_TYPE_API.DEVICE,
450 when: NOTIFICATION_WHEN.AFTER,
455 const notifications = [...beforeNotifications, ...onSameDayNotifications, ...afterNotifications];
456 const expected = [...beforeNotifications, ...onSameDayNotifications];
457 expect(filterFutureNotifications(notifications)).toEqual(expected);
461 describe('normalizeTrigger', () => {
462 const dtstartPartDay = {
463 value: { year: 2020, month: 5, day: 11, hours: 12, minutes: 30, seconds: 0, isUTC: true },
465 const dtstartAllDay = {
466 value: { year: 2020, month: 5, day: 11 },
467 parameters: { type: 'date' },
468 } as VcalDateProperty;
469 const utcStartPartDay = propertyToUTCDate(dtstartPartDay);
471 it('should keep just one component for part-day events with relative triggers', () => {
472 const triggerValues = [
473 { weeks: 1, days: 6, hours: 0, minutes: 30, seconds: 0, isNegative: true },
474 { weeks: 0, days: 1, hours: 2, minutes: 1, seconds: 30, isNegative: false },
475 { weeks: 1, days: 3, hours: 2, minutes: 0, seconds: 0, isNegative: true },
476 { weeks: 2, days: 0, hours: 0, minutes: 0, seconds: 30, isNegative: false },
477 { weeks: 2, days: 0, hours: 0, minutes: 0, seconds: 0, isNegative: true },
478 { weeks: 2, days: 7, hours: 7 * 24, minutes: 0, seconds: 0, isNegative: true },
485 minutes: (WEEK + 6 * DAY + 30 * MINUTE) / MINUTE,
489 { weeks: 0, days: 0, hours: 0, minutes: (DAY + 2 * HOUR + MINUTE) / MINUTE, seconds: 0, isNegative: false },
490 { weeks: 0, days: 0, hours: (WEEK + 3 * DAY + 2 * HOUR) / HOUR, minutes: 0, seconds: 0, isNegative: true },
491 { weeks: 2, days: 0, hours: 0, minutes: 0, seconds: 0, isNegative: false },
492 { weeks: 2, days: 0, hours: 0, minutes: 0, seconds: 0, isNegative: true },
493 { weeks: 4, days: 0, hours: 0, minutes: 0, seconds: 0, isNegative: true },
495 const results = triggerValues.map((trigger) => normalizeTrigger({ value: trigger }, dtstartPartDay));
496 expect(results).toEqual(expected);
499 it('should keep just one component for part-day events with absolute triggers', () => {
500 const triggerValues = [
501 { year: 2020, month: 5, day: 2, hours: 9, minutes: 0, seconds: 0, isUTC: true },
502 { year: 2020, month: 4, day: 12, hours: 9, minutes: 30, seconds: 0, isUTC: true },
503 { year: 2020, month: 5, day: 22, hours: 12, minutes: 30, seconds: 0, isUTC: true },
504 { year: 2020, month: 8, day: 1, hours: 0, minutes: 15, seconds: 0, isUTC: true },
505 { year: 2000, month: 5, day: 15, hours: 12, minutes: 30, seconds: 0, isUTC: true },
507 const utcDates = triggerValues.map((dateTime) => propertyToUTCDate({ value: dateTime }));
513 minutes: differenceInMinutes(utcStartPartDay, utcDates[0]),
520 hours: differenceInHours(utcStartPartDay, utcDates[1]),
527 days: -differenceInDays(utcStartPartDay, utcDates[2]),
537 minutes: -differenceInMinutes(utcStartPartDay, utcDates[3]),
542 weeks: differenceInWeeks(utcStartPartDay, utcDates[4]),
550 const results = triggerValues.map((triggerValue) => {
553 parameters: { type: 'date-time' },
554 } as VcalTriggerProperty;
555 return normalizeTrigger(trigger, dtstartPartDay);
557 expect(results).toEqual(expected);
560 it('should keep all components for all-day events (except forbidden combinations of weeks and days) for relative triggers', () => {
561 const triggerValues = [
562 { weeks: 1, days: 6, hours: 0, minutes: 30, seconds: 0, isNegative: true },
563 { weeks: 0, days: 1, hours: 2, minutes: 1, seconds: 30, isNegative: false },
564 { weeks: 1, days: 3, hours: 2, minutes: 0, seconds: 0, isNegative: true },
565 { weeks: 2, days: 0, hours: 0, minutes: 0, seconds: 30, isNegative: false },
566 { weeks: 2, days: 0, hours: 0, minutes: 0, seconds: 0, isNegative: true },
569 { weeks: 1, days: 6, hours: 0, minutes: 30, seconds: 0, isNegative: true },
570 { weeks: 0, days: 1, hours: 2, minutes: 1, seconds: 0, isNegative: false },
571 { weeks: 0, days: 10, hours: 2, minutes: 0, seconds: 0, isNegative: true },
572 { weeks: 2, days: 0, hours: 0, minutes: 0, seconds: 0, isNegative: false },
573 { weeks: 2, days: 0, hours: 0, minutes: 0, seconds: 0, isNegative: true },
575 const results = triggerValues.map((trigger) => normalizeTrigger({ value: trigger }, dtstartAllDay));
576 expect(results).toEqual(expected);
579 it('should keep all components for all-day events (except forbidden combinations of weeks and days) for absolute triggers', () => {
580 const triggerValues = [
581 { year: 2020, month: 5, day: 2, hours: 9, minutes: 0, seconds: 0, isUTC: true },
582 { year: 2020, month: 4, day: 12, hours: 9, minutes: 30, seconds: 0, isUTC: true },
583 { year: 2020, month: 5, day: 22, hours: 12, minutes: 30, seconds: 0, isUTC: true },
584 { year: 2020, month: 8, day: 1, hours: 0, minutes: 15, seconds: 0, isUTC: true },
585 { year: 2000, month: 5, day: 15, hours: 12, minutes: 30, seconds: 0, isUTC: true },
588 { weeks: 0, days: 8, hours: 15, minutes: 0, seconds: 0, isNegative: true },
589 { weeks: 0, days: 28, hours: 14, minutes: 30, seconds: 0, isNegative: true },
590 { weeks: 0, days: 11, hours: 12, minutes: 30, seconds: 0, isNegative: false },
591 { weeks: 0, days: 82, hours: 0, minutes: 15, seconds: 0, isNegative: false },
592 { weeks: 1042, days: 6, hours: 11, minutes: 30, seconds: 0, isNegative: true },
594 const results = triggerValues.map((triggerValue) => {
597 parameters: { type: 'date-time' },
598 } as VcalTriggerProperty;
599 return normalizeTrigger(trigger, dtstartAllDay);
601 expect(results).toEqual(expected);
605 describe('dedupeNotifications', () => {
606 it('de-duplicates alarms as expected', () => {
607 const notifications = [
610 unit: NOTIFICATION_UNITS.WEEK,
611 type: NOTIFICATION_TYPE_API.DEVICE,
612 when: NOTIFICATION_WHEN.BEFORE,
618 unit: NOTIFICATION_UNITS.DAY,
619 type: NOTIFICATION_TYPE_API.DEVICE,
620 when: NOTIFICATION_WHEN.BEFORE,
626 unit: NOTIFICATION_UNITS.HOUR,
627 type: NOTIFICATION_TYPE_API.DEVICE,
628 when: NOTIFICATION_WHEN.BEFORE,
634 unit: NOTIFICATION_UNITS.WEEK,
635 type: NOTIFICATION_TYPE_API.DEVICE,
636 when: NOTIFICATION_WHEN.BEFORE,
639 at: new Date(2000, 1, 1),
643 unit: NOTIFICATION_UNITS.DAY,
644 type: NOTIFICATION_TYPE_API.DEVICE,
645 when: NOTIFICATION_WHEN.BEFORE,
648 at: new Date(2000, 1, 1),
652 unit: NOTIFICATION_UNITS.HOUR,
653 type: NOTIFICATION_TYPE_API.DEVICE,
654 when: NOTIFICATION_WHEN.BEFORE,
657 at: new Date(2000, 1, 1),
661 expect(dedupeNotifications(notifications)).toEqual([
664 unit: NOTIFICATION_UNITS.WEEK,
665 type: NOTIFICATION_TYPE_API.DEVICE,
666 when: NOTIFICATION_WHEN.BEFORE,
672 at: new Date(2000, 1, 1),
674 type: NOTIFICATION_TYPE_API.DEVICE,
675 unit: NOTIFICATION_UNITS.HOUR,
677 when: NOTIFICATION_WHEN.BEFORE,
682 it('sorts when deduping', () => {
683 const notifications = [
686 unit: NOTIFICATION_UNITS.DAY,
687 type: NOTIFICATION_TYPE_API.DEVICE,
688 when: NOTIFICATION_WHEN.BEFORE,
694 unit: NOTIFICATION_UNITS.HOUR,
695 type: NOTIFICATION_TYPE_API.DEVICE,
696 when: NOTIFICATION_WHEN.BEFORE,
702 unit: NOTIFICATION_UNITS.WEEK,
703 type: NOTIFICATION_TYPE_API.DEVICE,
704 when: NOTIFICATION_WHEN.BEFORE,
710 unit: NOTIFICATION_UNITS.DAY,
711 type: NOTIFICATION_TYPE_API.DEVICE,
712 when: NOTIFICATION_WHEN.BEFORE,
718 expect(dedupeNotifications(notifications)).toEqual([
721 unit: NOTIFICATION_UNITS.DAY,
722 type: NOTIFICATION_TYPE_API.DEVICE,
723 when: NOTIFICATION_WHEN.BEFORE,
729 unit: NOTIFICATION_UNITS.WEEK,
730 type: NOTIFICATION_TYPE_API.DEVICE,
731 when: NOTIFICATION_WHEN.BEFORE,
739 describe('dedupeAlarmsWithNormalizedTriggers()', () => {
740 it('dedupes alarms', () => {
741 const alarms: VcalValarmRelativeComponent[] = [
784 minutes: 20160, // 2 weeks
855 const expectedAlarms: VcalValarmRelativeComponent[] = [
921 expect(dedupeAlarmsWithNormalizedTriggers(alarms)).toEqual(expectedAlarms);
925 describe('sortNotificationsByAscendingTrigger()', () => {
926 it('sorts case 1 correctly', () => {
928 unit: NOTIFICATION_UNITS.MINUTE,
929 type: NOTIFICATION_TYPE_API.DEVICE,
930 when: NOTIFICATION_WHEN.AFTER,
935 unit: NOTIFICATION_UNITS.HOUR,
936 type: NOTIFICATION_TYPE_API.DEVICE,
937 when: NOTIFICATION_WHEN.BEFORE,
942 unit: NOTIFICATION_UNITS.HOUR,
943 type: NOTIFICATION_TYPE_API.DEVICE,
944 when: NOTIFICATION_WHEN.BEFORE,
949 unit: NOTIFICATION_UNITS.MINUTE,
950 type: NOTIFICATION_TYPE_API.DEVICE,
951 when: NOTIFICATION_WHEN.BEFORE,
955 const input = [a, b, c, d] as NotificationModel[];
956 const expectedResult = [b, c, d, a] as NotificationModel[];
957 expect(sortNotificationsByAscendingTrigger(input)).toEqual(expectedResult);
960 it('sorts case 2 correctly', () => {
962 unit: NOTIFICATION_UNITS.DAY,
963 type: NOTIFICATION_TYPE_API.DEVICE,
964 when: NOTIFICATION_WHEN.AFTER,
965 at: new Date(2000, 0, 1, 12, 30),
971 unit: NOTIFICATION_UNITS.DAY,
972 type: NOTIFICATION_TYPE_API.DEVICE,
973 when: NOTIFICATION_WHEN.BEFORE,
974 at: new Date(2000, 0, 1, 1, 30),
980 unit: NOTIFICATION_UNITS.DAY,
981 type: NOTIFICATION_TYPE_API.DEVICE,
982 when: NOTIFICATION_WHEN.BEFORE,
983 at: new Date(2000, 0, 1, 9, 30),
989 unit: NOTIFICATION_UNITS.DAY,
990 type: NOTIFICATION_TYPE_API.DEVICE,
991 when: NOTIFICATION_WHEN.BEFORE,
992 at: new Date(2000, 0, 1, 9, 30),
998 unit: NOTIFICATION_UNITS.WEEK,
999 type: NOTIFICATION_TYPE_API.DEVICE,
1000 when: NOTIFICATION_WHEN.BEFORE,
1001 at: new Date(2000, 0, 1, 9, 30),
1006 const input = [a, b, c, d, e] as NotificationModel[];
1007 const expectedResult = [d, e, b, c, a] as NotificationModel[];
1009 expect(sortNotificationsByAscendingTrigger(input)).toEqual(expectedResult);