| /* |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| */ |
| |
| // 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, |
| isWindowsPhone = cordova.platformId == 'windowsphone'; |
| |
| var removeContact = function(){ |
| if (gContactObj) { |
| gContactObj.remove(function(){},function(){ |
| console.log("[CONTACTS ERROR]: removeContact cleanup method failed to clean up test artifacts."); |
| }); |
| gContactObj = null; |
| } |
| }; |
| |
| describe("Contacts (navigator.contacts)", function () { |
| it("contacts.spec.1 should exist", function() { |
| expect(navigator.contacts).toBeDefined(); |
| }); |
| |
| it("contacts.spec.2 should contain a find function", function() { |
| expect(navigator.contacts.find).toBeDefined(); |
| expect(typeof navigator.contacts.find).toBe('function'); |
| }); |
| |
| describe("find method", function() { |
| it("contacts.spec.3 success callback should be called with an array", function() { |
| var win = jasmine.createSpy().andCallFake(function(result) { |
| expect(result).toBeDefined(); |
| expect(result instanceof Array).toBe(true); |
| }), |
| fail = jasmine.createSpy(), |
| obj = new ContactFindOptions(); |
| |
| runs(function () { |
| obj.filter=""; |
| obj.multiple=true; |
| navigator.contacts.find(["displayName", "name", "phoneNumbers", "emails"], win, fail, obj); |
| }); |
| |
| waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT); |
| |
| runs(function () { |
| expect(fail).not.toHaveBeenCalled(); |
| }); |
| }); |
| |
| it("success callback should be called with an array, even if partial ContactFindOptions specified", function () { |
| var win = jasmine.createSpy().andCallFake(function (result) { |
| expect(result).toBeDefined(); |
| expect(result instanceof Array).toBe(true); |
| }), |
| fail = jasmine.createSpy(); |
| |
| runs(function () { |
| navigator.contacts.find(["displayName", "name", "phoneNumbers", "emails"], win, fail, { |
| multiple: true |
| }); |
| }); |
| |
| waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT); |
| |
| runs(function () { |
| expect(fail).not.toHaveBeenCalled(); |
| }); |
| }); |
| |
| it("contacts.spec.4 should throw an exception if success callback is empty", function() { |
| var fail = function() {}; |
| var obj = new ContactFindOptions(); |
| obj.filter=""; |
| obj.multiple=true; |
| |
| expect(function () { |
| navigator.contacts.find(["displayName", "name", "emails", "phoneNumbers"], null, fail, obj); |
| }).toThrow(); |
| }); |
| |
| it("contacts.spec.5 error callback should be called when no fields are specified", function() { |
| var win = jasmine.createSpy(), |
| fail = jasmine.createSpy(function(result) { |
| expect(result).toBeDefined(); |
| expect(result.code).toBe(ContactError.INVALID_ARGUMENT_ERROR); |
| }), |
| obj = new ContactFindOptions(); |
| |
| runs(function () { |
| obj.filter=""; |
| obj.multiple=true; |
| navigator.contacts.find([], win, fail, obj); |
| }); |
| |
| waitsFor(function () { return fail.wasCalled; }, Tests.TEST_TIMEOUT); |
| |
| runs(function () { |
| expect(win).not.toHaveBeenCalled(); |
| expect(fail).toHaveBeenCalled(); |
| }); |
| }); |
| |
| describe("with newly-created contact", function () { |
| |
| afterEach(removeContact); |
| |
| it("contacts.spec.6 should be able to find a contact by name", function() { |
| |
| // this api requires manual user confirmation on WP7/8 so skip it |
| if (isWindowsPhone) return; |
| |
| var foundName = jasmine.createSpy().andCallFake(function(result) { |
| var bFound = false; |
| try { |
| for (var i=0; i < result.length; i++) { |
| if (result[i].name.familyName == "Delete") { |
| bFound = true; |
| break; |
| } |
| } |
| } catch(e) { |
| return false; |
| } |
| return bFound; |
| }), |
| fail = jasmine.createSpy(), |
| test = jasmine.createSpy().andCallFake(function(savedContact) { |
| console.log('in test'); |
| // update so contact will get removed |
| gContactObj = savedContact; |
| // ---- |
| // Find asserts |
| // --- |
| var findWin = jasmine.createSpy().andCallFake(function(object) { |
| console.log('in findwin'); |
| expect(object instanceof Array).toBe(true); |
| expect(object.length >= 1).toBe(true); |
| expect(foundName(object)).toBe(true); |
| }), |
| findFail = jasmine.createSpy(), |
| obj = new ContactFindOptions(); |
| |
| obj.filter="Delete"; |
| obj.multiple=true; |
| |
| runs(function () { |
| navigator.contacts.find(["displayName", "name", "phoneNumbers", "emails"], findWin, findFail, obj); |
| }); |
| |
| waitsFor(function () { return foundName.wasCalled; }, "foundName not done", Tests.TEST_TIMEOUT); |
| |
| runs(function () { |
| expect(findFail).not.toHaveBeenCalled(); |
| expect(fail).not.toHaveBeenCalled(); |
| }); |
| }); |
| |
| runs(function () { |
| gContactObj = new Contact(); |
| gContactObj.name = new ContactName(); |
| gContactObj.name.familyName = "Delete"; |
| gContactObj.save(test, fail); |
| }); |
| |
| waitsFor(function () { return test.wasCalled; }, "test not done", Tests.TEST_TIMEOUT); |
| }); |
| }); |
| }); |
| |
| describe('create method', function() { |
| |
| it("contacts.spec.7 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() { |
| var bDay = new Date(1976, 7,4); |
| var obj = navigator.contacts.create({"displayName": "test name", "gender": "male", "note": "my note", "name": {"formatted": "Mr. Test Name"}, "emails": [{"value": "here@there.com"}, {"value": "there@here.com"}], "birthday": bDay}); |
| |
| expect(obj).toBeDefined(); |
| expect(obj.displayName).toBe('test name'); |
| expect(obj.note).toBe('my note'); |
| expect(obj.name.formatted).toBe('Mr. Test Name'); |
| expect(obj.emails.length).toBe(2); |
| expect(obj.emails[0].value).toBe('here@there.com'); |
| expect(obj.emails[1].value).toBe('there@here.com'); |
| expect(obj.nickname).toBe(null); |
| expect(obj.birthday).toBe(bDay); |
| }); |
| }); |
| |
| describe("Contact object", function () { |
| it("contacts.spec.9 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"); |
| expect(contact.displayName).toBe("b"); |
| expect(contact.name.formatted).toBe("a"); |
| expect(contact.nickname).toBe("c"); |
| expect(contact.phoneNumbers).toBeDefined(); |
| expect(contact.emails).toBeDefined(); |
| expect(contact.addresses).toBeDefined(); |
| expect(contact.ims).toBeDefined(); |
| expect(contact.organizations).toBeDefined(); |
| expect(contact.birthday).toBe("f"); |
| expect(contact.note).toBe("i"); |
| expect(contact.photos).toBeDefined(); |
| expect(contact.categories).toBeDefined(); |
| expect(contact.urls).toBeDefined(); |
| }); |
| |
| it("contacts.spec.10 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."); |
| expect(contactName.familyName).toBe("Last"); |
| expect(contactName.givenName).toBe("First"); |
| expect(contactName.middleName).toBe("Middle"); |
| expect(contactName.honorificPrefix).toBe("Dr."); |
| expect(contactName.honorificSuffix).toBe("Jr."); |
| }); |
| |
| it("contacts.spec.11 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() { |
| 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() { |
| var contactAddress = new ContactAddress(true, "home", "a","b","c","d","e","f"); |
| expect(contactAddress).toBeDefined(); |
| expect(contactAddress.pref).toBe(true); |
| expect(contactAddress.type).toBe("home"); |
| expect(contactAddress.formatted).toBe("a"); |
| expect(contactAddress.streetAddress).toBe("b"); |
| expect(contactAddress.locality).toBe("c"); |
| expect(contactAddress.region).toBe("d"); |
| expect(contactAddress.postalCode).toBe("e"); |
| expect(contactAddress.country).toBe("f"); |
| }); |
| |
| it("contacts.spec.14 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); |
| expect(contactOrg.type).toBe("home"); |
| expect(contactOrg.name).toBe("a"); |
| expect(contactOrg.department).toBe("b"); |
| expect(contactOrg.title).toBe("c"); |
| }); |
| |
| it("contacts.spec.15 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() { |
| 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() { |
| var contact = new Contact(); |
| contact.id=1; |
| contact.displayName="Test Name"; |
| contact.nickname="Testy"; |
| contact.gender="male"; |
| contact.note="note to be cloned"; |
| contact.name = new ContactName("Mr. Test Name"); |
| |
| var clonedContact = contact.clone(); |
| |
| expect(contact.id).toBe(1); |
| expect(clonedContact.id).toBe(null); |
| expect(clonedContact.displayName).toBe(contact.displayName); |
| expect(clonedContact.nickname).toBe(contact.nickname); |
| expect(clonedContact.gender).toBe(contact.gender); |
| expect(clonedContact.note).toBe(contact.note); |
| expect(clonedContact.name.formatted).toBe(contact.name.formatted); |
| expect(clonedContact.connected).toBe(contact.connected); |
| }); |
| |
| it("contacts.spec.18 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() { |
| var contact = new Contact(); |
| expect(contact.remove).toBeDefined(); |
| expect(typeof contact.remove).toBe('function'); |
| }); |
| }); |
| |
| describe('save method', function () { |
| it("contacts.spec.20 should be able to save a contact", function() { |
| |
| // this api requires manual user confirmation on WP7/8 so skip it |
| if (isWindowsPhone) return; |
| |
| var bDay = new Date(1976, 6,4); |
| gContactObj = navigator.contacts.create({"gender": "male", "note": "my note", "name": {"familyName": "Delete", "givenName": "Test"}, "emails": [{"value": "here@there.com"}, {"value": "there@here.com"}], "birthday": bDay}); |
| |
| var saveSuccess = jasmine.createSpy().andCallFake(function(obj) { |
| expect(obj).toBeDefined(); |
| if (cordova.platformId !== 'blackberry10') { |
| expect(obj.note).toBe('my note'); |
| } |
| expect(obj.name.familyName).toBe('Delete'); |
| expect(obj.name.givenName).toBe('Test'); |
| expect(obj.emails.length).toBe(2); |
| expect(obj.emails[0].value).toBe('here@there.com'); |
| 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; |
| }), |
| saveFail = jasmine.createSpy(); |
| |
| runs(function () { |
| gContactObj.save(saveSuccess, saveFail); |
| }); |
| |
| waitsFor(function () { return saveSuccess.wasCalled; }, "saveSuccess never called", Tests.TEST_TIMEOUT); |
| |
| runs(function () { |
| expect(saveFail).not.toHaveBeenCalled(); |
| }); |
| }); |
| // HACK: there is a reliance between the previous and next test. This is bad form. |
| it("contacts.spec.21 update a contact", function() { |
| |
| // this api requires manual user confirmation on WP7/8 so skip it |
| if (isWindowsPhone) return; |
| |
| expect(gContactObj).toBeDefined(); |
| |
| var bDay = new Date(1975, 5,4); |
| var noteText = "an UPDATED note"; |
| |
| var win = jasmine.createSpy().andCallFake(function(obj) { |
| expect(obj).toBeDefined(); |
| expect(obj.id).toBe(gContactObj.id); |
| if (cordova.platformId !== 'blackberry10') { |
| expect(obj.note).toBe(noteText); |
| } |
| expect(obj.birthday.toDateString()).toBe(bDay.toDateString()); |
| expect(obj.emails.length).toBe(1); |
| expect(obj.emails[0].value).toBe('here@there.com'); |
| removeContact(); // Clean up contact object |
| }), fail = jasmine.createSpy().andCallFake(removeContact); |
| |
| runs(function () { |
| // remove an email |
| gContactObj.emails[1].value = ""; |
| // change birthday |
| gContactObj.birthday = bDay; |
| // update note |
| gContactObj.note = noteText; |
| gContactObj.save(win, fail); |
| }); |
| |
| waitsFor(function () { return win.wasCalled; }, "saveSuccess never called", Tests.TEST_TIMEOUT); |
| |
| runs(function () { |
| expect(fail).not.toHaveBeenCalled(); |
| }); |
| }); |
| }); |
| |
| describe('Contact.remove method', function () { |
| afterEach(removeContact); |
| |
| it("contacts.spec.22 calling remove on a contact has an id of null should return ContactError.UNKNOWN_ERROR", function() { |
| var win = jasmine.createSpy(); |
| var fail = jasmine.createSpy().andCallFake(function(result) { |
| expect(result.code).toBe(ContactError.UNKNOWN_ERROR); |
| }); |
| |
| runs(function () { |
| var rmContact = new Contact(); |
| rmContact.remove(win, fail); |
| }); |
| |
| waitsFor(function () { return fail.wasCalled; }, Tests.TEST_TIMEOUT); |
| |
| runs(function () { |
| expect(win).not.toHaveBeenCalled(); |
| }); |
| }); |
| |
| it("contacts.spec.23 calling remove on a contact that does not exist should return ContactError.UNKNOWN_ERROR", function() { |
| var win = jasmine.createSpy(); |
| var fail = jasmine.createSpy().andCallFake(function(result) { |
| expect(result.code).toBe(ContactError.UNKNOWN_ERROR); |
| }); |
| |
| runs(function () { |
| var rmContact = new Contact(); |
| // this is a bit risky as some devices may have contact ids that large |
| var contact = new Contact("this string is supposed to be a unique identifier that will never show up on a device"); |
| contact.remove(win, fail); |
| }); |
| |
| waitsFor(function () { return fail.wasCalled; }, Tests.TEST_TIMEOUT); |
| |
| runs(function () { |
| expect(win).not.toHaveBeenCalled(); |
| }); |
| }); |
| }); |
| |
| describe("Round trip Contact tests (creating + save + delete + find).", function () { |
| 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() { |
| |
| // this api requires manual user confirmation on WP7/8 so skip it |
| if (isWindowsPhone) return; |
| |
| var done = false; |
| runs(function () { |
| gContactObj = new Contact(); |
| gContactObj.name = new ContactName(); |
| gContactObj.name.familyName = "DeleteMe"; |
| gContactObj.save(function(c_obj) { |
| var findWin = function(cs) { |
| expect(cs.length).toBe(1); |
| // update to have proper saved id |
| gContactObj = cs[0]; |
| gContactObj.remove(function() { |
| var findWinAgain = 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 = true; |
| }); |
| }; |
| 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 = function(e) { |
| throw("Failure callback invoked in navigator.contacts.find call, test failed."); |
| }; |
| var obj = new ContactFindOptions(); |
| obj.filter="DeleteMe"; |
| obj.multiple=true; |
| navigator.contacts.find(["displayName", "name", "phoneNumbers", "emails"], findWin, findFail, obj); |
| }, function(e) { |
| throw("Contact creation failed, error callback was invoked."); |
| }); |
| }); |
| |
| waitsFor(function () { return done; }, Tests.TEST_TIMEOUT); |
| }); |
| }); |
| |
| describe('ContactError interface', function () { |
| it("contacts.spec.25 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); |
| expect(ContactError.PENDING_OPERATION_ERROR).toBe(3); |
| expect(ContactError.IO_ERROR).toBe(4); |
| expect(ContactError.NOT_SUPPORTED_ERROR).toBe(5); |
| expect(ContactError.PERMISSION_DENIED_ERROR).toBe(20); |
| }); |
| }); |
| |
| describe("Contacts autotests cleanup", function () { |
| it("contacts.spec.26 Cleanup any DeleteMe contacts from Contacts tests.", function() { |
| var done = false; |
| var obj = new ContactFindOptions(); |
| obj.filter="DeleteMe"; |
| obj.multiple=true; |
| runs(function () { |
| var findSuccess = function (cs) { |
| var contactObj = new Contact(); |
| if (cs.length>0){ |
| contactObj = cs[0]; |
| contactObj.remove(function(){ |
| console.log("[CONTACTS CLEANUP] DeleteMe contact successfully removed"); |
| navigator.contacts.find(["displayName", "name", "phoneNumbers", "emails"], findSuccess, findFail, obj); |
| },function(){ |
| console.log("[CONTACTS CLEANUP ERROR]: failed to remove DeleteMe contact"); |
| }); |
| } else { |
| done = true; |
| } |
| }; |
| var findFail = function(e) { |
| throw("Failure callback invoked in navigator.contacts.find call, test failed."); |
| }; |
| navigator.contacts.find(["displayName", "name", "phoneNumbers", "emails"], findSuccess, findFail, obj); |
| }); |
| waitsFor(function () { return done; }, Tests.TEST_TIMEOUT); |
| }); |
| }); |
| |
| }); |