tor-browser

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

test_history_tracker.js (7174B)


      1 /* Any copyright is dedicated to the Public Domain.
      2   http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 const { PlacesDBUtils } = ChromeUtils.importESModule(
      5  "resource://gre/modules/PlacesDBUtils.sys.mjs"
      6 );
      7 const { HistoryEngine } = ChromeUtils.importESModule(
      8  "resource://services-sync/engines/history.sys.mjs"
      9 );
     10 const { Service } = ChromeUtils.importESModule(
     11  "resource://services-sync/service.sys.mjs"
     12 );
     13 
     14 let engine;
     15 let tracker;
     16 
     17 add_task(async function setup() {
     18  await Service.engineManager.clear();
     19  await Service.engineManager.register(HistoryEngine);
     20  engine = Service.engineManager.get("history");
     21  tracker = engine._tracker;
     22 });
     23 
     24 async function verifyTrackerEmpty() {
     25  let changes = await engine.pullNewChanges();
     26  do_check_empty(changes);
     27  equal(tracker.score, 0);
     28 }
     29 
     30 async function verifyTrackedCount(expected) {
     31  let changes = await engine.pullNewChanges();
     32  do_check_attribute_count(changes, expected);
     33 }
     34 
     35 async function verifyTrackedItems(tracked) {
     36  let changes = await engine.pullNewChanges();
     37  let trackedIDs = new Set(Object.keys(changes));
     38  for (let guid of tracked) {
     39    ok(guid in changes, `${guid} should be tracked`);
     40    Assert.greater(changes[guid], 0, `${guid} should have a modified time`);
     41    trackedIDs.delete(guid);
     42  }
     43  equal(
     44    trackedIDs.size,
     45    0,
     46    `Unhandled tracked IDs: ${JSON.stringify(Array.from(trackedIDs))}`
     47  );
     48 }
     49 
     50 async function resetTracker() {
     51  await tracker.clearChangedIDs();
     52  tracker.resetScore();
     53 }
     54 
     55 async function cleanup() {
     56  await PlacesUtils.history.clear();
     57  await resetTracker();
     58  await tracker.stop();
     59 }
     60 
     61 add_task(async function test_empty() {
     62  _("Verify we've got an empty, disabled tracker to work with.");
     63  await verifyTrackerEmpty();
     64  Assert.ok(!tracker._isTracking);
     65 
     66  await cleanup();
     67 });
     68 
     69 add_task(async function test_not_tracking() {
     70  _("Create history item. Won't show because we haven't started tracking yet");
     71  await addVisit("not_tracking");
     72  await verifyTrackerEmpty();
     73 
     74  await cleanup();
     75 });
     76 
     77 add_task(async function test_start_tracking() {
     78  _("Add hook for save completion.");
     79  let savePromise = new Promise((resolve, reject) => {
     80    let save = tracker._storage._save;
     81    tracker._storage._save = async function () {
     82      try {
     83        await save.call(this);
     84        resolve();
     85      } catch (ex) {
     86        reject(ex);
     87      } finally {
     88        tracker._storage._save = save;
     89      }
     90    };
     91  });
     92 
     93  _("Tell the tracker to start tracking changes.");
     94  tracker.start();
     95  let scorePromise = promiseOneObserver("weave:engine:score:updated");
     96  await addVisit("start_tracking");
     97  await scorePromise;
     98 
     99  _("Score updated in test_start_tracking.");
    100  await verifyTrackedCount(1);
    101  Assert.equal(tracker.score, SCORE_INCREMENT_SMALL);
    102 
    103  await savePromise;
    104 
    105  _("changedIDs written to disk. Proceeding.");
    106  await cleanup();
    107 });
    108 
    109 add_task(async function test_start_tracking_twice() {
    110  _("Verifying preconditions.");
    111  tracker.start();
    112  await addVisit("start_tracking_twice1");
    113  await verifyTrackedCount(1);
    114  Assert.equal(tracker.score, SCORE_INCREMENT_SMALL);
    115 
    116  _("Notifying twice won't do any harm.");
    117  tracker.start();
    118  let scorePromise = promiseOneObserver("weave:engine:score:updated");
    119  await addVisit("start_tracking_twice2");
    120  await scorePromise;
    121 
    122  _("Score updated in test_start_tracking_twice.");
    123  await verifyTrackedCount(2);
    124  Assert.equal(tracker.score, 2 * SCORE_INCREMENT_SMALL);
    125 
    126  await cleanup();
    127 });
    128 
    129 add_task(async function test_track_delete() {
    130  _("Deletions are tracked.");
    131 
    132  // This isn't present because we weren't tracking when it was visited.
    133  await addVisit("track_delete");
    134  let uri = CommonUtils.makeURI("http://getfirefox.com/track_delete");
    135  let guid = await engine._store.GUIDForUri(uri.spec);
    136  await verifyTrackerEmpty();
    137 
    138  tracker.start();
    139  let visitRemovedPromise = promiseVisit("removed", uri);
    140  let scorePromise = promiseOneObserver("weave:engine:score:updated");
    141  await PlacesUtils.history.remove(uri);
    142  await Promise.all([scorePromise, visitRemovedPromise]);
    143 
    144  await verifyTrackedItems([guid]);
    145  Assert.equal(tracker.score, SCORE_INCREMENT_XLARGE);
    146 
    147  await cleanup();
    148 });
    149 
    150 add_task(async function test_dont_track_expiration() {
    151  _("Expirations are not tracked.");
    152  let uriToRemove = await addVisit("to_remove");
    153  let guidToRemove = await engine._store.GUIDForUri(uriToRemove.spec);
    154 
    155  await resetTracker();
    156  await verifyTrackerEmpty();
    157 
    158  tracker.start();
    159  let visitRemovedPromise = promiseVisit("removed", uriToRemove);
    160  let scorePromise = promiseOneObserver("weave:engine:score:updated");
    161 
    162  // Observe expiration.
    163  Services.obs.addObserver(function onExpiration(aSubject, aTopic) {
    164    Services.obs.removeObserver(onExpiration, aTopic);
    165    // Remove the remaining page to update its score.
    166    PlacesUtils.history.remove(uriToRemove);
    167  }, PlacesUtils.TOPIC_EXPIRATION_FINISHED);
    168 
    169  // Force expiration of 1 entry.
    170  Services.prefs.setIntPref("places.history.expiration.max_pages", 0);
    171  Cc["@mozilla.org/places/expiration;1"]
    172    .getService(Ci.nsIObserver)
    173    .observe(null, "places-debug-start-expiration", 1);
    174 
    175  await Promise.all([scorePromise, visitRemovedPromise]);
    176  await verifyTrackedItems([guidToRemove]);
    177 
    178  await cleanup();
    179 });
    180 
    181 add_task(async function test_stop_tracking() {
    182  _("Let's stop tracking again.");
    183  await tracker.stop();
    184  await addVisit("stop_tracking");
    185  await verifyTrackerEmpty();
    186 
    187  await cleanup();
    188 });
    189 
    190 add_task(async function test_stop_tracking_twice() {
    191  await tracker.stop();
    192  await addVisit("stop_tracking_twice1");
    193 
    194  _("Notifying twice won't do any harm.");
    195  await tracker.stop();
    196  await addVisit("stop_tracking_twice2");
    197  await verifyTrackerEmpty();
    198 
    199  await cleanup();
    200 });
    201 
    202 add_task(async function test_filter_file_uris() {
    203  tracker.start();
    204 
    205  let uri = CommonUtils.makeURI("file:///Users/eoger/tps/config.json");
    206  let visitAddedPromise = promiseVisit("added", uri);
    207  await PlacesTestUtils.addVisits({
    208    uri,
    209    visitDate: Date.now() * 1000,
    210    transition: PlacesUtils.history.TRANSITION_LINK,
    211  });
    212  await visitAddedPromise;
    213 
    214  await verifyTrackerEmpty();
    215  await tracker.stop();
    216  await cleanup();
    217 });
    218 
    219 add_task(async function test_filter_hidden() {
    220  tracker.start();
    221 
    222  _("Add visit; should be hidden by the redirect");
    223  let hiddenURI = await addVisit("hidden");
    224  let hiddenGUID = await engine._store.GUIDForUri(hiddenURI.spec);
    225  _(`Hidden visit GUID: ${hiddenGUID}`);
    226 
    227  _("Add redirect visit; should be tracked");
    228  let trackedURI = await addVisit(
    229    "redirect",
    230    hiddenURI.spec,
    231    PlacesUtils.history.TRANSITION_REDIRECT_PERMANENT
    232  );
    233  let trackedGUID = await engine._store.GUIDForUri(trackedURI.spec);
    234  _(`Tracked visit GUID: ${trackedGUID}`);
    235 
    236  _("Add visit for framed link; should be ignored");
    237  let embedURI = await addVisit(
    238    "framed_link",
    239    null,
    240    PlacesUtils.history.TRANSITION_FRAMED_LINK
    241  );
    242  let embedGUID = await engine._store.GUIDForUri(embedURI.spec);
    243  _(`Framed link visit GUID: ${embedGUID}`);
    244 
    245  _("Run Places maintenance to mark redirect visit as hidden");
    246  await PlacesDBUtils.maintenanceOnIdle();
    247 
    248  await verifyTrackedItems([trackedGUID]);
    249 
    250  await cleanup();
    251 });