summaryrefslogtreecommitdiffstats
path: root/services/sync/tests/unit/test_bookmark_store.js
diff options
context:
space:
mode:
Diffstat (limited to 'services/sync/tests/unit/test_bookmark_store.js')
-rw-r--r--services/sync/tests/unit/test_bookmark_store.js425
1 files changed, 425 insertions, 0 deletions
diff --git a/services/sync/tests/unit/test_bookmark_store.js b/services/sync/tests/unit/test_bookmark_store.js
new file mode 100644
index 0000000000..c46c3228fa
--- /dev/null
+++ b/services/sync/tests/unit/test_bookmark_store.js
@@ -0,0 +1,425 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+const { Bookmark, BookmarkFolder, BookmarkQuery, PlacesItem } =
+ ChromeUtils.importESModule(
+ "resource://services-sync/engines/bookmarks.sys.mjs"
+ );
+// `Service` is used as a global in head_helpers.js.
+// eslint-disable-next-line no-unused-vars
+const { Service } = ChromeUtils.importESModule(
+ "resource://services-sync/service.sys.mjs"
+);
+
+const BookmarksToolbarTitle = "toolbar";
+
+// apply some test records without going via a test server.
+async function apply_records(engine, records) {
+ for (record of records) {
+ await engine._store.applyIncoming(record);
+ }
+ await engine._apply();
+}
+
+add_bookmark_test(async function test_ignore_specials(engine) {
+ _("Ensure that we can't delete bookmark roots.");
+ let store = engine._store;
+
+ // Belt...
+ let record = new BookmarkFolder("bookmarks", "toolbar", "folder");
+ record.deleted = true;
+ Assert.notEqual(
+ null,
+ await PlacesUtils.promiseItemId(PlacesUtils.bookmarks.toolbarGuid)
+ );
+
+ await apply_records(engine, [record]);
+
+ // Ensure that the toolbar exists.
+ Assert.notEqual(
+ null,
+ await PlacesUtils.promiseItemId(PlacesUtils.bookmarks.toolbarGuid)
+ );
+
+ await apply_records(engine, [record]);
+
+ Assert.notEqual(
+ null,
+ await PlacesUtils.promiseItemId(PlacesUtils.bookmarks.toolbarGuid)
+ );
+ await store.wipe();
+});
+
+add_bookmark_test(async function test_bookmark_create(engine) {
+ let store = engine._store;
+
+ try {
+ _("Ensure the record isn't present yet.");
+ let item = await PlacesUtils.bookmarks.fetch({
+ url: "http://getfirefox.com/",
+ });
+ Assert.equal(null, item);
+
+ _("Let's create a new record.");
+ let fxrecord = new Bookmark("bookmarks", "get-firefox1");
+ fxrecord.bmkUri = "http://getfirefox.com/";
+ fxrecord.title = "Get Firefox!";
+ fxrecord.tags = ["firefox", "awesome", "browser"];
+ fxrecord.keyword = "awesome";
+ fxrecord.parentName = BookmarksToolbarTitle;
+ fxrecord.parentid = "toolbar";
+ await apply_records(engine, [fxrecord]);
+
+ _("Verify it has been created correctly.");
+ item = await PlacesUtils.bookmarks.fetch(fxrecord.id);
+ Assert.equal(item.type, PlacesUtils.bookmarks.TYPE_BOOKMARK);
+ Assert.equal(item.url.href, "http://getfirefox.com/");
+ Assert.equal(item.title, fxrecord.title);
+ Assert.equal(item.parentGuid, PlacesUtils.bookmarks.toolbarGuid);
+ let keyword = await PlacesUtils.keywords.fetch(fxrecord.keyword);
+ Assert.equal(keyword.url.href, "http://getfirefox.com/");
+
+ _(
+ "Have the store create a new record object. Verify that it has the same data."
+ );
+ let newrecord = await store.createRecord(fxrecord.id);
+ Assert.ok(newrecord instanceof Bookmark);
+ for (let property of [
+ "type",
+ "bmkUri",
+ "title",
+ "keyword",
+ "parentName",
+ "parentid",
+ ]) {
+ Assert.equal(newrecord[property], fxrecord[property]);
+ }
+ Assert.ok(Utils.deepEquals(newrecord.tags.sort(), fxrecord.tags.sort()));
+
+ _("The calculated sort index is based on frecency data.");
+ Assert.ok(newrecord.sortindex >= 150);
+
+ _("Create a record with some values missing.");
+ let tbrecord = new Bookmark("bookmarks", "thunderbird1");
+ tbrecord.bmkUri = "http://getthunderbird.com/";
+ tbrecord.parentName = BookmarksToolbarTitle;
+ tbrecord.parentid = "toolbar";
+ await apply_records(engine, [tbrecord]);
+
+ _("Verify it has been created correctly.");
+ item = await PlacesUtils.bookmarks.fetch(tbrecord.id);
+ Assert.equal(item.type, PlacesUtils.bookmarks.TYPE_BOOKMARK);
+ Assert.equal(item.url.href, "http://getthunderbird.com/");
+ Assert.equal(item.title, "");
+ Assert.equal(item.parentGuid, PlacesUtils.bookmarks.toolbarGuid);
+ keyword = await PlacesUtils.keywords.fetch({
+ url: "http://getthunderbird.com/",
+ });
+ Assert.equal(null, keyword);
+ } finally {
+ _("Clean up.");
+ await store.wipe();
+ }
+});
+
+add_bookmark_test(async function test_bookmark_update(engine) {
+ let store = engine._store;
+
+ try {
+ _("Create a bookmark whose values we'll change.");
+ let bmk1 = await PlacesUtils.bookmarks.insert({
+ parentGuid: PlacesUtils.bookmarks.toolbarGuid,
+ url: "http://getfirefox.com/",
+ title: "Get Firefox!",
+ });
+ await PlacesUtils.keywords.insert({
+ url: "http://getfirefox.com/",
+ keyword: "firefox",
+ });
+
+ _("Update the record with some null values.");
+ let record = await store.createRecord(bmk1.guid);
+ record.title = null;
+ record.keyword = null;
+ record.tags = null;
+ await apply_records(engine, [record]);
+
+ _("Verify that the values have been cleared.");
+ let item = await PlacesUtils.bookmarks.fetch(bmk1.guid);
+ Assert.equal(item.title, "");
+ let keyword = await PlacesUtils.keywords.fetch({
+ url: "http://getfirefox.com/",
+ });
+ Assert.equal(null, keyword);
+ } finally {
+ _("Clean up.");
+ await store.wipe();
+ }
+});
+
+add_bookmark_test(async function test_bookmark_createRecord(engine) {
+ let store = engine._store;
+
+ try {
+ _("Create a bookmark without a title.");
+ let bmk1 = await PlacesUtils.bookmarks.insert({
+ parentGuid: PlacesUtils.bookmarks.toolbarGuid,
+ url: "http://getfirefox.com/",
+ });
+
+ _("Verify that the record is created accordingly.");
+ let record = await store.createRecord(bmk1.guid);
+ Assert.equal(record.title, "");
+ Assert.equal(record.keyword, null);
+ } finally {
+ _("Clean up.");
+ await store.wipe();
+ }
+});
+
+add_bookmark_test(async function test_folder_create(engine) {
+ let store = engine._store;
+
+ try {
+ _("Create a folder.");
+ let folder = new BookmarkFolder("bookmarks", "testfolder-1");
+ folder.parentName = BookmarksToolbarTitle;
+ folder.parentid = "toolbar";
+ folder.title = "Test Folder";
+ await apply_records(engine, [folder]);
+
+ _("Verify it has been created correctly.");
+ let item = await PlacesUtils.bookmarks.fetch(folder.id);
+ Assert.equal(item.type, PlacesUtils.bookmarks.TYPE_FOLDER);
+ Assert.equal(item.title, folder.title);
+ Assert.equal(item.parentGuid, PlacesUtils.bookmarks.toolbarGuid);
+
+ _(
+ "Have the store create a new record object. Verify that it has the same data."
+ );
+ let newrecord = await store.createRecord(folder.id);
+ Assert.ok(newrecord instanceof BookmarkFolder);
+ for (let property of ["title", "parentName", "parentid"]) {
+ Assert.equal(newrecord[property], folder[property]);
+ }
+
+ _("Folders have high sort index to ensure they're synced first.");
+ Assert.equal(newrecord.sortindex, 1000000);
+ } finally {
+ _("Clean up.");
+ await store.wipe();
+ }
+});
+
+add_bookmark_test(async function test_folder_createRecord(engine) {
+ let store = engine._store;
+
+ try {
+ _("Create a folder.");
+ let folder1 = await PlacesUtils.bookmarks.insert({
+ parentGuid: PlacesUtils.bookmarks.toolbarGuid,
+ type: PlacesUtils.bookmarks.TYPE_FOLDER,
+ title: "Folder1",
+ });
+
+ _("Create two bookmarks in that folder without assigning them GUIDs.");
+ let bmk1 = await PlacesUtils.bookmarks.insert({
+ parentGuid: folder1.guid,
+ url: "http://getfirefox.com/",
+ title: "Get Firefox!",
+ });
+ let bmk2 = await PlacesUtils.bookmarks.insert({
+ parentGuid: folder1.guid,
+ url: "http://getthunderbird.com/",
+ title: "Get Thunderbird!",
+ });
+
+ _("Create a record for the folder and verify basic properties.");
+ let record = await store.createRecord(folder1.guid);
+ Assert.ok(record instanceof BookmarkFolder);
+ Assert.equal(record.title, "Folder1");
+ Assert.equal(record.parentid, "toolbar");
+ Assert.equal(record.parentName, BookmarksToolbarTitle);
+
+ _(
+ "Verify the folder's children. Ensures that the bookmarks were given GUIDs."
+ );
+ Assert.deepEqual(record.children, [bmk1.guid, bmk2.guid]);
+ } finally {
+ _("Clean up.");
+ await store.wipe();
+ }
+});
+
+add_bookmark_test(async function test_deleted(engine) {
+ let store = engine._store;
+
+ try {
+ _("Create a bookmark that will be deleted.");
+ let bmk1 = await PlacesUtils.bookmarks.insert({
+ parentGuid: PlacesUtils.bookmarks.toolbarGuid,
+ url: "http://getfirefox.com/",
+ title: "Get Firefox!",
+ });
+ // The engine needs to think we've previously synced it.
+ await PlacesTestUtils.markBookmarksAsSynced();
+
+ _("Delete the bookmark through the store.");
+ let record = new PlacesItem("bookmarks", bmk1.guid);
+ record.deleted = true;
+ await apply_records(engine, [record]);
+ _("Ensure it has been deleted.");
+ let item = await PlacesUtils.bookmarks.fetch(bmk1.guid);
+ let newrec = await store.createRecord(bmk1.guid);
+ Assert.equal(null, item);
+ Assert.equal(newrec.deleted, true);
+ _("Verify that the keyword has been cleared.");
+ let keyword = await PlacesUtils.keywords.fetch({
+ url: "http://getfirefox.com/",
+ });
+ Assert.equal(null, keyword);
+ } finally {
+ _("Clean up.");
+ await store.wipe();
+ }
+});
+
+add_bookmark_test(async function test_move_folder(engine) {
+ let store = engine._store;
+ store._childrenToOrder = {}; // *sob* - only needed for legacy.
+
+ try {
+ _("Create two folders and a bookmark in one of them.");
+ let folder1 = await PlacesUtils.bookmarks.insert({
+ parentGuid: PlacesUtils.bookmarks.toolbarGuid,
+ type: PlacesUtils.bookmarks.TYPE_FOLDER,
+ title: "Folder1",
+ });
+ let folder2 = await PlacesUtils.bookmarks.insert({
+ parentGuid: PlacesUtils.bookmarks.toolbarGuid,
+ type: PlacesUtils.bookmarks.TYPE_FOLDER,
+ title: "Folder2",
+ });
+ let bmk = await PlacesUtils.bookmarks.insert({
+ parentGuid: folder1.guid,
+ url: "http://getfirefox.com/",
+ title: "Get Firefox!",
+ });
+ // add records to the store that represent the current state.
+ await apply_records(engine, [
+ await store.createRecord(folder1.guid),
+ await store.createRecord(folder2.guid),
+ await store.createRecord(bmk.guid),
+ ]);
+
+ _("Now simulate incoming records reparenting it.");
+ let bmkRecord = await store.createRecord(bmk.guid);
+ Assert.equal(bmkRecord.parentid, folder1.guid);
+ bmkRecord.parentid = folder2.guid;
+
+ let folder1Record = await store.createRecord(folder1.guid);
+ Assert.deepEqual(folder1Record.children, [bmk.guid]);
+ folder1Record.children = [];
+ let folder2Record = await store.createRecord(folder2.guid);
+ Assert.deepEqual(folder2Record.children, []);
+ folder2Record.children = [bmk.guid];
+
+ await apply_records(engine, [bmkRecord, folder1Record, folder2Record]);
+
+ _("Verify the new parent.");
+ let movedBmk = await PlacesUtils.bookmarks.fetch(bmk.guid);
+ Assert.equal(movedBmk.parentGuid, folder2.guid);
+ } finally {
+ _("Clean up.");
+ await store.wipe();
+ }
+});
+
+add_bookmark_test(async function test_move_order(engine) {
+ let store = engine._store;
+ let tracker = engine._tracker;
+
+ // Make sure the tracker is turned on.
+ tracker.start();
+ try {
+ _("Create two bookmarks");
+ let bmk1 = await PlacesUtils.bookmarks.insert({
+ parentGuid: PlacesUtils.bookmarks.toolbarGuid,
+ url: "http://getfirefox.com/",
+ title: "Get Firefox!",
+ });
+ let bmk2 = await PlacesUtils.bookmarks.insert({
+ parentGuid: PlacesUtils.bookmarks.toolbarGuid,
+ url: "http://getthunderbird.com/",
+ title: "Get Thunderbird!",
+ });
+
+ _("Verify order.");
+ let childIds = await PlacesSyncUtils.bookmarks.fetchChildRecordIds(
+ "toolbar"
+ );
+ Assert.deepEqual(childIds, [bmk1.guid, bmk2.guid]);
+ let toolbar = await store.createRecord("toolbar");
+ Assert.deepEqual(toolbar.children, [bmk1.guid, bmk2.guid]);
+
+ _("Move bookmarks around.");
+ store._childrenToOrder = {};
+ toolbar.children = [bmk2.guid, bmk1.guid];
+ await apply_records(engine, [
+ toolbar,
+ await store.createRecord(bmk1.guid),
+ await store.createRecord(bmk2.guid),
+ ]);
+ delete store._childrenToOrder;
+
+ _("Verify new order.");
+ let newChildIds = await PlacesSyncUtils.bookmarks.fetchChildRecordIds(
+ "toolbar"
+ );
+ Assert.deepEqual(newChildIds, [bmk2.guid, bmk1.guid]);
+ } finally {
+ await tracker.stop();
+ _("Clean up.");
+ await store.wipe();
+ }
+});
+
+// Tests Bug 806460, in which query records arrive with empty folder
+// names and missing bookmark URIs.
+add_bookmark_test(async function test_empty_query_doesnt_die(engine) {
+ let record = new BookmarkQuery("bookmarks", "8xoDGqKrXf1P");
+ record.folderName = "";
+ record.queryId = "";
+ record.parentName = "Toolbar";
+ record.parentid = "toolbar";
+
+ // These should not throw.
+ await apply_records(engine, [record]);
+
+ delete record.folderName;
+ await apply_records(engine, [record]);
+});
+
+add_bookmark_test(async function test_calculateIndex_for_invalid_url(engine) {
+ let store = engine._store;
+
+ let folderIndex = await store._calculateIndex({
+ type: "folder",
+ });
+ equal(folderIndex, 1000000, "Should use high sort index for folders");
+
+ let toolbarIndex = await store._calculateIndex({
+ parentid: "toolbar",
+ });
+ equal(toolbarIndex, 150, "Should bump sort index for toolbar bookmarks");
+
+ let validURLIndex = await store._calculateIndex({
+ bmkUri: "http://example.com/a",
+ });
+ greaterOrEqual(validURLIndex, 0, "Should use frecency for index");
+
+ let invalidURLIndex = await store._calculateIndex({
+ bmkUri: "!@#$%",
+ });
+ equal(invalidURLIndex, 0, "Should not throw for invalid URLs");
+});