tor-browser

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

test_FormHistoryBackupResource.js (7475B)


      1 /* Any copyright is dedicated to the Public Domain.
      2 https://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 "use strict";
      5 
      6 const { FormHistoryBackupResource } = ChromeUtils.importESModule(
      7  "resource:///modules/backup/FormHistoryBackupResource.sys.mjs"
      8 );
      9 
     10 /**
     11 * Tests that we can measure the Form History db in a profile directory.
     12 */
     13 add_task(async function test_measure() {
     14  const EXPECTED_FORM_HISTORY_DB_SIZE = 500;
     15 
     16  Services.fog.testResetFOG();
     17 
     18  // Create resource files in temporary directory
     19  let tempDir = PathUtils.tempDir;
     20  let tempFormHistoryDBPath = PathUtils.join(tempDir, "formhistory.sqlite");
     21  await createKilobyteSizedFile(
     22    tempFormHistoryDBPath,
     23    EXPECTED_FORM_HISTORY_DB_SIZE
     24  );
     25 
     26  let formHistoryBackupResource = new FormHistoryBackupResource();
     27  await formHistoryBackupResource.measure(tempDir);
     28 
     29  let formHistoryMeasurement =
     30    Glean.browserBackup.formHistorySize.testGetValue();
     31  let scalars = TelemetryTestUtils.getProcessScalars("parent", false, false);
     32 
     33  // Compare glean vs telemetry measurements
     34  TelemetryTestUtils.assertScalar(
     35    scalars,
     36    "browser.backup.form_history_size",
     37    formHistoryMeasurement,
     38    "Glean and telemetry measurements for formhistory.sqlite should be equal"
     39  );
     40 
     41  // Compare glean measurements vs actual file sizes
     42  Assert.equal(
     43    formHistoryMeasurement,
     44    EXPECTED_FORM_HISTORY_DB_SIZE,
     45    "Should have collected the correct glean measurement for formhistory.sqlite"
     46  );
     47 
     48  await IOUtils.remove(tempFormHistoryDBPath);
     49 });
     50 
     51 /**
     52 * Test that the backup method correctly copies items from the profile directory
     53 * into the staging directory.
     54 */
     55 add_task(async function test_backup() {
     56  let sandbox = sinon.createSandbox();
     57 
     58  let formHistoryBackupResource = new FormHistoryBackupResource();
     59  let sourcePath = await IOUtils.createUniqueDirectory(
     60    PathUtils.tempDir,
     61    "FormHistoryBackupResource-source-test"
     62  );
     63  let stagingPath = await IOUtils.createUniqueDirectory(
     64    PathUtils.tempDir,
     65    "FormHistoryBackupResource-staging-test"
     66  );
     67 
     68  // Make sure this file exists in the source directory, otherwise
     69  // BackupResource will skip attempting to back it up.
     70  await createTestFiles(sourcePath, [{ path: "formhistory.sqlite" }]);
     71 
     72  // We have no need to test that Sqlite.sys.mjs's backup method is working -
     73  // this is something that is tested in Sqlite's own tests. We can just make
     74  // sure that it's being called using sinon. Unfortunately, we cannot do the
     75  // same thing with IOUtils.copy, as its methods are not stubbable.
     76  let fakeConnection = {
     77    backup: sandbox.stub().resolves(true),
     78    close: sandbox.stub().resolves(true),
     79  };
     80  sandbox.stub(Sqlite, "openConnection").returns(fakeConnection);
     81 
     82  let manifestEntry = await formHistoryBackupResource.backup(
     83    stagingPath,
     84    sourcePath
     85  );
     86  Assert.equal(
     87    manifestEntry,
     88    null,
     89    "FormHistoryBackupResource.backup should return null as its ManifestEntry"
     90  );
     91 
     92  // Next, we'll make sure that the Sqlite connection had `backup` called on it
     93  // with the right arguments.
     94  Assert.ok(
     95    fakeConnection.backup.calledOnce,
     96    "Called backup the expected number of times for all connections"
     97  );
     98  Assert.ok(
     99    fakeConnection.backup.calledWith(
    100      PathUtils.join(stagingPath, "formhistory.sqlite")
    101    ),
    102    "Called backup on the formhistory.sqlite Sqlite connection"
    103  );
    104 
    105  await maybeRemovePath(stagingPath);
    106  await maybeRemovePath(sourcePath);
    107 
    108  sandbox.restore();
    109 });
    110 
    111 /**
    112 * Tests that the backup method does not copy the form history database if the
    113 * browser is configured to not save history - either while running, or to
    114 * clear it at shutdown.
    115 */
    116 add_task(async function test_backup_no_saved_history() {
    117  let formHistoryBackupResource = new FormHistoryBackupResource();
    118  let sourcePath = await IOUtils.createUniqueDirectory(
    119    PathUtils.tempDir,
    120    "FormHistoryBackupResource-source-test"
    121  );
    122  let stagingPath = await IOUtils.createUniqueDirectory(
    123    PathUtils.tempDir,
    124    "FormHistoryBackupResource-staging-test"
    125  );
    126 
    127  let sandbox = sinon.createSandbox();
    128  let fakeConnection = {
    129    backup: sandbox.stub().resolves(true),
    130    close: sandbox.stub().resolves(true),
    131  };
    132  sandbox.stub(Sqlite, "openConnection").returns(fakeConnection);
    133 
    134  Services.prefs.setBoolPref(FORM_HISTORY_CLEARED_ON_SHUTDOWN_PREF, true);
    135  Services.prefs.setBoolPref(SANITIZE_ON_SHUTDOWN_PREF, true);
    136 
    137  Assert.ok(
    138    !FormHistoryBackupResource.canBackupResource,
    139    "Cannot backup form history since it is being cleared on shutdown"
    140  );
    141 
    142  Services.prefs.setBoolPref(SANITIZE_ON_SHUTDOWN_PREF, false);
    143  Services.prefs.setBoolPref(FORM_HISTORY_CLEARED_ON_SHUTDOWN_PREF, false);
    144 
    145  // We'll try with browsing history in general being disabled.
    146  Services.prefs.setBoolPref(HISTORY_ENABLED_PREF, false);
    147 
    148  Assert.ok(
    149    !FormHistoryBackupResource.canBackupResource,
    150    "Cannot backup form history since it is being cleared on shutdown"
    151  );
    152 
    153  Assert.ok(
    154    fakeConnection.backup.notCalled,
    155    "No sqlite connections should have been made with remember history disabled"
    156  );
    157 
    158  Services.prefs.setBoolPref(HISTORY_ENABLED_PREF, true);
    159 
    160  Assert.ok(
    161    FormHistoryBackupResource.canBackupResource,
    162    "We should be allowed to backup this resource now"
    163  );
    164 
    165  fakeConnection.backup.resetHistory();
    166  let manifestEntry = await formHistoryBackupResource.backup(
    167    stagingPath,
    168    sourcePath
    169  );
    170  Assert.deepEqual(
    171    manifestEntry,
    172    null,
    173    "Should have gotten back a null ManifestEntry"
    174  );
    175 
    176  Assert.ok(
    177    fakeConnection.backup.notCalled,
    178    "No sqlite connections should have been made with sanitize shutdown enabled"
    179  );
    180 
    181  await maybeRemovePath(stagingPath);
    182  await maybeRemovePath(sourcePath);
    183 
    184  sandbox.restore();
    185  Services.prefs.clearUserPref(HISTORY_ENABLED_PREF);
    186  Services.prefs.clearUserPref(SANITIZE_ON_SHUTDOWN_PREF);
    187 });
    188 
    189 /**
    190 * Tests that the backup method correctly skips backing up form history when
    191 * permanent private browsing mode is enabled.
    192 */
    193 add_task(async function test_backup_private_browsing() {
    194  let sandbox = sinon.createSandbox();
    195  sandbox.stub(PrivateBrowsingUtils, "permanentPrivateBrowsing").value(true);
    196 
    197  Assert.ok(
    198    !FormHistoryBackupResource.canBackupResource,
    199    "Cannot backup form history since Private Browsing is enabled"
    200  );
    201 
    202  sandbox.restore();
    203 });
    204 
    205 /**
    206 * Test that the recover method correctly copies items from the recovery
    207 * directory into the destination profile directory.
    208 */
    209 add_task(async function test_recover() {
    210  let formHistoryBackupResource = new FormHistoryBackupResource();
    211  let recoveryPath = await IOUtils.createUniqueDirectory(
    212    PathUtils.tempDir,
    213    "FormHistoryBackupResource-recovery-test"
    214  );
    215  let destProfilePath = await IOUtils.createUniqueDirectory(
    216    PathUtils.tempDir,
    217    "FormHistoryBackupResource-test-profile"
    218  );
    219 
    220  const simpleCopyFiles = [{ path: "formhistory.sqlite" }];
    221  await createTestFiles(recoveryPath, simpleCopyFiles);
    222 
    223  // The backup method is expected to have returned a null ManifestEntry
    224  let postRecoveryEntry = await formHistoryBackupResource.recover(
    225    null /* manifestEntry */,
    226    recoveryPath,
    227    destProfilePath
    228  );
    229  Assert.equal(
    230    postRecoveryEntry,
    231    null,
    232    "FormHistoryBackupResource.recover should return null as its post " +
    233      "recovery entry"
    234  );
    235 
    236  await assertFilesExist(destProfilePath, simpleCopyFiles);
    237 
    238  await maybeRemovePath(recoveryPath);
    239  await maybeRemovePath(destProfilePath);
    240 });