dom/contacts/tests/shared.js

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/dom/contacts/tests/shared.js	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,504 @@
     1.4 +"use strict";
     1.5 +
     1.6 +// Fix the environment to run Contacts tests
     1.7 +if (SpecialPowers.isMainProcess()) {
     1.8 +  SpecialPowers.Cu.import("resource://gre/modules/ContactService.jsm");
     1.9 +  SpecialPowers.Cu.import("resource://gre/modules/PermissionPromptHelper.jsm");
    1.10 +}
    1.11 +
    1.12 +SpecialPowers.addPermission("contacts-write", true, document);
    1.13 +SpecialPowers.addPermission("contacts-read", true, document);
    1.14 +SpecialPowers.addPermission("contacts-create", true, document);
    1.15 +
    1.16 +// Some helpful global vars
    1.17 +var isAndroid = (navigator.userAgent.indexOf("Android") !== -1);
    1.18 +
    1.19 +var defaultOptions = {
    1.20 +  sortBy: "givenName",
    1.21 +};
    1.22 +
    1.23 +var mozContacts = navigator.mozContacts;
    1.24 +
    1.25 +// To test sorting
    1.26 +var c1 = {
    1.27 +  name: ["a a"],
    1.28 +  familyName: ["a"],
    1.29 +  givenName: ["a"],
    1.30 +};
    1.31 +
    1.32 +var c2 = {
    1.33 +  name: ["b b"],
    1.34 +  familyName: ["b"],
    1.35 +  givenName: ["b"],
    1.36 +};
    1.37 +
    1.38 +var c3 = {
    1.39 +  name: ["c c", "a a", "b b"],
    1.40 +  familyName: ["c","a","b"],
    1.41 +  givenName: ["c","a","b"],
    1.42 +};
    1.43 +
    1.44 +var c4 = {
    1.45 +  name: ["c c", "a a", "c c"],
    1.46 +  familyName: ["c","a","c"],
    1.47 +  givenName: ["c","a","c"],
    1.48 +};
    1.49 +
    1.50 +var c5 = {
    1.51 +  familyName: [],
    1.52 +  givenName: [],
    1.53 +};
    1.54 +
    1.55 +var c6 = {
    1.56 +  name: ["e"],
    1.57 +  familyName: ["e","e","e"],
    1.58 +  givenName: ["e","e","e"],
    1.59 +};
    1.60 +
    1.61 +var c7 = {
    1.62 +  name: ["e"],
    1.63 +  familyName: ["e","e","e"],
    1.64 +  givenName: ["e","e","e"],
    1.65 +};
    1.66 +
    1.67 +var c8 = {
    1.68 +  name: ["e"],
    1.69 +  familyName: ["e","e","e"],
    1.70 +  givenName: ["e","e","e"],
    1.71 +};
    1.72 +
    1.73 +var adr1 = {
    1.74 +  type: ["work"],
    1.75 +  streetAddress: "street 1",
    1.76 +  locality: "locality 1",
    1.77 +  region: "region 1",
    1.78 +  postalCode: "postal code 1",
    1.79 +  countryName: "country 1"
    1.80 +};
    1.81 +
    1.82 +var adr2 = {
    1.83 +  type: ["home, fax"],
    1.84 +  streetAddress: "street2",
    1.85 +  locality: "locality2",
    1.86 +  region: "region2",
    1.87 +  postalCode: "postal code2",
    1.88 +  countryName: "country2"
    1.89 +};
    1.90 +
    1.91 +var properties1 = {
    1.92 +  // please keep capital letters at the start of these names
    1.93 +  name: ["Test1 TestFamilyName", "Test2 Wagner"],
    1.94 +  familyName: ["TestFamilyName","Wagner"],
    1.95 +  givenName: ["Test1","Test2"],
    1.96 +  phoneticFamilyName: ["TestphoneticFamilyName1","TestphoneticFamilyName2"],
    1.97 +  phoneticGivenName: ["TestphoneticGivenName1","TestphoneticGivenName2"],
    1.98 +  nickname: ["nicktest"],
    1.99 +  tel: [{type: ["work"], value: "123456", carrier: "testCarrier"} , {type: ["home", "fax"], value: "+55 (31) 9876-3456"}, {type: ["home"], value: "+49 451 491934"}],
   1.100 +  adr: [adr1],
   1.101 +  email: [{type: ["work"], value: "x@y.com"}],
   1.102 +};
   1.103 +
   1.104 +var properties2 = {
   1.105 +  name: ["dummyHonorificPrefix dummyGivenName dummyFamilyName dummyHonorificSuffix", "dummyHonorificPrefix2"],
   1.106 +  familyName: ["dummyFamilyName"],
   1.107 +  givenName: ["dummyGivenName"],
   1.108 +  phoneticFamilyName: ["dummyphoneticFamilyName"],
   1.109 +  phoneticGivenName: ["dummyphoneticGivenName"],
   1.110 +  honorificPrefix: ["dummyHonorificPrefix","dummyHonorificPrefix2"],
   1.111 +  honorificSuffix: ["dummyHonorificSuffix"],
   1.112 +  additionalName: ["dummyadditionalName"],
   1.113 +  nickname: ["dummyNickname"],
   1.114 +  tel: [{type: ["test"], value: "7932012345", carrier: "myCarrier", pref: 1},{type: ["home", "custom"], value: "7932012346", pref: 0}],
   1.115 +  email: [{type: ["test"], value: "a@b.c"}, {value: "b@c.d", pref: 1}],
   1.116 +  adr: [adr1, adr2],
   1.117 +  impp: [{type: ["aim"], value:"im1", pref: 1}, {value: "im2"}],
   1.118 +  org: ["org1", "org2"],
   1.119 +  jobTitle: ["boss", "superboss"],
   1.120 +  note: ["test note"],
   1.121 +  category: ["cat1", "cat2"],
   1.122 +  url: [{type: ["work", "work2"], value: "www.1.com", pref: 1}, {value:"www2.com"}],
   1.123 +  bday: new Date("1980, 12, 01"),
   1.124 +  anniversary: new Date("2000, 12, 01"),
   1.125 +  sex: "male",
   1.126 +  genderIdentity: "test",
   1.127 +  key: ["ERPJ394GJJWEVJ0349GJ09W3H4FG0WFW80VHW3408GH30WGH348G3H"]
   1.128 +};
   1.129 +
   1.130 +// To test sorting(CJK)
   1.131 +var c9 = {
   1.132 +  phoneticFamilyName: ["a"],
   1.133 +  phoneticGivenName: ["a"],
   1.134 +};
   1.135 +
   1.136 +var c10 = {
   1.137 +  phoneticFamilyName: ["b"],
   1.138 +  phoneticGivenName: ["b"],
   1.139 +};
   1.140 +
   1.141 +var c11 = {
   1.142 +  phoneticFamilyName: ["c","a","b"],
   1.143 +  phoneticGivenName: ["c","a","b"],
   1.144 +};
   1.145 +
   1.146 +var c12 = {
   1.147 +  phoneticFamilyName: ["c","a","c"],
   1.148 +  phoneticGivenName: ["c","a","c"],
   1.149 +};
   1.150 +
   1.151 +var c13 = {
   1.152 +  phoneticFamilyName: [],
   1.153 +  phoneticGivenName: [],
   1.154 +};
   1.155 +
   1.156 +var c14 = {
   1.157 +  phoneticFamilyName: ["e","e","e"],
   1.158 +  phoneticGivenName: ["e","e","e"],
   1.159 +};
   1.160 +
   1.161 +var c15 = {
   1.162 +  phoneticFamilyName: ["e","e","e"],
   1.163 +  phoneticGivenName: ["e","e","e"],
   1.164 +};
   1.165 +
   1.166 +var c16 = {
   1.167 +  phoneticFamilyName: ["e","e","e"],
   1.168 +  phoneticGivenName: ["e","e","e"],
   1.169 +};
   1.170 +
   1.171 +var properties3 = {
   1.172 +  // please keep capital letters at the start of these names
   1.173 +  name: ["Taro Yamada", "Ichiro Suzuki"],
   1.174 +  familyName: ["Yamada","Suzuki"],
   1.175 +  givenName: ["Taro","Ichiro"],
   1.176 +  phoneticFamilyName: ["TestPhoneticFamilyYamada","TestPhoneticFamilySuzuki"],
   1.177 +  phoneticGivenName: ["TestPhoneticGivenTaro","TestPhoneticGivenIchiro"],
   1.178 +  nickname: ["phoneticNicktest"],
   1.179 +  tel: [{type: ["work"], value: "123456", carrier: "testCarrier"} , {type: ["home", "fax"], value: "+55 (31) 9876-3456"}, {type: ["home"], value: "+49 451 491934"}],
   1.180 +  adr: [adr1],
   1.181 +  email: [{type: ["work"], value: "x@y.com"}],
   1.182 +};
   1.183 +
   1.184 +var properties4 = {
   1.185 +  name: ["dummyHonorificPrefix dummyTaro dummyYamada dummyHonorificSuffix", "dummyHonorificPrefix2"],
   1.186 +  familyName: ["dummyYamada"],
   1.187 +  givenName: ["dummyTaro"],
   1.188 +  phoneticFamilyName: ["dummyTestPhoneticFamilyYamada"],
   1.189 +  phoneticGivenName: ["dummyTestPhoneticGivenTaro"],
   1.190 +  honorificPrefix: ["dummyPhoneticHonorificPrefix","dummyPhoneticHonorificPrefix2"],
   1.191 +  honorificSuffix: ["dummyPhoneticHonorificSuffix"],
   1.192 +  additionalName: ["dummyPhoneticAdditionalName"],
   1.193 +  nickname: ["dummyPhoneticNickname"],
   1.194 +  tel: [{type: ["test"], value: "7932012345", carrier: "myCarrier", pref: 1},{type: ["home", "custom"], value: "7932012346", pref: 0}],
   1.195 +  email: [{type: ["test"], value: "a@b.c"}, {value: "b@c.d", pref: 1}],
   1.196 +  adr: [adr1, adr2],
   1.197 +  impp: [{type: ["aim"], value:"im1", pref: 1}, {value: "im2"}],
   1.198 +  org: ["org1", "org2"],
   1.199 +  jobTitle: ["boss", "superboss"],
   1.200 +  note: ["test note"],
   1.201 +  category: ["cat1", "cat2"],
   1.202 +  url: [{type: ["work", "work2"], value: "www.1.com", pref: 1}, {value:"www2.com"}],
   1.203 +  bday: new Date("1980, 12, 01"),
   1.204 +  anniversary: new Date("2000, 12, 01"),
   1.205 +  sex: "male",
   1.206 +  genderIdentity: "test",
   1.207 +  key: ["ERPJ394GJJWEVJ0349GJ09W3H4FG0WFW80VHW3408GH30WGH348G3H"]
   1.208 +};
   1.209 +
   1.210 +var sample_id1;
   1.211 +var sample_id2;
   1.212 +
   1.213 +var createResult1;
   1.214 +var createResult2;
   1.215 +
   1.216 +var findResult1;
   1.217 +var findResult2;
   1.218 +
   1.219 +// DOMRequest helper functions
   1.220 +function onUnwantedSuccess() {
   1.221 +  ok(false, "onUnwantedSuccess: shouldn't get here");
   1.222 +}
   1.223 +
   1.224 +function onFailure() {
   1.225 +  ok(false, "in on Failure!");
   1.226 +  next();
   1.227 +}
   1.228 +
   1.229 +// Validation helper functions
   1.230 +function checkStr(str1, str2, msg) {
   1.231 +  if (str1 ^ str2) {
   1.232 +    ok(false, "Expected both strings to be either present or absent");
   1.233 +    return;
   1.234 +  }
   1.235 +  if (!str1 || str1 == "null") {
   1.236 +    str1 = null;
   1.237 +  }
   1.238 +  if (!str2 || str2 == "null") {
   1.239 +    str2 = null;
   1.240 +  }
   1.241 +  is(str1, str2, msg);
   1.242 +}
   1.243 +
   1.244 +function checkStrArray(str1, str2, msg) {
   1.245 +  function normalize_falsy(v) {
   1.246 +    if (!v || v == "null" || v == "undefined") {
   1.247 +      return "";
   1.248 +    }
   1.249 +    return v;
   1.250 +  }
   1.251 +  function optArray(val) {
   1.252 +    return Array.isArray(val) ? val : [val];
   1.253 +  }
   1.254 +  str1 = optArray(str1).map(normalize_falsy).filter(v => v != "");
   1.255 +  str2 = optArray(str2).map(normalize_falsy).filter(v => v != "");
   1.256 +  ise(JSON.stringify(str1), JSON.stringify(str2), msg);
   1.257 +}
   1.258 +
   1.259 +function checkPref(pref1, pref2) {
   1.260 +  // If on Android treat one preference as 0 and the other as undefined as matching
   1.261 +  if (isAndroid) {
   1.262 +    if ((!pref1 && pref2 == undefined) || (pref1 == undefined && !pref2)) {
   1.263 +      pref1 = false;
   1.264 +      pref2 = false;
   1.265 +    }
   1.266 +  }
   1.267 +  ise(!!pref1, !!pref2, "Same pref");
   1.268 +}
   1.269 +
   1.270 +function checkAddress(adr1, adr2) {
   1.271 +  if (adr1 ^ adr2) {
   1.272 +    ok(false, "Expected both adrs to be either present or absent");
   1.273 +    return;
   1.274 +  }
   1.275 +  checkStrArray(adr1.type, adr2.type, "Same type");
   1.276 +  checkStr(adr1.streetAddress, adr2.streetAddress, "Same streetAddress");
   1.277 +  checkStr(adr1.locality, adr2.locality, "Same locality");
   1.278 +  checkStr(adr1.region, adr2.region, "Same region");
   1.279 +  checkStr(adr1.postalCode, adr2.postalCode, "Same postalCode");
   1.280 +  checkStr(adr1.countryName, adr2.countryName, "Same countryName");
   1.281 +  checkPref(adr1.pref, adr2.pref);
   1.282 +}
   1.283 +
   1.284 +function checkField(field1, field2) {
   1.285 +  if (field1 ^ field2) {
   1.286 +    ok(false, "Expected both fields to be either present or absent");
   1.287 +    return;
   1.288 +  }
   1.289 +  checkStrArray(field1.type, field2.type, "Same type");
   1.290 +  checkStr(field1.value, field2.value, "Same value");
   1.291 +  checkPref(field1.pref, field2.pref);
   1.292 +}
   1.293 +
   1.294 +function checkTel(tel1, tel2) {
   1.295 +  if (tel1 ^ tel2) {
   1.296 +    ok(false, "Expected both tels to be either present or absent");
   1.297 +    return;
   1.298 +  }
   1.299 +  checkField(tel1, tel2);
   1.300 +  checkStr(tel1.carrier, tel2.carrier, "Same carrier");
   1.301 +}
   1.302 +
   1.303 +function checkCategory(category1, category2) {
   1.304 +  // Android adds contacts to the a default category. This should be removed from the
   1.305 +  // results before comparing them
   1.306 +  if (isAndroid) {
   1.307 +    category1 = removeAndroidDefaultCategory(category1);
   1.308 +    category2 = removeAndroidDefaultCategory(category2);
   1.309 +  }
   1.310 +  checkStrArray(category1, category2, "Same Category")
   1.311 +}
   1.312 +
   1.313 +function removeAndroidDefaultCategory(category) {
   1.314 +  if (!category) {
   1.315 +    return category;
   1.316 +  }
   1.317 +
   1.318 +  var result = [];
   1.319 +
   1.320 +  for (var i of category) {
   1.321 +    // Some devices may return the full group name (prefixed with "System Group: ")
   1.322 +    if (i != "My Contacts" && i != "System Group: My Contacts") {
   1.323 +      result.push(i);
   1.324 +    }
   1.325 +  }
   1.326 +
   1.327 +  return result;
   1.328 +}
   1.329 +
   1.330 +function checkArrayField(array1, array2, func, msg) {
   1.331 +  if (!!array1 ^ !!array2) {
   1.332 +    ok(false, "Expected both arrays to be either present or absent: " + JSON.stringify(array1) + " vs. " + JSON.stringify(array2) + ". (" + msg + ")");
   1.333 +    return;
   1.334 +  }
   1.335 +  if (!array1 && !array2)  {
   1.336 +    ok(true, msg);
   1.337 +    return;
   1.338 +  }
   1.339 +  ise(array1.length, array2.length, "Same length");
   1.340 +  for (var i = 0; i < array1.length; ++i) {
   1.341 +    func(array1[i], array2[i], msg);
   1.342 +  }
   1.343 +}
   1.344 +
   1.345 +function checkContacts(contact1, contact2) {
   1.346 +  if (!!contact1 ^ !!contact2) {
   1.347 +    ok(false, "Expected both contacts to be either present or absent");
   1.348 +    return;
   1.349 +  }
   1.350 +  checkStrArray(contact1.name, contact2.name, "Same name");
   1.351 +  checkStrArray(contact1.honorificPrefix, contact2.honorificPrefix, "Same honorificPrefix");
   1.352 +  checkStrArray(contact1.givenName, contact2.givenName, "Same givenName");
   1.353 +  checkStrArray(contact1.additionalName, contact2.additionalName, "Same additionalName");
   1.354 +  checkStrArray(contact1.familyName, contact2.familyName, "Same familyName");
   1.355 +  checkStrArray(contact1.phoneticFamilyName, contact2.phoneticFamilyName, "Same phoneticFamilyName");
   1.356 +  checkStrArray(contact1.phoneticGivenName, contact2.phoneticGivenName, "Same phoneticGivenName");
   1.357 +  checkStrArray(contact1.honorificSuffix, contact2.honorificSuffix, "Same honorificSuffix");
   1.358 +  checkStrArray(contact1.nickname, contact2.nickname, "Same nickname");
   1.359 +  checkCategory(contact1.category, contact2.category);
   1.360 +  checkStrArray(contact1.org, contact2.org, "Same org");
   1.361 +  checkStrArray(contact1.jobTitle, contact2.jobTitle, "Same jobTitle");
   1.362 +  is(contact1.bday ? contact1.bday.valueOf() : null, contact2.bday ? contact2.bday.valueOf() : null, "Same birthday");
   1.363 +  checkStrArray(contact1.note, contact2.note, "Same note");
   1.364 +  is(contact1.anniversary ? contact1.anniversary.valueOf() : null , contact2.anniversary ? contact2.anniversary.valueOf() : null, "Same anniversary");
   1.365 +  checkStr(contact1.sex, contact2.sex, "Same sex");
   1.366 +  checkStr(contact1.genderIdentity, contact2.genderIdentity, "Same genderIdentity");
   1.367 +  checkStrArray(contact1.key, contact2.key, "Same key");
   1.368 +
   1.369 +  checkArrayField(contact1.adr, contact2.adr, checkAddress, "Same adr");
   1.370 +  checkArrayField(contact1.tel, contact2.tel, checkTel, "Same tel");
   1.371 +  checkArrayField(contact1.email, contact2.email, checkField, "Same email");
   1.372 +  checkArrayField(contact1.url, contact2.url, checkField, "Same url");
   1.373 +  checkArrayField(contact1.impp, contact2.impp, checkField, "Same impp");
   1.374 +}
   1.375 +
   1.376 +function addContacts() {
   1.377 +  ok(true, "Adding 40 contacts");
   1.378 +  let req;
   1.379 +  for (let i = 0; i < 39; ++i) {
   1.380 +    properties1.familyName[0] = "Testname" + (i < 10 ? "0" + i : i);
   1.381 +    properties1.name = [properties1.givenName[0] + " " + properties1.familyName[0]];
   1.382 +    createResult1 = new mozContact(properties1);
   1.383 +    req = mozContacts.save(createResult1);
   1.384 +    req.onsuccess = function() {
   1.385 +      ok(createResult1.id, "The contact now has an ID.");
   1.386 +    };
   1.387 +    req.onerror = onFailure;
   1.388 +  };
   1.389 +  properties1.familyName[0] = "Testname39";
   1.390 +  properties1.name = [properties1.givenName[0] + " Testname39"];
   1.391 +  createResult1 = new mozContact(properties1);
   1.392 +  req = mozContacts.save(createResult1);
   1.393 +  req.onsuccess = function() {
   1.394 +    ok(createResult1.id, "The contact now has an ID.");
   1.395 +    checkStrArray(createResult1.name, properties1.name, "Same Name");
   1.396 +    next();
   1.397 +  };
   1.398 +  req.onerror = onFailure;
   1.399 +}
   1.400 +
   1.401 +function getOne(msg) {
   1.402 +  return function() {
   1.403 +    ok(true, msg || "Retrieving one contact with getAll");
   1.404 +    let req = mozContacts.getAll({});
   1.405 +
   1.406 +    let count = 0;
   1.407 +    req.onsuccess = function(event) {
   1.408 +      ok(true, "on success");
   1.409 +      if (req.result) {
   1.410 +        ok(true, "result is valid");
   1.411 +        count++;
   1.412 +        req.continue();
   1.413 +      } else {
   1.414 +        is(count, 1, "last contact - only one contact returned");
   1.415 +        next();
   1.416 +      }
   1.417 +    };
   1.418 +    req.onerror = onFailure;
   1.419 +  };
   1.420 +}
   1.421 +
   1.422 +function getAll(msg) {
   1.423 +  return function() {
   1.424 +    ok(true, msg || "Retrieving 40 contacts with getAll");
   1.425 +    let req = mozContacts.getAll({
   1.426 +      sortBy: "familyName",
   1.427 +      sortOrder: "ascending"
   1.428 +    });
   1.429 +    let count = 0;
   1.430 +    let result;
   1.431 +    let props;
   1.432 +    req.onsuccess = function(event) {
   1.433 +      if (req.result) {
   1.434 +        ok(true, "result is valid");
   1.435 +        result = req.result;
   1.436 +        properties1.familyName[0] = "Testname" + (count < 10 ? "0" + count : count);
   1.437 +        is(result.familyName[0], properties1.familyName[0], "Same familyName");
   1.438 +        count++;
   1.439 +        req.continue();
   1.440 +      } else {
   1.441 +        is(count, 40, "last contact - 40 contacts returned");
   1.442 +        next();
   1.443 +      }
   1.444 +    };
   1.445 +    req.onerror = onFailure;
   1.446 +  };
   1.447 +}
   1.448 +
   1.449 +function clearTemps() {
   1.450 +  sample_id1 = null;
   1.451 +  sample_id2 = null;
   1.452 +  createResult1 = null;
   1.453 +  createResult2 = null;
   1.454 +  findResult1 = null;
   1.455 +  findResult2 = null;
   1.456 +}
   1.457 +
   1.458 +function clearDatabase() {
   1.459 +  ok(true, "Deleting database");
   1.460 +  let req = mozContacts.clear()
   1.461 +  req.onsuccess = function () {
   1.462 +    ok(true, "Deleted the database");
   1.463 +    next();
   1.464 +  }
   1.465 +  req.onerror = onFailure;
   1.466 +}
   1.467 +
   1.468 +function checkCount(count, msg, then) {
   1.469 +  var request = mozContacts.getCount();
   1.470 +  request.onsuccess = function(e) {
   1.471 +    is(e.target.result, count, msg);
   1.472 +    then();
   1.473 +  };
   1.474 +  request.onerror = onFailure;
   1.475 +}
   1.476 +
   1.477 +// Helper functions to run tests
   1.478 +var index = 0;
   1.479 +
   1.480 +function next() {
   1.481 +  info("Step " + index);
   1.482 +  if (index >= steps.length) {
   1.483 +    ok(false, "Shouldn't get here!");
   1.484 +    return;
   1.485 +  }
   1.486 +  try {
   1.487 +    var i = index++;
   1.488 +    steps[i]();
   1.489 +  } catch(ex) {
   1.490 +    ok(false, "Caught exception", ex);
   1.491 +  }
   1.492 +}
   1.493 +
   1.494 +SimpleTest.waitForExplicitFinish();
   1.495 +
   1.496 +function start_tests() {
   1.497 +  // Skip tests on Android < 4.0 due to test failures on tbpl (see bugs 897924 & 888891)
   1.498 +  let androidVersion = SpecialPowers.Cc['@mozilla.org/system-info;1']
   1.499 +                                    .getService(SpecialPowers.Ci.nsIPropertyBag2)
   1.500 +                                    .getProperty('version');
   1.501 +  if (!isAndroid || androidVersion >= 14) {
   1.502 +    next();
   1.503 +  } else {
   1.504 +    ok(true, "Skip tests on Android < 4.0 (bugs 897924 & 888891");
   1.505 +    SimpleTest.finish();
   1.506 +  }
   1.507 +}

mercurial