tor-browser

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

browser_resources_unwatch_early.js (3819B)


      1 /* Any copyright is dedicated to the Public Domain.
      2   http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 "use strict";
      5 
      6 // Test that calling unwatchResources before watchResources could resolve still
      7 // removes watcher entries correctly.
      8 
      9 const ResourceCommand = require("resource://devtools/shared/commands/resource/resource-command.js");
     10 
     11 const TEST_URI = "data:text/html;charset=utf-8,";
     12 
     13 add_task(async function () {
     14  const tab = await addTab(TEST_URI);
     15 
     16  const { client, resourceCommand, targetCommand } =
     17    await initResourceCommand(tab);
     18  const { CONSOLE_MESSAGE, ROOT_NODE } = resourceCommand.TYPES;
     19 
     20  info("Use console.log in the content page");
     21  await logInTab(tab, "msg-1");
     22 
     23  info("Call watchResources with various configurations");
     24 
     25  // Watcher 1 only watches for CONSOLE_MESSAGE.
     26  // For this call site, unwatchResource will be called before onAvailable has
     27  // resolved.
     28  const messages1 = [];
     29  const onAvailable1 = createMessageCallback(messages1);
     30  const onWatcher1Ready = resourceCommand.watchResources([CONSOLE_MESSAGE], {
     31    onAvailable: onAvailable1,
     32  });
     33  resourceCommand.unwatchResources([CONSOLE_MESSAGE], {
     34    onAvailable: onAvailable1,
     35  });
     36 
     37  info(
     38    "Calling unwatchResources for an already unregistered callback should be a no-op"
     39  );
     40  // and more importantly, it should not throw
     41  resourceCommand.unwatchResources([CONSOLE_MESSAGE], {
     42    onAvailable: onAvailable1,
     43  });
     44 
     45  // Watcher 2 watches for CONSOLE_MESSAGE & another resource (ROOT_NODE).
     46  // Again unwatchResource will be called before onAvailable has resolved.
     47  // But unwatchResource is only called for CONSOLE_MESSAGE, not for ROOT_NODE.
     48  const messages2 = [];
     49  const onAvailable2 = createMessageCallback(messages2);
     50  const onWatcher2Ready = resourceCommand.watchResources(
     51    [CONSOLE_MESSAGE, ROOT_NODE],
     52    {
     53      onAvailable: onAvailable2,
     54    }
     55  );
     56  resourceCommand.unwatchResources([CONSOLE_MESSAGE], {
     57    onAvailable: onAvailable2,
     58  });
     59 
     60  // Watcher 3 watches for CONSOLE_MESSAGE, but we will not call unwatchResource
     61  // explicitly for it before the end of test. Used as a reference.
     62  const messages3 = [];
     63  const onAvailable3 = createMessageCallback(messages3);
     64  const onWatcher3Ready = resourceCommand.watchResources([CONSOLE_MESSAGE], {
     65    onAvailable: onAvailable3,
     66  });
     67 
     68  info("Call unwatchResources for CONSOLE_MESSAGE on watcher 1 & 2");
     69 
     70  info("Wait for all watchers `watchResources` to resolve");
     71  await Promise.all([onWatcher1Ready, onWatcher2Ready, onWatcher3Ready]);
     72  ok(!hasMessage(messages1, "msg-1"), "Watcher 1 did not receive msg-1");
     73  ok(!hasMessage(messages2, "msg-1"), "Watcher 2 did not receive msg-1");
     74  ok(hasMessage(messages3, "msg-1"), "Watcher 3 received msg-1");
     75 
     76  info("Log a new message");
     77  await logInTab(tab, "msg-2");
     78 
     79  info("Wait until watcher 3 received the new message");
     80  await waitUntil(() => hasMessage(messages3, "msg-2"));
     81 
     82  ok(!hasMessage(messages1, "msg-2"), "Watcher 1 did not receive msg-2");
     83  ok(!hasMessage(messages2, "msg-2"), "Watcher 2 did not receive msg-2");
     84 
     85  targetCommand.destroy();
     86  await client.close();
     87 });
     88 
     89 function logInTab(tab, message) {
     90  return ContentTask.spawn(tab.linkedBrowser, message, function (_message) {
     91    content.console.log(_message);
     92  });
     93 }
     94 
     95 function hasMessage(messageResources, text) {
     96  return messageResources.find(resource => resource.arguments[0] === text);
     97 }
     98 
     99 // All resource command callbacks share the same pattern here: they add all
    100 // console message resources to a provided `messages` array.
    101 function createMessageCallback(messages) {
    102  const { CONSOLE_MESSAGE } = ResourceCommand.TYPES;
    103  return async resources => {
    104    for (const resource of resources) {
    105      if (resource.resourceType === CONSOLE_MESSAGE) {
    106        messages.push(resource);
    107      }
    108    }
    109  };
    110 }