michael@0: /* Any copyright is dedicated to the Public Domain. michael@0: http://creativecommons.org/publicdomain/zero/1.0/ */ michael@0: michael@0: Cu.import("resource://gre/modules/PlacesUtils.jsm"); michael@0: Cu.import("resource://services-sync/engines.js"); michael@0: Cu.import("resource://services-sync/engines/bookmarks.js"); michael@0: Cu.import("resource://services-sync/service.js"); michael@0: Cu.import("resource://services-sync/util.js"); michael@0: michael@0: const PARENT_ANNO = "sync/parent"; michael@0: michael@0: Service.engineManager.register(BookmarksEngine); michael@0: michael@0: let engine = Service.engineManager.get("bookmarks"); michael@0: let store = engine._store; michael@0: let tracker = engine._tracker; michael@0: michael@0: // Don't write some persistence files asynchronously. michael@0: tracker.persistChangedIDs = false; michael@0: michael@0: let fxuri = Utils.makeURI("http://getfirefox.com/"); michael@0: let tburi = Utils.makeURI("http://getthunderbird.com/"); michael@0: michael@0: add_test(function test_ignore_specials() { michael@0: _("Ensure that we can't delete bookmark roots."); michael@0: michael@0: // Belt... michael@0: let record = new BookmarkFolder("bookmarks", "toolbar", "folder"); michael@0: record.deleted = true; michael@0: do_check_neq(null, store.idForGUID("toolbar")); michael@0: michael@0: store.applyIncoming(record); michael@0: michael@0: // Ensure that the toolbar exists. michael@0: do_check_neq(null, store.idForGUID("toolbar")); michael@0: michael@0: // This will fail painfully in getItemType if the deletion worked. michael@0: engine._buildGUIDMap(); michael@0: michael@0: // Braces... michael@0: store.remove(record); michael@0: do_check_neq(null, store.idForGUID("toolbar")); michael@0: engine._buildGUIDMap(); michael@0: michael@0: store.wipe(); michael@0: run_next_test(); michael@0: }); michael@0: michael@0: add_test(function test_bookmark_create() { michael@0: try { michael@0: _("Ensure the record isn't present yet."); michael@0: let ids = PlacesUtils.bookmarks.getBookmarkIdsForURI(fxuri, {}); michael@0: do_check_eq(ids.length, 0); michael@0: michael@0: _("Let's create a new record."); michael@0: let fxrecord = new Bookmark("bookmarks", "get-firefox1"); michael@0: fxrecord.bmkUri = fxuri.spec; michael@0: fxrecord.description = "Firefox is awesome."; michael@0: fxrecord.title = "Get Firefox!"; michael@0: fxrecord.tags = ["firefox", "awesome", "browser"]; michael@0: fxrecord.keyword = "awesome"; michael@0: fxrecord.loadInSidebar = false; michael@0: fxrecord.parentName = "Bookmarks Toolbar"; michael@0: fxrecord.parentid = "toolbar"; michael@0: store.applyIncoming(fxrecord); michael@0: michael@0: _("Verify it has been created correctly."); michael@0: let id = store.idForGUID(fxrecord.id); michael@0: do_check_eq(store.GUIDForId(id), fxrecord.id); michael@0: do_check_eq(PlacesUtils.bookmarks.getItemType(id), michael@0: PlacesUtils.bookmarks.TYPE_BOOKMARK); michael@0: do_check_true(PlacesUtils.bookmarks.getBookmarkURI(id).equals(fxuri)); michael@0: do_check_eq(PlacesUtils.bookmarks.getItemTitle(id), fxrecord.title); michael@0: do_check_eq(PlacesUtils.annotations.getItemAnnotation(id, "bookmarkProperties/description"), michael@0: fxrecord.description); michael@0: do_check_eq(PlacesUtils.bookmarks.getFolderIdForItem(id), michael@0: PlacesUtils.bookmarks.toolbarFolder); michael@0: do_check_eq(PlacesUtils.bookmarks.getKeywordForBookmark(id), fxrecord.keyword); michael@0: michael@0: _("Have the store create a new record object. Verify that it has the same data."); michael@0: let newrecord = store.createRecord(fxrecord.id); michael@0: do_check_true(newrecord instanceof Bookmark); michael@0: for each (let property in ["type", "bmkUri", "description", "title", michael@0: "keyword", "parentName", "parentid"]) { michael@0: do_check_eq(newrecord[property], fxrecord[property]); michael@0: } michael@0: do_check_true(Utils.deepEquals(newrecord.tags.sort(), michael@0: fxrecord.tags.sort())); michael@0: michael@0: _("The calculated sort index is based on frecency data."); michael@0: do_check_true(newrecord.sortindex >= 150); michael@0: michael@0: _("Create a record with some values missing."); michael@0: let tbrecord = new Bookmark("bookmarks", "thunderbird1"); michael@0: tbrecord.bmkUri = tburi.spec; michael@0: tbrecord.parentName = "Bookmarks Toolbar"; michael@0: tbrecord.parentid = "toolbar"; michael@0: store.applyIncoming(tbrecord); michael@0: michael@0: _("Verify it has been created correctly."); michael@0: id = store.idForGUID(tbrecord.id); michael@0: do_check_eq(store.GUIDForId(id), tbrecord.id); michael@0: do_check_eq(PlacesUtils.bookmarks.getItemType(id), michael@0: PlacesUtils.bookmarks.TYPE_BOOKMARK); michael@0: do_check_true(PlacesUtils.bookmarks.getBookmarkURI(id).equals(tburi)); michael@0: do_check_eq(PlacesUtils.bookmarks.getItemTitle(id), null); michael@0: let error; michael@0: try { michael@0: PlacesUtils.annotations.getItemAnnotation(id, "bookmarkProperties/description"); michael@0: } catch(ex) { michael@0: error = ex; michael@0: } michael@0: do_check_eq(error.result, Cr.NS_ERROR_NOT_AVAILABLE); michael@0: do_check_eq(PlacesUtils.bookmarks.getFolderIdForItem(id), michael@0: PlacesUtils.bookmarks.toolbarFolder); michael@0: do_check_eq(PlacesUtils.bookmarks.getKeywordForBookmark(id), null); michael@0: } finally { michael@0: _("Clean up."); michael@0: store.wipe(); michael@0: run_next_test(); michael@0: } michael@0: }); michael@0: michael@0: add_test(function test_bookmark_update() { michael@0: try { michael@0: _("Create a bookmark whose values we'll change."); michael@0: let bmk1_id = PlacesUtils.bookmarks.insertBookmark( michael@0: PlacesUtils.bookmarks.toolbarFolder, fxuri, michael@0: PlacesUtils.bookmarks.DEFAULT_INDEX, michael@0: "Get Firefox!"); michael@0: PlacesUtils.annotations.setItemAnnotation( michael@0: bmk1_id, "bookmarkProperties/description", "Firefox is awesome.", 0, michael@0: PlacesUtils.annotations.EXPIRE_NEVER); michael@0: PlacesUtils.bookmarks.setKeywordForBookmark(bmk1_id, "firefox"); michael@0: let bmk1_guid = store.GUIDForId(bmk1_id); michael@0: michael@0: _("Update the record with some null values."); michael@0: let record = store.createRecord(bmk1_guid); michael@0: record.title = null; michael@0: record.description = null; michael@0: record.keyword = null; michael@0: record.tags = null; michael@0: store.applyIncoming(record); michael@0: michael@0: _("Verify that the values have been cleared."); michael@0: do_check_throws(function () { michael@0: PlacesUtils.annotations.getItemAnnotation( michael@0: bmk1_id, "bookmarkProperties/description"); michael@0: }, Cr.NS_ERROR_NOT_AVAILABLE); michael@0: do_check_eq(PlacesUtils.bookmarks.getItemTitle(bmk1_id), null); michael@0: do_check_eq(PlacesUtils.bookmarks.getKeywordForBookmark(bmk1_id), null); michael@0: } finally { michael@0: _("Clean up."); michael@0: store.wipe(); michael@0: run_next_test(); michael@0: } michael@0: }); michael@0: michael@0: add_test(function test_bookmark_createRecord() { michael@0: try { michael@0: _("Create a bookmark without a description or title."); michael@0: let bmk1_id = PlacesUtils.bookmarks.insertBookmark( michael@0: PlacesUtils.bookmarks.toolbarFolder, fxuri, michael@0: PlacesUtils.bookmarks.DEFAULT_INDEX, null); michael@0: let bmk1_guid = store.GUIDForId(bmk1_id); michael@0: michael@0: _("Verify that the record is created accordingly."); michael@0: let record = store.createRecord(bmk1_guid); michael@0: do_check_eq(record.title, null); michael@0: do_check_eq(record.description, null); michael@0: do_check_eq(record.keyword, null); michael@0: michael@0: } finally { michael@0: _("Clean up."); michael@0: store.wipe(); michael@0: run_next_test(); michael@0: } michael@0: }); michael@0: michael@0: add_test(function test_folder_create() { michael@0: try { michael@0: _("Create a folder."); michael@0: let folder = new BookmarkFolder("bookmarks", "testfolder-1"); michael@0: folder.parentName = "Bookmarks Toolbar"; michael@0: folder.parentid = "toolbar"; michael@0: folder.title = "Test Folder"; michael@0: store.applyIncoming(folder); michael@0: michael@0: _("Verify it has been created correctly."); michael@0: let id = store.idForGUID(folder.id); michael@0: do_check_eq(PlacesUtils.bookmarks.getItemType(id), michael@0: PlacesUtils.bookmarks.TYPE_FOLDER); michael@0: do_check_eq(PlacesUtils.bookmarks.getItemTitle(id), folder.title); michael@0: do_check_eq(PlacesUtils.bookmarks.getFolderIdForItem(id), michael@0: PlacesUtils.bookmarks.toolbarFolder); michael@0: michael@0: _("Have the store create a new record object. Verify that it has the same data."); michael@0: let newrecord = store.createRecord(folder.id); michael@0: do_check_true(newrecord instanceof BookmarkFolder); michael@0: for each (let property in ["title", "parentName", "parentid"]) michael@0: do_check_eq(newrecord[property], folder[property]); michael@0: michael@0: _("Folders have high sort index to ensure they're synced first."); michael@0: do_check_eq(newrecord.sortindex, 1000000); michael@0: } finally { michael@0: _("Clean up."); michael@0: store.wipe(); michael@0: run_next_test(); michael@0: } michael@0: }); michael@0: michael@0: add_test(function test_folder_createRecord() { michael@0: try { michael@0: _("Create a folder."); michael@0: let folder1_id = PlacesUtils.bookmarks.createFolder( michael@0: PlacesUtils.bookmarks.toolbarFolder, "Folder1", 0); michael@0: let folder1_guid = store.GUIDForId(folder1_id); michael@0: michael@0: _("Create two bookmarks in that folder without assigning them GUIDs."); michael@0: let bmk1_id = PlacesUtils.bookmarks.insertBookmark( michael@0: folder1_id, fxuri, PlacesUtils.bookmarks.DEFAULT_INDEX, "Get Firefox!"); michael@0: let bmk2_id = PlacesUtils.bookmarks.insertBookmark( michael@0: folder1_id, tburi, PlacesUtils.bookmarks.DEFAULT_INDEX, "Get Thunderbird!"); michael@0: michael@0: _("Create a record for the folder and verify basic properties."); michael@0: let record = store.createRecord(folder1_guid); michael@0: do_check_true(record instanceof BookmarkFolder); michael@0: do_check_eq(record.title, "Folder1"); michael@0: do_check_eq(record.parentid, "toolbar"); michael@0: do_check_eq(record.parentName, "Bookmarks Toolbar"); michael@0: michael@0: _("Verify the folder's children. Ensures that the bookmarks were given GUIDs."); michael@0: let bmk1_guid = store.GUIDForId(bmk1_id); michael@0: let bmk2_guid = store.GUIDForId(bmk2_id); michael@0: do_check_eq(record.children.length, 2); michael@0: do_check_eq(record.children[0], bmk1_guid); michael@0: do_check_eq(record.children[1], bmk2_guid); michael@0: michael@0: } finally { michael@0: _("Clean up."); michael@0: store.wipe(); michael@0: run_next_test(); michael@0: } michael@0: }); michael@0: michael@0: add_test(function test_deleted() { michael@0: try { michael@0: _("Create a bookmark that will be deleted."); michael@0: let bmk1_id = PlacesUtils.bookmarks.insertBookmark( michael@0: PlacesUtils.bookmarks.toolbarFolder, fxuri, michael@0: PlacesUtils.bookmarks.DEFAULT_INDEX, "Get Firefox!"); michael@0: let bmk1_guid = store.GUIDForId(bmk1_id); michael@0: michael@0: _("Delete the bookmark through the store."); michael@0: let record = new PlacesItem("bookmarks", bmk1_guid); michael@0: record.deleted = true; michael@0: store.applyIncoming(record); michael@0: michael@0: _("Ensure it has been deleted."); michael@0: let error; michael@0: try { michael@0: PlacesUtils.bookmarks.getBookmarkURI(bmk1_id); michael@0: } catch(ex) { michael@0: error = ex; michael@0: } michael@0: do_check_eq(error.result, Cr.NS_ERROR_ILLEGAL_VALUE); michael@0: michael@0: let newrec = store.createRecord(bmk1_guid); michael@0: do_check_eq(newrec.deleted, true); michael@0: michael@0: } finally { michael@0: _("Clean up."); michael@0: store.wipe(); michael@0: run_next_test(); michael@0: } michael@0: }); michael@0: michael@0: add_test(function test_move_folder() { michael@0: try { michael@0: _("Create two folders and a bookmark in one of them."); michael@0: let folder1_id = PlacesUtils.bookmarks.createFolder( michael@0: PlacesUtils.bookmarks.toolbarFolder, "Folder1", 0); michael@0: let folder1_guid = store.GUIDForId(folder1_id); michael@0: let folder2_id = PlacesUtils.bookmarks.createFolder( michael@0: PlacesUtils.bookmarks.toolbarFolder, "Folder2", 0); michael@0: let folder2_guid = store.GUIDForId(folder2_id); michael@0: let bmk_id = PlacesUtils.bookmarks.insertBookmark( michael@0: folder1_id, fxuri, PlacesUtils.bookmarks.DEFAULT_INDEX, "Get Firefox!"); michael@0: let bmk_guid = store.GUIDForId(bmk_id); michael@0: michael@0: _("Get a record, reparent it and apply it to the store."); michael@0: let record = store.createRecord(bmk_guid); michael@0: do_check_eq(record.parentid, folder1_guid); michael@0: record.parentid = folder2_guid; michael@0: store.applyIncoming(record); michael@0: michael@0: _("Verify the new parent."); michael@0: let new_folder_id = PlacesUtils.bookmarks.getFolderIdForItem(bmk_id); michael@0: do_check_eq(store.GUIDForId(new_folder_id), folder2_guid); michael@0: } finally { michael@0: _("Clean up."); michael@0: store.wipe(); michael@0: run_next_test(); michael@0: } michael@0: }); michael@0: michael@0: add_test(function test_move_order() { michael@0: // Make sure the tracker is turned on. michael@0: Svc.Obs.notify("weave:engine:start-tracking"); michael@0: try { michael@0: _("Create two bookmarks"); michael@0: let bmk1_id = PlacesUtils.bookmarks.insertBookmark( michael@0: PlacesUtils.bookmarks.toolbarFolder, fxuri, michael@0: PlacesUtils.bookmarks.DEFAULT_INDEX, "Get Firefox!"); michael@0: let bmk1_guid = store.GUIDForId(bmk1_id); michael@0: let bmk2_id = PlacesUtils.bookmarks.insertBookmark( michael@0: PlacesUtils.bookmarks.toolbarFolder, tburi, michael@0: PlacesUtils.bookmarks.DEFAULT_INDEX, "Get Thunderbird!"); michael@0: let bmk2_guid = store.GUIDForId(bmk2_id); michael@0: michael@0: _("Verify order."); michael@0: do_check_eq(PlacesUtils.bookmarks.getItemIndex(bmk1_id), 0); michael@0: do_check_eq(PlacesUtils.bookmarks.getItemIndex(bmk2_id), 1); michael@0: let toolbar = store.createRecord("toolbar"); michael@0: do_check_eq(toolbar.children.length, 2); michael@0: do_check_eq(toolbar.children[0], bmk1_guid); michael@0: do_check_eq(toolbar.children[1], bmk2_guid); michael@0: michael@0: _("Move bookmarks around."); michael@0: store._childrenToOrder = {}; michael@0: toolbar.children = [bmk2_guid, bmk1_guid]; michael@0: store.applyIncoming(toolbar); michael@0: // Bookmarks engine does this at the end of _processIncoming michael@0: tracker.ignoreAll = true; michael@0: store._orderChildren(); michael@0: tracker.ignoreAll = false; michael@0: delete store._childrenToOrder; michael@0: michael@0: _("Verify new order."); michael@0: do_check_eq(PlacesUtils.bookmarks.getItemIndex(bmk2_id), 0); michael@0: do_check_eq(PlacesUtils.bookmarks.getItemIndex(bmk1_id), 1); michael@0: michael@0: } finally { michael@0: Svc.Obs.notify("weave:engine:stop-tracking"); michael@0: _("Clean up."); michael@0: store.wipe(); michael@0: run_next_test(); michael@0: } michael@0: }); michael@0: michael@0: add_test(function test_orphan() { michael@0: try { michael@0: michael@0: _("Add a new bookmark locally."); michael@0: let bmk1_id = PlacesUtils.bookmarks.insertBookmark( michael@0: PlacesUtils.bookmarks.toolbarFolder, fxuri, michael@0: PlacesUtils.bookmarks.DEFAULT_INDEX, "Get Firefox!"); michael@0: let bmk1_guid = store.GUIDForId(bmk1_id); michael@0: do_check_eq(PlacesUtils.bookmarks.getFolderIdForItem(bmk1_id), michael@0: PlacesUtils.bookmarks.toolbarFolder); michael@0: let error; michael@0: try { michael@0: PlacesUtils.annotations.getItemAnnotation(bmk1_id, PARENT_ANNO); michael@0: } catch(ex) { michael@0: error = ex; michael@0: } michael@0: do_check_eq(error.result, Cr.NS_ERROR_NOT_AVAILABLE); michael@0: michael@0: _("Apply a server record that is the same but refers to non-existent folder."); michael@0: let record = store.createRecord(bmk1_guid); michael@0: record.parentid = "non-existent"; michael@0: store.applyIncoming(record); michael@0: michael@0: _("Verify that bookmark has been flagged as orphan, has not moved."); michael@0: do_check_eq(PlacesUtils.bookmarks.getFolderIdForItem(bmk1_id), michael@0: PlacesUtils.bookmarks.toolbarFolder); michael@0: do_check_eq(PlacesUtils.annotations.getItemAnnotation(bmk1_id, PARENT_ANNO), michael@0: "non-existent"); michael@0: michael@0: } finally { michael@0: _("Clean up."); michael@0: store.wipe(); michael@0: run_next_test(); michael@0: } michael@0: }); michael@0: michael@0: add_test(function test_reparentOrphans() { michael@0: try { michael@0: let folder1_id = PlacesUtils.bookmarks.createFolder( michael@0: PlacesUtils.bookmarks.toolbarFolder, "Folder1", 0); michael@0: let folder1_guid = store.GUIDForId(folder1_id); michael@0: michael@0: _("Create a bogus orphan record and write the record back to the store to trigger _reparentOrphans."); michael@0: PlacesUtils.annotations.setItemAnnotation( michael@0: folder1_id, PARENT_ANNO, folder1_guid, 0, michael@0: PlacesUtils.annotations.EXPIRE_NEVER); michael@0: let record = store.createRecord(folder1_guid); michael@0: record.title = "New title for Folder 1"; michael@0: store._childrenToOrder = {}; michael@0: store.applyIncoming(record); michael@0: michael@0: _("Verify that is has been marked as an orphan even though it couldn't be moved into itself."); michael@0: do_check_eq(PlacesUtils.annotations.getItemAnnotation(folder1_id, PARENT_ANNO), michael@0: folder1_guid); michael@0: michael@0: } finally { michael@0: _("Clean up."); michael@0: store.wipe(); michael@0: run_next_test(); michael@0: } michael@0: }); michael@0: michael@0: // Tests Bug 806460, in which query records arrive with empty folder michael@0: // names and missing bookmark URIs. michael@0: add_test(function test_empty_query_doesnt_die() { michael@0: let record = new BookmarkQuery("bookmarks", "8xoDGqKrXf1P"); michael@0: record.folderName = ""; michael@0: record.queryId = ""; michael@0: record.parentName = "Toolbar"; michael@0: record.parentid = "toolbar"; michael@0: michael@0: // These should not throw. michael@0: store.applyIncoming(record); michael@0: michael@0: delete record.folderName; michael@0: store.applyIncoming(record); michael@0: michael@0: run_next_test(); michael@0: }); michael@0: michael@0: function run_test() { michael@0: initTestLogging('Trace'); michael@0: run_next_test(); michael@0: }