Bug 1432427 - Remove synchronous Bookmarks::insertSeparator. r=standard8 draft
authorMarco Bonardo <mbonardo@mozilla.com>
Fri, 23 Feb 2018 15:50:28 +0100
changeset 759012 63e949717ddfec9c4f685a3d24aee3303877391b
parent 758927 6661c077325c35af028f1cdaa660f673cbea39be
child 759060 4d71ab1909ca6e1065e31dc1824de3b119e05e7c
push id100254
push usermak77@bonardo.net
push dateFri, 23 Feb 2018 16:04:00 +0000
reviewersstandard8
bugs1432427
milestone60.0a1
Bug 1432427 - Remove synchronous Bookmarks::insertSeparator. r=standard8 MozReview-Commit-ID: 2rZ1Vr1kwhi
services/sync/tests/unit/test_bookmark_tracker.js
toolkit/components/places/nsINavBookmarksService.idl
toolkit/components/places/nsNavBookmarks.cpp
toolkit/components/places/tests/bookmarks/test_458683.js
toolkit/components/places/tests/bookmarks/test_bookmarks_getRecent.js
toolkit/components/places/tests/bookmarks/test_sync_fields.js
toolkit/components/places/tests/legacy/test_bookmarks.js
--- a/services/sync/tests/unit/test_bookmark_tracker.js
+++ b/services/sync/tests/unit/test_bookmark_tracker.js
@@ -450,28 +450,16 @@ add_task(async function test_onItemAdded
     _("Insert a bookmark using the sync API");
     let syncBmkID = PlacesUtils.bookmarks.insertBookmark(syncFolderID,
       CommonUtils.makeURI("https://example.org/sync"),
       PlacesUtils.bookmarks.DEFAULT_INDEX,
       "Sync Bookmark");
     let syncBmkGUID = await PlacesUtils.promiseItemGuid(syncBmkID);
     await verifyTrackedItems([syncFolderGUID, syncBmkGUID]);
     Assert.equal(tracker.score, SCORE_INCREMENT_XLARGE);
-
-    await resetTracker();
-    await startTracking();
-
-    _("Insert a separator using the sync API");
-    let index = (await PlacesUtils.bookmarks.fetch(syncFolderGUID)).index;
-    let syncSepID = PlacesUtils.bookmarks.insertSeparator(
-      PlacesUtils.bookmarks.bookmarksMenuFolder,
-      index);
-    let syncSepGUID = await PlacesUtils.promiseItemGuid(syncSepID);
-    await verifyTrackedItems(["menu", syncSepGUID]);
-    Assert.equal(tracker.score, SCORE_INCREMENT_XLARGE);
   } finally {
     _("Clean up.");
     await cleanup();
   }
 });
 
 add_task(async function test_async_onItemAdded() {
   _("Items inserted via the asynchronous bookmarks API should be tracked");
--- a/toolkit/components/places/nsINavBookmarksService.idl
+++ b/toolkit/components/places/nsINavBookmarksService.idl
@@ -452,37 +452,16 @@ interface nsINavBookmarksService : nsISu
    * index Y > X you must use moveItem(id, folder, Y + 1)
    */
   void moveItem(in long long aItemId,
                 in long long aNewParentId,
                 in long aIndex,
                 [optional] in unsigned short aSource);
 
   /**
-   * Inserts a bookmark separator into the given folder at the given index.
-   * The separator can be removed using removeChildAt().
-   *  @param aParentId
-   *         The id of the parent folder
-   *  @param aIndex
-   *         The separator's index under folder, or DEFAULT_INDEX to append
-   *  @param [optional] aGuid
-   *         The GUID to be set for the new item.  If not set, a new GUID is
-   *         generated.  Unless you've a very sound reason, such as an undo
-   *         manager implementation, do not pass this argument.
-   *  @param [optional] aSource
-   *         The change source, forwarded to all bookmark observers. Defaults
-   *         to SOURCE_DEFAULT.
-   *  @return The ID of the new separator.
-   *  @throws if aGuid is malformed.
-   */
-  long long insertSeparator(in long long aParentId, in long aIndex,
-                            [optional] in ACString aGuid,
-                            [optional] in unsigned short aSource);
-
-  /**
    * Set the title for an item.
    *  @param aItemId
    *         The id of the item whose title should be updated.
    *  @param aTitle
    *         The new title for the bookmark.
    *  @param [optional] aSource
    *         The change source, forwarded to all bookmark observers. Defaults
    *         to SOURCE_DEFAULT.
--- a/toolkit/components/places/nsNavBookmarks.cpp
+++ b/toolkit/components/places/nsNavBookmarks.cpp
@@ -884,70 +884,16 @@ nsNavBookmarks::CreateContainerWithID(in
                                          nullptr, title, dateAdded, guid,
                                          folderGuid, aSource));
 
   *aIndex = index;
   return NS_OK;
 }
 
 
-NS_IMETHODIMP
-nsNavBookmarks::InsertSeparator(int64_t aParent,
-                                int32_t aIndex,
-                                const nsACString& aGUID,
-                                uint16_t aSource,
-                                int64_t* aNewItemId)
-{
-  NS_ENSURE_ARG_MIN(aParent, 1);
-  NS_ENSURE_ARG_MIN(aIndex, nsINavBookmarksService::DEFAULT_INDEX);
-  NS_ENSURE_ARG_POINTER(aNewItemId);
-
-  if (!aGUID.IsEmpty() && !IsValidGUID(aGUID))
-    return NS_ERROR_INVALID_ARG;
-
-  // Get the correct index for insertion.  This also ensures the parent exists.
-  int32_t index, folderCount;
-  int64_t grandParentId;
-  nsAutoCString folderGuid;
-  nsresult rv = FetchFolderInfo(aParent, &folderCount, folderGuid, &grandParentId);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  mozStorageTransaction transaction(mDB->MainConn(), false);
-
-  if (aIndex == nsINavBookmarksService::DEFAULT_INDEX ||
-      aIndex >= folderCount) {
-    index = folderCount;
-  }
-  else {
-    index = aIndex;
-    // Create space for the insertion.
-    rv = AdjustIndices(aParent, index, INT32_MAX, 1);
-    NS_ENSURE_SUCCESS(rv, rv);
-  }
-
-  *aNewItemId = -1;
-  nsAutoCString guid(aGUID);
-  PRTime dateAdded = RoundedPRNow();
-  rv = InsertBookmarkInDB(-1, SEPARATOR, aParent, index, EmptyCString(), dateAdded,
-                          0, folderGuid, grandParentId, nullptr, aSource,
-                          aNewItemId, guid);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  rv = transaction.Commit();
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  NOTIFY_BOOKMARKS_OBSERVERS(mCanNotify, mObservers, DontSkip,
-                             OnItemAdded(*aNewItemId, aParent, index, TYPE_SEPARATOR,
-                                         nullptr, EmptyCString(), dateAdded, guid,
-                                         folderGuid, aSource));
-
-  return NS_OK;
-}
-
-
 NS_IMPL_ISUPPORTS(nsNavBookmarks::RemoveFolderTransaction, nsITransaction)
 
 NS_IMETHODIMP
 nsNavBookmarks::GetRemoveFolderTransaction(int64_t aFolderId, uint16_t aSource,
                                            nsITransaction** aResult)
 {
   NS_ENSURE_ARG_MIN(aFolderId, 1);
   NS_ENSURE_ARG_POINTER(aResult);
--- a/toolkit/components/places/tests/bookmarks/test_458683.js
+++ b/toolkit/components/places/tests/bookmarks/test_458683.js
@@ -10,24 +10,17 @@
       bogus items (separators, folders)
 */
 
 const ITEM_TITLE = "invalid uri";
 const ITEM_URL = "http://test.mozilla.org/";
 const TAG_NAME = "testTag";
 
 function validateResults() {
-  var query = PlacesUtils.history.getNewQuery();
-  query.setFolders([PlacesUtils.bookmarks.toolbarFolder], 1);
-  var options = PlacesUtils.history.getNewQueryOptions();
-  var result = PlacesUtils.history.executeQuery(query, options);
-
-  var toolbar = result.root;
-  toolbar.containerOpen = true;
-
+  let toolbar = PlacesUtils.getFolderContents(PlacesUtils.toolbarFolderId).root;
   // test for our bookmark
   Assert.equal(toolbar.childCount, 1);
   for (var i = 0; i < toolbar.childCount; i++) {
     var folderNode = toolbar.getChild(0);
     Assert.equal(folderNode.type, folderNode.RESULT_TYPE_URI);
     Assert.equal(folderNode.title, ITEM_TITLE);
   }
   toolbar.containerOpen = false;
@@ -46,44 +39,55 @@ add_task(async function() {
     parentGuid: PlacesUtils.bookmarks.toolbarGuid,
     title: ITEM_TITLE,
     url: ITEM_URL,
   });
 
   // create a tag
   PlacesUtils.tagging.tagURI(Services.io.newURI(ITEM_URL), [TAG_NAME]);
   // get tag folder id
-  var options = PlacesUtils.history.getNewQueryOptions();
-  var query = PlacesUtils.history.getNewQuery();
-  query.setFolders([PlacesUtils.bookmarks.tagsFolder], 1);
-  var result = PlacesUtils.history.executeQuery(query, options);
-  var tagRoot = result.root;
-  tagRoot.containerOpen = true;
+  let tagRoot = PlacesUtils.getFolderContents(PlacesUtils.tagsFolderId).root;
   Assert.equal(tagRoot.childCount, 1);
-  var tagNode = tagRoot.getChild(0)
-                        .QueryInterface(Ci.nsINavHistoryContainerResultNode);
-  let tagItemId = tagNode.itemId;
+  let tagItemGuid = PlacesUtils.asContainer(tagRoot.getChild(0)).bookmarkGuid;
   tagRoot.containerOpen = false;
 
-  // Currently these use the old API as the new API doesn't support inserting
-  // invalid items into the tag folder.
+  function insert({type, parentGuid}) {
+    return PlacesUtils.withConnectionWrapper("test_458683: insert", async db => {
+      await db.executeCached(
+        `INSERT INTO moz_bookmarks (type, parent, position, guid)
+         VALUES (:type,
+                 (SELECT id FROM moz_bookmarks WHERE guid = :parentGuid),
+                 (SELECT MAX(position) + 1 FROM moz_bookmarks WHERE parent = (SELECT id FROM moz_bookmarks WHERE guid = :parentGuid)),
+                 GENERATE_GUID())`, {type, parentGuid});
+    });
+  }
 
   // add a separator and a folder inside tag folder
-  PlacesUtils.bookmarks.insertSeparator(tagItemId,
-                                       PlacesUtils.bookmarks.DEFAULT_INDEX);
-  PlacesUtils.bookmarks.createFolder(tagItemId,
-                                     "test folder",
-                                     PlacesUtils.bookmarks.DEFAULT_INDEX);
+  // We must insert these manually, because the new bookmarking API doesn't
+  // support inserting invalid items into the tag folder.
+  await insert({
+    parentGuid: tagItemGuid,
+    type: PlacesUtils.bookmarks.TYPE_SEPARATOR
+  });
+  await insert({
+    parentGuid: tagItemGuid,
+    type: PlacesUtils.bookmarks.TYPE_FOLDER
+  });
 
   // add a separator and a folder inside tag root
-  PlacesUtils.bookmarks.insertSeparator(PlacesUtils.bookmarks.tagsFolder,
-                                        PlacesUtils.bookmarks.DEFAULT_INDEX);
-  PlacesUtils.bookmarks.createFolder(PlacesUtils.bookmarks.tagsFolder,
-                                     "test tags root folder",
-                                     PlacesUtils.bookmarks.DEFAULT_INDEX);
+  await PlacesUtils.bookmarks.insert({
+    parentGuid: PlacesUtils.bookmarks.tagsGuid,
+    type: PlacesUtils.bookmarks.TYPE_SEPARATOR
+  });
+  await PlacesUtils.bookmarks.insert({
+    parentGuid: PlacesUtils.bookmarks.tagsGuid,
+    title: "test tags root folder",
+    type: PlacesUtils.bookmarks.TYPE_FOLDER
+  });
+
   // sanity
   validateResults();
 
   await BookmarkJSONUtils.exportToFile(jsonFile);
 
   // clean
   PlacesUtils.tagging.untagURI(Services.io.newURI(ITEM_URL), [TAG_NAME]);
   await PlacesUtils.bookmarks.remove(item);
--- a/toolkit/components/places/tests/bookmarks/test_bookmarks_getRecent.js
+++ b/toolkit/components/places/tests/bookmarks/test_bookmarks_getRecent.js
@@ -30,18 +30,20 @@ add_task(async function getRecent_return
   checkBookmarkObject(bm2);
   checkBookmarkObject(bm3);
   checkBookmarkObject(bm4);
 
   // Add a tag to the most recent url to prove it doesn't get returned.
   PlacesUtils.tagging.tagURI(uri(bm4.url), ["Test Tag"]);
 
   // Add a separator.
-  PlacesUtils.bookmarks.insertSeparator(PlacesUtils.unfiledBookmarksFolderId,
-                                        PlacesUtils.bookmarks.DEFAULT_INDEX);
+  await PlacesUtils.bookmarks.insert({
+    parentGuid: PlacesUtils.bookmarks.unfiledGuid,
+    type: PlacesUtils.bookmarks.TYPE_SEPARATOR
+  });
 
   // Add a query bookmark.
   let queryURL = `place:folder=${PlacesUtils.bookmarksMenuFolderId}&queryType=1`;
   let bm5 = await PlacesUtils.bookmarks.insert({ parentGuid: PlacesUtils.bookmarks.unfiledGuid,
                                                  url: queryURL,
                                                  title: "a test query" });
   checkBookmarkObject(bm5);
 
--- a/toolkit/components/places/tests/bookmarks/test_sync_fields.js
+++ b/toolkit/components/places/tests/bookmarks/test_sync_fields.js
@@ -70,22 +70,24 @@ class TestCases {
     info("Test 2: reparenting");
     try {
       await this.testReparenting();
     } finally {
       info("Reset sync fields after test 2");
       await PlacesTestUtils.markBookmarksAsSynced();
     }
 
-    info("Test 3: separators");
-    try {
-      await this.testSeparators();
-    } finally {
-      info("Reset sync fields after test 3");
-      await PlacesTestUtils.markBookmarksAsSynced();
+    if ("insertSeparator" in this) {
+      info("Test 3: separators");
+      try {
+        await this.testSeparators();
+      } finally {
+        info("Reset sync fields after test 3");
+        await PlacesTestUtils.markBookmarksAsSynced();
+      }
     }
   }
 
   async testChanges() {
     let testUri = NetUtil.newURI("http://test.mozilla.org");
 
     let guid = await this.insertBookmark(PlacesUtils.bookmarks.unfiledGuid,
                                           testUri,
@@ -257,22 +259,16 @@ class SyncTestCases extends TestCases {
   }
 
   async insertBookmark(parentGuid, uri, index, title) {
     let parentId = await PlacesUtils.promiseItemId(parentGuid);
     let id = PlacesUtils.bookmarks.insertBookmark(parentId, uri, index, title);
     return PlacesUtils.promiseItemGuid(id);
   }
 
-  async insertSeparator(parentGuid, index) {
-    let parentId = await PlacesUtils.promiseItemId(parentGuid);
-    let id = PlacesUtils.bookmarks.insertSeparator(parentId, index);
-    return PlacesUtils.promiseItemGuid(id);
-  }
-
   async moveItem(guid, newParentGuid, index) {
     let id = await PlacesUtils.promiseItemId(guid);
     let newParentId = await PlacesUtils.promiseItemId(newParentGuid);
     PlacesUtils.bookmarks.moveItem(id, newParentId, index);
   }
 
   async removeItem(guid) {
     let id = await PlacesUtils.promiseItemId(guid);
--- a/toolkit/components/places/tests/legacy/test_bookmarks.js
+++ b/toolkit/components/places/tests/legacy/test_bookmarks.js
@@ -268,31 +268,30 @@ add_task(async function test_bookmarks()
   Assert.equal(bookmarksObserver._itemMovedOldIndex, 0);
   Assert.equal(bookmarksObserver._itemMovedNewParent, testRoot);
   Assert.equal(bookmarksObserver._itemMovedNewIndex, 3);
 
   // test get folder's index
   let tmpFolder = bs.createFolder(testRoot, "tmp", 2);
 
   // test removeFolderChildren
-  // 1) add/remove each child type (bookmark, separator, folder)
+  // 1) add/remove each child type (bookmark, folder)
   tmpFolder = bs.createFolder(testRoot, "removeFolderChildren",
                               bs.DEFAULT_INDEX);
   bs.insertBookmark(tmpFolder, uri("http://foo9.com/"), bs.DEFAULT_INDEX, "");
   bs.createFolder(tmpFolder, "subfolder", bs.DEFAULT_INDEX);
-  bs.insertSeparator(tmpFolder, bs.DEFAULT_INDEX);
-  // 2) confirm that folder has 3 children
+  // 2) confirm that folder has 2 children
   let options = hs.getNewQueryOptions();
   let query = hs.getNewQuery();
   query.setFolders([tmpFolder], 1);
   try {
     let result = hs.executeQuery(query, options);
     let rootNode = result.root;
     rootNode.containerOpen = true;
-    Assert.equal(rootNode.childCount, 3);
+    Assert.equal(rootNode.childCount, 2);
     rootNode.containerOpen = false;
   } catch (ex) {
     do_throw("test removeFolderChildren() - querying for children failed: " + ex);
   }
   // 3) remove all children
   bs.removeFolderChildren(tmpFolder);
   // 4) confirm that folder has 0 children
   try {
@@ -527,19 +526,16 @@ function testSimpleFolderResult() {
   // create a folder
   let parent = bs.createFolder(root, "test", bs.DEFAULT_INDEX);
 
   // the time before we insert, in microseconds
   // Workaround possible VM timers issues subtracting 1ms.
   let beforeInsert = Date.now() * 1000 - 1;
   Assert.ok(beforeInsert > 0);
 
-  // insert a separator
-  let sep = bs.insertSeparator(parent, bs.DEFAULT_INDEX);
-
   // re-set item title separately so can test nodes' last modified
   let item = bs.insertBookmark(parent, uri("about:blank"),
                                bs.DEFAULT_INDEX, "");
   bs.setItemTitle(item, "test bookmark");
 
   // see above
   let folder = bs.createFolder(parent, "test folder", bs.DEFAULT_INDEX);
   bs.setItemTitle(folder, "test folder");
@@ -549,46 +545,41 @@ function testSimpleFolderResult() {
   Assert.equal(bookmarksObserver._itemAddedTitle, longName.substring(0, TITLE_LENGTH_MAX));
 
   let options = hs.getNewQueryOptions();
   let query = hs.getNewQuery();
   query.setFolders([parent], 1);
   let result = hs.executeQuery(query, options);
   let rootNode = result.root;
   rootNode.containerOpen = true;
-  Assert.equal(rootNode.childCount, 4);
+  Assert.equal(rootNode.childCount, 3);
 
   let node = rootNode.getChild(0);
-  Assert.ok(node.dateAdded > 0);
-  Assert.equal(node.lastModified, node.dateAdded);
-  Assert.equal(node.itemId, sep);
-  Assert.equal(node.title, "");
-  node = rootNode.getChild(1);
   Assert.equal(node.itemId, item);
   Assert.ok(node.dateAdded > 0);
   Assert.ok(node.lastModified > 0);
   Assert.equal(node.title, "test bookmark");
-  node = rootNode.getChild(2);
+  node = rootNode.getChild(1);
   Assert.equal(node.itemId, folder);
   Assert.equal(node.title, "test folder");
   Assert.ok(node.dateAdded > 0);
   Assert.ok(node.lastModified > 0);
-  node = rootNode.getChild(3);
+  node = rootNode.getChild(2);
   Assert.equal(node.itemId, folderLongName);
   Assert.equal(node.title, longName.substring(0, TITLE_LENGTH_MAX));
   Assert.ok(node.dateAdded > 0);
   Assert.ok(node.lastModified > 0);
 
   // update with another long title
   bs.setItemTitle(folderLongName, longName + " updated");
   Assert.equal(bookmarksObserver._itemChangedId, folderLongName);
   Assert.equal(bookmarksObserver._itemChangedProperty, "title");
   Assert.equal(bookmarksObserver._itemChangedValue, longName.substring(0, TITLE_LENGTH_MAX));
 
-  node = rootNode.getChild(3);
+  node = rootNode.getChild(2);
   Assert.equal(node.title, longName.substring(0, TITLE_LENGTH_MAX));
 
   rootNode.containerOpen = false;
 }
 
 function getChildCount(aFolderId) {
   let cc = -1;
   try {