tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

contacts-select.https.window.js (6992B)


      1 // META: script=/resources/test-only-api.js
      2 // META: script=/resources/testdriver.js
      3 // META: script=/resources/testdriver-vendor.js
      4 // META: script=resources/helpers.js
      5 'use strict';
      6 
      7 // Verifies that |func|, when invoked, throws a TypeError exception.
      8 async function expectTypeError(func) {
      9  try {
     10    await func();
     11  } catch (e) {
     12    assert_equals(e.name, 'TypeError');
     13    return;
     14  }
     15 
     16  assert_unreached('expected a TypeError, but none was thrown');
     17 }
     18 
     19 promise_test(async () => {
     20  try {
     21    await navigator.contacts.select(['name']);
     22    assert_unreached('expected a SecurityError, but none was thrown');
     23  } catch (e) {
     24    assert_equals(e.name, 'SecurityError');
     25  }
     26 }, 'The Contact API requires a user gesture')
     27 
     28 contactsTestWithUserActivation(async (test, setSelectedContacts) => {
     29  // At least one property must be provided.
     30  await expectTypeError(() => navigator.contacts.select());
     31  await expectTypeError(() => navigator.contacts.select([]));
     32 
     33  // Per WebIDL parsing, no invalid values may be provided.
     34  await expectTypeError(() =>
     35      navigator.contacts.select(['']));
     36  await expectTypeError(() =>
     37      navigator.contacts.select(['foo']));
     38  await expectTypeError(() =>
     39      navigator.contacts.select(['name', 'photo']));
     40 
     41 }, 'The Contact API requires valid properties to be provided');
     42 
     43 contactsTestWithUserActivation(async (test, setSelectedContacts) => {
     44  // Returns a NULL result, indicating that no results are available.
     45  setSelectedContacts(null);
     46 
     47  await expectTypeError(() => navigator.contacts.select(['name']));
     48 
     49 }, 'The Contact API can fail when the selector cannot be opened');
     50 
     51 contactsTestWithUserActivation(async (test, setSelectedContacts) => {
     52  setSelectedContacts([]);
     53 
     54  const properties = await navigator.contacts.getProperties();
     55  assert_true(properties.length > 0);
     56 
     57  // Requesting the available properties should not fail.
     58  await navigator.contacts.select(properties);
     59 
     60 }, 'Supported contact properties are exposed.');
     61 
     62 contactsTestWithUserActivation(async (test, setSelectedContacts) => {
     63  const dwightAddress = {
     64    country: 'US',
     65    city: 'Scranton',
     66    addressLine: ['Schrute Farms'],
     67  };
     68  const michaelIcons = [new Blob('image binary data'.split(''), {type: 'image/test'})];
     69 
     70  // Returns two contacts with all information available.
     71  setSelectedContacts([
     72      { name: ['Dwight Schrute'], email: ['dwight@schrutefarmsbnb.com'], tel: ['000-0000'], address: [dwightAddress] },
     73      { name: ['Michael Scott', 'Prison Mike'], email: ['michael@dundermifflin.com'], icon: michaelIcons },
     74  ]);
     75 
     76  let results = await navigator.contacts.select(['name', 'email', 'icon', 'tel', 'address'], { multiple: true });
     77  assert_equals(results.length, 2);
     78  results = results.sort((c1, c2) => JSON.stringify(c1) < JSON.stringify(c2) ? -1 : 1);
     79 
     80  {
     81    const michael = results[0];
     82 
     83    assert_own_property(michael, 'name');
     84    assert_own_property(michael, 'email');
     85    assert_own_property(michael, 'tel');
     86    assert_own_property(michael, 'address');
     87    assert_own_property(michael, 'icon');
     88 
     89    assert_array_equals(michael.name, ['Michael Scott', 'Prison Mike']);
     90    assert_array_equals(michael.email, ['michael@dundermifflin.com']);
     91    assert_array_equals(michael.tel, []);
     92    assert_array_equals(michael.address, []);
     93 
     94    assert_equals(michael.icon.length, michaelIcons.length);
     95    assert_equals(michael.icon[0].type, michaelIcons[0].type);
     96    assert_equals(michael.icon[0].size, michaelIcons[0].size);
     97    assert_equals(await michael.icon[0].text(), await michaelIcons[0].text());
     98  }
     99 
    100  {
    101    const dwight = results[1];
    102    assert_own_property(dwight, 'name');
    103    assert_own_property(dwight, 'email');
    104    assert_own_property(dwight, 'tel');
    105    assert_own_property(dwight, 'address');
    106    assert_own_property(dwight, 'icon');
    107 
    108    assert_array_equals(dwight.name, ['Dwight Schrute']);
    109    assert_array_equals(dwight.email, ['dwight@schrutefarmsbnb.com']);
    110    assert_array_equals(dwight.tel, ['000-0000']);
    111    assert_array_equals(dwight.icon, []);
    112 
    113    assert_equals(dwight.address.length, 1);
    114    const selectedAddress = dwight.address[0];
    115    assert_object_equals({
    116      country: selectedAddress.country,
    117      city: selectedAddress.city,
    118      addressLine: selectedAddress.addressLine,
    119    }, dwightAddress);
    120  }
    121 }, 'The Contact API correctly returns ContactInfo entries');
    122 
    123 contactsTestWithUserActivation(async (test, setSelectedContacts) => {
    124  // Returns two contacts with all information available.
    125  setSelectedContacts([
    126      { name: ['Dwight Schrute'], email: ['dwight@schrutefarmsbnb.com'], tel: ['000-0000'] },
    127      { name: ['Michael Scott', 'Prison Mike'], email: ['michael@dundermifflin.com'] },
    128  ]);
    129 
    130  const results = await navigator.contacts.select(['name', 'email', 'tel']);
    131  assert_equals(results.length, 1);
    132 
    133 }, 'Only one contact is returned if `multiple` is not set.');
    134 
    135 contactsTestWithUserActivation(async (test, setSelectedContacts) => {
    136  // Returns partial information since no e-mail addresses are requested.
    137  setSelectedContacts([{ name: ['Creed'], email: ['creedthoughts@www.creedthoughts.gov.www'] }]);
    138 
    139  const results = await navigator.contacts.select(['name']);
    140 
    141  assert_equals(results.length, 1);
    142 
    143  {
    144    const creed = results[0];
    145 
    146    assert_array_equals(creed.name, ['Creed']);
    147    assert_equals(creed.email, undefined);
    148    assert_equals(creed.tel, undefined);
    149  }
    150 }, 'The Contact API does not include fields that were not requested');
    151 
    152 contactsTestWithUserActivation(async (test, setSelectedContacts) => {
    153  // Returns partial information since no e-mail addresses are requested.
    154  setSelectedContacts([{ name: ['Kelly'] }]);
    155 
    156  // First request should work.
    157  const promise1 = new Promise((resolve, reject) => {
    158    navigator.contacts.select(['name']).then(resolve)
    159                                       .catch(e => reject(e.message));
    160  });
    161 
    162  // Second request should fail (since the first one didn't complete yet).
    163  const promise2 = new Promise((resolve, reject) => {
    164    navigator.contacts.select(['name']).then(contacts => reject('This was supposed to fail'))
    165                                       .catch(e => resolve(e.name));
    166  });
    167 
    168  const results = await Promise.all([promise1, promise2]);
    169  const contacts = results[0];
    170  assert_equals(contacts.length, 1);
    171  const contact = contacts[0];
    172  assert_equals(contact.name[0], 'Kelly');
    173  assert_equals(results[1], 'InvalidStateError');
    174 
    175 }, 'The Contact API cannot be used again until the first operation is complete.');
    176 
    177 contactsTestWithUserActivation(async (test, setSelectedContacts) => {
    178  const iframe = document.createElement('iframe');
    179  document.body.appendChild(iframe);
    180  iframe.src = 'resources/non-main-frame-select.html';
    181  await new Promise(resolve => window.addEventListener('message', event => resolve(event.data)))
    182      .then(data => assert_equals(data.errorMsg, 'InvalidStateError'))
    183      .finally(() => iframe.remove())
    184 
    185 }, 'Test contacts.select() throws an InvalidStateError in a sub-frame');