Bug 1460001 - Ensure alarm attendees and attachments are not added twice. r=MakeMyDay
authorPhilipp Kewisch <mozilla@kewis.ch>
Tue, 18 Sep 2018 15:22:59 -0400
changeset 33673 0ea2b141befb24a2436f66928e14ec65ef87d401
parent 33672 cb276ab0c381726c93f38fb969849076c25aeaa4
child 33674 668ac5092dad846cffa09dc1b5cc999af74dd901
push id388
push userclokep@gmail.com
push dateMon, 28 Jan 2019 20:54:56 +0000
reviewersMakeMyDay
bugs1460001
Bug 1460001 - Ensure alarm attendees and attachments are not added twice. r=MakeMyDay
calendar/base/src/calAlarm.js
calendar/test/unit/test_alarm.js
--- a/calendar/base/src/calAlarm.js
+++ b/calendar/base/src/calAlarm.js
@@ -360,17 +360,21 @@ calAlarm.prototype = {
 
     promotedProps: {
         "ACTION": "action",
         "TRIGGER": "offset",
         "REPEAT": "repeat",
         "DURATION": "duration",
         "SUMMARY": "summary",
         "DESCRIPTION": "description",
-        "X-MOZ-LASTACK": "lastAck"
+        "X-MOZ-LASTACK": "lastAck",
+
+        // These have complex setters and will be ignored in setProperty
+        "ATTACH": true,
+        "ATTENDEE": true
     },
 
     get icalComponent() {
         let icssvc = cal.getIcsService();
         let comp = icssvc.createIcalComponent("VALARM");
 
         // Set up action (REQUIRED)
         let actionProp = icssvc.createIcalProperty("ACTION");
@@ -574,27 +578,36 @@ calAlarm.prototype = {
 
     hasProperty: function(aName) {
         return (this.getProperty(aName.toUpperCase()) != null);
     },
 
     getProperty: function(aName) {
         let name = aName.toUpperCase();
         if (name in this.promotedProps) {
-            return this[this.promotedProps[name]];
+            if (this.promotedProps[name] === true) {
+                // Complex promoted props will return undefined
+                return undefined;
+            } else {
+                return this[this.promotedProps[name]];
+            }
         } else {
             return this.mProperties.get(name);
         }
     },
 
     setProperty: function(aName, aValue) {
         this.ensureMutable();
         let name = aName.toUpperCase();
         if (name in this.promotedProps) {
-            this[this.promotedProps[name]] = aValue;
+            if (this.promotedProps[name] !== true) {
+                this[this.promotedProps[name]] = aValue;
+            } else {
+                cal.WARN(`Attempted to set complex property ${name} to a simple value ${aValue}`);
+            }
         } else {
             this.mProperties.set(name, aValue);
         }
         return aValue;
     },
 
     deleteProperty: function(aName) {
         this.ensureMutable();
--- a/calendar/test/unit/test_alarm.js
+++ b/calendar/test/unit/test_alarm.js
@@ -113,16 +113,29 @@ function test_email_alarm() {
     ok(!!alarm.icalComponent.serializeToICS().match(/mailto:gustav/));
 
     alarm.deleteAttendee(attendee1);
     equal(alarm.getAttendees({}).length, 1);
 
     alarm.clearAttendees();
     equal(alarm.getAttendees({}).length, 0);
 
+    // Make sure attendees are correctly folded/imported
+    alarm.icalString = dedent`
+        BEGIN:VALARM
+        ACTION:EMAIL
+        TRIGGER;VALUE=DURATION:-PT5M
+        ATTENDEE:mailto:test@example.com
+        ATTENDEE:mailto:test@example.com
+        ATTENDEE:mailto:test2@example.com
+        END:VALARM
+    `;
+    equal(alarm.icalString.match(/ATTENDEE:mailto:test@example.com/g).length, 1);
+    equal(alarm.icalString.match(/ATTENDEE:mailto:test2@example.com/g).length, 1);
+
     // TODO test attachments
     dump("Done\n");
 }
 
 function test_audio_alarm() {
     dump("Testing AUDIO alarms...");
     let alarm = cal.createAlarm();
     alarm.related = Components.interfaces.calIAlarm.ALARM_RELATED_ABSOLUTE;
@@ -182,16 +195,29 @@ function test_audio_alarm() {
     equal(addedAttachments.length, 0);
 
     // As well as clearing
     alarm.addAttachment(sound);
     alarm.clearAttachments();
     addedAttachments = alarm.getAttachments({});
     equal(addedAttachments.length, 0);
 
+    // AUDIO alarms should only be allowing one attachment, and folding any with the same value
+    alarm.icalString = dedent`
+        BEGIN:VALARM
+        ACTION:AUDIO
+        TRIGGER;VALUE=DURATION:-PT5M
+        ATTACH:Basso
+        UID:28F8007B-FE56-442E-917C-1F4E48DD406A
+        X-APPLE-DEFAULT-ALARM:TRUE
+        ATTACH:Basso
+        END:VALARM
+    `;
+    equal(alarm.icalString.match(/ATTACH:Basso/g).length, 1);
+
     dump("Done\n");
 }
 
 function test_custom_alarm() {
     dump("Testing X-SMS (custom) alarms...");
     let alarm = cal.createAlarm();
     // Set ACTION to a custom value, make sure this was not rejected
     alarm.action = "X-SMS";