You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by al...@apache.org on 2015/12/16 12:17:53 UTC

cordova-plugin-contacts git commit: CB-10117 Added new tests

Repository: cordova-plugin-contacts
Updated Branches:
  refs/heads/master c7043c9e2 -> 48c972c73


CB-10117 Added new tests


Project: http://git-wip-us.apache.org/repos/asf/cordova-plugin-contacts/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-plugin-contacts/commit/48c972c7
Tree: http://git-wip-us.apache.org/repos/asf/cordova-plugin-contacts/tree/48c972c7
Diff: http://git-wip-us.apache.org/repos/asf/cordova-plugin-contacts/diff/48c972c7

Branch: refs/heads/master
Commit: 48c972c73c9b85fade2ea4ddcabe1db1e3fcf8c7
Parents: c7043c9
Author: Alexander Sorokin <al...@akvelon.com>
Authored: Wed Dec 2 19:51:50 2015 +0300
Committer: Alexander Sorokin <al...@akvelon.com>
Committed: Tue Dec 15 12:36:07 2015 +0300

----------------------------------------------------------------------
 tests/tests.js | 423 ++++++++++++++++++++++++++++++++++++++--------------
 1 file changed, 311 insertions(+), 112 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-plugin-contacts/blob/48c972c7/tests/tests.js
----------------------------------------------------------------------
diff --git a/tests/tests.js b/tests/tests.js
index 52250e6..376e5a9 100644
--- a/tests/tests.js
+++ b/tests/tests.js
@@ -23,7 +23,6 @@ exports.defineAutoTests = function() {
     // global to store a contact so it doesn't have to be created or retrieved multiple times
     // all of the setup/teardown test methods can reference the following variables to make sure to do the right cleanup
     var gContactObj = null,
-        gContactId = null,
         isWindowsPhone8 = cordova.platformId == 'windowsphone',
         isWindows = (cordova.platformId === "windows") || (cordova.platformId === "windows8"),
         isWindowsPhone81 = isWindows && WinJS.Utilities.isPhone;
@@ -51,6 +50,47 @@ exports.defineAutoTests = function() {
         });
     };
 
