Source code

Revision control

Copy as Markdown

Other Tools

Test Info: Warnings

/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set sts=2 sw=2 et tw=80: */
"use strict";
const { AddonTestUtils } = ChromeUtils.importESModule(
);
ChromeUtils.defineESModuleGetters(this, {
PlacesUtils: "resource://gre/modules/PlacesUtils.sys.mjs",
});
AddonTestUtils.init(this);
AddonTestUtils.overrideCertDB();
AddonTestUtils.createAppInfo(
"xpcshell@tests.mozilla.org",
"XPCShell",
"1",
"43"
);
add_task(async function test_bookmarks() {
async function background() {
let unsortedId, ourId;
let initialBookmarkCount = 0;
let createdBookmarks = new Set();
let createdFolderId;
let createdSeparatorId;
let collectedEvents = [];
const nonExistentId = "000000000000";
const bookmarkGuids = {
menuGuid: "menu________",
toolbarGuid: "toolbar_____",
unfiledGuid: "unfiled_____",
rootGuid: "root________",
};
function checkOurBookmark(bookmark) {
browser.test.assertEq(ourId, bookmark.id, "Bookmark has the expected Id");
browser.test.assertTrue(
"parentId" in bookmark,
"Bookmark has a parentId"
);
browser.test.assertEq(
0,
bookmark.index,
"Bookmark has the expected index"
); // We assume there are no other bookmarks.
browser.test.assertEq(
bookmark.url,
"Bookmark has the expected url"
);
browser.test.assertEq(
"test bookmark",
bookmark.title,
"Bookmark has the expected title"
);
browser.test.assertTrue(
"dateAdded" in bookmark,
"Bookmark has a dateAdded"
);
browser.test.assertFalse(
"dateGroupModified" in bookmark,
"Bookmark does not have a dateGroupModified"
);
browser.test.assertFalse(
"unmodifiable" in bookmark,
"Bookmark is not unmodifiable"
);
browser.test.assertEq(
"bookmark",
bookmark.type,
"Bookmark is of type bookmark"
);
}
function checkBookmark(expected, bookmark) {
browser.test.assertEq(
expected.url,
bookmark.url,
"Bookmark has the expected url"
);
browser.test.assertEq(
expected.title,
bookmark.title,
"Bookmark has the expected title"
);
browser.test.assertEq(
expected.index,
bookmark.index,
"Bookmark has expected index"
);
browser.test.assertEq(
"bookmark",
bookmark.type,
"Bookmark is of type bookmark"
);
if ("parentId" in expected) {
browser.test.assertEq(
expected.parentId,
bookmark.parentId,
"Bookmark has the expected parentId"
);
}
}
function checkOnCreated(
id,
parentId,
index,
title,
url,
dateAdded,
type = "bookmark"
) {
let createdData = collectedEvents.pop();
browser.test.assertEq(
"onCreated",
createdData.event,
"onCreated was the last event received"
);
browser.test.assertEq(
id,
createdData.id,
"onCreated event received the expected id"
);
let bookmark = createdData.bookmark;
browser.test.assertEq(
id,
bookmark.id,
"onCreated event received the expected bookmark id"
);
browser.test.assertEq(
parentId,
bookmark.parentId,
"onCreated event received the expected bookmark parentId"
);
browser.test.assertEq(
index,
bookmark.index,
"onCreated event received the expected bookmark index"
);
browser.test.assertEq(
title,
bookmark.title,
"onCreated event received the expected bookmark title"
);
browser.test.assertEq(
url,
bookmark.url,
"onCreated event received the expected bookmark url"
);
browser.test.assertEq(
dateAdded,
bookmark.dateAdded,
"onCreated event received the expected bookmark dateAdded"
);
browser.test.assertEq(
type,
bookmark.type,
"onCreated event received the expected bookmark type"
);
}
function checkOnChanged(id, url, title) {
// If both url and title are changed, then url is fired last.
let changedData = collectedEvents.pop();
browser.test.assertEq(
"onChanged",
changedData.event,
"onChanged was the last event received"
);
browser.test.assertEq(
id,
changedData.id,
"onChanged event received the expected id"
);
browser.test.assertEq(
url,
changedData.info.url,
"onChanged event received the expected url"
);
// title is fired first.
changedData = collectedEvents.pop();
browser.test.assertEq(
"onChanged",
changedData.event,
"onChanged was the last event received"
);
browser.test.assertEq(
id,
changedData.id,
"onChanged event received the expected id"
);
browser.test.assertEq(
title,
changedData.info.title,
"onChanged event received the expected title"
);
}
function checkOnMoved(id, parentId, oldParentId, index, oldIndex) {
let movedData = collectedEvents.pop();
browser.test.assertEq(
"onMoved",
movedData.event,
"onMoved was the last event received"
);
browser.test.assertEq(
id,
movedData.id,
"onMoved event received the expected id"
);
let info = movedData.info;
browser.test.assertEq(
parentId,
info.parentId,
"onMoved event received the expected parentId"
);
browser.test.assertEq(
oldParentId,
info.oldParentId,
"onMoved event received the expected oldParentId"
);
browser.test.assertEq(
index,
info.index,
"onMoved event received the expected index"
);
browser.test.assertEq(
oldIndex,
info.oldIndex,
"onMoved event received the expected oldIndex"
);
}
function checkOnRemoved(id, parentId, index, title, url, type = "folder") {
let removedData = collectedEvents.pop();
browser.test.assertEq(
"onRemoved",
removedData.event,
"onRemoved was the last event received"
);
browser.test.assertEq(
id,
removedData.id,
"onRemoved event received the expected id"
);
let info = removedData.info;
browser.test.assertEq(
parentId,
removedData.info.parentId,
"onRemoved event received the expected parentId"
);
browser.test.assertEq(
index,
removedData.info.index,
"onRemoved event received the expected index"
);
let node = info.node;
browser.test.assertEq(
id,
node.id,
"onRemoved event received the expected node id"
);
browser.test.assertEq(
parentId,
node.parentId,
"onRemoved event received the expected node parentId"
);
browser.test.assertEq(
index,
node.index,
"onRemoved event received the expected node index"
);
browser.test.assertEq(
url,
node.url,
"onRemoved event received the expected node url"
);
browser.test.assertEq(
title,
node.title,
"onRemoved event received the expected node title"
);
browser.test.assertEq(
type,
node.type,
"onRemoved event received the expected node type"
);
}
browser.bookmarks.onChanged.addListener((id, info) => {
collectedEvents.push({ event: "onChanged", id, info });
});
browser.bookmarks.onCreated.addListener((id, bookmark) => {
collectedEvents.push({ event: "onCreated", id, bookmark });
});
browser.bookmarks.onMoved.addListener((id, info) => {
collectedEvents.push({ event: "onMoved", id, info });
});
browser.bookmarks.onRemoved.addListener((id, info) => {
collectedEvents.push({ event: "onRemoved", id, info });
});
await browser.test.assertRejects(
browser.bookmarks.get(["not-a-bookmark-guid"]),
/Invalid value for property 'guid': "not-a-bookmark-guid"/,
"Expected error thrown when trying to get a bookmark using an invalid guid"
);
await browser.test
.assertRejects(
browser.bookmarks.get([nonExistentId]),
/Bookmark not found/,
"Expected error thrown when trying to get a bookmark using a non-existent Id"
)
.then(() => {
return browser.bookmarks.search({});
})
.then(results => {
initialBookmarkCount = results.length;
return browser.bookmarks.create({
title: "test bookmark",
type: "bookmark",
});
})
.then(result => {
ourId = result.id;
checkOurBookmark(result);
browser.test.assertEq(
1,
collectedEvents.length,
"1 expected event received"
);
checkOnCreated(
ourId,
bookmarkGuids.unfiledGuid,
0,
"test bookmark",
result.dateAdded
);
return browser.bookmarks.get(ourId);
})
.then(results => {
browser.test.assertEq(results.length, 1);
checkOurBookmark(results[0]);
unsortedId = results[0].parentId;
return browser.bookmarks.get(unsortedId);
})
.then(results => {
let folder = results[0];
browser.test.assertEq(1, results.length, "1 bookmark was returned");
browser.test.assertEq(
unsortedId,
folder.id,
"Folder has the expected id"
);
browser.test.assertTrue("parentId" in folder, "Folder has a parentId");
browser.test.assertTrue("index" in folder, "Folder has an index");
browser.test.assertEq(
undefined,
folder.url,
"Folder does not have a url"
);
browser.test.assertEq(
"Other Bookmarks",
folder.title,
"Folder has the expected title"
);
browser.test.assertTrue(
"dateAdded" in folder,
"Folder has a dateAdded"
);
browser.test.assertTrue(
"dateGroupModified" in folder,
"Folder has a dateGroupModified"
);
browser.test.assertFalse(
"unmodifiable" in folder,
"Folder is not unmodifiable"
); // TODO: Do we want to enable this?
browser.test.assertEq(
"folder",
folder.type,
"Folder has a type of folder"
);
return browser.bookmarks.getChildren(unsortedId);
})
.then(async results => {
browser.test.assertEq(1, results.length, "The folder has one child");
checkOurBookmark(results[0]);
await browser.test.assertRejects(
browser.bookmarks.update(nonExistentId, { title: "new test title" }),
/No bookmarks found for the provided GUID/,
"Expected error thrown when trying to update a non-existent bookmark"
);
return browser.bookmarks.update(ourId, {
title: "new test title",
});
})
.then(async result => {
browser.test.assertEq(
"new test title",
result.title,
"Updated bookmark has the expected title"
);
browser.test.assertEq(
result.url,
"Updated bookmark has the expected URL"
);
browser.test.assertEq(
ourId,
result.id,
"Updated bookmark has the expected id"
);
browser.test.assertEq(
"bookmark",
result.type,
"Updated bookmark has a type of bookmark"
);
browser.test.assertEq(
2,
collectedEvents.length,
"2 expected events received"
);
checkOnChanged(ourId, "http://example.com/", "new test title");
await browser.test.assertRejects(
browser.bookmarks.update(ourId, { url: "this is not a valid url" }),
/Invalid bookmark:/,
"Expected error thrown when trying update with an invalid url"
);
return browser.bookmarks.getTree();
})
.then(results => {
browser.test.assertEq(1, results.length, "getTree returns one result");
let bookmark = results[0].children.find(
bookmarkItem => bookmarkItem.id == unsortedId
);
browser.test.assertEq(
"Other Bookmarks",
bookmark.title,
"Folder returned from getTree has the expected title"
);
browser.test.assertEq(
"folder",
bookmark.type,
"Folder returned from getTree has the expected type"
);
return browser.test.assertRejects(
browser.bookmarks.create({ parentId: "invalid" }),
error =>
error.message.includes("Invalid bookmark") &&
error.message.includes(`"parentGuid":"invalid"`),
"Expected error thrown when trying to create a bookmark with an invalid parentId"
);
})
.then(() => {
return browser.bookmarks.remove(ourId);
})
.then(result => {
browser.test.assertEq(
undefined,
result,
"Removing a bookmark returns undefined"
);
browser.test.assertEq(
1,
collectedEvents.length,
"1 expected events received"
);
checkOnRemoved(
ourId,
bookmarkGuids.unfiledGuid,
0,
"new test title",
"bookmark"
);
return browser.test.assertRejects(
browser.bookmarks.get(ourId),
/Bookmark not found/,
"Expected error thrown when trying to get a removed bookmark"
);
})
.then(() => {
return browser.test.assertRejects(
browser.bookmarks.remove(nonExistentId),
/No bookmarks found for the provided GUID/,
"Expected error thrown when trying removed a non-existent bookmark"
);
})
.then(() => {
// test bookmarks.search
return Promise.all([
browser.bookmarks.create({
title: "Μοζιλλας",
}),
browser.bookmarks.create({
title: "Example",
}),
browser.bookmarks.create({ title: "Mozilla Folder", type: "folder" }),
browser.bookmarks.create({ title: "EFF", url: "http://eff.org/" }),
browser.bookmarks.create({
title: "Menu Item",
parentId: bookmarkGuids.menuGuid,
}),
browser.bookmarks.create({
title: "Toolbar Item",
parentId: bookmarkGuids.toolbarGuid,
}),
]);
})
.then(results => {
browser.test.assertEq(
6,
collectedEvents.length,
"6 expected events received"
);
checkOnCreated(
results[5].id,
bookmarkGuids.toolbarGuid,
0,
"Toolbar Item",
results[5].dateAdded
);
checkOnCreated(
results[4].id,
bookmarkGuids.menuGuid,
0,
"Menu Item",
results[4].dateAdded
);
checkOnCreated(
results[3].id,
bookmarkGuids.unfiledGuid,
0,
"EFF",
results[3].dateAdded
);
checkOnCreated(
results[2].id,
bookmarkGuids.unfiledGuid,
0,
"Mozilla Folder",
undefined,
results[2].dateAdded,
"folder"
);
checkOnCreated(
results[1].id,
bookmarkGuids.unfiledGuid,
0,
"Example",
results[1].dateAdded
);
checkOnCreated(
results[0].id,
bookmarkGuids.unfiledGuid,
0,
"Μοζιλλας",
results[0].dateAdded
);
for (let result of results) {
if (result.title !== "Mozilla Folder") {
createdBookmarks.add(result.id);
}
}
let folderResult = results[2];
createdFolderId = folderResult.id;
return Promise.all([
browser.bookmarks.create({
title: "Mozilla",
parentId: createdFolderId,
}),
browser.bookmarks.create({
parentId: createdFolderId,
type: "separator",
}),
browser.bookmarks.create({
title: "Mozilla Corporation",
parentId: createdFolderId,
}),
browser.bookmarks.create({
title: "Firefox",
parentId: createdFolderId,
}),
])
.then(newBookmarks => {
browser.test.assertEq(
4,
collectedEvents.length,
"4 expected events received"
);
checkOnCreated(
newBookmarks[3].id,
createdFolderId,
0,
"Firefox",
newBookmarks[3].dateAdded
);
checkOnCreated(
newBookmarks[2].id,
createdFolderId,
0,
"Mozilla Corporation",
newBookmarks[2].dateAdded
);
checkOnCreated(
newBookmarks[1].id,
createdFolderId,
0,
"",
"data:",
newBookmarks[1].dateAdded,
"separator"
);
checkOnCreated(
newBookmarks[0].id,
createdFolderId,
0,
"Mozilla",
newBookmarks[0].dateAdded
);
return browser.bookmarks.create({
title: "About Mozilla",
parentId: createdFolderId,
index: 1,
});
})
.then(result => {
browser.test.assertEq(
1,
collectedEvents.length,
"1 expected events received"
);
checkOnCreated(
result.id,
createdFolderId,
1,
"About Mozilla",
result.dateAdded
);
// returns all items on empty object
return browser.bookmarks.search({});
})
.then(async bookmarksSearchResults => {
browser.test.assertTrue(
bookmarksSearchResults.length >= 10,
"At least as many bookmarks as added were returned by search({})"
);
await browser.test.assertRejects(
browser.bookmarks.remove(createdFolderId),
/Cannot remove a non-empty folder/,
"Expected error thrown when trying to remove a non-empty folder"
);
return browser.bookmarks.getSubTree(createdFolderId);
});
})
.then(results => {
browser.test.assertEq(
1,
results.length,
"Expected number of nodes returned by getSubTree"
);
browser.test.assertEq(
"Mozilla Folder",
results[0].title,
"Folder has the expected title"
);
browser.test.assertEq(
bookmarkGuids.unfiledGuid,
results[0].parentId,
"Folder has the expected parentId"
);
browser.test.assertEq(
"folder",
results[0].type,
"Folder has the expected type"
);
let children = results[0].children;
browser.test.assertEq(
5,
children.length,
"Expected number of bookmarks returned by getSubTree"
);
browser.test.assertEq(
"Firefox",
children[0].title,
"Bookmark has the expected title"
);
browser.test.assertEq(
"bookmark",
children[0].type,
"Bookmark has the expected type"
);
browser.test.assertEq(
"About Mozilla",
children[1].title,
"Bookmark has the expected title"
);
browser.test.assertEq(
"bookmark",
children[1].type,
"Bookmark has the expected type"
);
browser.test.assertEq(
1,
children[1].index,
"Bookmark has the expected index"
);
browser.test.assertEq(
"Mozilla Corporation",
children[2].title,
"Bookmark has the expected title"
);
browser.test.assertEq(
"",
children[3].title,
"Separator has the expected title"
);
browser.test.assertEq(
"data:",
children[3].url,
"Separator has the expected url"
);
browser.test.assertEq(
"separator",
children[3].type,
"Separator has the expected type"
);
browser.test.assertEq(
"Mozilla",
children[4].title,
"Bookmark has the expected title"
);
// throws an error for invalid query objects
browser.test.assertThrows(
() => browser.bookmarks.search(),
/Incorrect argument types for bookmarks.search/,
"Expected error thrown when trying to search with no arguments"
);
browser.test.assertThrows(
() => browser.bookmarks.search(null),
/Incorrect argument types for bookmarks.search/,
"Expected error thrown when trying to search with null as an argument"
);
browser.test.assertThrows(
() => browser.bookmarks.search(() => {}),
/Incorrect argument types for bookmarks.search/,
"Expected error thrown when trying to search with a function as an argument"
);
browser.test.assertThrows(
() => browser.bookmarks.search({ banana: "banana" }),
/an unexpected "banana" property/,
"Expected error thrown when trying to search with a banana as an argument"
);
browser.test.assertThrows(
() => browser.bookmarks.search({ url: "spider-man vs. batman" }),
/must match the format "url"/,
"Expected error thrown when trying to search with a illegally formatted URL"
);
// queries the full url
return browser.bookmarks.search("http://example.org/");
})
.then(results => {
browser.test.assertEq(
1,
results.length,
"Expected number of results returned for url search"
);
checkBookmark(
{ title: "Example", url: "http://example.org/", index: 2 },
results[0]
);
// queries a partial url
return browser.bookmarks.search("example.org");
})
.then(results => {
browser.test.assertEq(
1,
results.length,
"Expected number of results returned for url search"
);
checkBookmark(
{ title: "Example", url: "http://example.org/", index: 2 },
results[0]
);
// queries the title
return browser.bookmarks.search("EFF");
})
.then(results => {
browser.test.assertEq(
1,
results.length,
"Expected number of results returned for title search"
);
checkBookmark(
{
title: "EFF",
url: "http://eff.org/",
index: 0,
parentId: bookmarkGuids.unfiledGuid,
},
results[0]
);
// finds menu items
return browser.bookmarks.search("Menu Item");
})
.then(results => {
browser.test.assertEq(
1,
results.length,
"Expected number of results returned for menu item search"
);
checkBookmark(
{
title: "Menu Item",
index: 0,
parentId: bookmarkGuids.menuGuid,
},
results[0]
);
// finds toolbar items
return browser.bookmarks.search("Toolbar Item");
})
.then(results => {
browser.test.assertEq(
1,
results.length,
"Expected number of results returned for toolbar item search"
);
checkBookmark(
{
title: "Toolbar Item",
index: 0,
parentId: bookmarkGuids.toolbarGuid,
},
results[0]
);
// finds folders
return browser.bookmarks.search("Mozilla Folder");
})
.then(results => {
browser.test.assertEq(
1,
results.length,
"Expected number of folders returned"
);
browser.test.assertEq(
"Mozilla Folder",
results[0].title,
"Folder has the expected title"
);
browser.test.assertEq(
"folder",
results[0].type,
"Folder has the expected type"
);
// is case-insensitive
return browser.bookmarks.search("corporation");
})
.then(results => {
browser.test.assertEq(
1,
results.length,
"Expected number of results returnedfor case-insensitive search"
);
browser.test.assertEq(
"Mozilla Corporation",
results[0].title,
"Bookmark has the expected title"
);
// is case-insensitive for non-ascii
return browser.bookmarks.search("ΜοΖΙΛΛΑς");
})
.then(results => {
browser.test.assertEq(
1,
results.length,
"Expected number of results returned for non-ascii search"
);
browser.test.assertEq(
"Μοζιλλας",
results[0].title,
"Bookmark has the expected title"
);
// returns multiple results
return browser.bookmarks.search("allizom");
})
.then(results => {
browser.test.assertEq(
4,
results.length,
"Expected number of multiple results returned"
);
browser.test.assertEq(
"Mozilla",
results[0].title,
"Bookmark has the expected title"
);
browser.test.assertEq(
"Mozilla Corporation",
results[1].title,
"Bookmark has the expected title"
);
browser.test.assertEq(
"Firefox",
results[2].title,
"Bookmark has the expected title"
);
browser.test.assertEq(
"About Mozilla",
results[3].title,
"Bookmark has the expected title"
);
// accepts a url field
return browser.bookmarks.search({ url: "http://allizom.com/" });
})
.then(results => {
browser.test.assertEq(
1,
results.length,
"Expected number of results returned for url field"
);
checkBookmark(
{
title: "Mozilla Corporation",
index: 2,
},
results[0]
);
// normalizes urls
return browser.bookmarks.search({ url: "http://allizom.com" });
})
.then(results => {
browser.test.assertEq(
results.length,
1,
"Expected number of results returned for normalized url field"
);
checkBookmark(
{
title: "Mozilla Corporation",
index: 2,
},
results[0]
);
// normalizes urls even more
return browser.bookmarks.search({ url: "http:allizom.com" });
})
.then(results => {
browser.test.assertEq(
results.length,
1,
"Expected number of results returned for normalized url field"
);
checkBookmark(
{
title: "Mozilla Corporation",
index: 2,
},
results[0]
);
// accepts a title field
return browser.bookmarks.search({ title: "Mozilla" });
})
.then(results => {
browser.test.assertEq(
results.length,
1,
"Expected number of results returned for title field"
);
checkBookmark(
{ title: "Mozilla", url: "http://allizom.org/", index: 4 },
results[0]
);
// can combine title and query
return browser.bookmarks.search({ title: "Mozilla", query: "allizom" });
})
.then(results => {
browser.test.assertEq(
1,
results.length,
"Expected number of results returned for title and query fields"
);
checkBookmark(
{ title: "Mozilla", url: "http://allizom.org/", index: 4 },
results[0]
);
// uses AND conditions
return browser.bookmarks.search({ title: "EFF", query: "allizom" });
})
.then(results => {
browser.test.assertEq(
0,
results.length,
"Expected number of results returned for non-matching title and query fields"
);
// returns an empty array on item not found
return browser.bookmarks.search("microsoft");
})
.then(results => {
browser.test.assertEq(
0,
results.length,
"Expected number of results returned for non-matching search"
);
browser.test.assertThrows(
() => browser.bookmarks.getRecent(""),
/Incorrect argument types for bookmarks.getRecent/,
"Expected error thrown when calling getRecent with an empty string"
);
})
.then(() => {
browser.test.assertThrows(
() => browser.bookmarks.getRecent(1.234),
/Incorrect argument types for bookmarks.getRecent/,
"Expected error thrown when calling getRecent with a decimal number"
);
})
.then(() => {
return Promise.all([
browser.bookmarks.search("corporation"),
browser.bookmarks.getChildren(bookmarkGuids.menuGuid),
]);
})
.then(results => {
let corporationBookmark = results[0][0];
let childCount = results[1].length;
browser.test.assertEq(
2,
corporationBookmark.index,
"Bookmark has the expected index"
);
return browser.bookmarks
.move(corporationBookmark.id, { index: 0 })
.then(result => {
browser.test.assertEq(
0,
result.index,
"Bookmark has the expected index"
);
browser.test.assertEq(
1,
collectedEvents.length,
"1 expected events received"
);
checkOnMoved(
corporationBookmark.id,
createdFolderId,
createdFolderId,
0,
2
);
return browser.bookmarks.move(corporationBookmark.id, {
parentId: bookmarkGuids.menuGuid,
});
})
.then(result => {
browser.test.assertEq(
bookmarkGuids.menuGuid,
result.parentId,
"Bookmark has the expected parent"
);
browser.test.assertEq(
childCount,
result.index,
"Bookmark has the expected index"
);
browser.test.assertEq(
1,
collectedEvents.length,
"1 expected events received"
);
checkOnMoved(
corporationBookmark.id,
bookmarkGuids.menuGuid,
createdFolderId,
1,
0
);
return browser.bookmarks.move(corporationBookmark.id, { index: 0 });
})
.then(result => {
browser.test.assertEq(
bookmarkGuids.menuGuid,
result.parentId,
"Bookmark has the expected parent"
);
browser.test.assertEq(
0,
result.index,
"Bookmark has the expected index"
);
browser.test.assertEq(
1,
collectedEvents.length,
"1 expected events received"
);
checkOnMoved(
corporationBookmark.id,
bookmarkGuids.menuGuid,
bookmarkGuids.menuGuid,
0,
1
);
return browser.bookmarks.move(corporationBookmark.id, {
parentId: bookmarkGuids.toolbarGuid,
index: 1,
});
})
.then(result => {
browser.test.assertEq(
bookmarkGuids.toolbarGuid,
result.parentId,
"Bookmark has the expected parent"
);
browser.test.assertEq(
1,
result.index,
"Bookmark has the expected index"
);
browser.test.assertEq(
1,
collectedEvents.length,
"1 expected events received"
);
checkOnMoved(
corporationBookmark.id,
bookmarkGuids.toolbarGuid,
bookmarkGuids.menuGuid,
1,
0
);
createdBookmarks.add(corporationBookmark.id);
});
})
.then(() => {
return browser.bookmarks.getRecent(4);
})
.then(results => {
browser.test.assertEq(
4,
results.length,
"Expected number of results returned by getRecent"
);
let prevDate = results[0].dateAdded;
for (let bookmark of results) {
browser.test.assertTrue(
bookmark.dateAdded <= prevDate,
"The recent bookmarks are sorted by dateAdded"
);
prevDate = bookmark.dateAdded;
}
let bookmarksByTitle = results.sort((a, b) => {
return a.title.localeCompare(b.title);
});
browser.test.assertEq(
"About Mozilla",
bookmarksByTitle[0].title,
"Bookmark has the expected title"
);
browser.test.assertEq(
"Firefox",
bookmarksByTitle[1].title,
"Bookmark has the expected title"
);
browser.test.assertEq(
"Mozilla",
bookmarksByTitle[2].title,
"Bookmark has the expected title"
);
browser.test.assertEq(
"Mozilla Corporation",
bookmarksByTitle[3].title,
"Bookmark has the expected title"
);
return browser.bookmarks.search({});
})
.then(results => {
let startBookmarkCount = results.length;
return browser.bookmarks
.search({ title: "Mozilla Folder" })
.then(result => {
return browser.bookmarks.removeTree(result[0].id);
})
.then(() => {
browser.test.assertEq(
1,
collectedEvents.length,
"1 expected events received"
);
checkOnRemoved(
createdFolderId,
bookmarkGuids.unfiledGuid,
1,
"Mozilla Folder"
);
return browser.bookmarks.search({}).then(searchResults => {
browser.test.assertEq(
startBookmarkCount - 5,
searchResults.length,
"Expected number of results returned after removeTree"
);
});
});
})
.then(() => {
return browser.bookmarks.create({ title: "Empty Folder" });
})
.then(result => {
createdFolderId = result.id;
browser.test.assertEq(
1,
collectedEvents.length,
"1 expected events received"
);
checkOnCreated(
createdFolderId,
bookmarkGuids.unfiledGuid,
3,
"Empty Folder",
undefined,
result.dateAdded,
"folder"
);
browser.test.assertEq(
"Empty Folder",
result.title,
"Folder has the expected title"
);
browser.test.assertEq(
"folder",
result.type,
"Folder has the expected type"
);
return browser.bookmarks.create({
parentId: createdFolderId,
type: "separator",
});
})
.then(result => {
createdSeparatorId = result.id;
browser.test.assertEq(
1,
collectedEvents.length,
"1 expected events received"
);
checkOnCreated(
createdSeparatorId,
createdFolderId,
0,
"",
"data:",
result.dateAdded,
"separator"
);
return browser.bookmarks.remove(createdSeparatorId);
})
.then(() => {
browser.test.assertEq(
1,
collectedEvents.length,
"1 expected events received"
);
checkOnRemoved(
createdSeparatorId,
createdFolderId,
0,
"",
"data:",
"separator"
);
return browser.bookmarks.remove(createdFolderId);
})
.then(() => {
browser.test.assertEq(
1,
collectedEvents.length,
"1 expected events received"
);
checkOnRemoved(
createdFolderId,
bookmarkGuids.unfiledGuid,
3,
"Empty Folder"
);
return browser.test.assertRejects(
browser.bookmarks.get(createdFolderId),
/Bookmark not found/,
"Expected error thrown when trying to get a removed folder"
);
})
.then(() => {
return browser.test.assertRejects(
browser.bookmarks.getChildren(nonExistentId),
/root is null/,
"Expected error thrown when trying to getChildren for a non-existent folder"
);
})
.then(() => {
return browser.test.assertRejects(
browser.bookmarks.move(nonExistentId, {}),
/No bookmarks found for the provided GUID/,
"Expected error thrown when calling move with a non-existent bookmark"
);
})
.then(() => {
return browser.test.assertRejects(
browser.bookmarks.create({
title: "test root folder",
parentId: bookmarkGuids.rootGuid,
}),
"The bookmark root cannot be modified",
"Expected error thrown when creating bookmark folder at the root"
);
})
.then(() => {
return browser.test.assertRejects(
browser.bookmarks.update(bookmarkGuids.rootGuid, {
title: "test update title",
}),
"The bookmark root cannot be modified",
"Expected error thrown when updating root"
);
})
.then(() => {
return browser.test.assertRejects(
browser.bookmarks.remove(bookmarkGuids.rootGuid),
"The bookmark root cannot be modified",
"Expected error thrown when removing root"
);
})
.then(() => {
return browser.test.assertRejects(
browser.bookmarks.removeTree(bookmarkGuids.rootGuid),
"The bookmark root cannot be modified",
"Expected error thrown when removing root tree"
);
})
.then(() => {
return browser.bookmarks.create({ title: "Empty Folder" });
})
.then(async result => {
createdFolderId = result.id;
browser.test.assertEq(
1,
collectedEvents.length,
"1 expected events received"
);
checkOnCreated(
createdFolderId,
bookmarkGuids.unfiledGuid,
3,
"Empty Folder",
undefined,
result.dateAdded,
"folder"
);
await browser.test.assertRejects(
browser.bookmarks.move(createdFolderId, {
parentId: bookmarkGuids.rootGuid,
}),
"The bookmark root cannot be modified",
"Expected error thrown when moving bookmark folder to the root"
);
return browser.bookmarks.remove(createdFolderId);
})
.then(() => {
browser.test.assertEq(
1,
collectedEvents.length,
"1 expected events received"
);
checkOnRemoved(
createdFolderId,
bookmarkGuids.unfiledGuid,
3,
"Empty Folder",
undefined,
"folder"
);
return browser.test.assertRejects(
browser.bookmarks.get(createdFolderId),
"Bookmark not found",
"Expected error thrown when trying to get a removed folder"
);
})
.then(() => {
return browser.test.assertRejects(
browser.bookmarks.move(bookmarkGuids.rootGuid, {
parentId: bookmarkGuids.unfiledGuid,
}),
"The bookmark root cannot be modified",
"Expected error thrown when moving root"
);
})
.then(() => {
// remove all created bookmarks
let promises = Array.from(createdBookmarks, guid =>
browser.bookmarks.remove(guid)
);
return Promise.all(promises);
})
.then(() => {
browser.test.assertEq(
createdBookmarks.size,
collectedEvents.length,
"expected number of events received"
);
return browser.bookmarks.search({});
})
.then(results => {
browser.test.assertEq(
initialBookmarkCount,
results.length,
"All created bookmarks have been removed"
);
return browser.test.notifyPass("bookmarks");
})
.catch(error => {
browser.test.fail(`Error: ${String(error)} :: ${error.stack}`);
browser.test.notifyFail("bookmarks");
});
}
let extension = ExtensionTestUtils.loadExtension({
background,
manifest: {
permissions: ["bookmarks"],
},
});
await extension.startup();
await extension.awaitFinish("bookmarks");
await extension.unload();
});
add_task(async function test_get_recent_with_tag_and_query() {
function background() {
browser.bookmarks.getRecent(100).then(bookmarks => {
browser.test.sendMessage("bookmarks", bookmarks);
});
}
let extension = ExtensionTestUtils.loadExtension({
background,
manifest: {
permissions: ["bookmarks"],
},
});
// Start with an empty bookmarks database.
await PlacesUtils.bookmarks.eraseEverything();
let createdBookmarks = [];
for (let i = 0; i < 3; i++) {
let bookmark = {
type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
title: `My bookmark ${i}`,
parentGuid: PlacesUtils.bookmarks.unfiledGuid,
};
createdBookmarks.unshift(bookmark);
await PlacesUtils.bookmarks.insert(bookmark);
}
// Add a tag to the most recent url to prove it doesn't get returned.
PlacesUtils.tagging.tagURI(NetUtil.newURI("http://example.com/${i}"), [
"Test Tag",
]);
// Add a query bookmark.
let queryURL = `place:parent=${PlacesUtils.bookmarks.menuGuid}&queryType=1`;
await PlacesUtils.bookmarks.insert({
parentGuid: PlacesUtils.bookmarks.unfiledGuid,
url: queryURL,
title: "a test query",
});
await extension.startup();
let receivedBookmarks = await extension.awaitMessage("bookmarks");
equal(
receivedBookmarks.length,
3,
"The expected number of bookmarks was returned."
);
for (let i = 0; i < 3; i++) {
let actual = receivedBookmarks[i];
let expected = createdBookmarks[i];
equal(actual.url, expected.url, "Bookmark has the expected url.");
equal(actual.title, expected.title, "Bookmark has the expected title.");
equal(
actual.parentId,
expected.parentGuid,
"Bookmark has the expected parentId."
);
}
await extension.unload();
});
add_task(async function test_tree_with_empty_folder() {
async function background() {
await browser.bookmarks.create({ title: "Empty Folder" });
let nonEmptyFolder = await browser.bookmarks.create({
title: "Non-Empty Folder",
});
await browser.bookmarks.create({
title: "A bookmark",
parentId: nonEmptyFolder.id,
});
let tree = await browser.bookmarks.getSubTree(nonEmptyFolder.parentId);
browser.test.assertEq(
0,
tree[0].children[0].children.length,
"The empty folder returns an empty array for children."
);
browser.test.assertEq(
1,
tree[0].children[1].children.length,
"The non-empty folder returns a single item array for children."
);
let children = await browser.bookmarks.getChildren(nonEmptyFolder.parentId);
// getChildren should only return immediate children. This is not tested in the
// monster test above.
for (let child of children) {
browser.test.assertEq(
undefined,
child.children,
"Child from getChildren does not contain any children."
);
}
browser.test.sendMessage("done");
}
let extension = ExtensionTestUtils.loadExtension({
background,
manifest: {
permissions: ["bookmarks"],
},
});
// Start with an empty bookmarks database.
await PlacesUtils.bookmarks.eraseEverything();
await extension.startup();
await extension.awaitMessage("done");
await extension.unload();
});
add_task(
{
pref_set: [["extensions.eventPages.enabled", true]],
},
async function test_bookmarks_event_page() {
await AddonTestUtils.promiseStartupManager();
let extension = ExtensionTestUtils.loadExtension({
useAddonManager: "permanent",
manifest: {
browser_specific_settings: { gecko: { id: "eventpage@bookmarks" } },
permissions: ["bookmarks"],
background: { persistent: false },
},
background() {
browser.bookmarks.onCreated.addListener(() => {
browser.test.sendMessage("onCreated");
});
browser.bookmarks.onRemoved.addListener(() => {
browser.test.sendMessage("onRemoved");
});
browser.bookmarks.onChanged.addListener(() => {});
browser.bookmarks.onMoved.addListener(() => {});
browser.test.sendMessage("ready");
},
});
const EVENTS = ["onCreated", "onRemoved", "onChanged", "onMoved"];
await PlacesUtils.bookmarks.eraseEverything();
await extension.startup();
await extension.awaitMessage("ready");
for (let event of EVENTS) {
assertPersistentListeners(extension, "bookmarks", event, {
primed: false,
});
}
// test events waken background
await extension.terminateBackground();
for (let event of EVENTS) {
assertPersistentListeners(extension, "bookmarks", event, {
primed: true,
});
}
let bookmark = {
type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
title: `My bookmark 12345`,
parentGuid: PlacesUtils.bookmarks.unfiledGuid,
};
await PlacesUtils.bookmarks.insert(bookmark);
await extension.awaitMessage("ready");
await extension.awaitMessage("onCreated");
for (let event of EVENTS) {
assertPersistentListeners(extension, "bookmarks", event, {
primed: false,
});
}
await AddonTestUtils.promiseRestartManager();
await extension.awaitStartup();
for (let event of EVENTS) {
assertPersistentListeners(extension, "bookmarks", event, {
primed: true,
});
}
await PlacesUtils.bookmarks.eraseEverything();
await extension.awaitMessage("ready");
await extension.awaitMessage("onRemoved");
await extension.unload();
await AddonTestUtils.promiseShutdownManager();
}
);