tor-browser

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

test_SessionData.js (17190B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
      3 * You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 const { ContextDescriptorType } = ChromeUtils.importESModule(
      6  "chrome://remote/content/shared/messagehandler/MessageHandler.sys.mjs"
      7 );
      8 const { RootMessageHandler } = ChromeUtils.importESModule(
      9  "chrome://remote/content/shared/messagehandler/RootMessageHandler.sys.mjs"
     10 );
     11 const { SessionData, SessionDataMethod } = ChromeUtils.importESModule(
     12  "chrome://remote/content/shared/messagehandler/sessiondata/SessionData.sys.mjs"
     13 );
     14 
     15 add_task(async function test_sessionData() {
     16  const sessionData = new SessionData(new RootMessageHandler("session-id-1"));
     17  equal(sessionData.getSessionData("mod", "event").length, 0);
     18 
     19  const globalContext = {
     20    type: ContextDescriptorType.All,
     21  };
     22  const otherContext = { type: "other-type", id: "some-id" };
     23 
     24  info("Add a first event for the global context");
     25  let updatedItems = sessionData.applySessionData([
     26    createUpdate(SessionDataMethod.Add, globalContext, ["first.event"]),
     27  ]);
     28  equal(updatedItems.length, 1, "One item updated");
     29  equal(updatedItems[0].method, SessionDataMethod.Add, "One item added");
     30  let updatedValues = updatedItems[0].values;
     31  equal(updatedValues.length, 1, "One value added");
     32  equal(updatedValues[0], "first.event", "Expected value was added");
     33  checkEvents(sessionData.getSessionData("mod", "event"), [
     34    {
     35      value: "first.event",
     36      contextDescriptor: globalContext,
     37    },
     38  ]);
     39 
     40  info("Add the exact same data (same module, type, context, value)");
     41  updatedItems = sessionData.applySessionData([
     42    createUpdate(SessionDataMethod.Add, globalContext, ["first.event"]),
     43  ]);
     44  equal(updatedItems.length, 0, "No new item updated");
     45  checkEvents(sessionData.getSessionData("mod", "event"), [
     46    {
     47      value: "first.event",
     48      contextDescriptor: globalContext,
     49    },
     50  ]);
     51 
     52  info("Add another context for the same event");
     53  updatedItems = sessionData.applySessionData([
     54    createUpdate(SessionDataMethod.Add, otherContext, ["first.event"]),
     55  ]);
     56  equal(updatedItems.length, 1, "One item updated");
     57  equal(updatedItems[0].method, SessionDataMethod.Add, "One item added");
     58  updatedValues = updatedItems[0].values;
     59  equal(updatedValues.length, 1, "One value added");
     60  equal(updatedValues[0], "first.event", "Expected value was added");
     61  checkEvents(sessionData.getSessionData("mod", "event"), [
     62    {
     63      value: "first.event",
     64      contextDescriptor: globalContext,
     65    },
     66    {
     67      value: "first.event",
     68      contextDescriptor: otherContext,
     69    },
     70  ]);
     71 
     72  info("Add a second event for the global context");
     73  updatedItems = sessionData.applySessionData([
     74    createUpdate(SessionDataMethod.Add, globalContext, ["second.event"]),
     75  ]);
     76  equal(updatedItems.length, 1, "One item updated");
     77  equal(updatedItems[0].method, SessionDataMethod.Add, "One item added");
     78  updatedValues = updatedItems[0].values;
     79  equal(updatedValues.length, 1, "One value added");
     80  equal(updatedValues[0], "second.event", "Expected value was added");
     81  checkEvents(sessionData.getSessionData("mod", "event"), [
     82    {
     83      value: "first.event",
     84      contextDescriptor: globalContext,
     85    },
     86    {
     87      value: "first.event",
     88      contextDescriptor: otherContext,
     89    },
     90    {
     91      value: "second.event",
     92      contextDescriptor: globalContext,
     93    },
     94  ]);
     95 
     96  info("Add two events for the global context");
     97  updatedItems = sessionData.applySessionData([
     98    createUpdate(SessionDataMethod.Add, globalContext, [
     99      "third.event",
    100      "fourth.event",
    101    ]),
    102  ]);
    103  equal(updatedItems.length, 1, "One item updated");
    104  equal(updatedItems[0].method, SessionDataMethod.Add, "One item added");
    105  updatedValues = updatedItems[0].values;
    106  equal(updatedValues.length, 2, "Two values added");
    107  equal(updatedValues[0], "third.event", "Expected value was added");
    108  equal(updatedValues[1], "fourth.event", "Expected value was added");
    109  checkEvents(sessionData.getSessionData("mod", "event"), [
    110    {
    111      value: "first.event",
    112      contextDescriptor: globalContext,
    113    },
    114    {
    115      value: "first.event",
    116      contextDescriptor: otherContext,
    117    },
    118    {
    119      value: "second.event",
    120      contextDescriptor: globalContext,
    121    },
    122    {
    123      value: "third.event",
    124      contextDescriptor: globalContext,
    125    },
    126    {
    127      value: "fourth.event",
    128      contextDescriptor: globalContext,
    129    },
    130  ]);
    131 
    132  info("Remove the second, third and fourth events");
    133  updatedItems = sessionData.applySessionData([
    134    createUpdate(SessionDataMethod.Remove, globalContext, [
    135      "second.event",
    136      "third.event",
    137      "fourth.event",
    138    ]),
    139  ]);
    140  equal(updatedItems.length, 1, "One item updated");
    141  equal(updatedItems[0].method, SessionDataMethod.Remove, "One item removed");
    142  updatedValues = updatedItems[0].values;
    143  equal(updatedValues.length, 3, "Three values removed");
    144  equal(updatedValues[0], "second.event", "Expected value was removed");
    145  equal(updatedValues[1], "third.event", "Expected value was removed");
    146  equal(updatedValues[2], "fourth.event", "Expected value was removed");
    147  checkEvents(sessionData.getSessionData("mod", "event"), [
    148    {
    149      value: "first.event",
    150      contextDescriptor: globalContext,
    151    },
    152    {
    153      value: "first.event",
    154      contextDescriptor: otherContext,
    155    },
    156  ]);
    157 
    158  info("Remove the global context from the first event");
    159  updatedItems = sessionData.applySessionData([
    160    createUpdate(SessionDataMethod.Remove, globalContext, ["first.event"]),
    161  ]);
    162  equal(updatedItems.length, 1, "One item updated");
    163  equal(updatedItems[0].method, SessionDataMethod.Remove, "One item removed");
    164  updatedValues = updatedItems[0].values;
    165  equal(updatedValues.length, 1, "One value removed");
    166  equal(updatedValues[0], "first.event", "Expected value was removed");
    167  checkEvents(sessionData.getSessionData("mod", "event"), [
    168    {
    169      value: "first.event",
    170      contextDescriptor: otherContext,
    171    },
    172  ]);
    173 
    174  info("Remove the other context from the first event");
    175  updatedItems = sessionData.applySessionData([
    176    createUpdate(SessionDataMethod.Remove, otherContext, ["first.event"]),
    177  ]);
    178  equal(updatedItems.length, 1, "One item updated");
    179  equal(updatedItems[0].method, SessionDataMethod.Remove, "One item removed");
    180  updatedValues = updatedItems[0].values;
    181  equal(updatedValues.length, 1, "One value removed");
    182  equal(updatedValues[0], "first.event", "Expected value was removed");
    183  checkEvents(sessionData.getSessionData("mod", "event"), []);
    184 
    185  info("Add two events for different contexts");
    186  updatedItems = sessionData.applySessionData([
    187    createUpdate(SessionDataMethod.Add, otherContext, ["first.event"]),
    188    createUpdate(SessionDataMethod.Add, globalContext, ["second.event"]),
    189  ]);
    190  equal(updatedItems.length, 2, "Two items updated");
    191  equal(updatedItems[0].method, SessionDataMethod.Add, "First item added");
    192  updatedValues = updatedItems[0].values;
    193  equal(updatedValues.length, 1, "One value for first item added");
    194  equal(updatedValues[0], "first.event", "Expected value first item was added");
    195  equal(updatedItems[1].method, SessionDataMethod.Add, "Second item added");
    196  updatedValues = updatedItems[1].values;
    197  equal(updatedValues.length, 1, "One value for second item added");
    198  equal(
    199    updatedValues[0],
    200    "second.event",
    201    "Expected value second item was added"
    202  );
    203  checkEvents(sessionData.getSessionData("mod", "event"), [
    204    {
    205      value: "first.event",
    206      contextDescriptor: otherContext,
    207    },
    208    {
    209      value: "second.event",
    210      contextDescriptor: globalContext,
    211    },
    212  ]);
    213 
    214  info("Remove two events for different contexts");
    215  updatedItems = sessionData.applySessionData([
    216    createUpdate(SessionDataMethod.Remove, otherContext, ["first.event"]),
    217    createUpdate(SessionDataMethod.Remove, globalContext, ["second.event"]),
    218  ]);
    219  equal(updatedItems.length, 2, "Two items updated");
    220  equal(updatedItems[0].method, SessionDataMethod.Remove, "First item removed");
    221  updatedValues = updatedItems[0].values;
    222  equal(updatedValues.length, 1, "One value for first item removed");
    223  equal(
    224    updatedValues[0],
    225    "first.event",
    226    "Expected value first item was removed"
    227  );
    228  equal(
    229    updatedItems[1].method,
    230    SessionDataMethod.Remove,
    231    "Second item removed"
    232  );
    233  updatedValues = updatedItems[1].values;
    234  equal(updatedValues.length, 1, "One value for second item removed");
    235  equal(
    236    updatedValues[0],
    237    "second.event",
    238    "Expected value second item was removed"
    239  );
    240  checkEvents(sessionData.getSessionData("mod", "event"), []);
    241 
    242  info("Add and remove event in different order");
    243  updatedItems = sessionData.applySessionData([
    244    createUpdate(SessionDataMethod.Remove, otherContext, ["first.event"]),
    245    createUpdate(SessionDataMethod.Add, otherContext, ["first.event"]),
    246  ]);
    247  equal(updatedItems.length, 1, "One item updated");
    248  equal(updatedItems[0].method, SessionDataMethod.Add, "One item added");
    249  updatedValues = updatedItems[0].values;
    250  equal(updatedValues.length, 1, "One value added");
    251  equal(updatedValues[0], "first.event", "Expected value was added");
    252  checkEvents(sessionData.getSessionData("mod", "event"), [
    253    {
    254      value: "first.event",
    255      contextDescriptor: otherContext,
    256    },
    257  ]);
    258 
    259  updatedItems = sessionData.applySessionData([
    260    createUpdate(SessionDataMethod.Add, otherContext, ["first.event"]),
    261    createUpdate(SessionDataMethod.Remove, otherContext, ["first.event"]),
    262  ]);
    263  equal(updatedItems.length, 1, "No item update");
    264  equal(updatedItems[0].method, SessionDataMethod.Remove, "One item removed");
    265  updatedValues = updatedItems[0].values;
    266  equal(updatedValues.length, 1, "One value removed");
    267  equal(updatedValues[0], "first.event", "Expected value was removed");
    268  checkEvents(sessionData.getSessionData("mod", "event"), []);
    269 });
    270 
    271 add_task(function test_hasSessionData() {
    272  const sessionData = new SessionData(new RootMessageHandler("session-id-1"));
    273 
    274  ok(
    275    !sessionData.hasSessionData("mod", "event"),
    276    "Starts with no session data"
    277  );
    278 
    279  const globalContext = {
    280    type: ContextDescriptorType.All,
    281  };
    282  const otherContext = { type: "other-type", id: "some-id" };
    283 
    284  sessionData.applySessionData([
    285    createUpdate(SessionDataMethod.Add, globalContext, ["test.event"]),
    286  ]);
    287  ok(sessionData.hasSessionData("mod", "event"), "Detects global context");
    288  sessionData.applySessionData([
    289    createUpdate(SessionDataMethod.Remove, globalContext, ["test.event"]),
    290  ]);
    291  ok(
    292    !sessionData.hasSessionData("mod", "event"),
    293    "Detects removal of global context data"
    294  );
    295 
    296  sessionData.applySessionData([
    297    createUpdate(SessionDataMethod.Add, otherContext, ["other.event"]),
    298  ]);
    299  ok(
    300    sessionData.hasSessionData("mod", "event"),
    301    "Detects specific context data"
    302  );
    303 
    304  sessionData.applySessionData([
    305    createUpdate(SessionDataMethod.Add, globalContext, ["global.event"]),
    306  ]);
    307  ok(sessionData.hasSessionData("mod", "event"), "Detects mixed context data");
    308 
    309  sessionData.applySessionData([
    310    createUpdate(SessionDataMethod.Remove, otherContext, ["other.event"]),
    311  ]);
    312  ok(
    313    sessionData.hasSessionData("mod", "event"),
    314    "Should still contain global context data"
    315  );
    316 
    317  sessionData.applySessionData([
    318    createUpdate(SessionDataMethod.Remove, globalContext, ["global.event"]),
    319  ]);
    320  ok(
    321    !sessionData.hasSessionData("mod", "event"),
    322    "Should detect removal of all context data"
    323  );
    324 
    325  const specificContext = { type: "specific-type", id: "some-id" };
    326 
    327  ok(!sessionData.hasSessionData("mod"), "Works without category");
    328  sessionData.applySessionData([
    329    createUpdate(SessionDataMethod.Add, specificContext, ["specific.event"]),
    330  ]);
    331  ok(sessionData.hasSessionData("mod"), "Detects without category");
    332  sessionData.applySessionData([
    333    createUpdate(SessionDataMethod.Remove, specificContext, ["specific.event"]),
    334  ]);
    335 
    336  ok(
    337    !sessionData.hasSessionData("mod", "event", specificContext),
    338    "No data for specific context initially"
    339  );
    340  sessionData.applySessionData([
    341    createUpdate(SessionDataMethod.Add, specificContext, ["specific.event"]),
    342  ]);
    343  ok(
    344    sessionData.hasSessionData("mod", "event", specificContext),
    345    "Detects specific context data"
    346  );
    347  ok(
    348    !sessionData.hasSessionData("mod", "event", otherContext),
    349    "Doesn't show for wrong context"
    350  );
    351  sessionData.applySessionData([
    352    createUpdate(SessionDataMethod.Remove, specificContext, ["specific.event"]),
    353  ]);
    354 
    355  ok(
    356    !sessionData.hasSessionData("non-existent-module"),
    357    "Unknown module returns false"
    358  );
    359 });
    360 
    361 add_task(async function test_getSessionDataForContext() {
    362  const sessionData = new SessionData(new RootMessageHandler("session-id-1"));
    363 
    364  const globalContextDescriptor = {
    365    type: ContextDescriptorType.All,
    366  };
    367 
    368  const userContextDescriptor = {
    369    type: ContextDescriptorType.UserContext,
    370    id: 1,
    371  };
    372 
    373  const browsingContextDescriptor = {
    374    type: ContextDescriptorType.TopBrowsingContext,
    375    id: 2,
    376  };
    377 
    378  sessionData.applySessionData([
    379    createUpdate(SessionDataMethod.Add, globalContextDescriptor, ["global"]),
    380    createUpdate(SessionDataMethod.Add, userContextDescriptor, ["userContext"]),
    381    createUpdate(SessionDataMethod.Add, browsingContextDescriptor, [
    382      "browsingContext",
    383    ]),
    384  ]);
    385 
    386  const browsingContext1 = {
    387    browserId: 2,
    388    originAttributes: {
    389      userContextId: 1,
    390    },
    391  };
    392 
    393  const sessionDataForContext1 = sessionData.getSessionDataForContext(
    394    "mod",
    395    "event",
    396    browsingContext1
    397  );
    398  equal(sessionDataForContext1.length, 3, "Get 3 session data items");
    399  equal(
    400    sessionDataForContext1[0].value,
    401    "global",
    402    "Get a session data item for the global context descriptor"
    403  );
    404  equal(
    405    sessionDataForContext1[1].value,
    406    "userContext",
    407    "Get a session data item for the user context descriptor"
    408  );
    409  equal(
    410    sessionDataForContext1[2].value,
    411    "browsingContext",
    412    "Get a session data item for the browsing context descriptor"
    413  );
    414 
    415  const browsingContext2 = {
    416    browserId: 3,
    417    originAttributes: {
    418      userContextId: 2,
    419    },
    420  };
    421 
    422  const sessionDataForContext2 = sessionData.getSessionDataForContext(
    423    "mod",
    424    "event",
    425    browsingContext2
    426  );
    427  equal(sessionDataForContext2.length, 1, "Get 1 session data items");
    428  equal(
    429    sessionDataForContext2[0].value,
    430    "global",
    431    "Get a session data item for the global context descriptor"
    432  );
    433 
    434  const browsingContext3 = {
    435    browserId: 4,
    436    originAttributes: {
    437      userContextId: 1,
    438    },
    439  };
    440 
    441  const sessionDataForContext3 = sessionData.getSessionDataForContext(
    442    "mod",
    443    "event",
    444    browsingContext3
    445  );
    446  equal(sessionDataForContext3.length, 2, "Get 2 session data items");
    447  equal(
    448    sessionDataForContext3[0].value,
    449    "global",
    450    "Get a session data item for the global context descriptor"
    451  );
    452  equal(
    453    sessionDataForContext3[1].value,
    454    "userContext",
    455    "Get a session data item for the user context descriptor"
    456  );
    457 });
    458 
    459 add_task(async function test_generateSessionDataItemUpdate() {
    460  const sessionData = new SessionData(new RootMessageHandler("session-id-1"));
    461 
    462  const browsingContextDescriptor = {
    463    type: ContextDescriptorType.TopBrowsingContext,
    464    id: 2,
    465  };
    466 
    467  sessionData.applySessionData([
    468    createUpdate(SessionDataMethod.Add, browsingContextDescriptor, [
    469      "old value",
    470    ]),
    471  ]);
    472 
    473  const newValue = "new value";
    474  const sessionDataItemUpdates = sessionData.generateSessionDataItemUpdate(
    475    "mod",
    476    "event",
    477    browsingContextDescriptor,
    478    false,
    479    newValue
    480  );
    481 
    482  equal(sessionDataItemUpdates.length, 2, "Get 2 session data item updates");
    483  equal(
    484    sessionDataItemUpdates[0].method,
    485    SessionDataMethod.Remove,
    486    "First update is to remove the old item"
    487  );
    488  equal(
    489    sessionDataItemUpdates[1].method,
    490    SessionDataMethod.Add,
    491    "Second update is to add the new item"
    492  );
    493  equal(sessionDataItemUpdates[1].values[0], newValue, "The new value is set");
    494 
    495  const sessionDataItemUpdatesOnlyRemove =
    496    sessionData.generateSessionDataItemUpdate(
    497      "mod",
    498      "event",
    499      browsingContextDescriptor,
    500      true,
    501      newValue
    502    );
    503 
    504  equal(
    505    sessionDataItemUpdatesOnlyRemove.length,
    506    1,
    507    "Get 1 session data item update"
    508  );
    509  equal(
    510    sessionDataItemUpdatesOnlyRemove[0].method,
    511    SessionDataMethod.Remove,
    512    "Update is to remove the old item"
    513  );
    514 });
    515 
    516 function checkEvents(events, expectedEvents) {
    517  // Check the arrays have the same size.
    518  equal(events.length, expectedEvents.length);
    519 
    520  // Check all the expectedEvents can be found in the events array.
    521  for (const expected of expectedEvents) {
    522    ok(
    523      events.some(
    524        event =>
    525          expected.contextDescriptor.type === event.contextDescriptor.type &&
    526          expected.contextDescriptor.id === event.contextDescriptor.id &&
    527          expected.value == event.value
    528      )
    529    );
    530  }
    531 }
    532 
    533 function createUpdate(method, contextDescriptor, values) {
    534  return {
    535    method,
    536    moduleName: "mod",
    537    category: "event",
    538    contextDescriptor,
    539    values,
    540  };
    541 }