Bug 784099 - Contacts API is not saving contacts. r=fabrice
authorGregor Wagner <anygregor@gmail.com>
Wed, 22 Aug 2012 10:56:25 -0700
changeset 105080 cc589462f4ca7879fac34b7a0c48f2d9eacc287c
parent 105079 c29869656f46a7c3dc14854b40294664d47687cb
child 105081 236d384dc4f98ab74e5bdece2a9da58eac7c1fdd
push id55
push usershu@rfrn.org
push dateThu, 30 Aug 2012 01:33:09 +0000
reviewersfabrice
bugs784099
milestone17.0a1
Bug 784099 - Contacts API is not saving contacts. r=fabrice
dom/contacts/ContactManager.js
dom/contacts/tests/test_contacts_basics.html
--- a/dom/contacts/ContactManager.js
+++ b/dom/contacts/ContactManager.js
@@ -62,16 +62,24 @@ function ContactAddress(aType, aStreetAd
   this.streetAddress = aStreetAddress || null;
   this.locality = aLocality || null;
   this.region = aRegion || null;
   this.postalCode = aPostalCode || null;
   this.countryName = aCountryName || null;
 };
 
 ContactAddress.prototype = {
+  __exposedProps__: {
+                      type: 'rw',
+                      streetAddress: 'rw',
+                      locality: 'rw',
+                      region: 'rw',
+                      postalCode: 'rw',
+                      countryName: 'rw'
+                     },
 
   classID : CONTACTADDRESS_CID,
   classInfo : XPCOMUtils.generateCI({classID: CONTACTADDRESS_CID,
                                      contractID: CONTACTADDRESS_CONTRACTID,
                                      classDescription: "ContactAddress",
                                      interfaces: [nsIDOMContactAddress],
                                      flags: nsIClassInfo.DOM_OBJECT}),
 
@@ -85,16 +93,20 @@ const CONTACTFIELD_CID        = Componen
 const nsIDOMContactField      = Components.interfaces.nsIDOMContactField;
 
 function ContactField(aType, aValue) {
   this.type = aType || null;
   this.value = aValue || null;
 };
 
 ContactField.prototype = {
+  __exposedProps__: {
+                      type: 'rw',
+                      value: 'rw'
+                     },
 
   classID : CONTACTFIELD_CID,
   classInfo : XPCOMUtils.generateCI({classID: CONTACTFIELD_CID,
                                      contractID: CONTACTFIELD_CONTRACTID,
                                      classDescription: "ContactField",
                                      interfaces: [nsIDOMContactField],
                                      flags: nsIClassInfo.DOM_OBJECT}),
 
@@ -109,16 +121,21 @@ const nsIDOMContactTelField      = Compo
 
 function ContactTelField(aType, aValue, aCarrier) {
   this.type = aType || null;
   this.value = aValue || null;
   this.carrier = aCarrier || null;
 };
 
 ContactTelField.prototype = {
+  __exposedProps__: {
+                      type: 'rw',
+                      value: 'rw',
+                      carrier: 'rw'
+                     },
 
   classID : CONTACTTELFIELD_CID,
   classInfo : XPCOMUtils.generateCI({classID: CONTACTTELFIELD_CID,
                                      contractID: CONTACTTELFIELD_CONTRACTID,
                                      classDescription: "ContactTelField",
                                      interfaces: [nsIDOMContactTelField],
                                      flags: nsIClassInfo.DOM_OBJECT}),
 
@@ -152,17 +169,43 @@ const CONTACT_CID        = Components.ID
 const nsIDOMContact      = Components.interfaces.nsIDOMContact;
 
 // The wrappedJSObject magic here allows callers to get at the underlying JS object
 // of the XPCOM component. We use this below to modify properties that are read-only
 // per-idl. See https://developer.mozilla.org/en-US/docs/wrappedJSObject.
 function Contact() { debug("Contact constr: "); this.wrappedJSObject = this; };
 
 Contact.prototype = {
-  
+  __exposedProps__: {
+                      id: 'rw',
+                      updated: 'rw',
+                      published:  'rw',
+                      name: 'rw',
+                      honorificPrefix: 'rw',
+                      givenName: 'rw',
+                      additionalName: 'rw',
+                      familyName: 'rw',
+                      honorificSuffix: 'rw',
+                      nickname: 'rw',
+                      email: 'rw',
+                      photo: 'rw',
+                      url: 'rw',
+                      category: 'rw',
+                      adr: 'rw',
+                      tel: 'rw',
+                      org: 'rw',
+                      jobTitle: 'rw',
+                      bday: 'rw',
+                      note: 'rw',
+                      impp: 'rw',
+                      anniversary: 'rw',
+                      sex: 'rw',
+                      genderIdentity: 'rw'
+                     },
+
   init: function init(aProp) {
     // Accept non-array strings for DOMString[] properties and convert them.
     function _create(aField) {   
       if (Array.isArray(aField)) {
         for (let i = 0; i < aField.length; i++) {
           if (typeof aField[i] !== "string")
             aField[i] = String(aField[i]);
         }
@@ -316,35 +359,34 @@ ContactManager.prototype = {
     aNewContact.id = aRecord.id;
     aNewContact.published = aRecord.published;
     aNewContact.updated = aRecord.updated;
   },
 
   _convertContactsArray: function(aContacts) {
     let contacts = new Array();
     for (let i in aContacts) {
-      let newContact = Components.classes['@mozilla.org/contact;1'].createInstance();
+      let newContact = new Contact();
       newContact.init(aContacts[i].properties);
-      this._setMetaData(newContact.wrappedJSObject, aContacts[i]);
+      this._setMetaData(newContact, aContacts[i]);
       contacts.push(newContact);
     }
     return contacts;
   },
 
   receiveMessage: function(aMessage) {
     debug("Contactmanager::receiveMessage: " + aMessage.name);
     let msg = aMessage.json;
     let contacts = msg.contacts;
 
     switch (aMessage.name) {
       case "Contacts:Find:Return:OK":
         let req = this.getRequest(msg.requestID);
         if (req) {
           let result = this._convertContactsArray(contacts);
-          debug("result: " + JSON.stringify(result));
           Services.DOMRequest.fireSuccess(req.request, result);
         } else {
           debug("no request stored!" + msg.requestID);
         }
         break;
       case "Contact:Save:Return:OK":
       case "Contacts:Clear:Return:OK":
       case "Contact:Remove:Return:OK":
--- a/dom/contacts/tests/test_contacts_basics.html
+++ b/dom/contacts/tests/test_contacts_basics.html
@@ -87,17 +87,17 @@ var properties1 = {
 var properties2 = {
   name: ["dummyName", "dummyName2"],
   familyName: "dummyFamilyName",
   givenName: "dummyGivenName",
   honorificPrefix: ["dummyHonorificPrefix","dummyHonorificPrefix2"],
   honorificSuffix: "dummyHonorificSuffix",
   additionalName: "dummyadditionalName",
   nickname: "dummyNickname",
-  tel: [{type: ["test"], value: "123456789"},{type: ["home", "custom"], value: "234567890"}],
+  tel: [{type: ["test"], value: "123456789", carrier: "myCarrier"},{type: ["home", "custom"], value: "234567890"}],
   email: [{type: ["test"], value: "a@b.c"}, {value: "b@c.d"}],
   adr: [adr1, adr2],
   impp: [{type: ["aim"], value:"im1"}, {value: "im2"}],
   org: ["org1", "org2"],
   jobTitle: ["boss", "superboss"],
   bday: new Date("1980, 12, 01"),
   note: "test note",
   category: ["cat1", "cat2"],
@@ -149,18 +149,18 @@ function checkAddress(adr1, adr2) {
 
 function checkTel(tel1, tel2) {
   checkStr(tel1.type, tel2.type, "Same type");
   checkStr(tel1.value, tel2.value, "Same value");
   checkStr(tel1.carrier, tel2.carrier, "Same carrier");
 }
 
 function checkField(field1, field2) {
-  checkStr(field1.type, field1.type, "Same type");
-  checkStr(field1.value, field1.value, "Same value");
+  checkStr(field1.type, field2.type, "Same type");
+  checkStr(field1.value, field2.value, "Same value");
 }
 
 function checkContacts(contact1, contact2) {
   checkStr(contact1.name, contact2.name, "Same name");
   checkStr(contact1.honorificPrefix, contact2.honorificPrefix, "Same honorificPrefix");
   checkStr(contact1.givenName, contact2.givenName, "Same givenName");
   checkStr(contact1.additionalName, contact2.additionalName, "Same additionalName");
   checkStr(contact1.familyName, contact2.familyName, "Same familyName");
@@ -307,16 +307,30 @@ var steps = [
                    filterOp: "contains",
                    filterValue: properties1.name.substring(0,3)};
     req = mozContacts.find(options);
     req.onsuccess = function () {
       ok(req.result.length == 1, "Found exactly 1 contact.");
       findResult1 = req.result[0];
       ok(findResult1.id == sample_id1, "Same ID");
       checkContacts(createResult1, properties1);
+      dump("findResult: " + JSON.stringify(findResult1) + "\n");
+      // Some manual testing. Testint the testfunctions
+      // tel: [{type: ["work"], value: "123456", carrier: "testCarrier"} , {type: ["home", "fax"], value: "+9-876-5432"}],
+      is(findResult1.tel[0].carrier, "testCarrier", "Same Carrier");
+      is(findResult1.tel[0].type, "work", "Same type");
+      is(findResult1.tel[0].value, "123456", "Same Value");
+      is(findResult1.tel[1].type[1], "fax", "Same type");
+      is(findResult1.tel[1].value, "+9-876-5432", "Same Value");
+
+      is(findResult1.adr[0].countryName, "country 1", "Same country");
+
+      // email: [{type: ["work"], value: "x@y.com"}]
+      is(findResult1.email[0].type, "work", "Same Type");
+      is(findResult1.email[0].value, "x@y.com", "Same Value");
       next();
     };
     req.onerror = onFailure;
   },
   function () {
     ok(true, "Searching for exact email");
     var options = {filterBy: ["email"],
                    filterOp: "equals",