tor-browser

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

test_MemoriesHistoryScheduler.js (4778B)


      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
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 do_get_profile();
      6 ("use strict");
      7 
      8 const { sinon } = ChromeUtils.importESModule(
      9  "resource://testing-common/Sinon.sys.mjs"
     10 );
     11 const { MemoriesHistoryScheduler } = ChromeUtils.importESModule(
     12  "moz-src:///browser/components/aiwindow/models/memories/MemoriesHistoryScheduler.sys.mjs"
     13 );
     14 const { MemoriesDriftDetector } = ChromeUtils.importESModule(
     15  "moz-src:///browser/components/aiwindow/models/memories/MemoriesDriftDetector.sys.mjs"
     16 );
     17 const { MemoriesManager } = ChromeUtils.importESModule(
     18  "moz-src:///browser/components/aiwindow/models/memories/MemoriesManager.sys.mjs"
     19 );
     20 
     21 const { PREF_GENERATE_MEMORIES } = ChromeUtils.importESModule(
     22  "moz-src:///browser/components/aiwindow/models/memories/MemoriesConstants.sys.mjs"
     23 );
     24 
     25 // insert N visits so the scheduler crosses its page threshold.
     26 async function addTestVisits(count) {
     27  let seeded = [];
     28  let base = Date.now();
     29  for (let i = 0; i < count; i++) {
     30    seeded.push({
     31      url: `https://example${i}.com/`,
     32      title: `Example ${i}`,
     33      visits: [{ date: new Date(base - i * 1000) }],
     34    });
     35  }
     36  await PlacesUtils.history.insertMany(seeded);
     37 }
     38 
     39 registerCleanupFunction(async () => {
     40  Services.prefs.clearUserPref(PREF_GENERATE_MEMORIES);
     41  await PlacesUtils.history.clear();
     42 });
     43 
     44 // Drift triggers => memories run
     45 add_task(async function test_scheduler_runs_when_drift_triggers() {
     46  Services.prefs.setBoolPref(PREF_GENERATE_MEMORIES, true);
     47 
     48  const generateStub = sinon
     49    .stub(MemoriesManager, "generateMemoriesFromBrowsingHistory")
     50    .resolves();
     51 
     52  const driftStub = sinon
     53    .stub(MemoriesDriftDetector, "computeHistoryDriftAndTrigger")
     54    .resolves({
     55      baselineMetrics: [{ sessionId: 1, jsScore: 0.1, avgSurprisal: 1.0 }],
     56      deltaMetrics: [{ sessionId: 2, jsScore: 0.9, avgSurprisal: 3.0 }],
     57      trigger: {
     58        jsThreshold: 0.5,
     59        surpriseThreshold: 2.0,
     60        triggered: true,
     61        triggeredSessionIds: [2],
     62      },
     63    });
     64 
     65  try {
     66    let scheduler = MemoriesHistoryScheduler.maybeInit();
     67 
     68    // Force pagesVisited above threshold for the test.
     69    scheduler.setPagesVisitedForTesting(100);
     70 
     71    // Run the interval logic once.
     72    await scheduler.runNowForTesting();
     73 
     74    sinon.assert.calledOnce(generateStub);
     75  } finally {
     76    generateStub.restore();
     77    driftStub.restore();
     78  }
     79 });
     80 
     81 // Drift does NOT trigger => memories skipped
     82 add_task(async function test_scheduler_skips_when_drift_not_triggered() {
     83  Services.prefs.setBoolPref(PREF_GENERATE_MEMORIES, true);
     84 
     85  const generateStub = sinon
     86    .stub(MemoriesManager, "generateMemoriesFromBrowsingHistory")
     87    .resolves();
     88 
     89  const driftStub = sinon
     90    .stub(MemoriesDriftDetector, "computeHistoryDriftAndTrigger")
     91    .resolves({
     92      baselineMetrics: [{ sessionId: 1, jsScore: 0.1, avgSurprisal: 1.0 }],
     93      deltaMetrics: [{ sessionId: 2, jsScore: 0.2, avgSurprisal: 1.2 }],
     94      trigger: {
     95        jsThreshold: 0.5,
     96        surpriseThreshold: 2.0,
     97        triggered: false,
     98        triggeredSessionIds: [],
     99      },
    100    });
    101 
    102  try {
    103    let scheduler = MemoriesHistoryScheduler.maybeInit();
    104    await addTestVisits(60);
    105    await scheduler.runNowForTesting();
    106    sinon.assert.notCalled(generateStub);
    107  } finally {
    108    generateStub.restore();
    109    driftStub.restore();
    110  }
    111 });
    112 
    113 // First run (no previous memories) => memories run even with small history.
    114 add_task(async function test_scheduler_runs_on_first_run_with_small_history() {
    115  Services.prefs.setBoolPref(PREF_GENERATE_MEMORIES, true);
    116 
    117  const generateStub = sinon
    118    .stub(MemoriesManager, "generateMemoriesFromBrowsingHistory")
    119    .resolves();
    120 
    121  const driftStub = sinon
    122    .stub(MemoriesDriftDetector, "computeHistoryDriftAndTrigger")
    123    .resolves({
    124      baselineMetrics: [],
    125      deltaMetrics: [],
    126      trigger: {
    127        jsThreshold: 0,
    128        surpriseThreshold: 0,
    129        triggered: false,
    130        triggeredSessionIds: [],
    131      },
    132    });
    133 
    134  const lastTsStub = sinon
    135    .stub(MemoriesManager, "getLastHistoryMemoryTimestamp")
    136    .resolves(0);
    137 
    138  try {
    139    let scheduler = MemoriesHistoryScheduler.maybeInit();
    140    Assert.ok(scheduler, "Scheduler should be initialized when pref is true");
    141 
    142    // Set a number of pages that is:
    143    // - below the normal threshold (25), but
    144    // - high enough for the special first-run threshold (e.g. 15).
    145    scheduler.setPagesVisitedForTesting(20);
    146 
    147    // Run the interval logic once.
    148    await scheduler.runNowForTesting();
    149    sinon.assert.calledOnce(generateStub);
    150  } finally {
    151    generateStub.restore();
    152    driftStub.restore();
    153    lastTsStub.restore();
    154  }
    155 });