gecko/dom/contacts/tests/test_contacts_getall.html

430 lines
12 KiB
HTML

<!DOCTYPE html>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=836519
-->
<head>
<title>Mozilla Bug 836519</title>
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=836519">Mozilla Bug 836519</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script class="testbody" type="text/javascript;version=1.7">
"use strict";
if (SpecialPowers.isMainProcess()) {
SpecialPowers.Cu.import("resource://gre/modules/ContactService.jsm");
SpecialPowers.Cu.import("resource://gre/modules/PermissionPromptHelper.jsm");
}
SpecialPowers.addPermission("contacts-write", true, document);
SpecialPowers.addPermission("contacts-read", true, document);
SpecialPowers.addPermission("contacts-create", true, document);
var isAndroid = (navigator.userAgent.indexOf("Android") !== -1);
var androidVersion = SpecialPowers.Cc['@mozilla.org/system-info;1']
.getService(SpecialPowers.Ci.nsIPropertyBag2)
.getProperty('version');
let adr1 = {
type: ["work"],
streetAddress: "street 1",
locality: "locality 1",
region: "region 1",
postalCode: "postal code 1",
countryName: "country 1"
};
let properties1 = {
name: ["Testname1 TestFamilyName"],
familyName: ["TestFamilyName","Wagner"],
givenName: ["Test1","Test2"],
nickname: ["nicktest"],
tel: [{type: ["work"], value: "123456", carrier: "testCarrier"} , {type: ["home", "fax"], value: "+9-876-5432"}],
adr: [adr1],
email: [{type: ["work"], value: "x@y.com"}]
};
function onFailure() {
ok(false, "in on Failure!");
next();
}
function checkStr(str1, str2, msg) {
if (str1 ^ str2) {
ok(false, "Expected both strings to be either present or absent");
return;
}
is(str1, str2, msg);
}
function checkStrArray(str1, str2, msg) {
function normalize_falsy(k, v) {
if (!v || v == "null" || v == "undefined") {
return "";
}
return v;
}
ise(JSON.stringify(str1, normalize_falsy), JSON.stringify(str2, normalize_falsy), msg);
}
function checkPref(pref1, pref2) {
// If on Android treat one preference as 0 and the other as undefined as matching
if (isAndroid) {
if ((!pref1 && pref2 == undefined) || (pref1 == undefined && !pref2)) {
pref1 = false;
pref2 = false;
}
}
ise(!!pref1, !!pref2, "Same pref");
}
function checkAddress(adr1, adr2) {
if (adr1 ^ adr2) {
ok(false, "Expected both adrs to be either present or absent");
return;
}
checkStrArray(adr1.type, adr2.type, "Same type");
checkStrArray(adr1.streetAddress, adr2.streetAddress, "Same streetAddress");
checkStrArray(adr1.locality, adr2.locality, "Same locality");
checkStrArray(adr1.region, adr2.region, "Same region");
checkStrArray(adr1.postalCode, adr2.postalCode, "Same postalCode");
checkStrArray(adr1.countryName, adr2.countryName, "Same countryName");
checkPref(adr1.pref, adr2.pref);
}
function checkField(field1, field2) {
if (field1 ^ field2) {
ok(false, "Expected both fields to be either present or absent");
return;
}
checkStrArray(field1.type, field2.type, "Same type");
checkStrArray(field1.value, field2.value, "Same value");
checkPref(field1.pref, field2.pref);
}
function checkTel(tel1, tel2) {
if (tel1 ^ tel2) {
ok(false, "Expected both tels to be either present or absent");
return;
}
checkField(tel1, tel2);
checkStrArray(tel1.carrier, tel2.carrier, "Same carrier");
}
function checkCategory(category1, category2) {
// Android adds contacts to the a default category. This should be removed from the
// results before comparing them
if (isAndroid) {
category1 = removeAndroidDefaultCategory(category1);
category2 = removeAndroidDefaultCategory(category2);
}
checkStrArray(category1, category2, "Same Category")
}
function removeAndroidDefaultCategory(category) {
if (!category) {
return category;
}
var result = [];
for (var i of category) {
// Some devices may return the full group name (prefixed with "System Group: ")
if (i != "My Contacts" && i != "System Group: My Contacts") {
result.push(i);
}
}
return result;
}
function checkArrayField(array1, array2, func, msg) {
if (!!array1 ^ !!array2) {
ok(false, "Expected both arrays to be either present or absent");
return;
}
if (!array1 && !array2) {
ok(true, msg);
return;
}
ise(array1.length, array2.length, "Same length");
for (var i = 0; i < array1.length; ++i) {
func(array1[i], array2[i], msg);
}
}
function checkContacts(contact1, contact2) {
if (!!contact1 ^ !!contact2) {
ok(false, "Expected both contacts to be either present or absent");
return;
}
checkStrArray(contact1.name, contact2.name, "Same name");
checkStrArray(contact1.honorificPrefix, contact2.honorificPrefix, "Same honorificPrefix");
checkStrArray(contact1.givenName, contact2.givenName, "Same givenName");
checkStrArray(contact1.additionalName, contact2.additionalName, "Same additionalName");
checkStrArray(contact1.familyName, contact2.familyName, "Same familyName");
checkStrArray(contact1.honorificSuffix, contact2.honorificSuffix, "Same honorificSuffix");
checkStrArray(contact1.nickname, contact2.nickname, "Same nickname");
checkCategory(contact1.category, contact2.category);
checkStrArray(contact1.org, contact2.org, "Same org");
checkStrArray(contact1.jobTitle, contact2.jobTitle, "Same jobTitle");
is(contact1.bday ? contact1.bday.valueOf() : null, contact2.bday ? contact2.bday.valueOf() : null, "Same birthday");
checkStrArray(contact1.note, contact2.note, "Same note");
is(contact1.anniversary ? contact1.anniversary.valueOf() : null , contact2.anniversary ? contact2.anniversary.valueOf() : null, "Same anniversary");
checkStr(contact1.sex, contact2.sex, "Same sex");
checkStr(contact1.genderIdentity, contact2.genderIdentity, "Same genderIdentity");
checkStrArray(contact1.key, contact2.key, "Same key");
checkArrayField(contact1.adr, contact2.adr, checkAddress, "Same adr");
checkArrayField(contact1.tel, contact2.tel, checkTel, "Same tel");
checkArrayField(contact1.email, contact2.email, checkField, "Same email");
checkArrayField(contact1.url, contact2.url, checkField, "Same url");
checkArrayField(contact1.impp, contact2.impp, checkField, "Same impp");
}
function clearDatabase() {
ok(true, "Clearing database");
req = mozContacts.clear();
req.onsuccess = function() {
ok(true, "Cleared the database");
next();
};
req.onerror = onFailure;
}
function addContacts() {
ok(true, "Adding 40 contacts");
for (let i = 0; i < 39; ++i) {
properties1.familyName[0] = "Testname" + (i < 10 ? "0" + i : i);
properties1.name = [properties1.givenName[0] + " " + properties1.familyName[0]];
createResult1 = new mozContact(properties1);
req = mozContacts.save(createResult1);
req.onsuccess = function() {
ok(createResult1.id, "The contact now has an ID.");
};
req.onerror = onFailure;
};
properties1.familyName[0] = "Testname39";
properties1.name = [properties1.givenName[0] + " Testname39"];
createResult1 = new mozContact(properties1);
req = mozContacts.save(createResult1);
req.onsuccess = function() {
ok(createResult1.id, "The contact now has an ID.");
checkStrArray(createResult1.name, properties1.name, "Same Name");
next();
};
req.onerror = onFailure;
}
let createResult1;
let index = 0;
let req;
let mozContacts = window.navigator.mozContacts;
function getOne(msg) {
return function() {
ok(true, msg || "Retrieving one contact with getAll");
req = mozContacts.getAll({});
let count = 0;
req.onsuccess = function(event) {
ok(true, "on success");
if (req.result) {
ok(true, "result is valid");
count++;
req.continue();
} else {
is(count, 1, "last contact - only one contact returned");
next();
}
};
req.onerror = onFailure;
};
}
function getAll(msg) {
return function() {
ok(true, msg || "Retrieving 40 contacts with getAll");
req = mozContacts.getAll({
sortBy: "familyName",
sortOrder: "ascending"
});
let count = 0;
let result;
let props;
req.onsuccess = function(event) {
if (req.result) {
ok(true, "result is valid");
result = req.result;
properties1.familyName[0] = "Testname" + (count < 10 ? "0" + count : count);
is(result.familyName[0], properties1.familyName[0], "Same familyName");
count++;
req.continue();
} else {
is(count, 40, "last contact - 40 contacts returned");
next();
}
};
req.onerror = onFailure;
}
}
let steps = [
function start() {
SpecialPowers.Cc["@mozilla.org/tools/profiler;1"].getService(SpecialPowers.Ci.nsIProfiler).AddMarker("GETALL_START");
next();
},
clearDatabase,
addContacts,
function() {
ok(true, "Delete the current contact while iterating");
req = mozContacts.getAll({});
let count = 0;
let previousId = null;
req.onsuccess = function() {
if (req.result) {
ok(true, "on success");
if (previousId) {
isnot(previousId, req.result.id, "different contacts returned");
}
previousId = req.result.id;
count++;
let delReq = mozContacts.remove(req.result);
delReq.onsuccess = function() {
ok(true, "deleted current contact");
req.continue();
};
} else {
is(count, 40, "returned 40 contacts");
next();
}
};
},
clearDatabase,
addContacts,
function() {
ok(true, "Iterating through the contact list inside a cursor callback");
let count1 = 0, count2 = 0;
let req1 = mozContacts.getAll({});
let req2;
req1.onsuccess = function() {
if (count1 == 0) {
count1++;
req2 = mozContacts.getAll({});
req2.onsuccess = function() {
if (req2.result) {
count2++;
req2.continue();
} else {
is(count2, 40, "inner cursor returned 40 contacts");
req1.continue();
}
};
} else {
if (req1.result) {
count1++;
req1.continue();
} else {
is(count1, 40, "outer cursor returned 40 contacts");
next();
}
}
};
},
clearDatabase,
addContacts,
function() {
ok(true, "20 concurrent cursors");
const NUM_CURSORS = 20;
let completed = 0;
for (let i = 0; i < NUM_CURSORS; ++i) {
mozContacts.getAll({}).onsuccess = (function(i) {
let count = 0;
return function(event) {
let req = event.target;
if (req.result) {
count++;
req.continue();
} else {
is(count, 40, "cursor " + i + " returned 40 contacts");
if (++completed == NUM_CURSORS) {
next();
}
}
};
})(i);
}
},
clearDatabase,
addContacts,
function() {
if (!SpecialPowers.isMainProcess()) {
// We stop calling continue() intentionally here to see if the cursor gets
// cleaned up properly in the parent.
ok(true, "Leaking a cursor");
req = mozContacts.getAll({
sortBy: "familyName",
sortOrder: "ascending"
});
req.onsuccess = function(event) {
next();
};
req.onerror = onFailure;
} else {
next();
}
},
clearDatabase,
function() {
ok(true, "all done!\n");
SpecialPowers.Cc["@mozilla.org/tools/profiler;1"].getService(SpecialPowers.Ci.nsIProfiler).AddMarker("GETALL_END");
SimpleTest.finish();
}
];
function next() {
ok(true, "Begin!");
if (index >= steps.length) {
ok(false, "Shouldn't get here!");
return;
}
let i = index++;
try {
steps[i]();
} catch(ex) {
ok(false, "Caught exception", ex);
}
}
// Skip tests on Android < 4.0 due to test failures on tbpl (see bugs 897924 & 888891)
if (!isAndroid || androidVersion >= 14) {
SimpleTest.waitForExplicitFinish();
addLoadEvent(next);
} else {
ok(true, "Skip tests on Android < 4.0 (bugs 897924 & 888891");
}
</script>
</pre>
</body>
</html>