tor-browser

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

test_TaskbarTabsRegistry.js (11560B)


      1 /* vim: set ts=2 sw=2 sts=2 et : */
      2 /* This Source Code Form is subject to the terms of the Mozilla Public
      3 * License, v. 2.0. If a copy of the MPL was not distributed with this
      4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      5 
      6 "use strict";
      7 
      8 const { TaskbarTabsRegistry, TaskbarTabsRegistryStorage } =
      9  ChromeUtils.importESModule(
     10    "resource:///modules/taskbartabs/TaskbarTabsRegistry.sys.mjs"
     11  );
     12 
     13 function testFile() {
     14  let path = do_get_tempdir();
     15  let filename = Services.uuid.generateUUID().toString().slice(1, -1);
     16  path.append(filename + ".json");
     17 
     18  registerCleanupFunction(() => {
     19    if (path.exists()) {
     20      path.remove(false);
     21    }
     22  });
     23 
     24  return path;
     25 }
     26 
     27 add_task(async function test_create_taskbar_tab() {
     28  const url = Services.io.newURI("https://www.test.com/start");
     29  const userContextId = 0; // Default container.
     30 
     31  const registry = new TaskbarTabsRegistry();
     32 
     33  Assert.ok(
     34    !registry.findTaskbarTab(url, userContextId),
     35    "Initially, no Taskbar Tab should exist for the given URL and container."
     36  );
     37 
     38  const taskbarTab = createTaskbarTab(registry, url, userContextId);
     39 
     40  Assert.ok(taskbarTab, "Taskbar Tab should be created.");
     41  Assert.deepEqual(
     42    registry.findTaskbarTab(url, userContextId),
     43    taskbarTab,
     44    "Found Taskbar Tab should match the one returned on creation."
     45  );
     46 
     47  const secondUrl = Services.io.newURI("https://www.another-test.com/start");
     48  const secondUserContextId = 1;
     49  const secondTaskbarTab = createTaskbarTab(
     50    registry,
     51    secondUrl,
     52    secondUserContextId
     53  );
     54  Assert.deepEqual(
     55    registry.findTaskbarTab(url, userContextId),
     56    taskbarTab,
     57    "First Taskbar Tab created should still be present."
     58  );
     59  Assert.deepEqual(
     60    registry.findTaskbarTab(secondUrl, secondUserContextId),
     61    secondTaskbarTab,
     62    "Second Taskbar Tab created should still be present."
     63  );
     64 
     65  const repeated = registry.findOrCreateTaskbarTab(
     66    secondUrl,
     67    secondUserContextId
     68  );
     69  Assert.equal(
     70    repeated.created,
     71    false,
     72    "The existing taskbar tab should have been found, not created"
     73  );
     74  Assert.deepEqual(
     75    repeated.taskbarTab,
     76    secondTaskbarTab,
     77    "Should have found the second created Taskbar Tab instead of creating a new Taskbar Tab."
     78  );
     79 });
     80 
     81 add_task(async function test_remove_taskbar_tab() {
     82  const url = Services.io.newURI("https://www.test.com/start");
     83  const userContextId = 0;
     84 
     85  const registry = new TaskbarTabsRegistry();
     86  const taskbarTab = createTaskbarTab(registry, url, userContextId);
     87 
     88  Assert.deepEqual(
     89    registry.findTaskbarTab(url, userContextId),
     90    taskbarTab,
     91    "Taskbar Tab ID should match the ID returned on creation."
     92  );
     93 
     94  Assert.deepEqual(
     95    registry.removeTaskbarTab(taskbarTab.id),
     96    taskbarTab,
     97    "The removed Taskbar Tab was removed"
     98  );
     99 
    100  Assert.ok(
    101    !registry.findTaskbarTab(url, userContextId),
    102    "Taskbar Tab ID should be removed."
    103  );
    104 
    105  Assert.strictEqual(
    106    registry.removeTaskbarTab(taskbarTab.id),
    107    null,
    108    "Null was returned since no Taskbar Tab with that ID exists"
    109  );
    110 });
    111 
    112 add_task(async function test_container_mismatch() {
    113  const url = Services.io.newURI("https://www.test.com/start");
    114  const userContextId = 0;
    115  const mismatchedUserContextId = 1;
    116 
    117  const registry = new TaskbarTabsRegistry();
    118  const taskbarTab = createTaskbarTab(registry, url, userContextId);
    119  Assert.ok(taskbarTab, "Taskbar Tab ID should be created.");
    120 
    121  Assert.ok(
    122    !registry.findTaskbarTab(url, mismatchedUserContextId),
    123    `${mismatchedUserContextId} should not match a Taskbar Tab created with container ${userContextId}.`
    124  );
    125 });
    126 
    127 add_task(async function test_scope_navigable() {
    128  const url = Services.io.newURI("https://www.test.com/start");
    129  const validNavigationDomain = Services.io.newURI("https://www.test.com/test");
    130  const validNavigationSubdomain = Services.io.newURI(
    131    "https://www.subdomain.test.com"
    132  );
    133  const invalidNavigationDomain = Services.io.newURI(
    134    "https://www.anothertest.com"
    135  );
    136  const userContextId = 0;
    137 
    138  const registry = new TaskbarTabsRegistry();
    139  const taskbarTab = createTaskbarTab(registry, url, userContextId);
    140 
    141  Assert.ok(
    142    taskbarTab.isScopeNavigable(validNavigationDomain),
    143    `${validNavigationDomain} should be a valid navigation target for ${taskbarTab.scopes[0].hostname}.`
    144  );
    145 
    146  Assert.ok(
    147    taskbarTab.isScopeNavigable(validNavigationSubdomain),
    148    `${validNavigationSubdomain} should be a valid navigation target for ${taskbarTab.scopes[0].hostname}.`
    149  );
    150  Assert.ok(
    151    !taskbarTab.isScopeNavigable(invalidNavigationDomain),
    152    `${invalidNavigationDomain} should be a valid navigation target for ${taskbarTab.scopes[0].hostname}.`
    153  );
    154 });
    155 
    156 add_task(async function test_psl_navigable() {
    157  const url = Services.io.newURI("https://www.bmoattachments.org/start");
    158  const invalidNavigationPublicSuffixList = Services.io.newURI(
    159    "https://www.invalid.bmoattachments.org"
    160  );
    161  const userContextId = 0;
    162 
    163  const registry = new TaskbarTabsRegistry();
    164  const taskbarTab = createTaskbarTab(registry, url, userContextId);
    165 
    166  Assert.ok(
    167    !taskbarTab.isScopeNavigable(invalidNavigationPublicSuffixList),
    168    `bmoattachments.org is on the Public Suffix List, therefore ${invalidNavigationPublicSuffixList} should not be a valid navigation target for ${taskbarTab.scopes[0].hostname}.`
    169  );
    170 });
    171 
    172 add_task(async function test_save_and_load_consistency() {
    173  const url = Services.io.newURI("https://www.test.com/start");
    174  const userContextId = 0;
    175 
    176  let saveRegistry = new TaskbarTabsRegistry();
    177  const saveTaskbarTab = createTaskbarTab(saveRegistry, url, userContextId);
    178 
    179  let file = testFile();
    180  let storage = new TaskbarTabsRegistryStorage(saveRegistry, file);
    181  await storage.save();
    182 
    183  const loadRegistry = await TaskbarTabsRegistry.create({ loadFile: file });
    184  let loadTaskbarTab = loadRegistry.getTaskbarTab(saveTaskbarTab.id);
    185 
    186  Assert.deepEqual(
    187    saveTaskbarTab,
    188    loadTaskbarTab,
    189    "Taskbar Tab object should be identical after save and load."
    190  );
    191 });
    192 
    193 add_task(async function test_load_and_save_consistency() {
    194  const loadFile = do_get_file("test_taskbarTabs.json");
    195 
    196  // Test loading from the mock file
    197  const registry = await TaskbarTabsRegistry.create({ loadFile });
    198  Assert.equal(
    199    registry.findTaskbarTab(Services.io.newURI("https://www.test.com"), 0).id,
    200    "4186657a-0fe5-492a-af64-dc628c232c4c",
    201    "Taskbar Tab ID should match the one in the test JSON file."
    202  );
    203 
    204  // Test saving to a new file
    205  let file = testFile();
    206  let storage = new TaskbarTabsRegistryStorage(registry, file);
    207  await storage.save();
    208 
    209  // Verify the output against the original file on disk.
    210  const originalData = await IOUtils.readJSON(loadFile.path);
    211  const outputData = await IOUtils.readJSON(file.path);
    212 
    213  // Even though the Taskbar Tabs are kept in a map, entries remember their
    214  // insertion orders.
    215  Assert.deepEqual(
    216    outputData,
    217    originalData,
    218    "The in-memory mock file output should match the original file on disk."
    219  );
    220 });
    221 
    222 add_task(async function test_load_and_save_migrates_name() {
    223  const loadFile = do_get_file("test_taskbarTabs_nonames.json");
    224 
    225  const registry = await TaskbarTabsRegistry.create({ loadFile });
    226  const tt = registry.findTaskbarTab(
    227    Services.io.newURI("https://www.test.com"),
    228    0
    229  );
    230  equal(
    231    tt.id,
    232    "4186657a-0fe5-492a-af64-dc628c232c4c",
    233    "Taskbar Tab ID should match the one in the test JSON file."
    234  );
    235 
    236  equal(typeof tt.name, "string", "A name should be present in-memory.");
    237 
    238  let file = testFile();
    239  let storage = new TaskbarTabsRegistryStorage(registry, file);
    240  await storage.save();
    241 
    242  const outputData = await IOUtils.readJSON(file.path);
    243  equal(
    244    typeof outputData.taskbarTabs[0].name,
    245    "string",
    246    "A name should be saved to storage."
    247  );
    248 });
    249 
    250 add_task(async function test_guards_against_commandline_strings() {
    251  const validUrl = Services.io.newURI("https://www.test.com/start");
    252  const invalidUrl = "https://www.test.com/start";
    253 
    254  const validUserContextId = 0;
    255  const invalidUserContextId = "0";
    256 
    257  const registry = new TaskbarTabsRegistry();
    258 
    259  Assert.throws(
    260    () => registry.findTaskbarTab(invalidUrl, validUserContextId),
    261    /Invalid argument, `aUrl` should be instance of `nsIURL`/,
    262    "Should reject URLs provided as a string."
    263  );
    264  Assert.throws(
    265    () => registry.findTaskbarTab(validUrl, invalidUserContextId),
    266    /Invalid argument, `aUserContextId` should be type of `number`/,
    267    "Should reject userContextId provided as a string."
    268  );
    269 });
    270 
    271 add_task(async function test_guards_against_non_urls() {
    272  // about:blank is a URI, but not a URL.
    273  const url = Services.io.newURI("about:blank");
    274  const userContextId = 0;
    275 
    276  const registry = new TaskbarTabsRegistry();
    277 
    278  throws(
    279    () => createTaskbarTab(registry, url, userContextId),
    280    /Invalid argument, `aUrl` should be instance of `nsIURL`/,
    281    "Should reject URIs that are not URLs."
    282  );
    283 });
    284 
    285 add_task(async function test_patch_becomes_visible() {
    286  const registry = new TaskbarTabsRegistry();
    287  const tt = createTaskbarTab(
    288    registry,
    289    Services.io.newURI("https://www.test.com/start"),
    290    0
    291  );
    292 
    293  let called = 0;
    294  registry.on(TaskbarTabsRegistry.events.patched, () => {
    295    called += 1;
    296  });
    297 
    298  Assert.equal(
    299    tt.shortcutRelativePath,
    300    null,
    301    "Should not start with a relative path"
    302  );
    303  registry.patchTaskbarTab(tt, {
    304    shortcutRelativePath: "some\\path\\string.lnk",
    305  });
    306  Assert.equal(
    307    tt.shortcutRelativePath,
    308    "some\\path\\string.lnk",
    309    "Should update to the new value"
    310  );
    311  Assert.equal(called, 1, "Should emit the callback function once");
    312 });
    313 
    314 add_task(async function test_shortcutRelativePath_is_saved() {
    315  const registry = new TaskbarTabsRegistry();
    316  const tt = createTaskbarTab(
    317    registry,
    318    Services.io.newURI("https://www.test.com/start"),
    319    0
    320  );
    321 
    322  registry.patchTaskbarTab(tt, {
    323    shortcutRelativePath: "some\\path\\string.lnk",
    324  });
    325 
    326  const file = testFile();
    327  const storage = new TaskbarTabsRegistryStorage(registry, file);
    328  await storage.save();
    329 
    330  const data = await IOUtils.readJSON(file.path);
    331  Assert.equal(
    332    data.taskbarTabs[0].shortcutRelativePath,
    333    "some\\path\\string.lnk",
    334    "Shortcut relative path should be saved"
    335  );
    336 });
    337 
    338 add_task(async function test_multiple_match_longest_prefix() {
    339  const registry = new TaskbarTabsRegistry();
    340 
    341  const uriWithPrefix = prefix =>
    342    Services.io.newURI("https://example.com" + prefix);
    343 
    344  const createWithScope = uri =>
    345    createTaskbarTab(registry, uri, 0, {
    346      manifest: {
    347        scope: uri.spec,
    348      },
    349    });
    350  const find = prefix => registry.findTaskbarTab(uriWithPrefix(prefix), 0);
    351 
    352  // Register them in an arbitrary order.
    353  const ttAB = createWithScope(uriWithPrefix("/ab"));
    354  const ttA = createWithScope(uriWithPrefix("/a"));
    355  const ttABC = createWithScope(uriWithPrefix("/abc"));
    356  const ttABCD = createWithScope(uriWithPrefix("/abc/d/"));
    357 
    358  equal(find("/q"), null, "/q does not exist");
    359  equal(find("/a").id, ttA.id, "/a matches /a");
    360  equal(find("/az").id, ttA.id, "/a matches /az");
    361 
    362  equal(find("/ab").id, ttAB.id, "/ab matches /ab");
    363  equal(find("/abq").id, ttAB.id, "/abq matches /ab");
    364 
    365  equal(find("/abc").id, ttABC.id, "/abc matches /abc");
    366  equal(find("/abc/").id, ttABC.id, "/abc/ matches /abc");
    367  equal(find("/abc/d").id, ttABC.id, "/abc/d matches /abc (not /abc/d/)");
    368 
    369  equal(find("/abc/d/").id, ttABCD.id, "/abc/d/ matches /abc/d/");
    370  equal(find("/abc/d/efgh").id, ttABCD.id, "/abc/d/efgh matches /abc/d/");
    371 }).skip(); // TODO bug 2000948