1 import type { VcalVeventComponent } from '@proton/shared/lib/interfaces/calendar';
3 import { CALENDAR_CARD_TYPE } from '../../lib/calendar/constants';
4 import { parse } from '../../lib/calendar/vcal';
5 import { getVeventParts, withMandatoryPublishFields, withoutRedundantDtEnd } from '../../lib/calendar/veventHelper';
6 import { toCRLF } from '../../lib/helpers/string';
8 const { ENCRYPTED_AND_SIGNED, SIGNED, CLEAR_TEXT } = CALENDAR_CARD_TYPE;
10 describe('getVeventParts()', () => {
11 it('should split shared parts', () => {
12 const y = parse(`BEGIN:VEVENT
14 DTSTART;TZID=Europe/Zurich:20200311T100000
15 DTEND;TZID=Europe/Zurich:20200312T100000
21 `) as VcalVeventComponent;
22 const result = getVeventParts(y);
24 expect(result).toEqual({
26 [SIGNED]: toCRLF(`BEGIN:VCALENDAR
30 DTSTART;TZID=Europe/Zurich:20200311T100000
31 DTEND;TZID=Europe/Zurich:20200312T100000
35 [ENCRYPTED_AND_SIGNED]: toCRLF(`BEGIN:VCALENDAR
45 calendarPart: { [SIGNED]: undefined, [ENCRYPTED_AND_SIGNED]: undefined },
46 personalPart: { [SIGNED]: undefined, [ENCRYPTED_AND_SIGNED]: undefined },
47 attendeesPart: { [CLEAR_TEXT]: [], [SIGNED]: undefined, [ENCRYPTED_AND_SIGNED]: undefined },
48 notificationsPart: [],
52 it('should split shared, calendar, and personal parts', () => {
53 const y = parse(`BEGIN:VEVENT
55 DTSTART;TZID=Europe/Zurich:20200311T100000
56 DTEND;TZID=Europe/Zurich:20200312T100000
71 `) as VcalVeventComponent;
72 const result = getVeventParts(y);
73 expect(result).toEqual({
75 [SIGNED]: toCRLF(`BEGIN:VCALENDAR
79 DTSTART;TZID=Europe/Zurich:20200311T100000
80 DTEND;TZID=Europe/Zurich:20200312T100000
84 [ENCRYPTED_AND_SIGNED]: toCRLF(`BEGIN:VCALENDAR
95 [SIGNED]: toCRLF(`BEGIN:VCALENDAR
103 [ENCRYPTED_AND_SIGNED]: toCRLF(`BEGIN:VCALENDAR
112 [SIGNED]: toCRLF(`BEGIN:VCALENDAR
124 [ENCRYPTED_AND_SIGNED]: undefined,
126 attendeesPart: { [CLEAR_TEXT]: [], [SIGNED]: undefined, [ENCRYPTED_AND_SIGNED]: undefined },
127 notificationsPart: [{ Type: 1, Trigger: '-PT15H' }],
132 describe('withMandatoryPublishFields()', () => {
133 it('should add description for display alarms, and description, summary and attendee for email ones', () => {
134 const vevent = parse(`BEGIN:VEVENT
136 DTSTART;TZID=Europe/Zurich:20200311T100000
137 DTSTAMP:20200308T134254Z
158 `) as VcalVeventComponent;
159 const expected: VcalVeventComponent = {
161 uid: { value: 'abc' },
163 value: { year: 2020, month: 3, day: 11, hours: 10, minutes: 0, seconds: 0, isUTC: false },
164 parameters: { tzid: 'Europe/Zurich' },
167 value: { year: 2020, month: 3, day: 8, hours: 13, minutes: 42, seconds: 54, isUTC: true },
169 status: { value: 'TENTATIVE' },
170 comment: [{ value: 'my comment' }],
171 description: { value: 'bca' },
172 transp: { value: 'TRANSPARENT' },
173 summary: { value: 'dcf' },
174 location: { value: 'asd' },
175 sequence: { value: 1 },
192 description: { value: 'dcf' },
209 description: { value: 'dcf' },
226 summary: { value: 'dcf' },
227 description: { value: 'dcf' },
228 attendee: [{ value: 'mailto:protonlovestesting@proton.me' }],
233 expect(withMandatoryPublishFields(vevent, 'protonlovestesting@proton.me')).toEqual(expected);
236 it('should add a null summary if the event has no title', () => {
237 const vevent = parse(`BEGIN:VEVENT
239 DTSTART;TZID=Europe/Zurich:20200311T100000
240 DTSTAMP:20200308T134254Z
250 `) as VcalVeventComponent;
251 const expected: VcalVeventComponent = {
253 uid: { value: 'abc' },
255 value: { year: 2020, month: 3, day: 11, hours: 10, minutes: 0, seconds: 0, isUTC: false },
256 parameters: { tzid: 'Europe/Zurich' },
259 value: { year: 2020, month: 3, day: 8, hours: 13, minutes: 42, seconds: 54, isUTC: true },
261 summary: { value: '' },
278 description: { value: '(no title)' },
295 summary: { value: '(no title)' },
296 description: { value: '(no title)' },
297 attendee: [{ value: 'mailto:protonlovestesting@proton.me' }],
302 expect(withMandatoryPublishFields(vevent, 'protonlovestesting@proton.me')).toEqual(expected);
306 describe('withoutRedundantDtEnd', () => {
307 describe('full day', () => {
308 it('should remove redundant dtend', () => {
309 const ALL_DAY_COMPONENT = parse(`BEGIN:VEVENT
311 DTSTAMP:20230614T101702Z
312 DTSTART;VALUE=DATE:20190812
313 DTEND;VALUE=DATE:20190813
316 END:VEVENT`) as VcalVeventComponent;
318 expect(withoutRedundantDtEnd(ALL_DAY_COMPONENT)).toEqual({
320 uid: { value: 'abc' },
321 dtstart: { value: { year: 2019, month: 8, day: 12 }, parameters: { type: 'date' } },
322 dtstamp: { value: { year: 2023, month: 6, day: 14, hours: 10, minutes: 17, seconds: 2, isUTC: true } },
323 summary: { value: 'text' },
324 rrule: { value: { freq: 'DAILY' } },
328 it('should not remove dtend', () => {
329 const ALL_DAY_COMPONENT = parse(`BEGIN:VEVENT
331 DTSTAMP:20230614T101702Z
332 DTSTART;VALUE=DATE:20190812
333 DTEND;VALUE=DATE:20190814
336 END:VEVENT`) as VcalVeventComponent;
338 expect(withoutRedundantDtEnd(ALL_DAY_COMPONENT)).toEqual({
340 uid: { value: 'abc' },
341 dtstart: { value: { year: 2019, month: 8, day: 12 }, parameters: { type: 'date' } },
342 dtstamp: { value: { year: 2023, month: 6, day: 14, hours: 10, minutes: 17, seconds: 2, isUTC: true } },
343 dtend: { value: { year: 2019, month: 8, day: 14 }, parameters: { type: 'date' } },
344 summary: { value: 'text' },
345 rrule: { value: { freq: 'DAILY' } },
350 describe('part day', () => {
351 it('should remove redundant dtend', () => {
352 const PART_DAY_COMPONENT = parse(`BEGIN:VEVENT
354 DTSTAMP:20230614T101702Z
355 DTSTART;TZID=Europe/Zurich:20190719T120000
356 DTEND;TZID=Europe/Zurich:20190719T120000
359 END:VEVENT`) as VcalVeventComponent;
361 expect(withoutRedundantDtEnd(PART_DAY_COMPONENT)).toEqual({
363 uid: { value: 'abc' },
364 dtstamp: { value: { year: 2023, month: 6, day: 14, hours: 10, minutes: 17, seconds: 2, isUTC: true } },
366 value: { year: 2019, month: 7, day: 19, hours: 12, minutes: 0, seconds: 0, isUTC: false },
368 tzid: 'Europe/Zurich',
371 summary: { value: 'text' },
372 rrule: { value: { freq: 'DAILY' } },
376 it('should not remove dtend', () => {
377 const PART_DAY_COMPONENT = parse(`BEGIN:VEVENT
379 DTSTAMP:20230614T101702Z
380 DTSTART;TZID=Europe/Zurich:20190719T120000
381 DTEND:20190719T160000Z
384 END:VEVENT`) as VcalVeventComponent;
386 expect(withoutRedundantDtEnd(PART_DAY_COMPONENT)).toEqual({
388 uid: { value: 'abc' },
389 dtstamp: { value: { year: 2023, month: 6, day: 14, hours: 10, minutes: 17, seconds: 2, isUTC: true } },
391 value: { year: 2019, month: 7, day: 19, hours: 12, minutes: 0, seconds: 0, isUTC: false },
392 parameters: { tzid: 'Europe/Zurich' },
394 dtend: { value: { year: 2019, month: 7, day: 19, hours: 16, minutes: 0, seconds: 0, isUTC: true } },
395 summary: { value: 'text' },
396 rrule: { value: { freq: 'DAILY' } },