UNPKG

25.7 kBJavaScriptView Raw
1/*
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20*/
21
22exports.defineAutoTests = function () {
23 // global to store a contact so it doesn't have to be created or retrieved multiple times
24 // all of the setup/teardown test methods can reference the following variables to make sure to do the right cleanup
25 var gContactObj = null,
26 gContactId = null,
27 isWindowsPhone8 = cordova.platformId == 'windowsphone',
28 isWindows = (cordova.platformId === "windows") || (cordova.platformId === "windows8"),
29 isWindowsPhone81 = isWindows && WinJS.Utilities.isPhone;
30 var fail = function(done) {
31 expect(true).toBe(false);
32 done();
33 };
34
35
36 var removeContact = function(){
37 if (gContactObj) {
38 gContactObj.remove(function(){},function(){
39 console.log("[CONTACTS ERROR]: removeContact cleanup method failed to clean up test artifacts.");
40 });
41 gContactObj = null;
42 }
43 };
44
45 describe("Contacts (navigator.contacts)", function () {
46 it("contacts.spec.1 should exist", function() {
47 expect(navigator.contacts).toBeDefined();
48 });
49 it("contacts.spec.2 should contain a find function", function() {
50 expect(navigator.contacts.find).toBeDefined();
51 expect(typeof navigator.contacts.find).toBe('function');
52 });
53 describe("find method", function() {
54 it("contacts.spec.3 success callback should be called with an array", function(done) {
55 // Find method is not supported on Windows platform
56 if (isWindows && !isWindowsPhone81) {
57 pending();
58 return;
59 }
60 var win = function(result) {
61 expect(result).toBeDefined();
62 expect(result instanceof Array).toBe(true);
63 done();
64 },
65 obj = new ContactFindOptions();
66
67 obj.filter="";
68 obj.multiple=true;
69 navigator.contacts.find(["displayName", "name", "phoneNumbers", "emails"], win, fail.bind(null, done), obj);
70 });
71 it("success callback should be called with an array, even if partial ContactFindOptions specified", function (done) {
72 // Find method is not supported on Windows platform
73 if (isWindows && !isWindowsPhone81) {
74 pending();
75 return;
76 }
77 var win = function (result) {
78 expect(result).toBeDefined();
79 expect(result instanceof Array).toBe(true);
80 done();
81 };
82
83 navigator.contacts.find(["displayName", "name", "phoneNumbers", "emails"], win, fail.bind(null, done),
84 { multiple: true });
85 });
86 it("contacts.spec.4 should throw an exception if success callback is empty", function() {
87 var obj = new ContactFindOptions();
88 obj.filter="";
89 obj.multiple=true;
90
91 expect(function () {
92 navigator.contacts.find(["displayName", "name", "emails", "phoneNumbers"], null, fail.bind(null, done), obj);
93 }).toThrow();
94 });
95 it("contacts.spec.5 error callback should be called when no fields are specified", function(done) {
96 var win = fail, // we don't want this to be called
97 error = function(result) {
98 expect(result).toBeDefined();
99 expect(result.code).toBe(ContactError.INVALID_ARGUMENT_ERROR);
100 done();
101 },
102 obj = new ContactFindOptions();
103
104 obj.filter="";
105 obj.multiple=true;
106 navigator.contacts.find([], win, error, obj);
107 });
108 describe("with newly-created contact", function () {
109
110 afterEach(removeContact);
111
112 it("contacts.spec.6 should be able to find a contact by name", function (done) {
113 // Find method is not supported on Windows Store apps.
114 // also this test will be skipped for Windows Phone 8.1 because function "save" not supported on WP8.1
115 if (isWindows) {
116 pending();
117 return;
118 }
119
120 if (isWindowsPhone8) {
121 done();
122 return;
123 }
124 var foundName = function(result) {
125 var bFound = false;
126 try {
127 for (var i=0; i < result.length; i++) {
128 if (result[i].name.familyName == "Delete") {
129 bFound = true;
130 break;
131 }
132 }
133 } catch(e) {
134 return false;
135 }
136 return bFound;
137 },
138 test = function(savedContact) {
139 // update so contact will get removed
140 gContactObj = savedContact;
141 // ----
142 // Find asserts
143 // ---
144 var findWin = function(object) {
145 console.log('in findwin');
146 expect(object instanceof Array).toBe(true);
147 expect(object.length >= 1).toBe(true);
148 expect(foundName(object)).toBe(true);
149 done();
150 },
151 findFail = fail,
152 obj = new ContactFindOptions();
153
154 obj.filter="Delete";
155 obj.multiple=true;
156
157 navigator.contacts.find(["displayName", "name", "phoneNumbers", "emails"], findWin, findFail.bind(null, done), obj);
158 };
159
160 gContactObj = new Contact();
161 gContactObj.name = new ContactName();
162 gContactObj.name.familyName = "Delete";
163 gContactObj.save(test, fail.bind(null, done));
164 });
165 });
166
167 });
168 describe('create method', function() {
169 it("contacts.spec.1 should exist", function() {
170 expect(navigator.contacts.create).toBeDefined();
171 expect(typeof navigator.contacts.create).toBe('function');
172 });
173 it("contacts.spec.8 should return a Contact object", function() {
174 var bDay = new Date(1976, 7,4);
175 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});
176
177 expect(obj).toBeDefined();
178 expect(obj.displayName).toBe('test name');
179 expect(obj.note).toBe('my note');
180 expect(obj.name.formatted).toBe('Mr. Test Name');
181 expect(obj.emails.length).toBe(2);
182 expect(obj.emails[0].value).toBe('here@there.com');
183 expect(obj.emails[1].value).toBe('there@here.com');
184 expect(obj.nickname).toBe(null);
185 expect(obj.birthday).toBe(bDay);
186 });
187 });
188
189 describe("Contact object", function () {
190 it("contacts.spec.9 should be able to create instance", function() {
191 var contact = new Contact("a", "b", new ContactName("a", "b", "c", "d", "e", "f"), "c", [], [], [], [], [], "f", "i",
192 [], [], []);
193 expect(contact).toBeDefined();
194 expect(contact.id).toBe("a");
195 expect(contact.displayName).toBe("b");
196 expect(contact.name.formatted).toBe("a");
197 expect(contact.nickname).toBe("c");
198 expect(contact.phoneNumbers).toBeDefined();
199 expect(contact.emails).toBeDefined();
200 expect(contact.addresses).toBeDefined();
201 expect(contact.ims).toBeDefined();
202 expect(contact.organizations).toBeDefined();
203 expect(contact.birthday).toBe("f");
204 expect(contact.note).toBe("i");
205 expect(contact.photos).toBeDefined();
206 expect(contact.categories).toBeDefined();
207 expect(contact.urls).toBeDefined();
208 });
209 it("contacts.spec.10 should be able to define a ContactName object", function() {
210 var contactName = new ContactName("Dr. First Last Jr.", "Last", "First", "Middle", "Dr.", "Jr.");
211 expect(contactName).toBeDefined();
212 expect(contactName.formatted).toBe("Dr. First Last Jr.");
213 expect(contactName.familyName).toBe("Last");
214 expect(contactName.givenName).toBe("First");
215 expect(contactName.middleName).toBe("Middle");
216 expect(contactName.honorificPrefix).toBe("Dr.");
217 expect(contactName.honorificSuffix).toBe("Jr.");
218 });
219 it("contacts.spec.11 should be able to define a ContactField object", function() {
220 var contactField = new ContactField("home", "8005551212", true);
221 expect(contactField).toBeDefined();
222 expect(contactField.type).toBe("home");
223 expect(contactField.value).toBe("8005551212");
224 expect(contactField.pref).toBe(true);
225 });
226 it("contacts.spec.12 ContactField object should coerce type and value properties to strings", function() {
227 var contactField = new ContactField(12345678, 12345678, true);
228 expect(contactField.type).toBe("12345678");
229 expect(contactField.value).toBe("12345678");
230 });
231 it("contacts.spec.13 should be able to define a ContactAddress object", function() {
232 var contactAddress = new ContactAddress(true, "home", "a","b","c","d","e","f");
233 expect(contactAddress).toBeDefined();
234 expect(contactAddress.pref).toBe(true);
235 expect(contactAddress.type).toBe("home");
236 expect(contactAddress.formatted).toBe("a");
237 expect(contactAddress.streetAddress).toBe("b");
238 expect(contactAddress.locality).toBe("c");
239 expect(contactAddress.region).toBe("d");
240 expect(contactAddress.postalCode).toBe("e");
241 expect(contactAddress.country).toBe("f");
242 });
243 it("contacts.spec.14 should be able to define a ContactOrganization object", function() {
244 var contactOrg = new ContactOrganization(true, "home", "a","b","c","d","e","f","g");
245 expect(contactOrg).toBeDefined();
246 expect(contactOrg.pref).toBe(true);
247 expect(contactOrg.type).toBe("home");
248 expect(contactOrg.name).toBe("a");
249 expect(contactOrg.department).toBe("b");
250 expect(contactOrg.title).toBe("c");
251 });
252 it("contacts.spec.15 should be able to define a ContactFindOptions object", function() {
253 var contactFindOptions = new ContactFindOptions("a", true, "b");
254 expect(contactFindOptions).toBeDefined();
255 expect(contactFindOptions.filter).toBe("a");
256 expect(contactFindOptions.multiple).toBe(true);
257 });
258 it("contacts.spec.16 should contain a clone function", function() {
259 var contact = new Contact();
260 expect(contact.clone).toBeDefined();
261 expect(typeof contact.clone).toBe('function');
262 });
263 it("contacts.spec.17 clone function should make deep copy of Contact Object", function() {
264 var contact = new Contact();
265 contact.id=1;
266 contact.displayName="Test Name";
267 contact.nickname="Testy";
268 contact.gender="male";
269 contact.note="note to be cloned";
270 contact.name = new ContactName("Mr. Test Name");
271
272 var clonedContact = contact.clone();
273
274 expect(contact.id).toBe(1);
275 expect(clonedContact.id).toBe(null);
276 expect(clonedContact.displayName).toBe(contact.displayName);
277 expect(clonedContact.nickname).toBe(contact.nickname);
278 expect(clonedContact.gender).toBe(contact.gender);
279 expect(clonedContact.note).toBe(contact.note);
280 expect(clonedContact.name.formatted).toBe(contact.name.formatted);
281 expect(clonedContact.connected).toBe(contact.connected);
282 });
283 it("contacts.spec.18 should contain a save function", function() {
284 var contact = new Contact();
285 expect(contact.save).toBeDefined();
286 expect(typeof contact.save).toBe('function');
287 });
288 it("contacts.spec.19 should contain a remove function", function() {
289 var contact = new Contact();
290 expect(contact.remove).toBeDefined();
291 expect(typeof contact.remove).toBe('function');
292 });
293 });
294 describe('save method', function () {
295 it("contacts.spec.20 should be able to save a contact", function (done) {
296 // Save method is not supported on Windows platform
297 if (isWindows) {
298 pending();
299 return;
300 }
301 if (isWindowsPhone8) {
302 done();
303 return;
304 }
305 var bDay = new Date(1976, 6,4);
306 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});
307
308 var saveSuccess = function(obj) {
309 expect(obj).toBeDefined();
310 expect(obj.note).toBe('my note');
311 expect(obj.name.familyName).toBe('Delete');
312 expect(obj.name.givenName).toBe('Test');
313 expect(obj.emails.length).toBe(2);
314 expect(obj.emails[0].value).toBe('here@there.com');
315 expect(obj.emails[1].value).toBe('there@here.com');
316 expect(obj.birthday.toDateString()).toBe(bDay.toDateString());
317 expect(obj.addresses).toBe(null);
318 // must store returned object in order to have id for update test below
319 gContactObj = obj;
320 done();
321 },
322 saveFail = fail;
323
324 gContactObj.save(saveSuccess, saveFail);
325 });
326 // HACK: there is a reliance between the previous and next test. This is bad form.
327 it("contacts.spec.21 update a contact", function (done) {
328 // Save method is not supported on Windows platform
329 if (isWindows) {
330 pending();
331 return;
332 }
333 if (isWindowsPhone8) {
334 done();
335 return;
336 }
337 expect(gContactObj).toBeDefined();
338
339 var bDay = new Date(1975, 5,4);
340 var noteText = "an UPDATED note";
341
342 var win = function(obj) {
343 expect(obj).toBeDefined();
344 expect(obj.id).toBe(gContactObj.id);
345 expect(obj.note).toBe(noteText);
346 expect(obj.birthday.toDateString()).toBe(bDay.toDateString());
347 expect(obj.emails.length).toBe(1);
348 expect(obj.emails[0].value).toBe('here@there.com');
349 removeContact(); // Clean up contact object
350 done();
351 }, fail = function() { removeContact(); fail(done); };
352
353 // remove an email
354 gContactObj.emails[1].value = "";
355 // change birthday
356 gContactObj.birthday = bDay;
357 // update note
358 gContactObj.note = noteText;
359 gContactObj.save(win, fail);
360 });
361 });
362 describe('Contact.remove method', function (done) {
363 afterEach(removeContact);
364
365 it("contacts.spec.22 calling remove on a contact has an id of null should return ContactError.UNKNOWN_ERROR", function(done) {
366 var win = function() {};
367 var fail = function(result) {
368 expect(result.code).toBe(ContactError.UNKNOWN_ERROR);
369 done();
370 };
371
372 var rmContact = new Contact();
373 rmContact.remove(win, fail);
374 });
375 it("contacts.spec.23 calling remove on a contact that does not exist should return ContactError.UNKNOWN_ERROR", function(done) {
376 var rmWin = fail;
377 var rmFail = function(result) {
378 expect(result.code).toBe(ContactError.UNKNOWN_ERROR);
379 done();
380 };
381
382 var rmContact = new Contact();
383 // this is a bit risky as some devices may have contact ids that large
384 var contact = new Contact("this string is supposed to be a unique identifier that will never show up on a device");
385 contact.remove(rmWin, rmFail);
386 });
387 });
388 describe("Round trip Contact tests (creating + save + delete + find).", function () {
389 afterEach(removeContact);
390
391 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) {
392 // Save method is not supported on Windows platform
393 if (isWindows) {
394 pending();
395 return;
396 }
397 if (isWindowsPhone8) {
398 done();
399 return;
400 }
401 gContactObj = new Contact();
402 gContactObj.name = new ContactName();
403 gContactObj.name.familyName = "DeleteMe";
404 gContactObj.save(function(c_obj) {
405 var findWin = function(cs) {
406 expect(cs.length).toBe(1);
407 // update to have proper saved id
408 gContactObj = cs[0];
409 gContactObj.remove(function() {
410 var findWinAgain = function(seas) {
411 expect(seas.length).toBe(0);
412 gContactObj.remove(function() {
413 throw("success callback called after non-existent Contact object called remove(). Test failed.");
414 }, function(e) {
415 expect(e.code).toBe(ContactError.UNKNOWN_ERROR);
416 done();
417 });
418 };
419 var findFailAgain = function(e) {
420 throw("find error callback invoked after delete, test failed.");
421 };
422 var obj = new ContactFindOptions();
423 obj.filter="DeleteMe";
424 obj.multiple=true;
425 navigator.contacts.find(["displayName", "name", "phoneNumbers", "emails"], findWinAgain, findFailAgain, obj);
426 }, function(e) {
427 throw("Newly created contact's remove function invoked error callback. Test failed.");
428 });
429 };
430 var findFail = fail;
431 var obj = new ContactFindOptions();
432 obj.filter="DeleteMe";
433 obj.multiple=true;
434 navigator.contacts.find(["displayName", "name", "phoneNumbers", "emails"], findWin, findFail, obj);
435 }, fail);
436 });
437 });
438 describe('ContactError interface', function () {
439 it("contacts.spec.25 ContactError constants should be defined", function() {
440 expect(ContactError.UNKNOWN_ERROR).toBe(0);
441 expect(ContactError.INVALID_ARGUMENT_ERROR).toBe(1);
442 expect(ContactError.TIMEOUT_ERROR).toBe(2);
443 expect(ContactError.PENDING_OPERATION_ERROR).toBe(3);
444 expect(ContactError.IO_ERROR).toBe(4);
445 expect(ContactError.NOT_SUPPORTED_ERROR).toBe(5);
446 expect(ContactError.PERMISSION_DENIED_ERROR).toBe(20);
447 });
448 });
449 });
450};
451
452/******************************************************************************/
453/******************************************************************************/
454/******************************************************************************/
455
456exports.defineManualTests = function (contentEl, createActionButton) {
457 function getContacts() {
458 var results = document.getElementById('contact_results');
459 obj = new ContactFindOptions();
460 // show all contacts, so don't filter
461 obj.multiple = true;
462 navigator.contacts.find(
463 ["displayName", "name", "phoneNumbers", "emails", "urls", "note"],
464 function (contacts) {
465 var s = "";
466 if (contacts.length == 0) {
467 s = "No contacts found";
468 }
469 else {
470 s = "Number of contacts: " + contacts.length + "<br><table width='100%'><tr><th>Name</th><td>Phone</td><td>Email</td></tr>";
471 for (var i = 0; i < contacts.length; i++) {
472 var contact = contacts[i];
473 s = s + "<tr><td>" + contact.name.formatted + "</td><td>";
474 if (contact.phoneNumbers && contact.phoneNumbers.length > 0) {
475 s = s + contact.phoneNumbers[0].value;
476 }
477 s = s + "</td><td>"
478 if (contact.emails && contact.emails.length > 0) {
479 s = s + contact.emails[0].value;
480 }
481 s = s + "</td></tr>";
482 }
483 s = s + "</table>";
484 }
485
486 results.innerHTML = s;
487 },
488 function (e) {
489 if (e.code === ContactError.NOT_SUPPORTED_ERROR) {
490 results.innerHTML = "Searching for contacts is not supported.";
491 } else {
492 results.innerHTML = "Search failed: error " + e.code;
493 }
494 },
495 obj);
496 }
497
498 function addContact() {
499 var results = document.getElementById('contact_results');
500
501 try {
502 var contact = navigator.contacts.create({ "displayName": "Dooney Evans" });
503 var contactName = {
504 formatted: "Dooney Evans",
505 familyName: "Evans",
506 givenName: "Dooney",
507 middleName: ""
508 };
509
510 contact.name = contactName;
511
512 var phoneNumbers = [1];
513 phoneNumbers[0] = new ContactField('work', '512-555-1234', true);
514 contact.phoneNumbers = phoneNumbers;
515
516 contact.save(
517 function () { results.innerHTML = "Contact saved."; },
518 function (e) {
519 if (e.code === ContactError.NOT_SUPPORTED_ERROR) {
520 results.innerHTML = "Saving contacts not supported.";
521 } else {
522 results.innerHTML = "Contact save failed: error " + e.code;
523 }
524 }
525 );
526 }
527 catch (e) {
528 alert(e);
529 }
530 }
531
532 /******************************************************************************/
533
534 contentEl.innerHTML = '<div id="info">' +
535 '<b>Results:</b><br>' +
536 '<div id="contact_results"></div>' +
537 '</div>' +
538 '<div id="get_contacts"></div>' +
539 'Expected result: Status box will show number of contacts and list them. May be empty on a fresh device until you click Add.' +
540 '</p> <div id="add_contact"></div>' +
541 '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';
542
543 createActionButton("Get phone's contacts", function () {
544 getContacts();
545 }, 'get_contacts');
546
547 createActionButton("Add a new contact 'Dooney Evans'", function () {
548 addContact();
549 }, 'add_contact');
550};