Source code
Revision control
Copy as Markdown
Other Tools
Test Info:
/* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
add_task(async function test_fetch_existent() {
await PlacesUtils.history.clear();
await PlacesUtils.bookmarks.eraseEverything();
// Populate places and historyvisits.
let uri = NetUtil.newURI(uriString);
let title = `Test Visit ${Math.random()}`;
let dates = [];
let visits = [];
let transitions = [
PlacesUtils.history.TRANSITION_LINK,
PlacesUtils.history.TRANSITION_TYPED,
PlacesUtils.history.TRANSITION_BOOKMARK,
PlacesUtils.history.TRANSITION_REDIRECT_TEMPORARY,
PlacesUtils.history.TRANSITION_REDIRECT_PERMANENT,
PlacesUtils.history.TRANSITION_DOWNLOAD,
PlacesUtils.history.TRANSITION_FRAMED_LINK,
PlacesUtils.history.TRANSITION_RELOAD,
];
let guid = "";
for (let i = 0; i != transitions.length; i++) {
dates.push(new Date(Date.now() - i * 10000000));
visits.push({
uri,
title,
transition: transitions[i],
visitDate: dates[i],
});
}
await PlacesTestUtils.addVisits(visits);
Assert.ok(await PlacesTestUtils.isPageInDB(uri));
Assert.equal(await PlacesTestUtils.visitsInDB(uri), visits.length);
// Store guid for further use in testing.
guid = await PlacesTestUtils.getDatabaseValue("moz_places", "guid", {
url: uri,
});
Assert.ok(guid, guid);
// Initialize the objects to compare against.
let idealPageInfo = {
url: new URL(uriString),
guid,
title,
};
let idealVisits = visits.map(v => {
return {
date: v.visitDate,
transition: v.transition,
};
});
// We should check these 4 cases:
// 1, 2: visits not included, by URL and guid (same result expected).
// 3, 4: visits included, by URL and guid (same result expected).
for (let includeVisits of [true, false]) {
for (let guidOrURL of [uri, guid]) {
let pageInfo = await PlacesUtils.history.fetch(guidOrURL, {
includeVisits,
});
if (includeVisits) {
idealPageInfo.visits = idealVisits;
} else {
// We need to explicitly delete this property since deepEqual looks at
// the list of properties as well (`visits in pageInfo` is true here).
delete idealPageInfo.visits;
}
// Since idealPageInfo doesn't contain a frecency, check it and delete.
Assert.ok(typeof pageInfo.frecency === "number");
delete pageInfo.frecency;
// Visits should be from newer to older.
if (includeVisits) {
for (let i = 0; i !== pageInfo.visits.length - 1; i++) {
Assert.lessOrEqual(
pageInfo.visits[i + 1].date.getTime(),
pageInfo.visits[i].date.getTime()
);
}
}
Assert.deepEqual(idealPageInfo, pageInfo);
}
}
});
add_task(async function test_fetch_page_meta_info() {
await PlacesUtils.history.clear();
await PlacesTestUtils.addVisits(TEST_URI);
Assert.ok(page_in_database(TEST_URI));
// Test fetching the null values
let includeMeta = true;
let pageInfo = await PlacesUtils.history.fetch(TEST_URI, { includeMeta });
Assert.strictEqual(
null,
pageInfo.previewImageURL,
"fetch should return a null previewImageURL"
);
Assert.strictEqual(
"",
pageInfo.siteName,
"fetch should return a null siteName"
);
Assert.equal(
"",
pageInfo.description,
"fetch should return a empty string description"
);
// Now set the pageMetaInfo for this page
let description = "Test description";
let siteName = "Mozilla";
await PlacesUtils.history.update({
url: TEST_URI,
description,
previewImageURL,
siteName,
});
includeMeta = true;
pageInfo = await PlacesUtils.history.fetch(TEST_URI, { includeMeta });
Assert.equal(
previewImageURL,
pageInfo.previewImageURL.href,
"fetch should return a previewImageURL"
);
Assert.equal(siteName, pageInfo.siteName, "fetch should return a siteName");
Assert.equal(
description,
pageInfo.description,
"fetch should return a description"
);
includeMeta = false;
pageInfo = await PlacesUtils.history.fetch(TEST_URI, { includeMeta });
Assert.ok(
!("description" in pageInfo),
"fetch should not return a description if includeMeta is false"
);
Assert.ok(
!("siteName" in pageInfo),
"fetch should not return a siteName if includeMeta is false"
);
Assert.ok(
!("previewImageURL" in pageInfo),
"fetch should not return a previewImageURL if includeMeta is false"
);
});
add_task(async function test_fetch_annotations() {
await PlacesUtils.history.clear();
await PlacesTestUtils.addVisits(TEST_URI);
Assert.ok(page_in_database(TEST_URI));
let includeAnnotations = true;
let pageInfo = await PlacesUtils.history.fetch(TEST_URI, {
includeAnnotations,
});
Assert.equal(
pageInfo.annotations.size,
0,
"fetch should return an empty annotation map"
);
await PlacesUtils.history.update({
url: TEST_URI,
annotations: new Map([["test/annotation", "testContent"]]),
});
pageInfo = await PlacesUtils.history.fetch(TEST_URI, { includeAnnotations });
Assert.equal(
pageInfo.annotations.size,
1,
"fetch should have only one annotation"
);
Assert.equal(
pageInfo.annotations.get("test/annotation"),
"testContent",
"fetch should return the expected annotation"
);
await PlacesUtils.history.update({
url: TEST_URI,
annotations: new Map([["test/annotation2", 123]]),
});
pageInfo = await PlacesUtils.history.fetch(TEST_URI, { includeAnnotations });
Assert.equal(
pageInfo.annotations.size,
2,
"fetch should have returned two annotations"
);
Assert.equal(
pageInfo.annotations.get("test/annotation"),
"testContent",
"fetch should still have the first annotation"
);
Assert.equal(
pageInfo.annotations.get("test/annotation2"),
123,
"fetch should have the second annotation"
);
includeAnnotations = false;
pageInfo = await PlacesUtils.history.fetch(TEST_URI, { includeAnnotations });
Assert.ok(
!("annotations" in pageInfo),
"fetch should not return annotations if includeAnnotations is false"
);
});
add_task(async function test_fetch_nonexistent() {
await PlacesUtils.history.clear();
await PlacesUtils.bookmarks.eraseEverything();
let pageInfo = await PlacesUtils.history.fetch(uri);
Assert.equal(pageInfo, null);
});
add_task(async function test_error_cases() {
Assert.throws(
() => PlacesUtils.history.fetch("3"),
/TypeError: URL constructor: 3 is not a valid /
);
Assert.throws(
() => PlacesUtils.history.fetch({ not: "a valid string or guid" }),
/TypeError: Invalid url or guid/
);
Assert.throws(
/TypeError: options should be/
);
Assert.throws(
/TypeError: options should be/
);
Assert.throws(
() =>
includeVisits: "not a boolean",
}),
/TypeError: includeVisits should be a/
);
Assert.throws(
() =>
includeMeta: "not a boolean",
}),
/TypeError: includeMeta should be a/
);
Assert.throws(
() =>
includeAnnotations: "not a boolean",
}),
/TypeError: includeAnnotations should be a/
);
});