+    function removeContactsByFields(fields, filter, done) {
+        var obj = new ContactFindOptions();
+        obj.filter = filter;
+        obj.multiple = true;
+        navigator.contacts.find(fields, function(contacts) {
+            var removes = [];
+            contacts.forEach(function(contact) {
+                removes.push(contact);
+            });
+            if (removes.length == 0) {
+                done();
+                return;
+            }
+
+            var nextToRemove = undefined;
+            if (removes.length > 0) {
+                nextToRemove = removes.shift();
+            }
+
+            function removeNext(item) {
+                if (typeof item === 'undefined') {
+                    done();
+                    return;
+                }
+
+                if (removes.length > 0) {
+                    nextToRemove = removes.shift();
+                } else {
+                    nextToRemove = undefined;
+                }
+
+                item.remove(function removeSucceeded() {
+                    removeNext(nextToRemove);
+                }, function removeFailed() {
+                    removeNext(nextToRemove);
+                });
+            }
+            removeNext(nextToRemove);
+        }, done, obj);
+    }
+
     describe("Contacts (navigator.contacts)", function() {
         it("contacts.spec.1 should exist", function() {
             expect(navigator.contacts).toBeDefined();
@@ -86,7 +126,8 @@ exports.defineAutoTests = function() {
                 }
                 navigator.contacts.find(["displayName", "name", "phoneNumbers", "emails"], win, failed, obj);
             });
-            it("success callback should be called with an array, even if partial ContactFindOptions specified", function(done) {
+
+            it("contacts.spec.4 success callback should be called with an array, even if partial ContactFindOptions specified", function(done) {
                 // Find method is not supported on Windows platform
                 if ((isWindows && !isWindowsPhone81) || isIOSPermissionBlocked) {
                     pending();
@@ -102,7 +143,8 @@ exports.defineAutoTests = function() {
                     multiple: true
                 });
             });
-            it("contacts.spec.4 should throw an exception if success callback is empty", function() {
+
+            it("contacts.spec.5 should throw an exception if success callback is empty", function() {
                 var obj = new ContactFindOptions();
                 obj.filter = "";
                 obj.multiple = true;
@@ -111,7 +153,8 @@ exports.defineAutoTests = function() {
                     navigator.contacts.find(["displayName", "name", "emails", "phoneNumbers"], null, fail.bind(null, done), obj);
                 }).toThrow();
             });
-            it("contacts.spec.5 error callback should be called when no fields are specified", function(done) {
+
+            it("contacts.spec.6 error callback should be called when no fields are specified", function(done) {
                 var win = fail,
                     // we don't want this to be called
                     error = function(result) {
@@ -125,13 +168,14 @@ exports.defineAutoTests = function() {
                 obj.multiple = true;
                 navigator.contacts.find([], win, error, obj);
             });
+
             describe("with newly-created contact", function() {
 
                 afterEach(function (done) {
                     removeContact(done);
                 });
 
-                it("contacts.spec.6 should be able to find a contact by name", function(done) {
+                it("contacts.spec.7 should be able to find a contact by name", function(done) {
                     // Find method is not supported on Windows Store apps.
                     // also this test will be skipped for Windows Phone 8.1 because function "save" not supported on WP8.1
                     if (isWindows || isWindowsPhone8 || isIOSPermissionBlocked) {
@@ -182,11 +226,12 @@ exports.defineAutoTests = function() {
         });
 
         describe('create method', function() {
-            it("contacts.spec.1 should exist", function() {
+            it("contacts.spec.8 should exist", function() {
                 expect(navigator.contacts.create).toBeDefined();
                 expect(typeof navigator.contacts.create).toBe('function');
             });
-            it("contacts.spec.8 should return a Contact object", function() {
+
+            it("contacts.spec.9 should return a Contact object", function() {
                 var bDay = new Date(1976, 7, 4);
                 var obj = navigator.contacts.create({
                     "displayName": "test name",
@@ -216,7 +261,7 @@ exports.defineAutoTests = function() {
         });
 
         describe("Contact object", function() {
-            it("contacts.spec.9 should be able to create instance", function() {
+            it("contacts.spec.10 should be able to create instance", function() {
                 var contact = new Contact("a", "b", new ContactName("a", "b", "c", "d", "e", "f"), "c", [], [], [], [], [], "f", "i", [], [], []);
                 expect(contact).toBeDefined();
                 expect(contact.id).toBe("a");
@@ -234,7 +279,8 @@ exports.defineAutoTests = function() {
                 expect(contact.categories).toBeDefined();
                 expect(contact.urls).toBeDefined();
             });
-            it("contacts.spec.10 should be able to define a ContactName object", function() {
+
+            it("contacts.spec.11 should be able to define a ContactName object", function() {
                 var contactName = new ContactName("Dr. First Last Jr.", "Last", "First", "Middle", "Dr.", "Jr.");
                 expect(contactName).toBeDefined();
                 expect(contactName.formatted).toBe("Dr. First Last Jr.");
@@ -244,19 +290,22 @@ exports.defineAutoTests = function() {
                 expect(contactName.honorificPrefix).toBe("Dr.");
                 expect(contactName.honorificSuffix).toBe("Jr.");
             });
-            it("contacts.spec.11 should be able to define a ContactField object", function() {
+
+            it("contacts.spec.12 should be able to define a ContactField object", function() {
                 var contactField = new ContactField("home", "8005551212", true);
                 expect(contactField).toBeDefined();
                 expect(contactField.type).toBe("home");
                 expect(contactField.value).toBe("8005551212");
                 expect(contactField.pref).toBe(true);
             });
-            it("contacts.spec.12 ContactField object should coerce type and value properties to strings", function() {
+
+            it("contacts.spec.13 ContactField object should coerce type and value properties to strings", function() {
                 var contactField = new ContactField(12345678, 12345678, true);
                 expect(contactField.type).toBe("12345678");
                 expect(contactField.value).toBe("12345678");
             });
-            it("contacts.spec.13 should be able to define a ContactAddress object", function() {
+
+            it("contacts.spec.14 should be able to define a ContactAddress object", function() {
                 var contactAddress = new ContactAddress(true, "home", "a", "b", "c", "d", "e", "f");
                 expect(contactAddress).toBeDefined();
                 expect(contactAddress.pref).toBe(true);
@@ -268,7 +317,8 @@ exports.defineAutoTests = function() {
                 expect(contactAddress.postalCode).toBe("e");
                 expect(contactAddress.country).toBe("f");
             });
-            it("contacts.spec.14 should be able to define a ContactOrganization object", function() {
+
+            it("contacts.spec.15 should be able to define a ContactOrganization object", function() {
                 var contactOrg = new ContactOrganization(true, "home", "a", "b", "c", "d", "e", "f", "g");
                 expect(contactOrg).toBeDefined();
                 expect(contactOrg.pref).toBe(true);
@@ -277,18 +327,21 @@ exports.defineAutoTests = function() {
                 expect(contactOrg.department).toBe("b");
                 expect(contactOrg.title).toBe("c");
             });
-            it("contacts.spec.15 should be able to define a ContactFindOptions object", function() {
+
+            it("contacts.spec.16 should be able to define a ContactFindOptions object", function() {
                 var contactFindOptions = new ContactFindOptions("a", true, "b");
                 expect(contactFindOptions).toBeDefined();
                 expect(contactFindOptions.filter).toBe("a");
                 expect(contactFindOptions.multiple).toBe(true);
             });
-            it("contacts.spec.16 should contain a clone function", function() {
+
+            it("contacts.spec.17 should contain a clone function", function() {
                 var contact = new Contact();
                 expect(contact.clone).toBeDefined();
                 expect(typeof contact.clone).toBe('function');
             });
-            it("contacts.spec.17 clone function should make deep copy of Contact Object", function() {
+
+            it("contacts.spec.18 clone function should make deep copy of Contact Object", function() {
                 var contact = new Contact();
                 contact.id = 1;
                 contact.displayName = "Test Name";
@@ -308,12 +361,14 @@ exports.defineAutoTests = function() {
                 expect(clonedContact.name.formatted).toBe(contact.name.formatted);
                 expect(clonedContact.connected).toBe(contact.connected);
             });
-            it("contacts.spec.18 should contain a save function", function() {
+
+            it("contacts.spec.19 should contain a save function", function() {
                 var contact = new Contact();
                 expect(contact.save).toBeDefined();
                 expect(typeof contact.save).toBe('function');
             });
-            it("contacts.spec.19 should contain a remove function", function() {
+
+            it("contacts.spec.20 should contain a remove function", function() {
                 var contact = new Contact();
                 expect(contact.remove).toBeDefined();
                 expect(typeof contact.remove).toBe('function');
@@ -326,14 +381,14 @@ exports.defineAutoTests = function() {
                 removeContact(done);
             });
 
-            it("contacts.spec.20 should be able to save a contact", function(done) {
+            it("contacts.spec.21 should be able to save a contact", function(done) {
                 // Save method is not supported on Windows platform
                 if (isWindows || isWindowsPhone8 || isIOSPermissionBlocked) {
                     pending();
                 }
 
                 var bDay = new Date(1976, 6, 4);
-                obj = {
+                var obj = {
                     "gender": "male",
                     "note": "my note",
                     "name": {
@@ -358,7 +413,6 @@ exports.defineAutoTests = function() {
                         expect(obj.emails[1].value).toBe('there@here.com');
                         expect(obj.birthday.toDateString()).toBe(bDay.toDateString());
                         expect(obj.addresses).toBe(null);
-                        // must store returned object in order to have id for update test below
                         gContactObj = obj;
                         done();
                     },
@@ -369,8 +423,7 @@ exports.defineAutoTests = function() {
                     .save(saveSuccess, saveFail);
             });
 
-            // HACK: there is a reliance between the previous and next test. This is bad form.
-            it("contacts.spec.21 update a contact", function(done) {
+            it("contacts.spec.22 update a contact", function(done) {
                 // Save method is not supported on Windows platform
                 if (isWindows || isWindowsPhone8 || isIOSPermissionBlocked) {
                     pending();
@@ -398,7 +451,6 @@ exports.defineAutoTests = function() {
                 var saveFail = fail.bind(null, done);
 
                 var saveSuccess = function(obj) {
-                    // must store returned object in order to have id for update test below
                     gContactObj = obj;
                     gContactObj.emails[1].value = "";
                     bDay = new Date(1975, 5, 4);
@@ -429,7 +481,7 @@ exports.defineAutoTests = function() {
                 removeContact(done);
             });
 
-            it("contacts.spec.22 calling remove on a contact has an id of null should return ContactError.UNKNOWN_ERROR", function(done) {
+            it("contacts.spec.23 calling remove on a contact that has an id of null should return ContactError.UNKNOWN_ERROR", function(done) {
                 var expectedFail = function(result) {
                     expect(result.code).toBe(ContactError.UNKNOWN_ERROR);
                     done();
@@ -438,7 +490,8 @@ exports.defineAutoTests = function() {
                 var rmContact = new Contact();
                 rmContact.remove(fail.bind(null, done), expectedFail);
             });
-            it("contacts.spec.23 calling remove on a contact that does not exist should return ContactError.UNKNOWN_ERROR", function(done) {
+
+            it("contacts.spec.24 calling remove on a contact that does not exist should return ContactError.UNKNOWN_ERROR", function(done) {
                 // remove method is not supported on Windows platform
                 if (isWindows || isWindowsPhone8 || isIOSPermissionBlocked) {
                     pending();
@@ -455,64 +508,118 @@ exports.defineAutoTests = function() {
             }, MEDIUM_TIMEOUT);
         });
 
-        describe("Round trip Contact tests (creating + save + delete + find).", function() {
+        describe("Round trip Contact tests (creating + save + delete + find)", function() {
+            var saveAndFindBy = function (fields, filter, done) {
+                removeContactsByFields(["note"], "DeleteMe", function() {
+                    gContactObj.save(function(c_obj) {
+                        var findWin = function(cs) {
+                            // update to have proper saved id
+                            gContactObj = cs[0];
+                            expect(cs.length).toBe(1);
+                            done();
+                        };
+                        var findFail = fail;
+                        var obj = new ContactFindOptions();
+                        obj.filter = filter;
+                        obj.multiple = true;
+                        navigator.contacts.find(fields, findWin, findFail, obj);
+                    }, fail);
+                });
+            };
+
             afterEach(function (done) {
                 removeContact(done);
             });
 
-            it("contacts.spec.24 Creating, saving, finding a contact should work, removing it should work, after which we should not be able to find it, and we should not be able to delete it again.", function(done) {
+            it("contacts.spec.25 Creating, saving, finding a contact should work", function(done) {
                 // Save method is not supported on Windows platform
                 if (isWindows || isWindowsPhone8 || isIOSPermissionBlocked) {
                     pending();
                 }
-                // First, count already existing 'DeleteMe' contacts, if any
-                var initialCount = 0;
-                var initialSearchOptions = new ContactFindOptions();
-                initialSearchOptions.filter = "DeleteMe";
-                initialSearchOptions.multiple = true;
-                navigator.contacts.find(["displayName", "name", "phoneNumbers", "emails"], function(initialContacts) {
-                    initialCount = initialContacts.length;
-                    gContactObj = new Contact();
-                    gContactObj.name = new ContactName();
-                    gContactObj.name.familyName = "DeleteMe";
-                    gContactObj.save(function(c_obj) {
-                        var findWin = function(cs) {
-                                expect(cs.length).toBe(initialCount + 1);
-                                // update to have proper saved id
-                                gContactObj = cs[0];
-                                gContactObj.remove(function() {
-                                    var findWinAgain = function(seas) {
-                                            expect(seas.length).toBe(initialCount);
-                                            gContactObj.remove(function() {
-                                                throw ("success callback called after non-existent Contact object called remove(). Test failed.");
-                                            }, function(e) {
-                                                expect(e.code).toBe(ContactError.UNKNOWN_ERROR);
-                                                done();
-                                            });
-                                        };
-                                    var findFailAgain = function(e) {
-                                            throw ("find error callback invoked after delete, test failed.");
-                                        };
-                                    var obj = new ContactFindOptions();
-                                    obj.filter = "DeleteMe";
-                                    obj.multiple = true;
-                                    navigator.contacts.find(["displayName", "name", "phoneNumbers", "emails"], findWinAgain, findFailAgain, obj);
-                                }, function(e) {
-                                    throw ("Newly created contact's remove function invoked error callback. Test failed.");
-                                });
-                            };
-                        var findFail = fail;
+                var contactName = "DeleteMe";
+                gContactObj = new Contact();
+                gContactObj.name = new ContactName();
+                gContactObj.name.familyName = contactName;
+                saveAndFindBy(["displayName", "name"], contactName, done);
+            }, MEDIUM_TIMEOUT);
+            
+            it("contacts.spec.26 Creating, saving, finding a contact should work, removing it should work", function(done) {
+                // Save method is not supported on Windows platform
+                if (isWindows || isWindowsPhone8 || isIOSPermissionBlocked) {
+                    pending();
+                }
+                var contactName = "DeleteMe";
+                gContactObj = new Contact();
+                gContactObj.name = new ContactName();
+                gContactObj.name.familyName = contactName;
+                saveAndFindBy(["displayName", "name"], contactName, function() {
+                    gContactObj.remove(function() {
+                        done();
+                    }, function(e) {
+                        throw ("Newly created contact's remove function invoked error callback. Test failed.");
+                    });
+                });
+            }, MEDIUM_TIMEOUT);
+            
+            it("contacts.spec.27 Should not be able to delete the same contact twice", function(done) {
+                // Save method is not supported on Windows platform
+                if (isWindows || isWindowsPhone8 || isIOSPermissionBlocked) {
+                    pending();
+                }
+                var contactName = "DeleteMe";
+                gContactObj = new Contact();
+                gContactObj.name = new ContactName();
+                gContactObj.name.familyName = contactName;
+                saveAndFindBy(["displayName", "name"], contactName, function() {
+                    gContactObj.remove(function() {
+                        var findWin = function(seas) {
+                            expect(seas.length).toBe(0);
+                            gContactObj.remove(function() {
+                                throw ("Success callback called after non-existent Contact object called remove(). Test failed.");
+                            }, function(e) {
+                                expect(e.code).toBe(ContactError.UNKNOWN_ERROR);
+                                done();
+                            });
+                        };
                         var obj = new ContactFindOptions();
-                        obj.filter = "DeleteMe";
+                        obj.filter = contactName;
                         obj.multiple = true;
-                        navigator.contacts.find(["displayName", "name", "phoneNumbers", "emails"], findWin, findFail, obj);
+                        navigator.contacts.find(["displayName", "name", "phoneNumbers", "emails"], findWin, fail, obj);
                     }, fail);
-                }, function() {}, initialSearchOptions);
+                });
+            }, MEDIUM_TIMEOUT);
+
+            it("contacts.spec.28 should find a contact with unicode name", function (done) {
+                // Save method is not supported on Windows platform
+                if (isWindows || isWindowsPhone8) {
+                    pending();
+                }
+                var contactName = "\u2602";
+                gContactObj = new Contact();
+                gContactObj.note = "DeleteMe";
+                gContactObj.name = new ContactName();
+                gContactObj.name.familyName = contactName;
+                saveAndFindBy(["displayName", "name"], contactName, done);
+            }, MEDIUM_TIMEOUT);
+
+            it("contacts.spec.29 should find a contact without a name", function (done) {
+                // Save method is not supported on Windows platform
+                if (isWindows || isWindowsPhone8) {
+                    pending();
+                }
+    
+                gContactObj = new Contact();
+                var phoneNumbers = [1];
+                phoneNumbers[0] = new ContactField('work', '555-555-1234', true);
+                gContactObj.phoneNumbers = phoneNumbers;
+                
+                saveAndFindBy(["phoneNumbers"], "555-555-1234", done);
+    
             }, MEDIUM_TIMEOUT);
         });
 
         describe('ContactError interface', function() {
-            it("contacts.spec.25 ContactError constants should be defined", function() {
+            it("contacts.spec.30 ContactError constants should be defined", function() {
                 expect(ContactError.UNKNOWN_ERROR).toBe(0);
                 expect(ContactError.INVALID_ARGUMENT_ERROR).toBe(1);
                 expect(ContactError.TIMEOUT_ERROR).toBe(2);
@@ -531,10 +638,12 @@ exports.defineAutoTests = function() {
 /******************************************************************************/
 
 exports.defineManualTests = function(contentEl, createActionButton) {
-    function getContacts() {
+    function getContacts(filter) {
         var results = document.getElementById('contact_results');
-        obj = new ContactFindOptions();
-        // show all contacts, so don't filter
+        var obj = new ContactFindOptions();
+        if (filter) {
+            obj.filter = filter;
+        }
         obj.multiple = true;
         navigator.contacts.find(["displayName", "name", "phoneNumbers", "emails", "urls", "note"], function(contacts) {
             var s = "";
@@ -544,7 +653,8 @@ exports.defineManualTests = function(contentEl, createActionButton) {
                 s = "Number of contacts: " + contacts.length + "<br><table width='100%'><tr><th>Name</th><td>Phone</td><td>Email</td></tr>";
                 for (var i = 0; i < contacts.length; i++) {
                     var contact = contacts[i];
-                    s = s + "<tr><td>" + contact.name.formatted + "</td><td>";
+                    var contactNameTag = contact.name ? "<tr><td>" + contact.name.formatted + "</td><td>" : "<tr><td>(No Name)</td><td>";
+                    s = s + contactNameTag;
                     if (contact.phoneNumbers && contact.phoneNumbers.length > 0) {
                         s = s + contact.phoneNumbers[0].value;
                     }
@@ -567,6 +677,11 @@ exports.defineManualTests = function(contentEl, createActionButton) {
         }, obj);
     }
 
+    function filterContacts() {
+        var filter = document.getElementById('searchstring');
+        getContacts(filter.value);
+    }
+
     function pickContact() {
         var results = document.getElementById('contact_results');
         navigator.contacts.pickContact(
@@ -585,31 +700,18 @@ exports.defineManualTests = function(contentEl, createActionButton) {
             }
         );
     }
-
-    function addContact() {
-        var results = document.getElementById('contact_results');
-
+    
+    function addContact(displayName, name, phoneNumber, birthday) {
         try {
-            var contact = navigator.contacts.create({
-                "displayName": "Dooney Evans"
-            });
-            var contactName = {
-                formatted: "Dooney Evans",
-                familyName: "Evans",
-                givenName: "Dooney",
-                middleName: ""
-            };
-
-            contact.name = contactName;
+            var results = document.getElementById('contact_results');
+            var contact = navigator.contacts.create({ "displayName": displayName, "name": name, "birthday": birthday, "note": "DeleteMe" });
 
             var phoneNumbers = [1];
-            phoneNumbers[0] = new ContactField('work', '512-555-1234', true);
+            phoneNumbers[0] = new ContactField('work', phoneNumber, true);
             contact.phoneNumbers = phoneNumbers;
 
-            contact.birthday = new Date(1985, 0, 23);
-
             contact.save(function() {
-                results.innerHTML = "Contact saved.";
+                results.innerHTML = (displayName || "Nameless contact") + " saved.";
             }, function(e) {
                 if (e.code === ContactError.NOT_SUPPORTED_ERROR) {
                     results.innerHTML = "Saving contacts not supported.";
@@ -618,20 +720,86 @@ exports.defineManualTests = function(contentEl, createActionButton) {
                 }
             });
         } catch (e) {
-            alert(e);
+            console.error(e.message);
         }
     }
 
-    function removeDooneyEvans() {
+    function addDooneyEvans() {
+        var displayName = "Dooney Evans";
+        var contactName = {
+            formatted: "Dooney Evans",
+            familyName: "Evans",
+            givenName: "Dooney",
+            middleName: ""
+        };
+        var phoneNumber = '512-555-1234';
+        var birthday = new Date(1985, 0, 23);
+
+        addContact(displayName, contactName, phoneNumber, birthday);
+    }
+
+    function addNamelessContact() {
+        addContact();
+    }
+
+    function addUnicodeContact() {
+        var displayName = "Н€йромонах \nФеофаЊ";
+        var contactName = {
+            formatted: "Н€йромонах \nФеофаЊ",
+            familyName: "\nФеофаЊ",
+            givenName: "Н€йромонах",
+            middleName: ""
+        };
+
+        addContact(displayName, contactName);
+    }
+
+    function renameDooneyEvans() {
         var results = document.getElementById('contact_results');
+        var obj = new ContactFindOptions();
+        obj.filter = 'Dooney Evans';
+        obj.multiple = false;
 
-        navigator.contacts.find(["displayName", "name", "phoneNumbers", "emails", "urls", "note"], function(contacts) {
+        navigator.contacts.find(['displayName', 'name'], function(contacts) {
+            if (contacts.length == 0) {
+                results.innerHTML = 'No contacts to update.';
+                return;
+            }
+            var contact = contacts[0];
+            contact.displayName = "Urist McContact";
+            var name = new ContactName();
+            name.givenName = "Urist";
+            name.familyName = "McContact";
+            contact.name = name;
+            contact.save(function(updated) {
+                results.innerHTML = 'Contact updated.';
+            },function(e) {
+                results.innerHTML = 'Update failed: error ' + e.code;
+            });
+        }, function(e) {
+            if (e.code === ContactError.NOT_SUPPORTED_ERROR) {
+                results.innerHTML = 'Searching for contacts is not supported.';
+            } else {
+                results.innerHTML = 'Search failed: error ' + e.code;
+            }
+        }, obj)
+    }
+
+    function removeTestContacts() {
+        var results = document.getElementById('contact_results');
+        results.innerHTML = "";
+        var obj = new ContactFindOptions();
+        obj.filter = 'DeleteMe';
+        obj.multiple = true;
+        navigator.contacts.find(['note'], function(contacts) {
             var removes = [];
             contacts.forEach(function(contact) {
-                if (contact.name.formatted.indexOf('Dooney Evans') > -1) {
-                    removes.push(contact);
-                }
+                removes.push(contact);
             });
+            if (removes.length == 0) {
+                results.innerHTML = "No contacts to remove";
+                return;
+            }
 
             var nextToRemove = undefined;
             if (removes.length > 0) {
@@ -639,7 +807,9 @@ exports.defineManualTests = function(contentEl, createActionButton) {
             }
 
             function removeNext(item) {
-                if (typeof item === 'undefined') return;
+                if (typeof item === 'undefined') {
+                    return;
+                }
 
                 if (removes.length > 0) {
                     nextToRemove = removes.shift();
@@ -648,10 +818,10 @@ exports.defineManualTests = function(contentEl, createActionButton) {
                 }
 
                 item.remove(function removeSucceeded() {
-                    results.innerHTML += '<br>Removed contact with ID ' + item.id;
+                    results.innerHTML += "Removed a contact with ID " + item.id + "<br/>";
                     removeNext(nextToRemove);
-                }, function removeFailed(e) {
-                    results.innerHTML += '<br>Remove failed contact with ID ' + item.id;
+                }, function removeFailed() {
+                    results.innerHTML += "Failed to remove a contact with ID " + item.id + "<br/>";
                     removeNext(nextToRemove);
                 });
             }
@@ -662,7 +832,16 @@ exports.defineManualTests = function(contentEl, createActionButton) {
             } else {
                 results.innerHTML = 'Search failed: error ' + e.code;
             }
-        })
+        }, obj);
+    }
+    
+    function nameMatches(contact, contactName) {
+        if (contactName === null && (contact.name === null || contact.name.formatted === null)) {
+            return true;
+        } else if (contact.name && contact.name.formatted && contact.name.formatted.indexOf(contactName) > -1) {
+            return true;
+        }
+        return false;
     }
 
     /******************************************************************************/
@@ -672,27 +851,47 @@ exports.defineManualTests = function(contentEl, createActionButton) {
             '<div id="contact_results"></div>' +
         '</div>' +
         '<div id="get_contacts"></div>' +
-            'Expected result: Status box will show number of contacts and list them. May be empty on a fresh device until you click Add.' +
+            '<p>Expected result: Status box will show number of contacts and list them. May be empty on a fresh device until you click Add.</p>' +
+        '<div id="filter_contacts">Search: <input type="text" id="searchstring"></div>' +
+            '<p>Expected result: Will return only contacts which contain specified string</p>' +
         '<div id="pick_contact"></div>' +
-            'Expected result: Device\'s address book will be shown. After picking a contact status box will show Contact object, passed to success callback</p>' +
+            '<p>Expected result: Device\'s address book will be shown. After picking a contact status box will show Contact object, passed to success callback</p>' +
         '<div id="add_contact"></div>' +
-            'Expected result: Will add a new contact. Log will say "Contact saved." or "Saving contacts not supported." if not supported on current platform. Verify by running Get phone contacts again' +
-        '<div id="remove_dooney_evans"></div>' +
-            '<p>Expected result: Will remove any contacts named "Dooney Evans".  Log will output success or failure, plus ID, or fail like getting contacts will fail.</p>';
+            '<p>Expected result: Will add a new contact. Log will say "Contact saved." or "Saving contacts not supported." if not supported on current platform. Verify by running Get phone contacts again</p>' +
+        '<div id="update_contact"></div>' +
+            '<p>Expected result: Will rename "Dooney Evans" to "Urist McContact".</p>' +
+        '<div id="remove_contacts"></div>' +
+            '<p>Expected result: Will remove all contacts created by these tests. Log will output success or failure and ID of the deleted contacts.</p>';
 
     createActionButton("Get phone's contacts", function() {
         getContacts();
     }, 'get_contacts');
 
+    createActionButton("Filter contacts", function() {
+        filterContacts();
+    }, 'filter_contacts');
+
     createActionButton("Pick contact", function() {
         pickContact();
     }, 'pick_contact');
 
     createActionButton("Add a new contact 'Dooney Evans'", function() {
-        addContact();
+        addDooneyEvans();
+    }, 'add_contact');
+
+    createActionButton("Add new nameless contact", function() {
+        addNamelessContact();
+    }, 'add_contact');
+
+    createActionButton("Add new unicode contact", function() {
+        addUnicodeContact();
     }, 'add_contact');
 
-    createActionButton("Delete all 'Dooney Evans'", function() {
-        removeDooneyEvans();
-    }, 'remove_dooney_evans');
+    createActionButton("Rename 'Dooney Evans'", function() {
+        renameDooneyEvans();
+    }, 'update_contact');
+
+    createActionButton("Delete all test contacts", function() {
+        removeTestContacts();
+    }, 'remove_contacts');
 };


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cordova.apache.org
For additional commands, e-mail: commits-help@cordova.apache.org