|
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 |
});
|