tor-browser

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

test_search_telemetry_categorization_sync.js (20448B)


      1 /* Any copyright is dedicated to the Public Domain.
      2   http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 /**
      5 * Tests the integration of Remote Settings with SERP domain categorization.
      6 */
      7 
      8 "use strict";
      9 
     10 ChromeUtils.defineESModuleGetters(this, {
     11  RemoteSettings: "resource://services-settings/remote-settings.sys.mjs",
     12  Region: "resource://gre/modules/Region.sys.mjs",
     13  SERPCategorization:
     14    "moz-src:///browser/components/search/SERPCategorization.sys.mjs",
     15  SERPDomainToCategoriesMap:
     16    "moz-src:///browser/components/search/SERPCategorization.sys.mjs",
     17  TELEMETRY_CATEGORIZATION_KEY:
     18    "moz-src:///browser/components/search/SERPCategorization.sys.mjs",
     19  TestUtils: "resource://testing-common/TestUtils.sys.mjs",
     20 });
     21 
     22 ChromeUtils.defineLazyGetter(this, "gCryptoHash", () => {
     23  return Cc["@mozilla.org/security/hash;1"].createInstance(Ci.nsICryptoHash);
     24 });
     25 
     26 function convertDomainsToHashes(domainsToCategories) {
     27  let newObj = {};
     28  for (let [key, value] of Object.entries(domainsToCategories)) {
     29    gCryptoHash.init(gCryptoHash.SHA256);
     30    let bytes = new TextEncoder().encode(key);
     31    gCryptoHash.update(bytes, key.length);
     32    let hash = gCryptoHash.finish(true);
     33    newObj[hash] = value;
     34  }
     35  return newObj;
     36 }
     37 
     38 async function waitForDomainToCategoriesUpdate() {
     39  return TestUtils.topicObserved("domain-to-categories-map-update-complete");
     40 }
     41 
     42 async function mockRecordWithCachedAttachment({
     43  id,
     44  version,
     45  filename,
     46  mapping,
     47  includeRegions,
     48  excludeRegions,
     49 }) {
     50  // Get the bytes of the file for the hash and size for attachment metadata.
     51  let buffer = new TextEncoder().encode(JSON.stringify(mapping)).buffer;
     52  let stream = Cc["@mozilla.org/io/arraybuffer-input-stream;1"].createInstance(
     53    Ci.nsIArrayBufferInputStream
     54  );
     55  stream.setData(buffer, 0, buffer.byteLength);
     56 
     57  // Generate a hash.
     58  let hasher = Cc["@mozilla.org/security/hash;1"].createInstance(
     59    Ci.nsICryptoHash
     60  );
     61  hasher.init(Ci.nsICryptoHash.SHA256);
     62  hasher.updateFromStream(stream, -1);
     63  let hash = hasher.finish(false);
     64  hash = Array.from(hash, (_, i) =>
     65    ("0" + hash.charCodeAt(i).toString(16)).slice(-2)
     66  ).join("");
     67 
     68  let record = {
     69    id,
     70    version,
     71    includeRegions,
     72    excludeRegions,
     73    attachment: {
     74      hash,
     75      location: `main-workspace/search-categorization/${filename}`,
     76      filename,
     77      size: buffer.byteLength,
     78      mimetype: "application/json",
     79    },
     80  };
     81 
     82  client.attachments.cacheImpl.set(id, {
     83    record,
     84    blob: new Blob([buffer]),
     85  });
     86 
     87  return record;
     88 }
     89 
     90 const RECORD_A_ID = Services.uuid.generateUUID().number.slice(1, -1);
     91 const RECORD_B_ID = Services.uuid.generateUUID().number.slice(1, -1);
     92 const RECORD_C_ID = Services.uuid.generateUUID().number.slice(1, -1);
     93 
     94 const client = RemoteSettings(TELEMETRY_CATEGORIZATION_KEY);
     95 const db = client.db;
     96 
     97 const RECORDS = {
     98  record1a: {
     99    id: RECORD_A_ID,
    100    version: 1,
    101    filename: "domain_category_mappings_1a.json",
    102    mapping: convertDomainsToHashes({
    103      "example.com": [1, 100],
    104    }),
    105    includeRegions: ["US"],
    106    excludeRegions: [],
    107  },
    108  record1b: {
    109    id: RECORD_B_ID,
    110    version: 1,
    111    filename: "domain_category_mappings_1b.json",
    112    mapping: convertDomainsToHashes({
    113      "example.org": [2, 90],
    114    }),
    115    includeRegions: ["US"],
    116    excludeRegions: [],
    117  },
    118  record1c: {
    119    id: RECORD_C_ID,
    120    version: 1,
    121    filename: "domain_category_mappings_1c.json",
    122    mapping: convertDomainsToHashes({
    123      "example.ca": [2, 90],
    124    }),
    125    includeRegions: ["CA"],
    126    excludeRegions: [],
    127  },
    128  record2a: {
    129    id: RECORD_A_ID,
    130    version: 2,
    131    filename: "domain_category_mappings_2a.json",
    132    mapping: convertDomainsToHashes({
    133      "example.com": [1, 80],
    134    }),
    135    includeRegions: ["US"],
    136    excludeRegions: [],
    137  },
    138  record2b: {
    139    id: RECORD_B_ID,
    140    version: 2,
    141    filename: "domain_category_mappings_2b.json",
    142    mapping: convertDomainsToHashes({
    143      "example.org": [2, 50, 4, 80],
    144    }),
    145    includeRegions: ["US"],
    146    excludeRegions: [],
    147  },
    148  record2c: {
    149    id: RECORD_C_ID,
    150    version: 2,
    151    filename: "domain_category_mappings_2c.json",
    152    mapping: convertDomainsToHashes({
    153      "example.ca": [2, 75],
    154    }),
    155    includeRegions: ["CA"],
    156    excludeRegions: [],
    157  },
    158 };
    159 
    160 add_setup(async () => {
    161  // Testing with Remote Settings requires a profile.
    162  do_get_profile();
    163  await Region.init();
    164  let originalRegion = Region.home;
    165  Region._setHomeRegion("US");
    166  await db.clear();
    167  registerCleanupFunction(() => {
    168    Region._setHomeRegion(originalRegion);
    169  });
    170 });
    171 
    172 add_task(async function test_initial_import() {
    173  info("Create record containing domain_category_mappings_1a.json attachment.");
    174  let record1a = await mockRecordWithCachedAttachment(RECORDS.record1a);
    175  await db.create(record1a);
    176 
    177  info("Create record containing domain_category_mappings_1b.json attachment.");
    178  let record1b = await mockRecordWithCachedAttachment(RECORDS.record1b);
    179  await db.create(record1b);
    180 
    181  info("Add data to Remote Settings DB.");
    182  await db.importChanges({}, Date.now());
    183 
    184  info("Initialize search categorization mappings.");
    185  let promise = waitForDomainToCategoriesUpdate();
    186  await SERPDomainToCategoriesMap.init();
    187  await promise;
    188 
    189  Assert.deepEqual(
    190    await SERPDomainToCategoriesMap.get("example.com"),
    191    [{ category: 1, score: 100 }],
    192    "Return value from lookup of example.com should be the same."
    193  );
    194 
    195  Assert.deepEqual(
    196    await SERPDomainToCategoriesMap.get("example.org"),
    197    [{ category: 2, score: 90 }],
    198    "Return value from lookup of example.org should be the same."
    199  );
    200 
    201  // Clean up.
    202  await db.clear();
    203  await SERPDomainToCategoriesMap.uninit(true);
    204 });
    205 
    206 add_task(async function test_update_records() {
    207  info("Create record containing domain_category_mappings_1a.json attachment.");
    208  let record1a = await mockRecordWithCachedAttachment(RECORDS.record1a);
    209  await db.create(record1a);
    210 
    211  info("Create record containing domain_category_mappings_1b.json attachment.");
    212  let record1b = await mockRecordWithCachedAttachment(RECORDS.record1b);
    213  await db.create(record1b);
    214 
    215  info("Add data to Remote Settings DB.");
    216  await db.importChanges({}, Date.now());
    217 
    218  info("Initialize search categorization mappings.");
    219  let promise = waitForDomainToCategoriesUpdate();
    220  await SERPDomainToCategoriesMap.init();
    221  await promise;
    222 
    223  info("Send update from Remote Settings with updates to attachments.");
    224  let record2a = await mockRecordWithCachedAttachment(RECORDS.record2a);
    225  let record2b = await mockRecordWithCachedAttachment(RECORDS.record2b);
    226  const payload = {
    227    current: [record2a, record2b],
    228    created: [],
    229    updated: [
    230      { old: record1a, new: record2a },
    231      { old: record1b, new: record2b },
    232    ],
    233    deleted: [],
    234  };
    235  promise = waitForDomainToCategoriesUpdate();
    236  await client.emit("sync", {
    237    data: payload,
    238  });
    239  await promise;
    240 
    241  Assert.deepEqual(
    242    await SERPDomainToCategoriesMap.get("example.com"),
    243    [{ category: 1, score: 80 }],
    244    "Return value from lookup of example.com should have changed."
    245  );
    246 
    247  Assert.deepEqual(
    248    await SERPDomainToCategoriesMap.get("example.org"),
    249    [
    250      { category: 2, score: 50 },
    251      { category: 4, score: 80 },
    252    ],
    253    "Return value from lookup of example.org should have changed."
    254  );
    255 
    256  Assert.equal(
    257    SERPDomainToCategoriesMap.version,
    258    2,
    259    "Version should be correct."
    260  );
    261 
    262  // Clean up.
    263  await db.clear();
    264  await SERPDomainToCategoriesMap.uninit(true);
    265 });
    266 
    267 add_task(async function test_delayed_initial_import() {
    268  info("Initialize search categorization mappings.");
    269  let observeNoRecordsFound = TestUtils.consoleMessageObserved(msg => {
    270    return (
    271      typeof msg.wrappedJSObject.arguments?.[0] == "string" &&
    272      msg.wrappedJSObject.arguments[0].includes(
    273        "No records found for domain-to-categories map."
    274      )
    275    );
    276  });
    277  info("Initialize without records.");
    278  await SERPDomainToCategoriesMap.init();
    279  await observeNoRecordsFound;
    280 
    281  Assert.ok(SERPDomainToCategoriesMap.empty, "Map is empty.");
    282 
    283  info("Send update from Remote Settings with updates to attachments.");
    284  let record1a = await mockRecordWithCachedAttachment(RECORDS.record1a);
    285  let record1b = await mockRecordWithCachedAttachment(RECORDS.record1b);
    286  const payload = {
    287    current: [record1a, record1b],
    288    created: [record1a, record1b],
    289    updated: [],
    290    deleted: [],
    291  };
    292  let promise = waitForDomainToCategoriesUpdate();
    293  await client.emit("sync", {
    294    data: payload,
    295  });
    296  await promise;
    297 
    298  Assert.deepEqual(
    299    await SERPDomainToCategoriesMap.get("example.com"),
    300    [{ category: 1, score: 100 }],
    301    "Return value from lookup of example.com should be the same."
    302  );
    303 
    304  Assert.deepEqual(
    305    await SERPDomainToCategoriesMap.get("example.org"),
    306    [{ category: 2, score: 90 }],
    307    "Return value from lookup of example.org should be the same."
    308  );
    309 
    310  Assert.equal(
    311    SERPDomainToCategoriesMap.version,
    312    1,
    313    "Version should be correct."
    314  );
    315 
    316  // Clean up.
    317  await db.clear();
    318  await SERPDomainToCategoriesMap.uninit(true);
    319 });
    320 
    321 add_task(async function test_remove_record() {
    322  info("Create record containing domain_category_mappings_2a.json attachment.");
    323  let record2a = await mockRecordWithCachedAttachment(RECORDS.record2a);
    324  await db.create(record2a);
    325 
    326  info("Create record containing domain_category_mappings_2b.json attachment.");
    327  let record2b = await mockRecordWithCachedAttachment(RECORDS.record2b);
    328  await db.create(record2b);
    329 
    330  info("Add data to Remote Settings DB.");
    331  await db.importChanges({}, Date.now());
    332 
    333  info("Initialize search categorization mappings.");
    334  let promise = waitForDomainToCategoriesUpdate();
    335  await SERPDomainToCategoriesMap.init();
    336  await promise;
    337 
    338  Assert.deepEqual(
    339    await SERPDomainToCategoriesMap.get("example.com"),
    340    [{ category: 1, score: 80 }],
    341    "Initialized properly."
    342  );
    343 
    344  info("Send update from Remote Settings with one removed record.");
    345  const payload = {
    346    current: [record2a],
    347    created: [],
    348    updated: [],
    349    deleted: [record2b],
    350  };
    351  promise = waitForDomainToCategoriesUpdate();
    352  await client.emit("sync", {
    353    data: payload,
    354  });
    355  await promise;
    356 
    357  Assert.deepEqual(
    358    await SERPDomainToCategoriesMap.get("example.com"),
    359    [{ category: 1, score: 80 }],
    360    "Return value from lookup of example.com should remain unchanged."
    361  );
    362 
    363  Assert.deepEqual(
    364    await SERPDomainToCategoriesMap.get("example.org"),
    365    [],
    366    "Return value from lookup of example.org should be empty."
    367  );
    368 
    369  Assert.equal(
    370    SERPDomainToCategoriesMap.version,
    371    2,
    372    "Version should be correct."
    373  );
    374 
    375  // Clean up.
    376  await db.clear();
    377  await SERPDomainToCategoriesMap.uninit(true);
    378 });
    379 
    380 add_task(async function test_different_versions_coexisting() {
    381  info("Create record containing domain_category_mappings_1a.json attachment.");
    382  let record1a = await mockRecordWithCachedAttachment(RECORDS.record1a);
    383  await db.create(record1a);
    384 
    385  info("Create record containing domain_category_mappings_2b.json attachment.");
    386  let record2b = await mockRecordWithCachedAttachment(RECORDS.record2b);
    387  await db.create(record2b);
    388 
    389  info("Add data to Remote Settings DB.");
    390  await db.importChanges({}, Date.now());
    391 
    392  info("Initialize search categorization mappings.");
    393  let promise = waitForDomainToCategoriesUpdate();
    394  await SERPDomainToCategoriesMap.init();
    395  await promise;
    396 
    397  Assert.deepEqual(
    398    await SERPDomainToCategoriesMap.get("example.com"),
    399    [
    400      {
    401        category: 1,
    402        score: 100,
    403      },
    404    ],
    405    "Should have a record from an older version."
    406  );
    407 
    408  Assert.deepEqual(
    409    await SERPDomainToCategoriesMap.get("example.org"),
    410    [
    411      { category: 2, score: 50 },
    412      { category: 4, score: 80 },
    413    ],
    414    "Return value from lookup of example.org should have the most recent value."
    415  );
    416 
    417  Assert.equal(
    418    SERPDomainToCategoriesMap.version,
    419    2,
    420    "Version should be the latest."
    421  );
    422 
    423  // Clean up.
    424  await db.clear();
    425  await SERPDomainToCategoriesMap.uninit(true);
    426 });
    427 
    428 add_task(async function test_download_error() {
    429  info("Create record containing domain_category_mappings_1a.json attachment.");
    430  let record1a = await mockRecordWithCachedAttachment(RECORDS.record1a);
    431  await db.create(record1a);
    432 
    433  info("Add data to Remote Settings DB.");
    434  await db.importChanges({}, Date.now());
    435 
    436  info("Initialize search categorization mappings.");
    437  let promise = waitForDomainToCategoriesUpdate();
    438  await SERPDomainToCategoriesMap.init();
    439  await promise;
    440 
    441  Assert.deepEqual(
    442    await SERPDomainToCategoriesMap.get("example.com"),
    443    [
    444      {
    445        category: 1,
    446        score: 100,
    447      },
    448    ],
    449    "Domain should have an entry in the map."
    450  );
    451 
    452  Assert.equal(
    453    SERPDomainToCategoriesMap.version,
    454    1,
    455    "Version should be present."
    456  );
    457 
    458  info("Delete attachment from local cache.");
    459  client.attachments.cacheImpl.delete(RECORD_A_ID);
    460 
    461  const payload = {
    462    current: [record1a],
    463    created: [],
    464    updated: [{ old: record1a, new: record1a }],
    465    deleted: [],
    466  };
    467 
    468  info("Sync payload.");
    469  let observeDownloadError = TestUtils.consoleMessageObserved(msg => {
    470    return (
    471      typeof msg.wrappedJSObject.arguments?.[0] == "string" &&
    472      msg.wrappedJSObject.arguments[0].includes("Could not download file:")
    473    );
    474  });
    475  await client.emit("sync", {
    476    data: payload,
    477  });
    478  await observeDownloadError;
    479 
    480  Assert.deepEqual(
    481    await SERPDomainToCategoriesMap.get("example.com"),
    482    [],
    483    "Domain should not exist in store."
    484  );
    485 
    486  Assert.equal(
    487    SERPDomainToCategoriesMap.version,
    488    null,
    489    "Version should remain null."
    490  );
    491 
    492  // Clean up.
    493  await db.clear();
    494  await SERPDomainToCategoriesMap.uninit(true);
    495 });
    496 
    497 add_task(async function test_mock_restart() {
    498  info("Create record containing domain_category_mappings_2a.json attachment.");
    499  let record2a = await mockRecordWithCachedAttachment(RECORDS.record2a);
    500  await db.create(record2a);
    501 
    502  info("Create record containing domain_category_mappings_2b.json attachment.");
    503  let record2b = await mockRecordWithCachedAttachment(RECORDS.record2b);
    504  await db.create(record2b);
    505 
    506  info("Add data to Remote Settings DB.");
    507  await db.importChanges({}, Date.now());
    508 
    509  info("Initialize search categorization mappings.");
    510  let promise = waitForDomainToCategoriesUpdate();
    511  await SERPCategorization.init();
    512  await promise;
    513 
    514  Assert.deepEqual(
    515    await SERPDomainToCategoriesMap.get("example.com"),
    516    [
    517      {
    518        category: 1,
    519        score: 80,
    520      },
    521    ],
    522    "Should have a record."
    523  );
    524 
    525  Assert.equal(
    526    SERPDomainToCategoriesMap.version,
    527    2,
    528    "Version should be the latest."
    529  );
    530 
    531  info("Mock a restart by un-initializing the map.");
    532  await SERPCategorization.uninit();
    533  promise = waitForDomainToCategoriesUpdate();
    534  await SERPCategorization.init();
    535  await promise;
    536 
    537  Assert.deepEqual(
    538    await SERPDomainToCategoriesMap.get("example.com"),
    539    [
    540      {
    541        category: 1,
    542        score: 80,
    543      },
    544    ],
    545    "Should have a record."
    546  );
    547 
    548  Assert.equal(
    549    SERPDomainToCategoriesMap.version,
    550    2,
    551    "Version should be the latest."
    552  );
    553 
    554  // Clean up.
    555  await db.clear();
    556  await SERPDomainToCategoriesMap.uninit(true);
    557 });
    558 
    559 add_task(async function update_record_from_non_matching_region() {
    560  info("Create record containing domain_category_mappings_1a.json attachment.");
    561  let record1a = await mockRecordWithCachedAttachment(RECORDS.record1a);
    562  await db.create(record1a);
    563 
    564  info("Add data to Remote Settings DB.");
    565  await db.importChanges({}, Date.now());
    566 
    567  info("Initialize search categorization mappings.");
    568  let promise = waitForDomainToCategoriesUpdate();
    569  await SERPDomainToCategoriesMap.init();
    570  await promise;
    571 
    572  Assert.deepEqual(
    573    await SERPDomainToCategoriesMap.get("example.com"),
    574    [{ category: 1, score: 100 }],
    575    "Return value from lookup of example.com should exist."
    576  );
    577 
    578  info(
    579    "Send update from Remote Settings with a record that doesn't match the home region."
    580  );
    581  let record1c = await mockRecordWithCachedAttachment(RECORDS.record1c);
    582  const payload = {
    583    current: [record1a, record1c],
    584    created: [record1c],
    585    updated: [],
    586    deleted: [],
    587  };
    588 
    589  let observeNoChange = TestUtils.consoleMessageObserved(msg => {
    590    return (
    591      typeof msg.wrappedJSObject.arguments?.[0] == "string" &&
    592      msg.wrappedJSObject.arguments[0].includes(
    593        "Domain-to-category records had no changes that matched the region."
    594      )
    595    );
    596  });
    597  await client.emit("sync", { data: payload });
    598  await observeNoChange;
    599 
    600  Assert.deepEqual(
    601    await SERPDomainToCategoriesMap.get("example.com"),
    602    [{ category: 1, score: 100 }],
    603    "Return value from lookup of example.com should still exist."
    604  );
    605 
    606  Assert.deepEqual(
    607    await SERPDomainToCategoriesMap.get("example.ca"),
    608    [],
    609    "Domain from non-home region should not exist."
    610  );
    611 
    612  Assert.equal(
    613    SERPDomainToCategoriesMap.version,
    614    1,
    615    "Version should be remain the same."
    616  );
    617 
    618  // Clean up.
    619  await db.clear();
    620  await SERPDomainToCategoriesMap.uninit(true);
    621 });
    622 
    623 add_task(async function update_record_from_non_matching_region() {
    624  info("Create record containing domain_category_mappings_1a.json attachment.");
    625  let record1a = await mockRecordWithCachedAttachment(RECORDS.record1a);
    626  await db.create(record1a);
    627 
    628  info("Add data to Remote Settings DB.");
    629  await db.importChanges({}, Date.now());
    630 
    631  info("Initialize search categorization mappings.");
    632  let promise = waitForDomainToCategoriesUpdate();
    633  await SERPDomainToCategoriesMap.init();
    634  await promise;
    635 
    636  Assert.deepEqual(
    637    await SERPDomainToCategoriesMap.get("example.com"),
    638    [{ category: 1, score: 100 }],
    639    "Return value from lookup of example.com should exist."
    640  );
    641 
    642  info(
    643    "Send update from Remote Settings with a record that doesn't match the home region."
    644  );
    645  let record1c = await mockRecordWithCachedAttachment(RECORDS.record1c);
    646  const payload = {
    647    current: [record1a, record1c],
    648    created: [record1c],
    649    updated: [],
    650    deleted: [],
    651  };
    652 
    653  let observeNoChange = TestUtils.consoleMessageObserved(msg => {
    654    return (
    655      typeof msg.wrappedJSObject.arguments?.[0] == "string" &&
    656      msg.wrappedJSObject.arguments[0].includes(
    657        "Domain-to-category records had no changes that matched the region."
    658      )
    659    );
    660  });
    661  await client.emit("sync", { data: payload });
    662  await observeNoChange;
    663 
    664  Assert.deepEqual(
    665    await SERPDomainToCategoriesMap.get("example.com"),
    666    [{ category: 1, score: 100 }],
    667    "Return value from lookup of example.com should still exist."
    668  );
    669 
    670  Assert.deepEqual(
    671    await SERPDomainToCategoriesMap.get("example.ca"),
    672    [],
    673    "Domain from non-home region should not exist."
    674  );
    675 
    676  Assert.equal(
    677    SERPDomainToCategoriesMap.version,
    678    1,
    679    "Version should be remain the same."
    680  );
    681 
    682  // Clean up.
    683  await db.clear();
    684  await SERPDomainToCategoriesMap.uninit(true);
    685 });
    686 
    687 add_task(async function update_() {
    688  info("Create record containing domain_category_mappings_1a.json attachment.");
    689  let record1a = await mockRecordWithCachedAttachment(RECORDS.record1a);
    690  await db.create(record1a);
    691 
    692  info("Add data to Remote Settings DB.");
    693  await db.importChanges({}, Date.now());
    694 
    695  info("Initialize search categorization mappings.");
    696  let promise = waitForDomainToCategoriesUpdate();
    697  await SERPDomainToCategoriesMap.init();
    698  await promise;
    699 
    700  Assert.deepEqual(
    701    await SERPDomainToCategoriesMap.get("example.com"),
    702    [{ category: 1, score: 100 }],
    703    "Return value from lookup of example.com should exist."
    704  );
    705 
    706  // Re-init the Map to mimic a restart.
    707  await SERPDomainToCategoriesMap.uninit();
    708 
    709  info("Change home region to one that doesn't match region of map.");
    710  let originalHomeRegion = Region.home;
    711  Region._setHomeRegion("DE");
    712 
    713  let observeDropStore = TestUtils.consoleMessageObserved(msg => {
    714    return (
    715      typeof msg.wrappedJSObject.arguments?.[0] == "string" &&
    716      msg.wrappedJSObject.arguments[0].includes(
    717        "Drop store because it no longer matches the home region."
    718      )
    719    );
    720  });
    721 
    722  await SERPDomainToCategoriesMap.init();
    723  await observeDropStore;
    724  Assert.deepEqual(
    725    await SERPDomainToCategoriesMap.get("example.com"),
    726    [],
    727    "Return value from lookup of example.com should be empty."
    728  );
    729 
    730  // Clean up.
    731  await db.clear();
    732  Region._setHomeRegion(originalHomeRegion);
    733  await SERPDomainToCategoriesMap.uninit(true);
    734 });