Blame services/sync/tests/unit/test_history_store.js

Packit f0b94e
/* Any copyright is dedicated to the Public Domain.
Packit f0b94e
   http://creativecommons.org/publicdomain/zero/1.0/ */
Packit f0b94e
Packit f0b94e
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
Packit f0b94e
ChromeUtils.import("resource://services-common/utils.js");
Packit f0b94e
ChromeUtils.import("resource://services-sync/engines/history.js");
Packit f0b94e
ChromeUtils.import("resource://services-sync/service.js");
Packit f0b94e
ChromeUtils.import("resource://services-sync/util.js");
Packit f0b94e
Packit f0b94e
const TIMESTAMP1 = (Date.now() - 103406528) * 1000;
Packit f0b94e
const TIMESTAMP2 = (Date.now() - 6592903) * 1000;
Packit f0b94e
const TIMESTAMP3 = (Date.now() - 123894) * 1000;
Packit f0b94e
Packit f0b94e
function promiseOnVisitObserved() {
Packit f0b94e
  return new Promise(res => {
Packit f0b94e
    PlacesUtils.history.addObserver({
Packit f0b94e
      onBeginUpdateBatch: function onBeginUpdateBatch() {},
Packit f0b94e
      onEndUpdateBatch: function onEndUpdateBatch() {},
Packit f0b94e
      onPageChanged: function onPageChanged() {},
Packit f0b94e
      onTitleChanged: function onTitleChanged() {
Packit f0b94e
      },
Packit f0b94e
      onVisits: function onVisits() {
Packit f0b94e
        PlacesUtils.history.removeObserver(this);
Packit f0b94e
        res();
Packit f0b94e
      },
Packit f0b94e
      onDeleteVisits: function onDeleteVisits() {},
Packit f0b94e
      onPageExpired: function onPageExpired() {},
Packit f0b94e
      onDeleteURI: function onDeleteURI() {},
Packit f0b94e
      onClearHistory: function onClearHistory() {},
Packit f0b94e
      QueryInterface: XPCOMUtils.generateQI([
Packit f0b94e
        Ci.nsINavHistoryObserver,
Packit f0b94e
        Ci.nsINavHistoryObserver_MOZILLA_1_9_1_ADDITIONS,
Packit f0b94e
        Ci.nsISupportsWeakReference
Packit f0b94e
      ])
Packit f0b94e
    }, true);
Packit f0b94e
  });
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
function isDateApproximately(actual, expected, skewMillis = 1000) {
Packit f0b94e
  let lowerBound = expected - skewMillis;
Packit f0b94e
  let upperBound = expected + skewMillis;
Packit f0b94e
  return actual >= lowerBound && actual <= upperBound;
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
let engine, store, fxuri, fxguid, tburi, tbguid;
Packit f0b94e
Packit f0b94e
async function applyEnsureNoFailures(records) {
Packit f0b94e
  Assert.equal((await store.applyIncomingBatch(records)).length, 0);
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
add_task(async function setup() {
Packit f0b94e
  engine = new HistoryEngine(Service);
Packit f0b94e
  await engine.initialize();
Packit f0b94e
  store = engine._store;
Packit f0b94e
});
Packit f0b94e
Packit f0b94e
add_task(async function test_store() {
Packit f0b94e
  _("Verify that we've got an empty store to work with.");
Packit f0b94e
  do_check_empty((await store.getAllIDs()));
Packit f0b94e
Packit f0b94e
  _("Let's create an entry in the database.");
Packit f0b94e
  fxuri = CommonUtils.makeURI("http://getfirefox.com/");
Packit f0b94e
Packit f0b94e
  await PlacesTestUtils.addVisits({ uri: fxuri, title: "Get Firefox!",
Packit f0b94e
                                  visitDate: TIMESTAMP1 });
Packit f0b94e
  _("Verify that the entry exists.");
Packit f0b94e
  let ids = Object.keys((await store.getAllIDs()));
Packit f0b94e
  Assert.equal(ids.length, 1);
Packit f0b94e
  fxguid = ids[0];
Packit f0b94e
  Assert.ok((await store.itemExists(fxguid)));
Packit f0b94e
Packit f0b94e
  _("If we query a non-existent record, it's marked as deleted.");
Packit f0b94e
  let record = await store.createRecord("non-existent");
Packit f0b94e
  Assert.ok(record.deleted);
Packit f0b94e
Packit f0b94e
  _("Verify createRecord() returns a complete record.");
Packit f0b94e
  record = await store.createRecord(fxguid);
Packit f0b94e
  Assert.equal(record.histUri, fxuri.spec);
Packit f0b94e
  Assert.equal(record.title, "Get Firefox!");
Packit f0b94e
  Assert.equal(record.visits.length, 1);
Packit f0b94e
  Assert.equal(record.visits[0].date, TIMESTAMP1);
Packit f0b94e
  Assert.equal(record.visits[0].type, Ci.nsINavHistoryService.TRANSITION_LINK);
Packit f0b94e
Packit f0b94e
  _("Let's modify the record and have the store update the database.");
Packit f0b94e
  let secondvisit = {date: TIMESTAMP2,
Packit f0b94e
                     type: Ci.nsINavHistoryService.TRANSITION_TYPED};
Packit f0b94e
  let onVisitObserved = promiseOnVisitObserved();
Packit f0b94e
  await applyEnsureNoFailures([
Packit f0b94e
    {id: fxguid,
Packit f0b94e
     histUri: record.histUri,
Packit f0b94e
     title: "Hol Dir Firefox!",
Packit f0b94e
     visits: [record.visits[0], secondvisit]}
Packit f0b94e
  ]);
Packit f0b94e
  await onVisitObserved;
Packit f0b94e
  let queryres = await PlacesUtils.history.fetch(fxuri.spec, {
Packit f0b94e
    includeVisits: true,
Packit f0b94e
  });
Packit f0b94e
  Assert.equal(queryres.title, "Hol Dir Firefox!");
Packit f0b94e
  Assert.deepEqual(queryres.visits, [{
Packit f0b94e
    date: new Date(TIMESTAMP2 / 1000),
Packit f0b94e
    transition: Ci.nsINavHistoryService.TRANSITION_TYPED,
Packit f0b94e
  }, {
Packit f0b94e
    date: new Date(TIMESTAMP1 / 1000),
Packit f0b94e
    transition: Ci.nsINavHistoryService.TRANSITION_LINK,
Packit f0b94e
  }]);
Packit f0b94e
  await PlacesUtils.history.clear();
Packit f0b94e
});
Packit f0b94e
Packit f0b94e
add_task(async function test_store_create() {
Packit f0b94e
  _("Create a brand new record through the store.");
Packit f0b94e
  tbguid = Utils.makeGUID();
Packit f0b94e
  tburi = CommonUtils.makeURI("http://getthunderbird.com");
Packit f0b94e
  let onVisitObserved = promiseOnVisitObserved();
Packit f0b94e
  await applyEnsureNoFailures([
Packit f0b94e
    {id: tbguid,
Packit f0b94e
     histUri: tburi.spec,
Packit f0b94e
     title: "The bird is the word!",
Packit f0b94e
     visits: [{date: TIMESTAMP3,
Packit f0b94e
               type: Ci.nsINavHistoryService.TRANSITION_TYPED}]}
Packit f0b94e
  ]);
Packit f0b94e
  await onVisitObserved;
Packit f0b94e
  Assert.ok((await store.itemExists(tbguid)));
Packit f0b94e
  do_check_attribute_count(await store.getAllIDs(), 1);
Packit f0b94e
  let queryres = await PlacesUtils.history.fetch(tburi.spec, {
Packit f0b94e
    includeVisits: true,
Packit f0b94e
  });
Packit f0b94e
  Assert.equal(queryres.title, "The bird is the word!");
Packit f0b94e
  Assert.deepEqual(queryres.visits, [{
Packit f0b94e
    date: new Date(TIMESTAMP3 / 1000),
Packit f0b94e
    transition: Ci.nsINavHistoryService.TRANSITION_TYPED,
Packit f0b94e
  }]);
Packit f0b94e
  await PlacesUtils.history.clear();
Packit f0b94e
});
Packit f0b94e
Packit f0b94e
add_task(async function test_null_title() {
Packit f0b94e
  _("Make sure we handle a null title gracefully (it can happen in some cases, e.g. for resource:// URLs)");
Packit f0b94e
  let resguid = Utils.makeGUID();
Packit f0b94e
  let resuri = CommonUtils.makeURI("unknown://title");
Packit f0b94e
  await applyEnsureNoFailures([
Packit f0b94e
    {id: resguid,
Packit f0b94e
     histUri: resuri.spec,
Packit f0b94e
     title: null,
Packit f0b94e
     visits: [{date: TIMESTAMP3,
Packit f0b94e
               type: Ci.nsINavHistoryService.TRANSITION_TYPED}]}
Packit f0b94e
  ]);
Packit f0b94e
  do_check_attribute_count((await store.getAllIDs()), 1);
Packit f0b94e
Packit f0b94e
  let queryres = await PlacesUtils.history.fetch(resuri.spec, {
Packit f0b94e
    includeVisits: true,
Packit f0b94e
  });
Packit f0b94e
  Assert.equal(queryres.title, "");
Packit f0b94e
  Assert.deepEqual(queryres.visits, [{
Packit f0b94e
    date: new Date(TIMESTAMP3 / 1000),
Packit f0b94e
    transition: Ci.nsINavHistoryService.TRANSITION_TYPED,
Packit f0b94e
  }]);
Packit f0b94e
  await PlacesUtils.history.clear();
Packit f0b94e
});
Packit f0b94e
Packit f0b94e
add_task(async function test_invalid_records() {
Packit f0b94e
  _("Make sure we handle invalid URLs in places databases gracefully.");
Packit f0b94e
  await PlacesUtils.withConnectionWrapper("test_invalid_record", async function(db) {
Packit f0b94e
    await db.execute(
Packit f0b94e
      "INSERT INTO moz_places "
Packit f0b94e
      + "(url, url_hash, title, rev_host, visit_count, last_visit_date) "
Packit f0b94e
      + "VALUES ('invalid-uri', hash('invalid-uri'), 'Invalid URI', '.', 1, " + TIMESTAMP3 + ")"
Packit f0b94e
    );
Packit f0b94e
    // Trigger the update on moz_hosts by deleting the added rows from
Packit f0b94e
    // moz_updatehostsinsert_temp
Packit f0b94e
    await db.execute("DELETE FROM moz_updatehostsinsert_temp");
Packit f0b94e
    // Add the corresponding visit to retain database coherence.
Packit f0b94e
    await db.execute(
Packit f0b94e
      "INSERT INTO moz_historyvisits "
Packit f0b94e
      + "(place_id, visit_date, visit_type, session) "
Packit f0b94e
      + "VALUES ((SELECT id FROM moz_places WHERE url_hash = hash('invalid-uri') AND url = 'invalid-uri'), "
Packit f0b94e
      + TIMESTAMP3 + ", " + Ci.nsINavHistoryService.TRANSITION_TYPED + ", 1)"
Packit f0b94e
    );
Packit f0b94e
  });
Packit f0b94e
  do_check_attribute_count((await store.getAllIDs()), 1);
Packit f0b94e
Packit f0b94e
  _("Make sure we report records with invalid URIs.");
Packit f0b94e
  let invalid_uri_guid = Utils.makeGUID();
Packit f0b94e
  let failed = await store.applyIncomingBatch([{
Packit f0b94e
    id: invalid_uri_guid,
Packit f0b94e
    histUri: ":::::::::::::::",
Packit f0b94e
    title: "Doesn't have a valid URI",
Packit f0b94e
    visits: [{date: TIMESTAMP3,
Packit f0b94e
              type: Ci.nsINavHistoryService.TRANSITION_EMBED}]}
Packit f0b94e
  ]);
Packit f0b94e
  Assert.equal(failed.length, 1);
Packit f0b94e
  Assert.equal(failed[0], invalid_uri_guid);
Packit f0b94e
Packit f0b94e
  _("Make sure we handle records with invalid GUIDs gracefully (ignore).");
Packit f0b94e
  await applyEnsureNoFailures([
Packit f0b94e
    {id: "invalid",
Packit f0b94e
     histUri: "http://invalid.guid/",
Packit f0b94e
     title: "Doesn't have a valid GUID",
Packit f0b94e
     visits: [{date: TIMESTAMP3,
Packit f0b94e
               type: Ci.nsINavHistoryService.TRANSITION_EMBED}]}
Packit f0b94e
  ]);
Packit f0b94e
Packit f0b94e
  _("Make sure we handle records with invalid visit codes or visit dates, gracefully ignoring those visits.");
Packit f0b94e
  let no_date_visit_guid = Utils.makeGUID();
Packit f0b94e
  let no_type_visit_guid = Utils.makeGUID();
Packit f0b94e
  let invalid_type_visit_guid = Utils.makeGUID();
Packit f0b94e
  let non_integer_visit_guid = Utils.makeGUID();
Packit f0b94e
  failed = await store.applyIncomingBatch([
Packit f0b94e
    {id: no_date_visit_guid,
Packit f0b94e
     histUri: "http://no.date.visit/",
Packit f0b94e
     title: "Visit has no date",
Packit f0b94e
     visits: [{type: Ci.nsINavHistoryService.TRANSITION_EMBED}]},
Packit f0b94e
    {id: no_type_visit_guid,
Packit f0b94e
     histUri: "http://no.type.visit/",
Packit f0b94e
     title: "Visit has no type",
Packit f0b94e
     visits: [{date: TIMESTAMP3}]},
Packit f0b94e
    {id: invalid_type_visit_guid,
Packit f0b94e
     histUri: "http://invalid.type.visit/",
Packit f0b94e
     title: "Visit has invalid type",
Packit f0b94e
     visits: [{date: TIMESTAMP3,
Packit f0b94e
               type: Ci.nsINavHistoryService.TRANSITION_LINK - 1}]},
Packit f0b94e
    {id: non_integer_visit_guid,
Packit f0b94e
     histUri: "http://non.integer.visit/",
Packit f0b94e
     title: "Visit has non-integer date",
Packit f0b94e
     visits: [{date: 1234.567,
Packit f0b94e
               type: Ci.nsINavHistoryService.TRANSITION_EMBED}]}
Packit f0b94e
  ]);
Packit f0b94e
  Assert.equal(failed.length, 0);
Packit f0b94e
Packit f0b94e
  _("Make sure we handle records with javascript: URLs gracefully.");
Packit f0b94e
  await applyEnsureNoFailures([
Packit f0b94e
    {id: Utils.makeGUID(),
Packit f0b94e
     histUri: "javascript:''",
Packit f0b94e
     title: "javascript:''",
Packit f0b94e
     visits: [{date: TIMESTAMP3,
Packit f0b94e
               type: Ci.nsINavHistoryService.TRANSITION_EMBED}]}
Packit f0b94e
  ]);
Packit f0b94e
Packit f0b94e
  _("Make sure we handle records without any visits gracefully.");
Packit f0b94e
  await applyEnsureNoFailures([
Packit f0b94e
    {id: Utils.makeGUID(),
Packit f0b94e
     histUri: "http://getfirebug.com",
Packit f0b94e
     title: "Get Firebug!",
Packit f0b94e
     visits: []}
Packit f0b94e
  ]);
Packit f0b94e
});
Packit f0b94e
Packit f0b94e
add_task(async function test_unknowingly_invalid_records() {
Packit f0b94e
  _("Make sure we handle rejection of records by places gracefully.");
Packit f0b94e
  let oldCAU = store._canAddURI;
Packit f0b94e
  store._canAddURI = () => true;
Packit f0b94e
  try {
Packit f0b94e
    _("Make sure that when places rejects this record we record it as failed");
Packit f0b94e
    let guid = Utils.makeGUID();
Packit f0b94e
    let result = await store.applyIncomingBatch([
Packit f0b94e
      {id: guid,
Packit f0b94e
       histUri: "javascript:''",
Packit f0b94e
       title: "javascript:''",
Packit f0b94e
       visits: [{date: TIMESTAMP3,
Packit f0b94e
                 type: Ci.nsINavHistoryService.TRANSITION_EMBED}]}
Packit f0b94e
    ]);
Packit f0b94e
    deepEqual(result, [guid]);
Packit f0b94e
  } finally {
Packit f0b94e
    store._canAddURI = oldCAU;
Packit f0b94e
  }
Packit f0b94e
});
Packit f0b94e
Packit f0b94e
add_task(async function test_clamp_visit_dates() {
Packit f0b94e
  let futureVisitTime = Date.now() + 5 * 60 * 1000;
Packit f0b94e
  let recentVisitTime = Date.now() - 5 * 60 * 1000;
Packit f0b94e
Packit f0b94e
  await applyEnsureNoFailures([{
Packit f0b94e
    id: "visitAAAAAAA",
Packit f0b94e
    histUri: "http://example.com/a",
Packit f0b94e
    title: "A",
Packit f0b94e
    visits: [{
Packit f0b94e
      date: "invalidDate",
Packit f0b94e
      type: Ci.nsINavHistoryService.TRANSITION_LINK,
Packit f0b94e
    }],
Packit f0b94e
  }, {
Packit f0b94e
    id: "visitBBBBBBB",
Packit f0b94e
    histUri: "http://example.com/b",
Packit f0b94e
    title: "B",
Packit f0b94e
    visits: [{
Packit f0b94e
      date: 100,
Packit f0b94e
      type: Ci.nsINavHistoryService.TRANSITION_TYPED,
Packit f0b94e
    }, {
Packit f0b94e
      date: 250,
Packit f0b94e
      type: Ci.nsINavHistoryService.TRANSITION_TYPED,
Packit f0b94e
    }, {
Packit f0b94e
      date: recentVisitTime * 1000,
Packit f0b94e
      type: Ci.nsINavHistoryService.TRANSITION_TYPED,
Packit f0b94e
    }],
Packit f0b94e
  }, {
Packit f0b94e
    id: "visitCCCCCCC",
Packit f0b94e
    histUri: "http://example.com/c",
Packit f0b94e
    title: "D",
Packit f0b94e
    visits: [{
Packit f0b94e
      date: futureVisitTime * 1000,
Packit f0b94e
      type: Ci.nsINavHistoryService.TRANSITION_BOOKMARK,
Packit f0b94e
    }],
Packit f0b94e
  }, {
Packit f0b94e
    id: "visitDDDDDDD",
Packit f0b94e
    histUri: "http://example.com/d",
Packit f0b94e
    title: "D",
Packit f0b94e
    visits: [{
Packit f0b94e
      date: recentVisitTime * 1000,
Packit f0b94e
      type: Ci.nsINavHistoryService.TRANSITION_DOWNLOAD,
Packit f0b94e
    }],
Packit f0b94e
  }]);
Packit f0b94e
Packit f0b94e
  let visitsForA = await PlacesSyncUtils.history.fetchVisitsForURL(
Packit f0b94e
    "http://example.com/a");
Packit f0b94e
  deepEqual(visitsForA, [], "Should ignore visits with invalid dates");
Packit f0b94e
Packit f0b94e
  let visitsForB = await PlacesSyncUtils.history.fetchVisitsForURL(
Packit f0b94e
    "http://example.com/b");
Packit f0b94e
  deepEqual(visitsForB, [{
Packit f0b94e
    date: recentVisitTime * 1000,
Packit f0b94e
    type: Ci.nsINavHistoryService.TRANSITION_TYPED,
Packit f0b94e
  }, {
Packit f0b94e
    // We should clamp visit dates older than original Mosaic release.
Packit f0b94e
    date: PlacesSyncUtils.bookmarks.EARLIEST_BOOKMARK_TIMESTAMP * 1000,
Packit f0b94e
    type: Ci.nsINavHistoryService.TRANSITION_TYPED,
Packit f0b94e
  }], "Should record clamped visit and valid visit for B");
Packit f0b94e
Packit f0b94e
  let visitsForC = await PlacesSyncUtils.history.fetchVisitsForURL(
Packit f0b94e
    "http://example.com/c");
Packit f0b94e
  equal(visitsForC.length, 1, "Should record clamped future visit for C");
Packit f0b94e
  let visitDateForC = PlacesUtils.toDate(visitsForC[0].date);
Packit f0b94e
  ok(isDateApproximately(visitDateForC, Date.now()),
Packit f0b94e
    "Should clamp future visit date for C to now");
Packit f0b94e
Packit f0b94e
  let visitsForD = await PlacesSyncUtils.history.fetchVisitsForURL(
Packit f0b94e
    "http://example.com/d");
Packit f0b94e
  deepEqual(visitsForD, [{
Packit f0b94e
    date: recentVisitTime * 1000,
Packit f0b94e
    type: Ci.nsINavHistoryService.TRANSITION_DOWNLOAD,
Packit f0b94e
  }], "Should not clamp valid visit dates");
Packit f0b94e
});
Packit f0b94e
Packit f0b94e
add_task(async function test_remove() {
Packit f0b94e
  _("Remove an existent record and a non-existent from the store.");
Packit f0b94e
  await applyEnsureNoFailures([{id: fxguid, deleted: true},
Packit f0b94e
                         {id: Utils.makeGUID(), deleted: true}]);
Packit f0b94e
  Assert.equal(false, (await store.itemExists(fxguid)));
Packit f0b94e
  let queryres = await PlacesUtils.history.fetch(fxuri.spec, {
Packit f0b94e
    includeVisits: true,
Packit f0b94e
  });
Packit f0b94e
  Assert.equal(null, queryres);
Packit f0b94e
Packit f0b94e
  _("Make sure wipe works.");
Packit f0b94e
  await store.wipe();
Packit f0b94e
  do_check_empty((await store.getAllIDs()));
Packit f0b94e
  queryres = await PlacesUtils.history.fetch(fxuri.spec, {
Packit f0b94e
    includeVisits: true,
Packit f0b94e
  });
Packit f0b94e
  Assert.equal(null, queryres);
Packit f0b94e
  queryres = await PlacesUtils.history.fetch(tburi.spec, {
Packit f0b94e
    includeVisits: true,
Packit f0b94e
  });
Packit f0b94e
  Assert.equal(null, queryres);
Packit f0b94e
});
Packit f0b94e
Packit f0b94e
add_task(async function test_chunking() {
Packit f0b94e
  let mvpi = store.MAX_VISITS_PER_INSERT;
Packit f0b94e
  store.MAX_VISITS_PER_INSERT = 3;
Packit f0b94e
  let checkChunks = function(input, expected) {
Packit f0b94e
    let chunks = Array.from(store._generateChunks(input));
Packit f0b94e
    deepEqual(chunks, expected);
Packit f0b94e
  };
Packit f0b94e
  try {
Packit f0b94e
    checkChunks([{visits: ["x"]}],
Packit f0b94e
                [[{visits: ["x"]}]]);
Packit f0b94e
Packit f0b94e
    // 3 should still be one chunk.
Packit f0b94e
    checkChunks([{visits: ["x", "x", "x"]}],
Packit f0b94e
                [[{visits: ["x", "x", "x"]}]]);
Packit f0b94e
Packit f0b94e
    // 4 should still be one chunk as we don't split individual records.
Packit f0b94e
    checkChunks([{visits: ["x", "x", "x", "x"]}],
Packit f0b94e
                [[{visits: ["x", "x", "x", "x"]}]]
Packit f0b94e
               );
Packit f0b94e
Packit f0b94e
    // 4 in the first and 1 in the second should be 2 chunks.
Packit f0b94e
    checkChunks([
Packit f0b94e
                  {visits: ["x", "x", "x", "x"]},
Packit f0b94e
                  {visits: ["x"]}
Packit f0b94e
                ],
Packit f0b94e
                // expected
Packit f0b94e
                [
Packit f0b94e
                  [
Packit f0b94e
                    {visits: ["x", "x", "x", "x"]}
Packit f0b94e
                  ],
Packit f0b94e
                  [
Packit f0b94e
                    {visits: ["x"]}
Packit f0b94e
                  ],
Packit f0b94e
                ]
Packit f0b94e
               );
Packit f0b94e
Packit f0b94e
    // we put multiple records into chunks
Packit f0b94e
    checkChunks([
Packit f0b94e
                  {visits: ["x", "x"]},
Packit f0b94e
                  {visits: ["x"]},
Packit f0b94e
                  {visits: ["x"]},
Packit f0b94e
                  {visits: ["x", "x"]},
Packit f0b94e
                  {visits: ["x", "x", "x", "x"]},
Packit f0b94e
                ],
Packit f0b94e
                // expected
Packit f0b94e
                [
Packit f0b94e
                  [
Packit f0b94e
                    {visits: ["x", "x"]},
Packit f0b94e
                    {visits: ["x"]},
Packit f0b94e
                  ],
Packit f0b94e
                  [
Packit f0b94e
                    {visits: ["x"]},
Packit f0b94e
                    {visits: ["x", "x"]},
Packit f0b94e
                  ],
Packit f0b94e
                  [
Packit f0b94e
                    {visits: ["x", "x", "x", "x"]},
Packit f0b94e
                  ],
Packit f0b94e
                ]
Packit f0b94e
               );
Packit f0b94e
  } finally {
Packit f0b94e
    store.MAX_VISITS_PER_INSERT = mvpi;
Packit f0b94e
  }
Packit f0b94e
});
Packit f0b94e
Packit f0b94e
add_task(async function test_getAllIDs_filters_file_uris() {
Packit f0b94e
  let uri = CommonUtils.makeURI("file:///Users/eoger/tps/config.json");
Packit f0b94e
  let visitAddedPromise = promiseVisit("added", uri);
Packit f0b94e
  await PlacesTestUtils.addVisits({
Packit f0b94e
    uri,
Packit f0b94e
    visitDate: Date.now() * 1000,
Packit f0b94e
    transition: PlacesUtils.history.TRANSITION_LINK
Packit f0b94e
  });
Packit f0b94e
  await visitAddedPromise;
Packit f0b94e
Packit f0b94e
  do_check_attribute_count(await store.getAllIDs(), 0);
Packit f0b94e
Packit f0b94e
  await PlacesUtils.history.clear();
Packit f0b94e
});
Packit f0b94e
Packit f0b94e
add_task(async function test_applyIncomingBatch_filters_file_uris() {
Packit f0b94e
  const guid = Utils.makeGUID();
Packit f0b94e
  let uri = CommonUtils.makeURI("file:///Users/eoger/tps/config.json");
Packit f0b94e
  await applyEnsureNoFailures([
Packit f0b94e
    {id: guid,
Packit f0b94e
     histUri: uri.spec,
Packit f0b94e
     title: "TPS CONFIG",
Packit f0b94e
     visits: [{date: TIMESTAMP3,
Packit f0b94e
               type: Ci.nsINavHistoryService.TRANSITION_TYPED}]}
Packit f0b94e
  ]);
Packit f0b94e
  Assert.equal(false, (await store.itemExists(guid)));
Packit f0b94e
  let queryres = await PlacesUtils.history.fetch(uri.spec, {
Packit f0b94e
    includeVisits: true,
Packit f0b94e
  });
Packit f0b94e
  Assert.equal(null, queryres);
Packit f0b94e
});
Packit f0b94e
Packit f0b94e
add_task(async function cleanup() {
Packit f0b94e
  _("Clean up.");
Packit f0b94e
  await PlacesUtils.history.clear();
Packit f0b94e
});