Cleanup - unused files / unused exports / duplicate exports
[ProtonMail-WebClient.git] / packages / shared / test / calendar / recurring.spec.js
blob249e6e4e7c44b4449aed146304185461d191aa48
1 import { getOccurrences, getOccurrencesBetween } from '../../lib/calendar/recurrence/recurring';
2 import { parse } from '../../lib/calendar/vcal';
4 const stringifyResult = (result) => {
5     return result.map(({ utcStart, utcEnd, occurrenceNumber }) => {
6         return `${utcStart.toISOString()} - ${utcEnd.toISOString()} | ${occurrenceNumber}`;
7     });
8 };
10 const stringifyResultFull = (result) => {
11     return result.map(({ localStart, localEnd, utcStart, utcEnd, occurrenceNumber }) => {
12         return `${localStart.toISOString()} - ${localEnd.toISOString()} | ${utcStart.toISOString()} - ${utcEnd.toISOString()} | ${occurrenceNumber}`;
13     });
16 const stringifyResultSimple = (result) => {
17     return result.map(({ utcStart, utcEnd }) => {
18         return `${utcStart.toISOString()} - ${utcEnd.toISOString()}`;
19     });
22 const stringifyLocalResultSimple = (result) => {
23     return result.map(({ localStart, occurrenceNumber }) => {
24         return `${localStart.toISOString()} - ${occurrenceNumber}`;
25     });
28 describe('recurring', () => {
29     const component = {
30         dtstart: {
31             value: { year: 2019, month: 1, day: 30, hours: 2, minutes: 30, seconds: 0, isUTC: false },
32             parameters: {
33                 type: 'date-time',
34                 tzid: 'Europe/Zurich',
35             },
36         },
37         dtend: {
38             value: { year: 2019, month: 1, day: 30, hours: 3, minutes: 30, seconds: 0, isUTC: false },
39             parameters: {
40                 type: 'date-time',
41                 tzid: 'Europe/Zurich',
42             },
43         },
44         rrule: {
45             value: {
46                 freq: 'DAILY',
47             },
48         },
49     };
51     it('should not get occurrences between if it is out of range', () => {
52         const result = getOccurrencesBetween(component, Date.UTC(2018, 3, 1), Date.UTC(2018, 3, 2));
53         expect(result).toEqual([]);
54     });
56     it('should get initial occurrences between a range', () => {
57         const result = getOccurrencesBetween(component, Date.UTC(2018, 1, 1), Date.UTC(2019, 1, 3));
59         expect(stringifyResult(result)).toEqual([
60             '2019-01-30T01:30:00.000Z - 2019-01-30T02:30:00.000Z | 1',
61             '2019-01-31T01:30:00.000Z - 2019-01-31T02:30:00.000Z | 2',
62             '2019-02-01T01:30:00.000Z - 2019-02-01T02:30:00.000Z | 3',
63             '2019-02-02T01:30:00.000Z - 2019-02-02T02:30:00.000Z | 4',
64         ]);
65     });
67     it('should get occurrences between a range', () => {
68         const result = getOccurrencesBetween(component, Date.UTC(2019, 2, 1), Date.UTC(2019, 2, 3));
70         expect(stringifyResult(result)).toEqual([
71             '2019-03-01T01:30:00.000Z - 2019-03-01T02:30:00.000Z | 31',
72             '2019-03-02T01:30:00.000Z - 2019-03-02T02:30:00.000Z | 32',
73         ]);
74     });
76     it('should get occurrences between a dst range', () => {
77         const result = getOccurrencesBetween(component, Date.UTC(2019, 9, 26), Date.UTC(2019, 9, 29));
79         expect(stringifyResultFull(result)).toEqual([
80             '2019-10-26T02:30:00.000Z - 2019-10-26T03:30:00.000Z | 2019-10-26T00:30:00.000Z - 2019-10-26T01:30:00.000Z | 270',
81             '2019-10-27T02:30:00.000Z - 2019-10-27T03:30:00.000Z | 2019-10-27T01:30:00.000Z - 2019-10-27T02:30:00.000Z | 271',
82             '2019-10-28T02:30:00.000Z - 2019-10-28T03:30:00.000Z | 2019-10-28T01:30:00.000Z - 2019-10-28T02:30:00.000Z | 272',
83         ]);
84     });
86     it('should get cached occurrences between a range', () => {
87         const cache = {};
88         const result1 = getOccurrencesBetween(component, Date.UTC(2019, 2, 1), Date.UTC(2019, 2, 3), cache);
89         const result2 = getOccurrencesBetween(component, Date.UTC(2019, 2, 1), Date.UTC(2019, 2, 3), cache);
90         expect(result1).toEqual(result2);
91     });
93     it('should fill cache if out of range', () => {
94         const cache = {};
95         getOccurrencesBetween(component, Date.UTC(2019, 2, 1), Date.UTC(2019, 2, 3), cache);
96         const result2 = getOccurrencesBetween(component, Date.UTC(2031, 2, 1), Date.UTC(2031, 2, 3), cache);
97         expect(stringifyResult(result2)).toEqual([
98             '2031-03-01T01:30:00.000Z - 2031-03-01T02:30:00.000Z | 4414',
99             '2031-03-02T01:30:00.000Z - 2031-03-02T02:30:00.000Z | 4415',
100         ]);
101     });
103     it('should fill occurrences with a count', () => {
104         const component = parse(`
105 BEGIN:VEVENT
106 DTSTART;VALUE=DATE:20200129
107 DTEND;VALUE=DATE:20200130
108 RRULE:FREQ=WEEKLY;BYDAY=SU,MO,TU,WE,TH,FR,SA;COUNT=3
109 END:VEVENT`);
110         const cache = {};
111         const result = getOccurrencesBetween(component, Date.UTC(2020, 0, 1), Date.UTC(2020, 2, 1), cache);
112         expect(stringifyResultSimple(result)).toEqual([
113             '2020-01-29T00:00:00.000Z - 2020-01-29T00:00:00.000Z',
114             '2020-01-30T00:00:00.000Z - 2020-01-30T00:00:00.000Z',
115             '2020-01-31T00:00:00.000Z - 2020-01-31T00:00:00.000Z',
116         ]);
117     });
119     it('should return no occurrences for a count = 0', () => {
120         const component = parse(`
121 BEGIN:VEVENT
122 DTSTART;VALUE=DATE:20200129
123 DTEND;VALUE=DATE:20200130
124 RRULE:FREQ=DAILY;COUNT=0
125 END:VEVENT`);
126         const cache = {};
127         const result = getOccurrencesBetween(component, Date.UTC(2020, 0, 1), Date.UTC(2020, 2, 1), cache);
128         expect(stringifyResultSimple(result)).toEqual([]);
129     });
131     it('should pick a targeted given occurrence ', () => {
132         const component = parse(`
133 BEGIN:VEVENT
134 DTSTART:20200129T113000Z
135 DTEND:20200129T123000Z
136 RRULE:FREQ=WEEKLY;BYDAY=SU,MO,TU,WE,TH,FR,SA;COUNT=3
137 END:VEVENT`);
138         const cache = {};
139         const result = getOccurrencesBetween(
140             component,
141             Date.UTC(2020, 0, 29, 11, 30),
142             Date.UTC(2020, 0, 29, 11, 30),
143             cache
144         );
145         expect(stringifyResultSimple(result)).toEqual(['2020-01-29T11:30:00.000Z - 2020-01-29T12:30:00.000Z']);
146     });
148     it('should fill occurrences until 31st of Jan in for all day events', () => {
149         const component = parse(`
150 BEGIN:VEVENT
151 DTSTART;VALUE=DATE:20200129
152 DTEND;VALUE=DATE:20200130
153 RRULE:FREQ=WEEKLY;BYDAY=SU,MO,TU,WE,TH,FR,SA;UNTIL=20200131
154 END:VEVENT`);
155         const cache = {};
156         const result = getOccurrencesBetween(component, Date.UTC(2020, 0, 1), Date.UTC(2020, 2, 1), cache);
157         expect(stringifyResultSimple(result)).toEqual([
158             '2020-01-29T00:00:00.000Z - 2020-01-29T00:00:00.000Z',
159             '2020-01-30T00:00:00.000Z - 2020-01-30T00:00:00.000Z',
160             '2020-01-31T00:00:00.000Z - 2020-01-31T00:00:00.000Z',
161         ]);
162     });
164     it('should fill occurrences until 31st of Jan in UTC time', () => {
165         const component = parse(`
166 BEGIN:VEVENT
167 DTSTART:20200129T130000Z
168 DTEND:20200129T133000Z
169 RRULE:FREQ=WEEKLY;BYDAY=SU,MO,TU,WE,TH,FR,SA;UNTIL=20200131T235959Z
170 END:VEVENT`);
171         const cache = {};
172         const result = getOccurrencesBetween(component, Date.UTC(2020, 0, 1), Date.UTC(2020, 2, 1), cache);
173         expect(stringifyResultSimple(result)).toEqual([
174             '2020-01-29T13:00:00.000Z - 2020-01-29T13:30:00.000Z',
175             '2020-01-30T13:00:00.000Z - 2020-01-30T13:30:00.000Z',
176             '2020-01-31T13:00:00.000Z - 2020-01-31T13:30:00.000Z',
177         ]);
178     });
180     it('should fill occurrences until 31st of Jan in Pago Pago time', () => {
181         const component = parse(`
182 BEGIN:VEVENT
183 DTSTART;TZID=Pacific/Pago_Pago:20200129T000000
184 DTEND;TZID=Europe/Zurich:20200129T133000
185 RRULE:FREQ=WEEKLY;BYDAY=SU,MO,TU,WE,TH,FR,SA;UNTIL=20200201T105959Z
186 END:VEVENT`);
187         const cache = {};
188         const result = getOccurrencesBetween(component, Date.UTC(2020, 0, 1), Date.UTC(2020, 2, 1), cache);
189         expect(stringifyResultSimple(result)).toEqual([
190             '2020-01-29T11:00:00.000Z - 2020-01-29T12:30:00.000Z',
191             '2020-01-30T11:00:00.000Z - 2020-01-30T12:30:00.000Z',
192             '2020-01-31T11:00:00.000Z - 2020-01-31T12:30:00.000Z',
193         ]);
194     });
196     it('should fill occurrences for an event starting on a sunday', () => {
197         const component = parse(`
198 BEGIN:VEVENT
199 RRULE:FREQ=WEEKLY;COUNT=4;BYDAY=SA,SU
200 DTSTART;VALUE=DATE:20200126
201 DTEND;VALUE=DATE:20200127
202 END:VEVENT
204         const cache = {};
205         const result = getOccurrencesBetween(component, Date.UTC(2020, 0, 1), Date.UTC(2021, 2, 1), cache);
206         expect(stringifyResultSimple(result)).toEqual([
207             '2020-01-26T00:00:00.000Z - 2020-01-26T00:00:00.000Z',
208             '2020-02-01T00:00:00.000Z - 2020-02-01T00:00:00.000Z',
209             '2020-02-02T00:00:00.000Z - 2020-02-02T00:00:00.000Z',
210             '2020-02-08T00:00:00.000Z - 2020-02-08T00:00:00.000Z',
211         ]);
212     });
214     it('should fill occurrences for an event with an exdate', () => {
215         const component = parse(`
216 BEGIN:VEVENT
217 RRULE:FREQ=DAILY;COUNT=6
218 DTSTART;TZID=Europe/Zurich:20200309T043000
219 DTEND;TZID=Europe/Zurich:20200309T063000
220 EXDATE;TZID=Europe/Zurich:20200311T043000
221 EXDATE;TZID=Europe/Zurich:20200313T043000
222 END:VEVENT
224         const cache = {};
225         const result = getOccurrencesBetween(component, Date.UTC(2020, 0, 1), Date.UTC(2021, 4, 1), cache);
226         expect(stringifyResult(result)).toEqual([
227             '2020-03-09T03:30:00.000Z - 2020-03-09T05:30:00.000Z | 1',
228             '2020-03-10T03:30:00.000Z - 2020-03-10T05:30:00.000Z | 2',
229             '2020-03-12T03:30:00.000Z - 2020-03-12T05:30:00.000Z | 4',
230             '2020-03-14T03:30:00.000Z - 2020-03-14T05:30:00.000Z | 6',
231         ]);
232     });
234     it('should fill occurrences for an all day event with an exdate', () => {
235         const component = parse(`
236 BEGIN:VEVENT
237 RRULE:FREQ=DAILY;COUNT=6
238 DTSTART;VALUE=DATE:20200201
239 DTEND;VALUE=DATE:20200202
240 EXDATE;VALUE=DATE:20200201
241 EXDATE;VALUE=DATE:20200202
242 EXDATE;VALUE=DATE:20200203
243 END:VEVENT
245         const cache = {};
246         const result = getOccurrencesBetween(component, Date.UTC(2020, 0, 1), Date.UTC(2021, 4, 1), cache);
247         expect(stringifyResultSimple(result)).toEqual([
248             '2020-02-04T00:00:00.000Z - 2020-02-04T00:00:00.000Z',
249             '2020-02-05T00:00:00.000Z - 2020-02-05T00:00:00.000Z',
250             '2020-02-06T00:00:00.000Z - 2020-02-06T00:00:00.000Z',
251         ]);
252     });
254     it('should not fill occurrences for an event without rrule', () => {
255         const component = parse(`
256 BEGIN:VEVENT
257 DTSTART:20200201T030000Z
258 DTEND:20200201T040000Z
259 END:VEVENT
261         const cache = {};
262         const result = getOccurrencesBetween(component, Date.UTC(2020, 0, 1), Date.UTC(2021, 4, 1), cache);
263         expect(stringifyResultSimple(result)).toEqual(['2020-02-01T03:00:00.000Z - 2020-02-01T04:00:00.000Z']);
264     });
266     it('should fill one occurrence without rrule', () => {
267         const component = parse(`
268 BEGIN:VEVENT
269 DTSTART:20200201T030000Z
270 DTEND:20200201T040000Z
271 END:VEVENT
273         expect(getOccurrences({ component, maxCount: 0 }).length).toBe(0);
274         expect(getOccurrences({ component, maxCount: 1 }).length).toBe(1);
275         expect(getOccurrences({ component, maxCount: 2 }).length).toBe(1);
276     });
278     it('should fill no occurrence for rrule with count = 0', () => {
279         const component = parse(`
280 BEGIN:VEVENT
281 DTSTART:20200201T030000Z
282 DTEND:20200201T040000Z
283 RRULE:FREQ=DAILY;COUNT=0
284 END:VEVENT
286         expect(getOccurrences({ component, maxCount: 1 }).length).toBe(0);
287     });
289     it('should fill occurrences with max start', () => {
290         const component = parse(`
291 BEGIN:VEVENT
292 DTSTART:20200201T030000Z
293 DTEND:20200201T040000Z
294 RRULE:FREQ=DAILY;COUNT=6
295 END:VEVENT
297         expect(
298             stringifyLocalResultSimple(
299                 getOccurrences({
300                     component,
301                     maxCount: 999,
302                     maxStart: new Date(Date.UTC(2020, 1, 4)),
303                 })
304             )
305         ).toEqual(['2020-02-01T03:00:00.000Z - 1', '2020-02-02T03:00:00.000Z - 2', '2020-02-03T03:00:00.000Z - 3']);
306     });
308     it('should fill occurrences for a UTC date with an exdate', () => {
309         const component = parse(`
310 BEGIN:VEVENT
311 RRULE:FREQ=DAILY;COUNT=6
312 DTSTART:20200201T030000Z
313 DTEND:20200201T040000Z
314 EXDATE:20200202T030000Z
315 EXDATE:20200203T030000Z
316 EXDATE:20200204T030000Z
317 END:VEVENT
319         const cache = {};
320         const result = getOccurrencesBetween(component, Date.UTC(2020, 0, 1), Date.UTC(2021, 4, 1), cache);
321         expect(stringifyResultSimple(result)).toEqual([
322             '2020-02-01T03:00:00.000Z - 2020-02-01T04:00:00.000Z',
323             '2020-02-05T03:00:00.000Z - 2020-02-05T04:00:00.000Z',
324             '2020-02-06T03:00:00.000Z - 2020-02-06T04:00:00.000Z',
325         ]);
326     });
328     it('should fill occurrences with an end date in another timezone', () => {
329         const component = parse(`
330 BEGIN:VEVENT
331 RRULE:FREQ=DAILY;COUNT=2;INTERVAL=60
332 DTSTART;TZID=Europe/Zurich:20200901T080000
333 DTEND:20200901T060000Z
334 END:VEVENT
336         const cache = {};
337         const result = getOccurrencesBetween(component, Date.UTC(2020, 0, 1), Date.UTC(2021, 4, 1), cache);
338         expect(stringifyResultFull(result)).toEqual([
339             '2020-09-01T08:00:00.000Z - 2020-09-01T06:00:00.000Z | 2020-09-01T06:00:00.000Z - 2020-09-01T06:00:00.000Z | 1',
340             '2020-10-31T08:00:00.000Z - 2020-10-31T07:00:00.000Z | 2020-10-31T07:00:00.000Z - 2020-10-31T07:00:00.000Z | 2',
341         ]);
342     });