Bug 1383623 - Remove synchronous Places API usage from the Sync unit tests. r?tcsc draft
authorKit Cambridge <kit@yakshaving.ninja>
Thu, 09 Nov 2017 15:46:27 -0800
changeset 695895 25b077ce0dc9115c87fbb7c0f30b2b3c453be895
parent 695600 2bdf6eed0f64a51dfe099e089852533595f1a896
child 739736 606ce6a20b9ffdcf37349bcdf924843713e1d4e5
push id88580
push userbmo:kit@mozilla.com
push dateThu, 09 Nov 2017 23:48:05 +0000
reviewerstcsc
bugs1383623
milestone58.0a1
Bug 1383623 - Remove synchronous Places API usage from the Sync unit tests. r?tcsc MozReview-Commit-ID: Cip7LSSi2fE
services/sync/tests/unit/head_helpers.js
services/sync/tests/unit/test_bookmark_decline_undecline.js
services/sync/tests/unit/test_bookmark_duping.js
services/sync/tests/unit/test_bookmark_engine.js
services/sync/tests/unit/test_bookmark_invalid.js
services/sync/tests/unit/test_bookmark_livemarks.js
services/sync/tests/unit/test_bookmark_places_query_rewriting.js
services/sync/tests/unit/test_bookmark_repair_responder.js
services/sync/tests/unit/test_bookmark_smart_bookmarks.js
services/sync/tests/unit/test_bookmark_store.js
services/sync/tests/unit/test_bookmark_tracker.js
services/sync/tests/unit/test_engine_changes_during_sync.js
services/sync/tests/unit/test_history_store.js
services/sync/tests/unit/test_places_guid_downgrade.js
services/sync/tests/unit/test_syncengine_sync.js
services/sync/tests/unit/test_telemetry.js
--- a/services/sync/tests/unit/head_helpers.js
+++ b/services/sync/tests/unit/head_helpers.js
@@ -11,16 +11,17 @@
 /* global Service */
 
 Cu.import("resource://services-common/async.js");
 Cu.import("resource://services-common/utils.js");
 Cu.import("resource://testing-common/PlacesTestUtils.jsm");
 Cu.import("resource://services-sync/util.js");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/PlacesUtils.jsm");
+Cu.import("resource://gre/modules/PlacesSyncUtils.jsm");
 Cu.import("resource://gre/modules/ObjectUtils.jsm");
 
 add_task(async function head_setup() {
   // If a test imports Service, make sure it is initialized first.
   if (this.Service) {
     await this.Service.promiseInitialized;
   }
 });
--- a/services/sync/tests/unit/test_bookmark_decline_undecline.js
+++ b/services/sync/tests/unit/test_bookmark_decline_undecline.js
@@ -1,12 +1,11 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
-Cu.import("resource://gre/modules/PlacesSyncUtils.jsm");
 Cu.import("resource://gre/modules/BookmarkJSONUtils.jsm");
 Cu.import("resource://gre/modules/Log.jsm");
 Cu.import("resource://services-sync/constants.js");
 Cu.import("resource://services-sync/engines.js");
 Cu.import("resource://services-sync/engines/bookmarks.js");
 Cu.import("resource://services-sync/service.js");
 Cu.import("resource://services-sync/util.js");
 Cu.import("resource://testing-common/services/sync/utils.js");
--- a/services/sync/tests/unit/test_bookmark_duping.js
+++ b/services/sync/tests/unit/test_bookmark_duping.js
@@ -1,12 +1,11 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
-Cu.import("resource://gre/modules/PlacesSyncUtils.jsm");
 Cu.import("resource://services-common/async.js");
 Cu.import("resource://gre/modules/Log.jsm");
 Cu.import("resource://services-sync/engines.js");
 Cu.import("resource://services-sync/engines/bookmarks.js");
 Cu.import("resource://services-sync/service.js");
 Cu.import("resource://services-sync/util.js");
 Cu.import("resource://testing-common/services/sync/utils.js");
 Cu.import("resource://services-sync/bookmark_validator.js");
@@ -546,18 +545,18 @@ add_task(async function test_dupe_repare
 
     // The record for folder1 on the server should reference the new GUID.
     let serverRecord1 = getServerRecord(collection, folder1_guid);
     ok(!serverRecord1.children.includes(bmk1_guid));
     ok(serverRecord1.children.includes(newGUID));
 
     // As the incoming parent is missing the item should have been annotated
     // with that missing parent.
-    equal(PlacesUtils.annotations.getItemAnnotation((await store.idForGUID(newGUID)), "sync/parent"),
-          newParentGUID);
+    equal(PlacesUtils.annotations.getItemAnnotation((await store.idForGUID(newGUID)),
+      PlacesSyncUtils.bookmarks.SYNC_PARENT_ANNO), newParentGUID);
 
     // Check the validator. Sadly, this is known to cause a mismatch between
     // the server and client views of the tree.
     let expected = [
       // We haven't fixed the incoming record that referenced the missing parent.
       { name: "orphans", count: 1 },
     ];
     await validate(collection, expected);
--- a/services/sync/tests/unit/test_bookmark_engine.js
+++ b/services/sync/tests/unit/test_bookmark_engine.js
@@ -1,12 +1,11 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
-Cu.import("resource://gre/modules/PlacesSyncUtils.jsm");
 Cu.import("resource://gre/modules/BookmarkHTMLUtils.jsm");
 Cu.import("resource://gre/modules/BookmarkJSONUtils.jsm");
 Cu.import("resource://gre/modules/Log.jsm");
 Cu.import("resource://services-common/utils.js");
 Cu.import("resource://services-sync/constants.js");
 Cu.import("resource://services-sync/engines.js");
 Cu.import("resource://services-sync/engines/bookmarks.js");
 Cu.import("resource://services-sync/service.js");
@@ -108,35 +107,32 @@ add_task(async function test_delete_inva
 });
 
 add_task(async function bad_record_allIDs() {
   let server = new SyncServer();
   server.start();
   await SyncTestingInfrastructure(server);
 
   _("Ensure that bad Places queries don't cause an error in getAllIDs.");
-  let badRecordID = PlacesUtils.bookmarks.insertBookmark(
-      PlacesUtils.bookmarks.toolbarFolder,
-      CommonUtils.makeURI("place:folder=1138"),
-      PlacesUtils.bookmarks.DEFAULT_INDEX,
-      null);
+  let badRecord = await PlacesUtils.bookmarks.insert({
+    parentGuid: PlacesUtils.bookmarks.toolbarGuid,
+    url: "place:folder=1138",
+  });
 
-  do_check_true(badRecordID > 0);
-  _("Record is " + badRecordID);
-  _("Type: " + PlacesUtils.bookmarks.getItemType(badRecordID));
+  _("Type: " + badRecord.type);
 
   _("Fetching all IDs.");
   let all = await fetchAllRecordIds();
 
   _("All IDs: " + JSON.stringify([...all]));
   do_check_true(all.has("menu"));
   do_check_true(all.has("toolbar"));
 
   _("Clean up.");
-  PlacesUtils.bookmarks.removeItem(badRecordID);
+  await PlacesUtils.bookmarks.eraseEverything();
   await PlacesSyncUtils.bookmarks.reset();
   await promiseStopServer(server);
 });
 
 add_task(async function test_processIncoming_error_orderChildren() {
   _("Ensure that _orderChildren() is called even when _processIncoming() throws an error.");
 
   let engine = new BookmarksEngine(Service);
@@ -144,34 +140,39 @@ add_task(async function test_processInco
   let store  = engine._store;
   let server = await serverForFoo(engine);
   await SyncTestingInfrastructure(server);
 
   let collection = server.user("foo").collection("bookmarks");
 
   try {
 
-    let folder1_id = PlacesUtils.bookmarks.createFolder(
-      PlacesUtils.bookmarks.toolbarFolder, "Folder 1", 0);
-    let folder1_guid = await store.GUIDForId(folder1_id);
+    let folder1 = await PlacesUtils.bookmarks.insert({
+      parentGuid: PlacesUtils.bookmarks.toolbarGuid,
+      type: PlacesUtils.bookmarks.TYPE_FOLDER,
+      title: "Folder 1",
+    });
 
-    let fxuri = CommonUtils.makeURI("http://getfirefox.com/");
-    let tburi = CommonUtils.makeURI("http://getthunderbird.com/");
-
-    let bmk1_id = PlacesUtils.bookmarks.insertBookmark(
-      folder1_id, fxuri, PlacesUtils.bookmarks.DEFAULT_INDEX, "Get Firefox!");
-    let bmk2_id = PlacesUtils.bookmarks.insertBookmark(
-      folder1_id, tburi, PlacesUtils.bookmarks.DEFAULT_INDEX, "Get Thunderbird!");
+    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 server record for folder1 where we flip the order of
     // the children.
-    let folder1_record = await store.createRecord(folder1_guid);
+    let folder1_record = await store.createRecord(folder1.guid);
     let folder1_payload = folder1_record.cleartext;
     folder1_payload.children.reverse();
-    collection.insert(folder1_guid, encryptPayload(folder1_payload));
+    collection.insert(folder1.guid, encryptPayload(folder1_payload));
 
     // Create a bogus record that when synced down will provoke a
     // network error which in turn provokes an exception in _processIncoming.
     const BOGUS_GUID = "zzzzzzzzzzzz";
     let bogus_record = collection.insert(BOGUS_GUID, "I'm a bogus record!");
     bogus_record.get = function get() {
       throw new Error("Sync this!");
     };
@@ -185,24 +186,24 @@ add_task(async function test_processInco
     try {
       await sync_engine_and_validate_telem(engine, true);
     } catch (ex) {
       error = ex;
     }
     ok(!!error);
 
     // Verify that the bookmark order has been applied.
-    folder1_record = await store.createRecord(folder1_guid);
+    folder1_record = await store.createRecord(folder1.guid);
     let new_children = folder1_record.children;
-    do_check_eq(new_children.length, 2);
-    do_check_eq(new_children[0], folder1_payload.children[0]);
-    do_check_eq(new_children[1], folder1_payload.children[1]);
+    do_check_matches(new_children,
+      [folder1_payload.children[0], folder1_payload.children[1]]);
 
-    do_check_eq(PlacesUtils.bookmarks.getItemIndex(bmk1_id), 1);
-    do_check_eq(PlacesUtils.bookmarks.getItemIndex(bmk2_id), 0);
+    let localChildIds = await PlacesSyncUtils.bookmarks.fetchChildRecordIds(
+      folder1.guid);
+    do_check_matches(localChildIds, [bmk2.guid, bmk1.guid]);
 
   } finally {
     await store.wipe();
     await engine.resetClient();
     Svc.Prefs.resetBranch("");
     Service.recordManager.clearCache();
     await PlacesSyncUtils.bookmarks.reset();
     await promiseStopServer(server);
@@ -233,65 +234,67 @@ async function test_restoreOrImport(aRep
   await SyncTestingInfrastructure(server);
 
   let collection = server.user("foo").collection("bookmarks");
 
   Svc.Obs.notify("weave:engine:start-tracking"); // We skip usual startup...
 
   try {
 
-    let folder1_id = PlacesUtils.bookmarks.createFolder(
-      PlacesUtils.bookmarks.toolbarFolder, "Folder 1", 0);
-    let folder1_guid = await store.GUIDForId(folder1_id);
-    _("Folder 1: " + folder1_id + ", " + folder1_guid);
-
-    let fxuri = CommonUtils.makeURI("http://getfirefox.com/");
-    let tburi = CommonUtils.makeURI("http://getthunderbird.com/");
+    let folder1 = await PlacesUtils.bookmarks.insert({
+      parentGuid: PlacesUtils.bookmarks.toolbarGuid,
+      type: PlacesUtils.bookmarks.TYPE_FOLDER,
+      title: "Folder 1",
+    });
 
     _("Create a single record.");
-    let bmk1_id = PlacesUtils.bookmarks.insertBookmark(
-      folder1_id, fxuri, PlacesUtils.bookmarks.DEFAULT_INDEX, "Get Firefox!");
-    let bmk1_guid = await store.GUIDForId(bmk1_id);
-    _(`Get Firefox!: ${bmk1_id}, ${bmk1_guid}`);
+    let bmk1 = await PlacesUtils.bookmarks.insert({
+      parentGuid: folder1.guid,
+      url: "http://getfirefox.com/",
+      title: "Get Firefox!",
+    });
+    _(`Get Firefox!: ${bmk1.guid}`);
 
     let dirSvc = Cc["@mozilla.org/file/directory_service;1"]
       .getService(Ci.nsIProperties);
 
     let backupFile = dirSvc.get("TmpD", Ci.nsIFile);
 
     _("Make a backup.");
     backupFile.append("t_b_e_" + Date.now() + ".json");
 
     _(`Backing up to file ${backupFile.path}`);
     await bookmarkUtils.exportToFile(backupFile.path);
 
     _("Create a different record and sync.");
-    let bmk2_id = PlacesUtils.bookmarks.insertBookmark(
-      folder1_id, tburi, PlacesUtils.bookmarks.DEFAULT_INDEX, "Get Thunderbird!");
-    let bmk2_guid = await store.GUIDForId(bmk2_id);
-    _(`Get Thunderbird!: ${bmk2_id}, ${bmk2_guid}`);
+    let bmk2 = await PlacesUtils.bookmarks.insert({
+      parentGuid: folder1.guid,
+      url: "http://getthunderbird.com/",
+      title: "Get Thunderbird!",
+    });
+    _(`Get Thunderbird!: ${bmk2.guid}`);
 
-    PlacesUtils.bookmarks.removeItem(bmk1_id);
+    await PlacesUtils.bookmarks.remove(bmk1.guid);
 
     let error;
     try {
       await sync_engine_and_validate_telem(engine, false);
     } catch (ex) {
       error = ex;
       _("Got error: " + Log.exceptionStr(ex));
     }
     do_check_true(!error);
 
     _("Verify that there's only one bookmark on the server, and it's Thunderbird.");
     // Of course, there's also the Bookmarks Toolbar and Bookmarks Menu...
     let wbos = collection.keys(function(id) {
-      return ["menu", "toolbar", "mobile", "unfiled", folder1_guid].indexOf(id) == -1;
+      return ["menu", "toolbar", "mobile", "unfiled", folder1.guid].indexOf(id) == -1;
     });
     do_check_eq(wbos.length, 1);
-    do_check_eq(wbos[0], bmk2_guid);
+    do_check_eq(wbos[0], bmk2.guid);
 
     _(`Now ${verb} from a backup.`);
     await bookmarkUtils.importFromFile(backupFile, aReplace);
 
     let bookmarksCollection = server.user("foo").collection("bookmarks");
     if (aReplace) {
       _("Verify that we wiped the server.");
       do_check_true(!bookmarksCollection);
@@ -302,34 +305,34 @@ async function test_restoreOrImport(aRep
 
     _("Ensure we have the bookmarks we expect locally.");
     let guids = await fetchAllRecordIds();
     _("GUIDs: " + JSON.stringify([...guids]));
     let bookmarkGuids = new Map();
     let count = 0;
     for (let guid of guids) {
       count++;
-      let id = await store.idForGUID(guid, true);
+      let info = await PlacesUtils.bookmarks.fetch(
+        PlacesSyncUtils.bookmarks.recordIdToGuid(guid));
       // Only one bookmark, so _all_ should be Firefox!
-      if (PlacesUtils.bookmarks.getItemType(id) == PlacesUtils.bookmarks.TYPE_BOOKMARK) {
-        let uri = PlacesUtils.bookmarks.getBookmarkURI(id);
-        _(`Found URI ${uri.spec} for GUID ${guid}`);
-        bookmarkGuids.set(uri.spec, guid);
+      if (info.type == PlacesUtils.bookmarks.TYPE_BOOKMARK) {
+        _(`Found URI ${info.url.href} for GUID ${guid}`);
+        bookmarkGuids.set(info.url.href, guid);
       }
     }
-    do_check_true(bookmarkGuids.has(fxuri.spec));
+    do_check_true(bookmarkGuids.has("http://getfirefox.com/"));
     if (!aReplace) {
-      do_check_true(bookmarkGuids.has(tburi.spec));
+      do_check_true(bookmarkGuids.has("http://getthunderbird.com/"));
     }
 
     _("Have the correct number of IDs locally, too.");
-    let expectedResults = ["menu", "toolbar", "mobile", "unfiled", folder1_id,
-                           bmk1_id];
+    let expectedResults = ["menu", "toolbar", "mobile", "unfiled", folder1.guid,
+                           bmk1.guid];
     if (!aReplace) {
-      expectedResults.push("toolbar", folder1_id, bmk2_id);
+      expectedResults.push("toolbar", folder1.guid, bmk2.guid);
     }
     do_check_eq(count, expectedResults.length);
 
     _("Sync again. This'll wipe bookmarks from the server.");
     try {
       await sync_engine_and_validate_telem(engine, false);
     } catch (ex) {
       error = ex;
@@ -349,23 +352,23 @@ async function test_restoreOrImport(aRep
                                  (wbo.id != "menu") &&
                                  (wbo.id != "toolbar") &&
                                  (wbo.id != "unfiled") &&
                                  (wbo.id != "mobile") &&
                                  (wbo.parentid != "menu"));
                        });
 
     let expectedFX = {
-      id: bookmarkGuids.get(fxuri.spec),
-      bmkUri: fxuri.spec,
+      id: bookmarkGuids.get("http://getfirefox.com/"),
+      bmkUri: "http://getfirefox.com/",
       title: "Get Firefox!"
     };
     let expectedTB = {
-      id: bookmarkGuids.get(tburi.spec),
-      bmkUri: tburi.spec,
+      id: bookmarkGuids.get("http://getthunderbird.com/"),
+      bmkUri: "http://getthunderbird.com/",
       title: "Get Thunderbird!"
     };
 
     let expectedBookmarks;
     if (aReplace) {
       expectedBookmarks = [expectedFX];
     } else {
       expectedBookmarks = [expectedTB, expectedFX];
@@ -453,39 +456,38 @@ add_task(async function test_mismatched_
   newRecord.cleartext = newRecord;
 
   let engine = new BookmarksEngine(Service);
   await engine.initialize();
   let store  = engine._store;
   let server = await serverForFoo(engine);
   await SyncTestingInfrastructure(server);
 
-  _("GUID: " + (await store.GUIDForId(6, true)));
-
   try {
-    let bms = PlacesUtils.bookmarks;
     let oldR = new FakeRecord(BookmarkFolder, oldRecord);
     let newR = new FakeRecord(Livemark, newRecord);
     oldR.parentid = PlacesUtils.bookmarks.toolbarGuid;
     newR.parentid = PlacesUtils.bookmarks.toolbarGuid;
 
     await store.applyIncoming(oldR);
     _("Applied old. It's a folder.");
-    let oldID = await store.idForGUID(oldR.id);
+    let oldID = await PlacesUtils.promiseItemId(oldR.id);
     _("Old ID: " + oldID);
-    do_check_eq(bms.getItemType(oldID), bms.TYPE_FOLDER);
+    let oldInfo = await PlacesUtils.bookmarks.fetch(oldR.id);
+    do_check_eq(oldInfo.type, PlacesUtils.bookmarks.TYPE_FOLDER);
     do_check_false(PlacesUtils.annotations
                               .itemHasAnnotation(oldID, PlacesUtils.LMANNO_FEEDURI));
 
     await store.applyIncoming(newR);
-    let newID = await store.idForGUID(newR.id);
+    let newID = await PlacesUtils.promiseItemId(newR.id);
     _("New ID: " + newID);
 
     _("Applied new. It's a livemark.");
-    do_check_eq(bms.getItemType(newID), bms.TYPE_FOLDER);
+    let newInfo = await PlacesUtils.bookmarks.fetch(newR.id);
+    do_check_eq(newInfo.type, PlacesUtils.bookmarks.TYPE_FOLDER);
     do_check_true(PlacesUtils.annotations
                              .itemHasAnnotation(newID, PlacesUtils.LMANNO_FEEDURI));
 
   } finally {
     await store.wipe();
     await engine.resetClient();
     Svc.Prefs.resetBranch("");
     Service.recordManager.clearCache();
@@ -501,22 +503,24 @@ add_task(async function test_bookmark_gu
   await engine.initialize();
   let store = engine._store;
 
   let server = await serverForFoo(engine);
   let coll   = server.user("foo").collection("bookmarks");
   await SyncTestingInfrastructure(server);
 
   // Add one item to the server.
-  let itemID = PlacesUtils.bookmarks.createFolder(
-    PlacesUtils.bookmarks.toolbarFolder, "Folder 1", 0);
-  let itemGUID = await store.GUIDForId(itemID);
-  let itemRecord = await store.createRecord(itemGUID);
+  let item = await PlacesUtils.bookmarks.insert({
+    parentGuid: PlacesUtils.bookmarks.toolbarGuid,
+    type: PlacesUtils.bookmarks.TYPE_FOLDER,
+    title: "Folder 1",
+  });
+  let itemRecord = await store.createRecord(item.guid);
   let itemPayload = itemRecord.cleartext;
-  coll.insert(itemGUID, encryptPayload(itemPayload));
+  coll.insert(item.guid, encryptPayload(itemPayload));
 
   engine.lastSync = 1; // So we don't back up.
 
   // Make building the GUID map fail.
 
   let pbt = PlacesUtils.promiseBookmarksTree;
   PlacesUtils.promiseBookmarksTree = function() { return Promise.reject("Nooo"); };
 
@@ -606,21 +610,23 @@ add_task(async function test_misreconcil
   // Log real hard for this test.
   store._log.trace = store._log.debug;
   engine._log.trace = engine._log.debug;
 
   await engine._syncStartup();
 
   // Let's find out where the toolbar is right now.
   let toolbarBefore = await store.createRecord("toolbar", "bookmarks");
-  let toolbarIDBefore = await store.idForGUID("toolbar");
+  let toolbarIDBefore = await PlacesUtils.promiseItemId(
+    PlacesUtils.bookmarks.toolbarGuid);
   do_check_neq(-1, toolbarIDBefore);
 
   let parentGUIDBefore = toolbarBefore.parentid;
-  let parentIDBefore = await store.idForGUID(parentGUIDBefore);
+  let parentIDBefore = await PlacesUtils.promiseItemId(
+    PlacesSyncUtils.bookmarks.recordIdToGuid(parentGUIDBefore));
   do_check_neq(-1, parentIDBefore);
   do_check_eq("string", typeof(parentGUIDBefore));
 
   _("Current parent: " + parentGUIDBefore + " (" + parentIDBefore + ").");
 
   let to_apply = {
     id: "zzzzzzzzzzzz",
     type: "folder",
@@ -636,18 +642,20 @@ add_task(async function test_misreconcil
   _("Applying record.");
   store.applyIncoming(rec);
 
   // Ensure that afterwards, toolbar is still there.
   // As of 2012-12-05, this only passes because Places doesn't use "toolbar" as
   // the real GUID, instead using a generated one. Sync does the translation.
   let toolbarAfter = await store.createRecord("toolbar", "bookmarks");
   let parentGUIDAfter = toolbarAfter.parentid;
-  let parentIDAfter = await store.idForGUID(parentGUIDAfter);
-  do_check_eq((await store.GUIDForId(toolbarIDBefore)), "toolbar");
+  let parentIDAfter = await PlacesUtils.promiseItemId(
+    PlacesSyncUtils.bookmarks.recordIdToGuid(parentGUIDAfter));
+  do_check_eq((await PlacesUtils.promiseItemGuid(toolbarIDBefore)),
+    PlacesUtils.bookmarks.toolbarGuid);
   do_check_eq(parentGUIDBefore, parentGUIDAfter);
   do_check_eq(parentIDBefore, parentIDAfter);
 
   await store.wipe();
   await engine.resetClient();
   await PlacesSyncUtils.bookmarks.reset();
   await promiseStopServer(server);
 });
@@ -755,36 +763,36 @@ add_task(async function test_sync_dateAd
     equal(record5.dateAdded, item5LastModified * 1000,
           "If no dateAdded is provided, lastModified should be used (even if it's in the future)");
 
     // Update item2 and try resyncing it.
     item2.dateAdded = now - 100000;
     collection.insert(item2GUID, encryptPayload(item2.cleartext), now / 1000 - 50);
 
 
-    // Also, add a local bookmark and make sure it's date added makes it up to the server
-    let bzid = PlacesUtils.bookmarks.insertBookmark(
-      PlacesUtils.bookmarksMenuFolderId, CommonUtils.makeURI("https://bugzilla.mozilla.org/"),
-      PlacesUtils.bookmarks.DEFAULT_INDEX, "Bugzilla");
-
-    let bzguid = await PlacesUtils.promiseItemGuid(bzid);
+    // Also, add a local bookmark and make sure its date added makes it up to the server
+    let bz = await PlacesUtils.bookmarks.insert({
+      parentGuid: PlacesUtils.bookmarks.menuGuid,
+      url: "https://bugzilla.mozilla.org/",
+      title: "Bugzilla",
+    });
 
     // last sync did a POST, which doesn't advance its lastModified value.
     // Next sync of the engine doesn't hit info/collections, so lastModified
     // remains stale. Setting it to null side-steps that.
     engine.lastModified = null;
     await sync_engine_and_validate_telem(engine, false);
 
     let newRecord2 = await store.createRecord(item2GUID);
     equal(newRecord2.dateAdded, item2.dateAdded, "dateAdded update should work for earlier date");
 
-    let bzWBO = JSON.parse(JSON.parse(collection._wbos[bzguid].payload).ciphertext);
+    let bzWBO = JSON.parse(JSON.parse(collection._wbos[bz.guid].payload).ciphertext);
     ok(bzWBO.dateAdded, "Locally added dateAdded lost");
 
-    let localRecord = await store.createRecord(bzguid);
+    let localRecord = await store.createRecord(bz.guid);
     equal(bzWBO.dateAdded, localRecord.dateAdded, "dateAdded should not change during upload");
 
     item2.dateAdded += 10000;
     collection.insert(item2GUID, encryptPayload(item2.cleartext), now / 1000 - 10);
 
     engine.lastModified = null;
     await sync_engine_and_validate_telem(engine, false);
 
--- a/services/sync/tests/unit/test_bookmark_invalid.js
+++ b/services/sync/tests/unit/test_bookmark_invalid.js
@@ -14,48 +14,50 @@ add_task(async function setup() {
   store = engine._store;
   tracker = engine._tracker;
 });
 
 add_task(async function test_ignore_invalid_uri() {
   _("Ensure that we don't die with invalid bookmarks.");
 
   // First create a valid bookmark.
-  let bmid = PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
-                                                  Services.io.newURI("http://example.com/"),
-                                                  PlacesUtils.bookmarks.DEFAULT_INDEX,
-                                                  "the title");
+  let bmInfo = await PlacesUtils.bookmarks.insert({
+    parentGuid: PlacesUtils.bookmarks.unfiledGuid,
+    url: "http://example.com/",
+    title: "the title",
+  });
 
   // Now update moz_places with an invalid url.
   await PlacesUtils.withConnectionWrapper("test_ignore_invalid_uri", async function(db) {
     await db.execute(
       `UPDATE moz_places SET url = :url, url_hash = hash(:url)
        WHERE id = (SELECT b.fk FROM moz_bookmarks b
-       WHERE b.id = :id LIMIT 1)`,
-      { id: bmid, url: "<invalid url>" });
+                   WHERE b.guid = :guid)`,
+      { guid: bmInfo.guid, url: "<invalid url>" });
   });
 
   // Ensure that this doesn't throw even though the DB is now in a bad state (a
   // bookmark has an illegal url).
   await engine._buildGUIDMap();
 });
 
 add_task(async function test_ignore_missing_uri() {
   _("Ensure that we don't die with a bookmark referencing an invalid bookmark id.");
 
   // First create a valid bookmark.
-  let bmid = PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
-                                                  Services.io.newURI("http://example.com/"),
-                                                  PlacesUtils.bookmarks.DEFAULT_INDEX,
-                                                  "the title");
+  let bmInfo = await PlacesUtils.bookmarks.insert({
+    parentGuid: PlacesUtils.bookmarks.unfiledGuid,
+    url: "http://example.com/",
+    title: "the title",
+  });
 
   // Now update moz_bookmarks to reference a non-existing places ID
   await PlacesUtils.withConnectionWrapper("test_ignore_missing_uri", async function(db) {
     await db.execute(
       `UPDATE moz_bookmarks SET fk = 999999
-       WHERE id = :id`
-      , { id: bmid });
+       WHERE guid = :guid`
+      , { guid: bmInfo.guid });
   });
 
   // Ensure that this doesn't throw even though the DB is now in a bad state (a
   // bookmark has an illegal url).
   await engine._buildGUIDMap();
 });
--- a/services/sync/tests/unit/test_bookmark_livemarks.js
+++ b/services/sync/tests/unit/test_bookmark_livemarks.js
@@ -81,50 +81,48 @@ add_task(async function test_livemark_de
 
   // Attempt to provoke an error by messing around with the description.
   record.description = null;
   await doRecord(makeLivemark(record));
   record.description = "";
   await doRecord(makeLivemark(record));
 
   // Attempt to provoke an error by adding a bad description anno.
-  let id = await store.idForGUID(record.id);
+  let id = await PlacesUtils.promiseItemId(record.id);
   PlacesUtils.annotations.setItemAnnotation(id, DESCRIPTION_ANNO, "", 0,
                                             PlacesUtils.annotations.EXPIRE_NEVER);
 
   await engine.finalize();
 });
 
 add_task(async function test_livemark_invalid() {
   let engine = new BookmarksEngine(Service);
   await engine.initialize();
   let store = engine._store;
 
   _("Livemarks considered invalid by nsLivemarkService are skipped.");
 
   _("Parent is unknown. Will be set to unfiled.");
   let lateParentRec = makeLivemark(record631361.payload, true);
-  let parentGUID = Utils.makeGUID();
-  lateParentRec.parentid = parentGUID;
-  do_check_eq(-1, (await store.idForGUID(parentGUID)));
+  lateParentRec.parentid = Utils.makeGUID();
 
   await store.create(lateParentRec);
-  let recID = await store.idForGUID(lateParentRec.id, true);
-  do_check_true(recID > 0);
-  do_check_eq(PlacesUtils.bookmarks.getFolderIdForItem(recID),
-              PlacesUtils.bookmarks.unfiledBookmarksFolder);
+  let recInfo = await PlacesUtils.bookmarks.fetch(lateParentRec.id);
+  do_check_eq(recInfo.parentGuid, PlacesUtils.bookmarks.unfiledGuid);
 
   _("No feed URI, which is invalid. Will be skipped.");
   let noFeedURIRec = makeLivemark(record631361.payload, true);
   delete noFeedURIRec.cleartext.feedUri;
   await store.create(noFeedURIRec);
   // No exception, but no creation occurs.
-  do_check_eq(-1, (await store.idForGUID(noFeedURIRec.id, true)));
+  let noFeedURIItem = await PlacesUtils.bookmarks.fetch(noFeedURIRec.id);
+  do_check_null(noFeedURIItem);
 
   _("Parent is a Livemark. Will be skipped.");
   let lmParentRec = makeLivemark(record631361.payload, true);
-  lmParentRec.parentid = await store.GUIDForId(recID);
+  lmParentRec.parentid = recInfo.guid;
   await store.create(lmParentRec);
   // No exception, but no creation occurs.
-  do_check_eq(-1, (await store.idForGUID(lmParentRec.id, true)));
+  let lmParentItem = await PlacesUtils.bookmarks.fetch(lmParentRec.id);
+  do_check_null(lmParentItem);
 
   await engine.finalize();
 });
--- a/services/sync/tests/unit/test_bookmark_places_query_rewriting.js
+++ b/services/sync/tests/unit/test_bookmark_places_query_rewriting.js
@@ -27,28 +27,26 @@ add_task(async function run_test() {
 
   let uri = "place:folder=499&type=7&queryType=1";
   let tagRecord = makeTagRecord("abcdefabcdef", uri);
 
   _("Type: " + tagRecord.type);
   _("Folder name: " + tagRecord.folderName);
   await store.applyIncoming(tagRecord);
 
-  let tags = PlacesUtils.getFolderContents(PlacesUtils.tagsFolderId).root;
-  let tagID;
-  try {
-    for (let i = 0; i < tags.childCount; ++i) {
-      let child = tags.getChild(i);
-      if (child.title == "bar") {
-        tagID = child.itemId;
-      }
-    }
-  } finally {
-    tags.containerOpen = false;
-  }
+  let tagID = -1;
+  let db = await PlacesUtils.promiseDBConnection();
+  let rows = await db.execute(`
+    SELECT id FROM moz_bookmarks
+    WHERE parent = :tagsFolderId AND
+          title = :title`,
+    { tagsFolderId: PlacesUtils.tagsFolderId,
+      title: "bar" });
+  equal(rows.length, 1);
+  tagID = rows[0].getResultByName("id");
 
   _("Tag ID: " + tagID);
   let insertedRecord = await store.createRecord("abcdefabcdef", "bookmarks");
   do_check_eq(insertedRecord.bmkUri, uri.replace("499", tagID));
 
   _("... but not if the type is wrong.");
   let wrongTypeURI = "place:folder=499&type=2&queryType=1";
   let wrongTypeRecord = makeTagRecord("fedcbafedcba", wrongTypeURI);
--- a/services/sync/tests/unit/test_bookmark_repair_responder.js
+++ b/services/sync/tests/unit/test_bookmark_repair_responder.js
@@ -1,13 +1,11 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
-Cu.import("resource://gre/modules/PlacesSyncUtils.jsm");
-Cu.import("resource://testing-common/PlacesTestUtils.jsm");
 Cu.import("resource:///modules/PlacesUIUtils.jsm");
 Cu.import("resource://gre/modules/Log.jsm");
 
 Cu.import("resource://services-sync/engines/bookmarks.js");
 Cu.import("resource://services-sync/service.js");
 Cu.import("resource://services-sync/bookmark_repair.js");
 Cu.import("resource://testing-common/services/sync/utils.js");
 
--- a/services/sync/tests/unit/test_bookmark_smart_bookmarks.js
+++ b/services/sync/tests/unit/test_bookmark_smart_bookmarks.js
@@ -4,50 +4,39 @@
 Cu.import("resource://gre/modules/Log.jsm");
 Cu.import("resource://services-common/utils.js");
 Cu.import("resource://services-sync/engines.js");
 Cu.import("resource://services-sync/engines/bookmarks.js");
 Cu.import("resource://services-sync/service.js");
 Cu.import("resource://services-sync/util.js");
 Cu.import("resource://testing-common/services/sync/utils.js");
 
-const SMART_BOOKMARKS_ANNO = "Places/SmartBookmark";
-const IOService = Cc["@mozilla.org/network/io-service;1"]
-                .getService(Ci.nsIIOService);
-
 async function newSmartBookmark(parentGuid, url, position, title, queryID) {
   let info = await PlacesUtils.bookmarks.insert({
     parentGuid,
     url,
     position,
     title,
   });
   let id = await PlacesUtils.promiseItemId(info.guid);
-  PlacesUtils.annotations.setItemAnnotation(id, SMART_BOOKMARKS_ANNO,
-                                            queryID, 0,
-                                            PlacesUtils.annotations.EXPIRE_NEVER);
+  PlacesUtils.annotations.setItemAnnotation(id,
+    PlacesSyncUtils.bookmarks.SMART_BOOKMARKS_ANNO, queryID, 0,
+    PlacesUtils.annotations.EXPIRE_NEVER);
   return info;
 }
 
 function smartBookmarkCount() {
   // We do it this way because PlacesUtils.annotations.getItemsWithAnnotation
   // doesn't work the same (or at all?) between 3.6 and 4.0.
   let out = {};
-  PlacesUtils.annotations.getItemsWithAnnotation(SMART_BOOKMARKS_ANNO, out);
+  PlacesUtils.annotations.getItemsWithAnnotation(
+    PlacesSyncUtils.bookmarks.SMART_BOOKMARKS_ANNO, out);
   return out.value;
 }
 
-function clearBookmarks() {
-  _("Cleaning up existing items.");
-  PlacesUtils.bookmarks.removeFolderChildren(PlacesUtils.bookmarks.bookmarksMenuFolder);
-  PlacesUtils.bookmarks.removeFolderChildren(PlacesUtils.bookmarks.tagsFolder);
-  PlacesUtils.bookmarks.removeFolderChildren(PlacesUtils.bookmarks.toolbarFolder);
-  PlacesUtils.bookmarks.removeFolderChildren(PlacesUtils.bookmarks.unfiledBookmarksFolder);
-}
-
 let engine;
 let store;
 
 add_task(async function setup() {
   initTestLogging("Trace");
   Log.repository.getLogger("Sync.Engine.Bookmarks").level = Log.Level.Trace;
 
   await generateNewKeys(Service.collectionKeys);
@@ -60,45 +49,42 @@ add_task(async function setup() {
 });
 
 // Verify that Places smart bookmarks have their annotation uploaded and
 // handled locally.
 add_task(async function test_annotation_uploaded() {
   let server = await serverForFoo(engine);
   await SyncTestingInfrastructure(server);
 
+  _("Cleaning up existing items.");
+  await PlacesUtils.bookmarks.eraseEverything();
+
   let startCount = smartBookmarkCount();
 
   _("Start count is " + startCount);
 
-  if (startCount > 0) {
-    // This can happen in XULRunner.
-    clearBookmarks();
-    _("Start count is now " + startCount);
-  }
-
   _("Create a smart bookmark in the toolbar.");
   let url = "place:sort=" +
             Ci.nsINavHistoryQueryOptions.SORT_BY_VISITCOUNT_DESCENDING +
             "&maxResults=10";
   let title = "Most Visited";
 
   let mostVisitedInfo = await newSmartBookmark(
     PlacesUtils.bookmarks.toolbarGuid, url, -1, title, "MostVisited");
   let mostVisitedID = await PlacesUtils.promiseItemId(mostVisitedInfo.guid);
 
   _("New item ID: " + mostVisitedID);
   do_check_true(!!mostVisitedID);
 
   let annoValue = PlacesUtils.annotations.getItemAnnotation(mostVisitedID,
-                                              SMART_BOOKMARKS_ANNO);
+    PlacesSyncUtils.bookmarks.SMART_BOOKMARKS_ANNO);
   _("Anno: " + annoValue);
   do_check_eq("MostVisited", annoValue);
 
-  let guid = await store.GUIDForId(mostVisitedID);
+  let guid = await PlacesUtils.promiseItemGuid(mostVisitedID);
   _("GUID: " + guid);
   do_check_true(!!guid);
 
   _("Create record object and verify that it's sane.");
   let record = await store.createRecord(guid);
   do_check_true(record instanceof Bookmark);
   do_check_true(record instanceof BookmarkQuery);
 
@@ -130,48 +116,51 @@ add_task(async function test_annotation_
 
     _("We still have the right count.");
     do_check_eq(smartBookmarkCount(), startCount + 1);
 
     _("Clear local records; now we can't find it.");
 
     // "Clear" by changing attributes: if we delete it, apparently it sticks
     // around as a deleted record...
-    PlacesUtils.bookmarks.setItemTitle(mostVisitedID, "Not Most Visited");
-    PlacesUtils.bookmarks.changeBookmarkURI(
-      mostVisitedID, CommonUtils.makeURI("http://something/else"));
+    await PlacesUtils.bookmarks.update({
+      guid: mostVisitedInfo.guid,
+      title: "Not Most Visited",
+      url: "http://something/else",
+    });
     PlacesUtils.annotations.removeItemAnnotation(mostVisitedID,
-                                                 SMART_BOOKMARKS_ANNO);
+      PlacesSyncUtils.bookmarks.SMART_BOOKMARKS_ANNO);
     await store.wipe();
     await engine.resetClient();
     do_check_eq(smartBookmarkCount(), startCount);
 
     _("Sync. Verify that the downloaded record carries the annotation.");
     await sync_engine_and_validate_telem(engine, false);
 
     _("Verify that the Places DB now has an annotated bookmark.");
     _("Our count has increased again.");
     do_check_eq(smartBookmarkCount(), startCount + 1);
 
     _("Find by GUID and verify that it's annotated.");
-    let newID = await store.idForGUID(serverGUID);
+    let newID = await PlacesUtils.promiseItemId(serverGUID);
     let newAnnoValue = PlacesUtils.annotations.getItemAnnotation(
-      newID, SMART_BOOKMARKS_ANNO);
+      newID, PlacesSyncUtils.bookmarks.SMART_BOOKMARKS_ANNO);
     do_check_eq(newAnnoValue, "MostVisited");
-    do_check_eq(PlacesUtils.bookmarks.getBookmarkURI(newID).spec, url);
+    let newInfo = await PlacesUtils.bookmarks.fetch(serverGUID);
+    do_check_eq(newInfo.url.href, url);
 
     _("Test updating.");
     let newRecord = await store.createRecord(serverGUID);
     do_check_eq(newRecord.queryId, newAnnoValue);
     newRecord.queryId = "LeastVisited";
     collection.insert(serverGUID, encryptPayload(newRecord.cleartext));
     engine.lastModified = collection.timestamp + 1;
     await sync_engine_and_validate_telem(engine, false);
     do_check_eq("LeastVisited", PlacesUtils.annotations.getItemAnnotation(
-      newID, SMART_BOOKMARKS_ANNO));
+      newID, PlacesSyncUtils.bookmarks.SMART_BOOKMARKS_ANNO));
 
   } finally {
     // Clean up.
     await store.wipe();
     Svc.Prefs.resetBranch("");
     Service.recordManager.clearCache();
     await promiseStopServer(server);
   }
--- a/services/sync/tests/unit/test_bookmark_store.js
+++ b/services/sync/tests/unit/test_bookmark_store.js
@@ -1,186 +1,188 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
-Cu.import("resource://gre/modules/PlacesSyncUtils.jsm");
 Cu.import("resource://services-common/utils.js");
 Cu.import("resource://services-sync/engines.js");
 Cu.import("resource://services-sync/engines/bookmarks.js");
 Cu.import("resource://services-sync/service.js");
 Cu.import("resource://services-sync/util.js");
 
-const PARENT_ANNO = "sync/parent";
-
-const fxuri = CommonUtils.makeURI("http://getfirefox.com/");
-const tburi = CommonUtils.makeURI("http://getthunderbird.com/");
-
 add_task(async function test_ignore_specials() {
   _("Ensure that we can't delete bookmark roots.");
 
   let engine = new BookmarksEngine(Service);
   let store = engine._store;
 
   // Belt...
   let record = new BookmarkFolder("bookmarks", "toolbar", "folder");
   record.deleted = true;
   do_check_neq(null, (await PlacesUtils.promiseItemId(
-    PlacesSyncUtils.bookmarks.recordIdToGuid("toolbar"))));
+    PlacesUtils.bookmarks.toolbarGuid)));
 
   await store.applyIncoming(record);
   await store.deletePending();
 
   // Ensure that the toolbar exists.
   do_check_neq(null, (await PlacesUtils.promiseItemId(
-    PlacesSyncUtils.bookmarks.recordIdToGuid("toolbar"))));
+    PlacesUtils.bookmarks.toolbarGuid)));
 
-  // This will fail painfully in getItemType if the deletion worked.
+  // This will fail to build the local tree if the deletion worked.
   await engine._buildGUIDMap();
 
   // Braces...
   await store.remove(record);
   await store.deletePending();
   do_check_neq(null, (await PlacesUtils.promiseItemId(
-    PlacesSyncUtils.bookmarks.recordIdToGuid("toolbar"))));
+    PlacesUtils.bookmarks.toolbarGuid)));
   await engine._buildGUIDMap();
 
   await store.wipe();
 
   await engine.finalize();
 });
 
 add_task(async function test_bookmark_create() {
   let engine = new BookmarksEngine(Service);
   let store = engine._store;
 
   try {
     _("Ensure the record isn't present yet.");
-    let ids = PlacesUtils.bookmarks.getBookmarkIdsForURI(fxuri, {});
-    do_check_eq(ids.length, 0);
+    let item = await PlacesUtils.bookmarks.fetch({
+      url: "http://getfirefox.com/",
+    });
+    do_check_null(item);
 
     _("Let's create a new record.");
     let fxrecord = new Bookmark("bookmarks", "get-firefox1");
-    fxrecord.bmkUri        = fxuri.spec;
+    fxrecord.bmkUri        = "http://getfirefox.com/";
     fxrecord.description   = "Firefox is awesome.";
     fxrecord.title         = "Get Firefox!";
     fxrecord.tags          = ["firefox", "awesome", "browser"];
     fxrecord.keyword       = "awesome";
     fxrecord.loadInSidebar = false;
     fxrecord.parentName    = "Bookmarks Toolbar";
     fxrecord.parentid      = "toolbar";
     await store.applyIncoming(fxrecord);
 
     _("Verify it has been created correctly.");
-    let id = await PlacesUtils.promiseItemId(PlacesSyncUtils.bookmarks.recordIdToGuid(fxrecord.id));
-    do_check_eq((await PlacesUtils.promiseItemGuid(id)), fxrecord.id);
-    do_check_eq(PlacesUtils.bookmarks.getItemType(id),
-                PlacesUtils.bookmarks.TYPE_BOOKMARK);
-    do_check_true(PlacesUtils.bookmarks.getBookmarkURI(id).equals(fxuri));
-    do_check_eq(PlacesUtils.bookmarks.getItemTitle(id), fxrecord.title);
-    do_check_eq(PlacesUtils.annotations.getItemAnnotation(id, "bookmarkProperties/description"),
-                fxrecord.description);
-    do_check_eq(PlacesUtils.bookmarks.getFolderIdForItem(id),
-                PlacesUtils.bookmarks.toolbarFolder);
-    do_check_eq(PlacesUtils.bookmarks.getKeywordForBookmark(id), fxrecord.keyword);
+    item = await PlacesUtils.bookmarks.fetch(fxrecord.id);
+    do_check_eq(item.type, PlacesUtils.bookmarks.TYPE_BOOKMARK);
+    do_check_eq(item.url.href, "http://getfirefox.com/");
+    do_check_eq(item.title, fxrecord.title);
+    let id = await PlacesUtils.promiseItemId(item.guid);
+    let description = PlacesUtils.annotations.getItemAnnotation(id,
+      PlacesSyncUtils.bookmarks.DESCRIPTION_ANNO);
+    do_check_eq(description, fxrecord.description);
+    do_check_eq(item.parentGuid, PlacesUtils.bookmarks.toolbarGuid);
+    let keyword = await PlacesUtils.keywords.fetch(fxrecord.keyword);
+    do_check_eq(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);
     do_check_true(newrecord instanceof Bookmark);
     for (let property of ["type", "bmkUri", "description", "title",
                           "keyword", "parentName", "parentid"]) {
       do_check_eq(newrecord[property], fxrecord[property]);
     }
     do_check_true(Utils.deepEquals(newrecord.tags.sort(),
                                    fxrecord.tags.sort()));
 
     _("The calculated sort index is based on frecency data.");
     do_check_true(newrecord.sortindex >= 150);
 
     _("Create a record with some values missing.");
     let tbrecord = new Bookmark("bookmarks", "thunderbird1");
-    tbrecord.bmkUri        = tburi.spec;
+    tbrecord.bmkUri        = "http://getthunderbird.com/";
     tbrecord.parentName    = "Bookmarks Toolbar";
     tbrecord.parentid      = "toolbar";
     await store.applyIncoming(tbrecord);
 
     _("Verify it has been created correctly.");
-    id = await PlacesUtils.promiseItemId(PlacesSyncUtils.bookmarks.recordIdToGuid(tbrecord.id));
-    do_check_eq((await PlacesUtils.promiseItemGuid(id)), tbrecord.id);
-    do_check_eq(PlacesUtils.bookmarks.getItemType(id),
-                PlacesUtils.bookmarks.TYPE_BOOKMARK);
-    do_check_true(PlacesUtils.bookmarks.getBookmarkURI(id).equals(tburi));
-    do_check_eq(PlacesUtils.bookmarks.getItemTitle(id), "");
-    let error;
-    try {
-      PlacesUtils.annotations.getItemAnnotation(id, "bookmarkProperties/description");
-    } catch (ex) {
-      error = ex;
-    }
-    do_check_eq(error.result, Cr.NS_ERROR_NOT_AVAILABLE);
-    do_check_eq(PlacesUtils.bookmarks.getFolderIdForItem(id),
-                PlacesUtils.bookmarks.toolbarFolder);
-    do_check_eq(PlacesUtils.bookmarks.getKeywordForBookmark(id), null);
+    item = await PlacesUtils.bookmarks.fetch(tbrecord.id);
+    id = await PlacesUtils.promiseItemId(item.guid);
+    do_check_eq(item.type, PlacesUtils.bookmarks.TYPE_BOOKMARK);
+    do_check_eq(item.url.href, "http://getthunderbird.com/");
+    do_check_eq(item.title, "");
+    do_check_throws(function() {
+      PlacesUtils.annotations.getItemAnnotation(id,
+        PlacesSyncUtils.bookmarks.DESCRIPTION_ANNO);
+    }, Cr.NS_ERROR_NOT_AVAILABLE);
+    do_check_eq(item.parentGuid, PlacesUtils.bookmarks.toolbarGuid);
+    keyword = await PlacesUtils.keywords.fetch({
+      url: "http://getthunderbird.com/",
+    });
+    do_check_null(keyword);
   } finally {
     _("Clean up.");
     await store.wipe();
     await engine.finalize();
   }
 });
 
 add_task(async function test_bookmark_update() {
   let engine = new BookmarksEngine(Service);
   let store = engine._store;
 
   try {
     _("Create a bookmark whose values we'll change.");
-    let bmk1_id = PlacesUtils.bookmarks.insertBookmark(
-      PlacesUtils.bookmarks.toolbarFolder, fxuri,
-      PlacesUtils.bookmarks.DEFAULT_INDEX,
-      "Get Firefox!");
+    let bmk1 = await PlacesUtils.bookmarks.insert({
+      parentGuid: PlacesUtils.bookmarks.toolbarGuid,
+      url: "http://getfirefox.com/",
+      title: "Get Firefox!",
+    });
+    let bmk1_id = await PlacesUtils.promiseItemId(bmk1.guid);
     PlacesUtils.annotations.setItemAnnotation(
-      bmk1_id, "bookmarkProperties/description", "Firefox is awesome.", 0,
-      PlacesUtils.annotations.EXPIRE_NEVER);
-    PlacesUtils.bookmarks.setKeywordForBookmark(bmk1_id, "firefox");
-    let bmk1_guid = await PlacesUtils.promiseItemGuid(bmk1_id);
+      bmk1_id, PlacesSyncUtils.bookmarks.DESCRIPTION_ANNO,
+      "Firefox is awesome.", 0, PlacesUtils.annotations.EXPIRE_NEVER);
+    await PlacesUtils.keywords.insert({
+      url: "http://getfirefox.com/",
+      keyword: "firefox",
+    });
 
     _("Update the record with some null values.");
-    let record = await store.createRecord(bmk1_guid);
+    let record = await store.createRecord(bmk1.guid);
     record.title = null;
     record.description = null;
     record.keyword = null;
     record.tags = null;
     await store.applyIncoming(record);
 
     _("Verify that the values have been cleared.");
     do_check_throws(function() {
       PlacesUtils.annotations.getItemAnnotation(
-        bmk1_id, "bookmarkProperties/description");
+        bmk1_id, PlacesSyncUtils.bookmarks.DESCRIPTION_ANNO);
     }, Cr.NS_ERROR_NOT_AVAILABLE);
-    do_check_eq(PlacesUtils.bookmarks.getItemTitle(bmk1_id), "");
-    do_check_eq(PlacesUtils.bookmarks.getKeywordForBookmark(bmk1_id), null);
+    let item = await PlacesUtils.bookmarks.fetch(bmk1.guid);
+    do_check_eq(item.title, "");
+    let keyword = await PlacesUtils.keywords.fetch({
+      url: "http://getfirefox.com/",
+    });
+    do_check_null(keyword);
   } finally {
     _("Clean up.");
     await store.wipe();
     await engine.finalize();
   }
 });
 
 add_task(async function test_bookmark_createRecord() {
   let engine = Service.engineManager.get("bookmarks");
   let store = engine._store;
 
   try {
     _("Create a bookmark without a description or title.");
-    let bmk1_id = PlacesUtils.bookmarks.insertBookmark(
-      PlacesUtils.bookmarks.toolbarFolder, fxuri,
-      PlacesUtils.bookmarks.DEFAULT_INDEX, null);
-    let bmk1_guid = await PlacesUtils.promiseItemGuid(bmk1_id);
+    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);
+    let record = await store.createRecord(bmk1.guid);
     do_check_eq(record.title, "");
     do_check_eq(record.description, null);
     do_check_eq(record.keyword, null);
 
   } finally {
     _("Clean up.");
     await store.wipe();
   }
@@ -194,249 +196,258 @@ add_task(async function test_folder_crea
     _("Create a folder.");
     let folder = new BookmarkFolder("bookmarks", "testfolder-1");
     folder.parentName = "Bookmarks Toolbar";
     folder.parentid   = "toolbar";
     folder.title      = "Test Folder";
     await store.applyIncoming(folder);
 
     _("Verify it has been created correctly.");
-    let id = await PlacesUtils.promiseItemId(PlacesSyncUtils.bookmarks.recordIdToGuid(folder.id));
-    do_check_eq(PlacesUtils.bookmarks.getItemType(id),
-                PlacesUtils.bookmarks.TYPE_FOLDER);
-    do_check_eq(PlacesUtils.bookmarks.getItemTitle(id), folder.title);
-    do_check_eq(PlacesUtils.bookmarks.getFolderIdForItem(id),
-                PlacesUtils.bookmarks.toolbarFolder);
+    let item = await PlacesUtils.bookmarks.fetch(folder.id);
+    do_check_eq(item.type, PlacesUtils.bookmarks.TYPE_FOLDER);
+    do_check_eq(item.title, folder.title);
+    do_check_eq(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);
     do_check_true(newrecord instanceof BookmarkFolder);
-    for (let property of ["title", "parentName", "parentid"])
+    for (let property of ["title", "parentName", "parentid"]) {
       do_check_eq(newrecord[property], folder[property]);
+    }
 
     _("Folders have high sort index to ensure they're synced first.");
     do_check_eq(newrecord.sortindex, 1000000);
   } finally {
     _("Clean up.");
     await store.wipe();
     await engine.finalize();
   }
 });
 
 add_task(async function test_folder_createRecord() {
   let engine = Service.engineManager.get("bookmarks");
   let store = engine._store;
 
   try {
     _("Create a folder.");
-    let folder1_id = PlacesUtils.bookmarks.createFolder(
-      PlacesUtils.bookmarks.toolbarFolder, "Folder1", 0);
-    let folder1_guid = await PlacesUtils.promiseItemGuid(folder1_id);
+    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_id = PlacesUtils.bookmarks.insertBookmark(
-      folder1_id, fxuri, PlacesUtils.bookmarks.DEFAULT_INDEX, "Get Firefox!");
-    let bmk2_id = PlacesUtils.bookmarks.insertBookmark(
-      folder1_id, tburi, PlacesUtils.bookmarks.DEFAULT_INDEX, "Get Thunderbird!");
+    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);
+    let record = await store.createRecord(folder1.guid);
     do_check_true(record instanceof BookmarkFolder);
     do_check_eq(record.title, "Folder1");
     do_check_eq(record.parentid, "toolbar");
     do_check_eq(record.parentName, "Bookmarks Toolbar");
 
     _("Verify the folder's children. Ensures that the bookmarks were given GUIDs.");
-    let bmk1_guid = await PlacesUtils.promiseItemGuid(bmk1_id);
-    let bmk2_guid = await PlacesUtils.promiseItemGuid(bmk2_id);
-    do_check_eq(record.children.length, 2);
-    do_check_eq(record.children[0], bmk1_guid);
-    do_check_eq(record.children[1], bmk2_guid);
+    do_check_matches(record.children, [bmk1.guid, bmk2.guid]);
 
   } finally {
     _("Clean up.");
     await store.wipe();
   }
 });
 
 add_task(async function test_deleted() {
   let engine = new BookmarksEngine(Service);
   let store = engine._store;
 
   try {
     _("Create a bookmark that will be deleted.");
-    let bmk1_id = PlacesUtils.bookmarks.insertBookmark(
-      PlacesUtils.bookmarks.toolbarFolder, fxuri,
-      PlacesUtils.bookmarks.DEFAULT_INDEX, "Get Firefox!");
-    let bmk1_guid = await PlacesUtils.promiseItemGuid(bmk1_id);
+    let bmk1 = await PlacesUtils.bookmarks.insert({
+      parentGuid: PlacesUtils.bookmarks.toolbarGuid,
+      url: "http://getfirefox.com/",
+      title: "Get Firefox!",
+    });
 
     _("Delete the bookmark through the store.");
-    let record = new PlacesItem("bookmarks", bmk1_guid);
+    let record = new PlacesItem("bookmarks", bmk1.guid);
     record.deleted = true;
     await store.applyIncoming(record);
     await store.deletePending();
     _("Ensure it has been deleted.");
-    let error;
-    try {
-      PlacesUtils.bookmarks.getBookmarkURI(bmk1_id);
-    } catch (ex) {
-      error = ex;
-    }
-    do_check_eq(error.result, Cr.NS_ERROR_ILLEGAL_VALUE);
+    let item = await PlacesUtils.bookmarks.fetch(bmk1.guid);
+    do_check_null(item);
 
-    let newrec = await store.createRecord(bmk1_guid);
+    let newrec = await store.createRecord(bmk1.guid);
     do_check_eq(newrec.deleted, true);
 
   } finally {
     _("Clean up.");
     await store.wipe();
     await engine.finalize();
   }
 });
 
 add_task(async function test_move_folder() {
   let engine = new BookmarksEngine(Service);
   let store = engine._store;
 
   try {
     _("Create two folders and a bookmark in one of them.");
-    let folder1_id = PlacesUtils.bookmarks.createFolder(
-      PlacesUtils.bookmarks.toolbarFolder, "Folder1", 0);
-    let folder1_guid = await PlacesUtils.promiseItemGuid(folder1_id);
-    let folder2_id = PlacesUtils.bookmarks.createFolder(
-      PlacesUtils.bookmarks.toolbarFolder, "Folder2", 0);
-    let folder2_guid = await PlacesUtils.promiseItemGuid(folder2_id);
-    let bmk_id = PlacesUtils.bookmarks.insertBookmark(
-      folder1_id, fxuri, PlacesUtils.bookmarks.DEFAULT_INDEX, "Get Firefox!");
-    let bmk_guid = await PlacesUtils.promiseItemGuid(bmk_id);
+    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!",
+    });
 
     _("Get a record, reparent it and apply it to the store.");
-    let record = await store.createRecord(bmk_guid);
-    do_check_eq(record.parentid, folder1_guid);
-    record.parentid = folder2_guid;
+    let record = await store.createRecord(bmk.guid);
+    do_check_eq(record.parentid, folder1.guid);
+    record.parentid = folder2.guid;
     await store.applyIncoming(record);
 
     _("Verify the new parent.");
-    let new_folder_id = PlacesUtils.bookmarks.getFolderIdForItem(bmk_id);
-    do_check_eq((await PlacesUtils.promiseItemGuid(new_folder_id)), folder2_guid);
+    let movedBmk = await PlacesUtils.bookmarks.fetch(bmk.guid);
+    do_check_eq(movedBmk.parentGuid, folder2.guid);
   } finally {
     _("Clean up.");
     await store.wipe();
     await engine.finalize();
   }
 });
 
 add_task(async function test_move_order() {
   let engine = new BookmarksEngine(Service);
   let store = engine._store;
   let tracker = engine._tracker;
 
   // Make sure the tracker is turned on.
   Svc.Obs.notify("weave:engine:start-tracking");
   try {
     _("Create two bookmarks");
-    let bmk1_id = PlacesUtils.bookmarks.insertBookmark(
-      PlacesUtils.bookmarks.toolbarFolder, fxuri,
-      PlacesUtils.bookmarks.DEFAULT_INDEX, "Get Firefox!");
-    let bmk1_guid = await PlacesUtils.promiseItemGuid(bmk1_id);
-    let bmk2_id = PlacesUtils.bookmarks.insertBookmark(
-      PlacesUtils.bookmarks.toolbarFolder, tburi,
-      PlacesUtils.bookmarks.DEFAULT_INDEX, "Get Thunderbird!");
-    let bmk2_guid = await PlacesUtils.promiseItemGuid(bmk2_id);
+    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.");
-    do_check_eq(PlacesUtils.bookmarks.getItemIndex(bmk1_id), 0);
-    do_check_eq(PlacesUtils.bookmarks.getItemIndex(bmk2_id), 1);
+    let childIds = await PlacesSyncUtils.bookmarks.fetchChildRecordIds(
+      "toolbar");
+    do_check_matches(childIds, [bmk1.guid, bmk2.guid]);
     let toolbar = await store.createRecord("toolbar");
-    do_check_eq(toolbar.children.length, 2);
-    do_check_eq(toolbar.children[0], bmk1_guid);
-    do_check_eq(toolbar.children[1], bmk2_guid);
+    do_check_matches(toolbar.children, [bmk1.guid, bmk2.guid]);
 
     _("Move bookmarks around.");
     store._childrenToOrder = {};
-    toolbar.children = [bmk2_guid, bmk1_guid];
+    toolbar.children = [bmk2.guid, bmk1.guid];
     await store.applyIncoming(toolbar);
     // Bookmarks engine does this at the end of _processIncoming
     tracker.ignoreAll = true;
     await store._orderChildren();
     tracker.ignoreAll = false;
     delete store._childrenToOrder;
 
     _("Verify new order.");
-    do_check_eq(PlacesUtils.bookmarks.getItemIndex(bmk2_id), 0);
-    do_check_eq(PlacesUtils.bookmarks.getItemIndex(bmk1_id), 1);
+    let newChildIds = await PlacesSyncUtils.bookmarks.fetchChildRecordIds(
+      "toolbar");
+    do_check_matches(newChildIds, [bmk2.guid, bmk1.guid]);
 
   } finally {
     Svc.Obs.notify("weave:engine:stop-tracking");
     _("Clean up.");
     await store.wipe();
     await engine.finalize();
   }
 });
 
 add_task(async function test_orphan() {
   let engine = new BookmarksEngine(Service);
   let store = engine._store;
 
   try {
 
     _("Add a new bookmark locally.");
-    let bmk1_id = PlacesUtils.bookmarks.insertBookmark(
-      PlacesUtils.bookmarks.toolbarFolder, fxuri,
-      PlacesUtils.bookmarks.DEFAULT_INDEX, "Get Firefox!");
-    let bmk1_guid = await PlacesUtils.promiseItemGuid(bmk1_id);
-    do_check_eq(PlacesUtils.bookmarks.getFolderIdForItem(bmk1_id),
-                PlacesUtils.bookmarks.toolbarFolder);
-    let error;
-    try {
-      PlacesUtils.annotations.getItemAnnotation(bmk1_id, PARENT_ANNO);
-    } catch (ex) {
-      error = ex;
-    }
-    do_check_eq(error.result, Cr.NS_ERROR_NOT_AVAILABLE);
+    let bmk1 = await PlacesUtils.bookmarks.insert({
+      parentGuid: PlacesUtils.bookmarks.toolbarGuid,
+      url: "http://getfirefox.com/",
+      title: "Get Firefox!",
+    });
+    let bmk1_id = await PlacesUtils.promiseItemId(bmk1.guid);
+    do_check_throws(function() {
+      PlacesUtils.annotations.getItemAnnotation(bmk1_id,
+        PlacesSyncUtils.bookmarks.SYNC_PARENT_ANNO);
+    }, Cr.NS_ERROR_NOT_AVAILABLE);
 
     _("Apply a server record that is the same but refers to non-existent folder.");
-    let record = await store.createRecord(bmk1_guid);
+    let record = await store.createRecord(bmk1.guid);
     record.parentid = "non-existent";
     await store.applyIncoming(record);
 
     _("Verify that bookmark has been flagged as orphan, has not moved.");
-    do_check_eq(PlacesUtils.bookmarks.getFolderIdForItem(bmk1_id),
-                PlacesUtils.bookmarks.toolbarFolder);
-    do_check_eq(PlacesUtils.annotations.getItemAnnotation(bmk1_id, PARENT_ANNO),
-                "non-existent");
+    let item = await PlacesUtils.bookmarks.fetch(bmk1.guid);
+    do_check_eq(item.parentGuid, PlacesUtils.bookmarks.toolbarGuid);
+    let orphanAnno = PlacesUtils.annotations.getItemAnnotation(bmk1_id,
+      PlacesSyncUtils.bookmarks.SYNC_PARENT_ANNO);
+    do_check_eq(orphanAnno, "non-existent");
 
   } finally {
     _("Clean up.");
     await store.wipe();
     await engine.finalize();
   }
 });
 
 add_task(async function test_reparentOrphans() {
   let engine = new BookmarksEngine(Service);
   let store = engine._store;
 
   try {
-    let folder1_id = PlacesUtils.bookmarks.createFolder(
-      PlacesUtils.bookmarks.toolbarFolder, "Folder1", 0);
-    let folder1_guid = await PlacesUtils.promiseItemGuid(folder1_id);
+    let folder1 = await PlacesUtils.bookmarks.insert({
+      parentGuid: PlacesUtils.bookmarks.toolbarGuid,
+      type: PlacesUtils.bookmarks.TYPE_FOLDER,
+      title: "Folder1",
+    });
+    let folder1_id = await PlacesUtils.promiseItemId(folder1.guid);
 
     _("Create a bogus orphan record and write the record back to the store to trigger _reparentOrphans.");
     PlacesUtils.annotations.setItemAnnotation(
-      folder1_id, PARENT_ANNO, folder1_guid, 0,
+      folder1_id, PlacesSyncUtils.bookmarks.SYNC_PARENT_ANNO, folder1.guid, 0,
       PlacesUtils.annotations.EXPIRE_NEVER);
-    let record = await store.createRecord(folder1_guid);
+    let record = await store.createRecord(folder1.guid);
     record.title = "New title for Folder 1";
     store._childrenToOrder = {};
     await store.applyIncoming(record);
 
     _("Verify that is has been marked as an orphan even though it couldn't be moved into itself.");
-    do_check_eq(PlacesUtils.annotations.getItemAnnotation(folder1_id, PARENT_ANNO),
-                folder1_guid);
+    let orphanAnno = PlacesUtils.annotations.getItemAnnotation(folder1_id,
+      PlacesSyncUtils.bookmarks.SYNC_PARENT_ANNO);
+    do_check_eq(orphanAnno, folder1.guid);
 
   } finally {
     _("Clean up.");
     await store.wipe();
     await engine.finalize();
   }
 });
 
@@ -456,24 +467,19 @@ add_task(async function test_empty_query
   await store.applyIncoming(record);
 
   delete record.folderName;
   await store.applyIncoming(record);
 
   await engine.finalize();
 });
 
-function assertDeleted(id) {
-  let error;
-  try {
-    PlacesUtils.bookmarks.getItemType(id);
-  } catch (e) {
-    error = e;
-  }
-  equal(error.result, Cr.NS_ERROR_ILLEGAL_VALUE);
+async function assertDeleted(guid) {
+  let item = await PlacesUtils.bookmarks.fetch(guid);
+  ok(!item);
 }
 
 add_task(async function test_delete_buffering() {
   let engine = new BookmarksEngine(Service);
   let store = engine._store;
 
   await store.wipe();
   await PlacesTestUtils.markBookmarksAsSynced();
@@ -483,86 +489,82 @@ add_task(async function test_delete_buff
     let folder = new BookmarkFolder("bookmarks", "testfolder-1");
     folder.parentName = "Bookmarks Toolbar";
     folder.parentid = "toolbar";
     folder.title = "Test Folder";
     await store.applyIncoming(folder);
 
 
     let fxRecord = new Bookmark("bookmarks", "get-firefox1");
-    fxRecord.bmkUri        = fxuri.spec;
+    fxRecord.bmkUri        = "http://getfirefox.com/";
     fxRecord.title         = "Get Firefox!";
     fxRecord.parentName    = "Test Folder";
     fxRecord.parentid      = "testfolder-1";
 
     let tbRecord = new Bookmark("bookmarks", "get-tndrbrd1");
-    tbRecord.bmkUri        = tburi.spec;
+    tbRecord.bmkUri        = "http://getthunderbird.com";
     tbRecord.title         = "Get Thunderbird!";
     tbRecord.parentName    = "Test Folder";
     tbRecord.parentid      = "testfolder-1";
 
     await store.applyIncoming(fxRecord);
     await store.applyIncoming(tbRecord);
 
-    let folderId = await PlacesUtils.promiseItemId(PlacesSyncUtils.bookmarks.recordIdToGuid(folder.id));
-    let fxRecordId = await PlacesUtils.promiseItemId(PlacesSyncUtils.bookmarks.recordIdToGuid(fxRecord.id));
-    let tbRecordId = await PlacesUtils.promiseItemId(PlacesSyncUtils.bookmarks.recordIdToGuid(tbRecord.id));
-
     _("Check everything was created correctly.");
 
-    equal(PlacesUtils.bookmarks.getItemType(fxRecordId),
-          PlacesUtils.bookmarks.TYPE_BOOKMARK);
-    equal(PlacesUtils.bookmarks.getItemType(tbRecordId),
-          PlacesUtils.bookmarks.TYPE_BOOKMARK);
-    equal(PlacesUtils.bookmarks.getItemType(folderId),
-          PlacesUtils.bookmarks.TYPE_FOLDER);
+    let folderItem = await PlacesUtils.bookmarks.fetch(folder.id);
+    let fxItem = await PlacesUtils.bookmarks.fetch(fxRecord.id);
+    let tbItem = await PlacesUtils.bookmarks.fetch(tbRecord.id);
 
-    equal(PlacesUtils.bookmarks.getFolderIdForItem(fxRecordId), folderId);
-    equal(PlacesUtils.bookmarks.getFolderIdForItem(tbRecordId), folderId);
-    equal(PlacesUtils.bookmarks.getFolderIdForItem(folderId),
-          PlacesUtils.bookmarks.toolbarFolder);
+    equal(fxItem.type, PlacesUtils.bookmarks.TYPE_BOOKMARK);
+    equal(tbItem.type, PlacesUtils.bookmarks.TYPE_BOOKMARK);
+    equal(folderItem.type, PlacesUtils.bookmarks.TYPE_FOLDER);
+
+    equal(fxItem.parentGuid, folderItem.guid);
+    equal(tbItem.parentGuid, folderItem.guid);
+    equal(folderItem.parentGuid, PlacesUtils.bookmarks.toolbarGuid);
 
     _("Delete the folder and one bookmark.");
 
     let deleteFolder = new PlacesItem("bookmarks", "testfolder-1");
     deleteFolder.deleted = true;
 
     let deleteFxRecord = new PlacesItem("bookmarks", "get-firefox1");
     deleteFxRecord.deleted = true;
 
     await store.applyIncoming(deleteFolder);
     await store.applyIncoming(deleteFxRecord);
 
     _("Check that we haven't deleted them yet, but that the deletions are queued");
-    // these will throw if we've deleted them
-    equal(PlacesUtils.bookmarks.getItemType(fxRecordId),
-           PlacesUtils.bookmarks.TYPE_BOOKMARK);
+    // these will return `null` if we've deleted them
+    fxItem = await PlacesUtils.bookmarks.fetch(fxRecord.id);
+    ok(fxItem);
 
-    equal(PlacesUtils.bookmarks.getItemType(folderId),
-           PlacesUtils.bookmarks.TYPE_FOLDER);
+    folderItem = await PlacesUtils.bookmarks.fetch(folder.id);
+    ok(folderItem);
 
-    equal(PlacesUtils.bookmarks.getFolderIdForItem(fxRecordId), folderId);
+    equal(fxItem.parentGuid, folderItem.guid);
 
     ok(store._itemsToDelete.has(folder.id));
     ok(store._itemsToDelete.has(fxRecord.id));
     ok(!store._itemsToDelete.has(tbRecord.id));
 
     _("Process pending deletions and ensure that the right things are deleted.");
     let newChangeRecords = await store.deletePending();
 
     deepEqual(Object.keys(newChangeRecords).sort(), ["get-tndrbrd1", "toolbar"]);
 
-    assertDeleted(fxRecordId);
-    assertDeleted(folderId);
+    await assertDeleted(fxItem.guid);
+    await assertDeleted(folderItem.guid);
 
     ok(!store._itemsToDelete.has(folder.id));
     ok(!store._itemsToDelete.has(fxRecord.id));
 
-    equal(PlacesUtils.bookmarks.getFolderIdForItem(tbRecordId),
-          PlacesUtils.bookmarks.toolbarFolder);
+    tbItem = await PlacesUtils.bookmarks.fetch(tbRecord.id);
+    equal(tbItem.parentGuid, PlacesUtils.bookmarks.toolbarGuid);
 
   } finally {
     _("Clean up.");
     await store.wipe();
     await engine.finalize();
   }
 });
 
--- a/services/sync/tests/unit/test_bookmark_tracker.js
+++ b/services/sync/tests/unit/test_bookmark_tracker.js
@@ -1,20 +1,18 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 Cu.import("resource://services-common/utils.js");
-Cu.import("resource://gre/modules/PlacesSyncUtils.jsm");
 Cu.import("resource://services-sync/constants.js");
 Cu.import("resource://services-sync/engines/bookmarks.js");
 Cu.import("resource://services-sync/engines.js");
 Cu.import("resource://services-sync/service.js");
 Cu.import("resource://services-sync/util.js");
 Cu.import("resource://gre/modules/osfile.jsm");
-Cu.import("resource://testing-common/PlacesTestUtils.jsm");
 Cu.import("resource:///modules/PlacesUIUtils.jsm");
 
 let engine;
 let store;
 let tracker;
 
 const DAY_IN_MS = 24 * 60 * 60 * 1000;
 
--- a/services/sync/tests/unit/test_engine_changes_during_sync.js
+++ b/services/sync/tests/unit/test_engine_changes_during_sync.js
@@ -1,11 +1,10 @@
 Cu.import("resource://gre/modules/FormHistory.jsm");
 Cu.import("resource://gre/modules/Log.jsm");
-Cu.import("resource://gre/modules/PlacesSyncUtils.jsm");
 Cu.import("resource://services-sync/service.js");
 Cu.import("resource://services-sync/engines/bookmarks.js");
 Cu.import("resource://services-sync/engines/history.js");
 Cu.import("resource://services-sync/engines/forms.js");
 Cu.import("resource://services-sync/engines/passwords.js");
 Cu.import("resource://services-sync/engines/prefs.js");
 Cu.import("resource://testing-common/services/sync/utils.js");
 
--- a/services/sync/tests/unit/test_history_store.js
+++ b/services/sync/tests/unit/test_history_store.js
@@ -1,45 +1,22 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
-Cu.import("resource://testing-common/PlacesTestUtils.jsm");
-Cu.import("resource://gre/modules/PlacesSyncUtils.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://services-common/async.js");
 Cu.import("resource://services-common/utils.js");
 Cu.import("resource://services-sync/engines/history.js");
 Cu.import("resource://services-sync/service.js");
 Cu.import("resource://services-sync/util.js");
 
 const TIMESTAMP1 = (Date.now() - 103406528) * 1000;
 const TIMESTAMP2 = (Date.now() - 6592903) * 1000;
 const TIMESTAMP3 = (Date.now() - 123894) * 1000;
 
-function queryPlaces(uri, options) {
-  let query = PlacesUtils.history.getNewQuery();
-  query.uri = uri;
-  let res = PlacesUtils.history.executeQuery(query, options);
-  res.root.containerOpen = true;
-
-  let results = [];
-  for (let i = 0; i < res.root.childCount; i++)
-    results.push(res.root.getChild(i));
-  res.root.containerOpen = false;
-  return results;
-}
-
-function queryHistoryVisits(uri) {
-  let options = PlacesUtils.history.getNewQueryOptions();
-  options.queryType = Ci.nsINavHistoryQueryOptions.QUERY_TYPE_HISTORY;
-  options.resultType = Ci.nsINavHistoryQueryOptions.RESULTS_AS_VISIT;
-  options.sortingMode = Ci.nsINavHistoryQueryOptions.SORT_BY_DATE_ASCENDING;
-  return queryPlaces(uri, options);
-}
-
 function promiseOnVisitObserved() {
   return new Promise(res => {
     PlacesUtils.history.addObserver({
       onBeginUpdateBatch: function onBeginUpdateBatch() {},
       onEndUpdateBatch: function onEndUpdateBatch() {},
       onPageChanged: function onPageChanged() {},
       onTitleChanged: function onTitleChanged() {
       },
@@ -113,70 +90,78 @@ add_task(async function test_store() {
   let onVisitObserved = promiseOnVisitObserved();
   await applyEnsureNoFailures([
     {id: fxguid,
      histUri: record.histUri,
      title: "Hol Dir Firefox!",
      visits: [record.visits[0], secondvisit]}
   ]);
   await onVisitObserved;
-  try {
-    let queryres = queryHistoryVisits(fxuri);
-    do_check_eq(queryres.length, 2);
-    do_check_eq(queryres[0].time, TIMESTAMP1);
-    do_check_eq(queryres[0].title, "Hol Dir Firefox!");
-    do_check_eq(queryres[1].time, TIMESTAMP2);
-    do_check_eq(queryres[1].title, "Hol Dir Firefox!");
-  } catch (ex) {
-    PlacesTestUtils.clearHistory();
-    do_throw(ex);
-  }
+  let queryres = await PlacesUtils.history.fetch(fxuri.spec, {
+    includeVisits: true,
+  });
+  do_check_eq(queryres.title, "Hol Dir Firefox!");
+  do_check_matches(queryres.visits, [{
+    date: new Date(TIMESTAMP2 / 1000),
+    transition: Ci.nsINavHistoryService.TRANSITION_TYPED,
+  }, {
+    date: new Date(TIMESTAMP1 / 1000),
+    transition: Ci.nsINavHistoryService.TRANSITION_LINK,
+  }]);
+  await PlacesTestUtils.clearHistory();
 });
 
 add_task(async function test_store_create() {
   _("Create a brand new record through the store.");
   tbguid = Utils.makeGUID();
   tburi = CommonUtils.makeURI("http://getthunderbird.com");
   let onVisitObserved = promiseOnVisitObserved();
   await applyEnsureNoFailures([
     {id: tbguid,
      histUri: tburi.spec,
      title: "The bird is the word!",
      visits: [{date: TIMESTAMP3,
                type: Ci.nsINavHistoryService.TRANSITION_TYPED}]}
   ]);
   await onVisitObserved;
-  try {
-    do_check_true((await store.itemExists(tbguid)));
-    do_check_attribute_count(await store.getAllIDs(), 2);
-    let queryres = queryHistoryVisits(tburi);
-    do_check_eq(queryres.length, 1);
-    do_check_eq(queryres[0].time, TIMESTAMP3);
-    do_check_eq(queryres[0].title, "The bird is the word!");
-  } catch (ex) {
-    PlacesTestUtils.clearHistory();
-    do_throw(ex);
-  }
+  do_check_true((await store.itemExists(tbguid)));
+  do_check_attribute_count(await store.getAllIDs(), 1);
+  let queryres = await PlacesUtils.history.fetch(tburi.spec, {
+    includeVisits: true,
+  });
+  do_check_eq(queryres.title, "The bird is the word!");
+  do_check_matches(queryres.visits, [{
+    date: new Date(TIMESTAMP3 / 1000),
+    transition: Ci.nsINavHistoryService.TRANSITION_TYPED,
+  }]);
+  await PlacesTestUtils.clearHistory();
 });
 
 add_task(async function test_null_title() {
   _("Make sure we handle a null title gracefully (it can happen in some cases, e.g. for resource:// URLs)");
   let resguid = Utils.makeGUID();
   let resuri = CommonUtils.makeURI("unknown://title");
   await applyEnsureNoFailures([
     {id: resguid,
      histUri: resuri.spec,
      title: null,
      visits: [{date: TIMESTAMP3,
                type: Ci.nsINavHistoryService.TRANSITION_TYPED}]}
   ]);
-  do_check_attribute_count((await store.getAllIDs()), 3);
-  let queryres = queryHistoryVisits(resuri);
-  do_check_eq(queryres.length, 1);
-  do_check_eq(queryres[0].time, TIMESTAMP3);
+  do_check_attribute_count((await store.getAllIDs()), 1);
+
+  let queryres = await PlacesUtils.history.fetch(resuri.spec, {
+    includeVisits: true,
+  });
+  do_check_eq(queryres.title, "");
+  do_check_matches(queryres.visits, [{
+    date: new Date(TIMESTAMP3 / 1000),
+    transition: Ci.nsINavHistoryService.TRANSITION_TYPED,
+  }]);
+  await PlacesTestUtils.clearHistory();
 });
 
 add_task(async function test_invalid_records() {
   _("Make sure we handle invalid URLs in places databases gracefully.");
   await PlacesUtils.withConnectionWrapper("test_invalid_record", async function(db) {
     await db.execute(
       "INSERT INTO moz_places "
       + "(url, url_hash, title, rev_host, visit_count, last_visit_date) "
@@ -185,17 +170,17 @@ add_task(async function test_invalid_rec
     // Add the corresponding visit to retain database coherence.
     await db.execute(
       "INSERT INTO moz_historyvisits "
       + "(place_id, visit_date, visit_type, session) "
       + "VALUES ((SELECT id FROM moz_places WHERE url_hash = hash('invalid-uri') AND url = 'invalid-uri'), "
       + TIMESTAMP3 + ", " + Ci.nsINavHistoryService.TRANSITION_TYPED + ", 1)"
     );
   });
-  do_check_attribute_count((await store.getAllIDs()), 4);
+  do_check_attribute_count((await store.getAllIDs()), 1);
 
   _("Make sure we report records with invalid URIs.");
   let invalid_uri_guid = Utils.makeGUID();
   let failed = await store.applyIncomingBatch([{
     id: invalid_uri_guid,
     histUri: ":::::::::::::::",
     title: "Doesn't have a valid URI",
     visits: [{date: TIMESTAMP3,
@@ -332,24 +317,30 @@ add_task(async function test_clamp_visit
   }], "Should not clamp valid visit dates");
 });
 
 add_task(async function test_remove() {
   _("Remove an existent record and a non-existent from the store.");
   await applyEnsureNoFailures([{id: fxguid, deleted: true},
                          {id: Utils.makeGUID(), deleted: true}]);
   do_check_false((await store.itemExists(fxguid)));
-  let queryres = queryHistoryVisits(fxuri);
-  do_check_eq(queryres.length, 0);
+  let queryres = await PlacesUtils.history.fetch(fxuri.spec, {
+    includeVisits: true,
+  });
+  do_check_null(queryres);
 
   _("Make sure wipe works.");
   await store.wipe();
   do_check_empty((await store.getAllIDs()));
-  queryres = queryHistoryVisits(fxuri);
-  do_check_eq(queryres.length, 0);
-  queryres = queryHistoryVisits(tburi);
-  do_check_eq(queryres.length, 0);
+  queryres = await PlacesUtils.history.fetch(fxuri.spec, {
+    includeVisits: true,
+  });
+  do_check_null(queryres);
+  queryres = await PlacesUtils.history.fetch(tburi.spec, {
+    includeVisits: true,
+  });
+  do_check_null(queryres);
 });
 
-add_test(function cleanup() {
+add_task(async function cleanup() {
   _("Clean up.");
-  PlacesTestUtils.clearHistory().then(run_next_test);
+  await PlacesTestUtils.clearHistory();
 });
--- a/services/sync/tests/unit/test_places_guid_downgrade.js
+++ b/services/sync/tests/unit/test_places_guid_downgrade.js
@@ -7,19 +7,16 @@ Cu.import("resource://services-sync/engi
 Cu.import("resource://services-sync/engines/history.js");
 Cu.import("resource://services-sync/engines/bookmarks.js");
 Cu.import("resource://services-sync/service.js");
 
 const kDBName = "places.sqlite";
 const storageSvc = Cc["@mozilla.org/storage/service;1"]
                      .getService(Ci.mozIStorageService);
 
-const fxuri = CommonUtils.makeURI("http://getfirefox.com/");
-const tburi = CommonUtils.makeURI("http://getthunderbird.com/");
-
 function setPlacesDatabase(aFileName) {
   removePlacesDatabase();
   _("Copying over places.sqlite.");
   let file = do_get_file(aFileName);
   file.copyTo(gSyncProfile, kDBName);
 }
 
 function removePlacesDatabase() {
@@ -88,36 +85,36 @@ add_test(function test_initial_state() {
 
 add_task(async function test_history_guids() {
   let engine = new HistoryEngine(Service);
   await engine.initialize();
   let store = engine._store;
 
   let places = [
     {
-      uri: fxuri,
+      url: "http://getfirefox.com/",
       title: "Get Firefox!",
       visits: [{
-        visitDate: Date.now() * 1000,
-        transitionType: Ci.nsINavHistoryService.TRANSITION_LINK
+        date: new Date(),
+        transition: Ci.nsINavHistoryService.TRANSITION_LINK
       }]
     },
     {
-      uri: tburi,
+      url: "http://getthunderbird.com/",
       title: "Get Thunderbird!",
       visits: [{
-        visitDate: Date.now() * 1000,
-        transitionType: Ci.nsINavHistoryService.TRANSITION_LINK
+        date: new Date(),
+        transition: Ci.nsINavHistoryService.TRANSITION_LINK
       }]
     }
   ];
 
   async function onVisitAdded() {
-    let fxguid = await store.GUIDForUri(fxuri, true);
-    let tbguid = await store.GUIDForUri(tburi, true);
+    let fxguid = await store.GUIDForUri("http://getfirefox.com/", true);
+    let tbguid = await store.GUIDForUri("http://getthunderbird.com/", true);
     dump("fxguid: " + fxguid + "\n");
     dump("tbguid: " + tbguid + "\n");
 
     _("History: Verify GUIDs are added to the guid column.");
     let db = await PlacesUtils.promiseDBConnection();
     let result = await db.execute(
       "SELECT id FROM moz_places WHERE guid = :guid",
       {guid: fxguid}
@@ -139,71 +136,60 @@ add_task(async function test_history_gui
 
     result = await db.execute(
       "SELECT a.content AS guid FROM moz_annos a WHERE guid = :guid",
       {guid: tbguid}
     );
     do_check_eq(result.length, 0);
   }
 
-  await new Promise((resolve, reject) => {
-    PlacesUtils.asyncHistory.updatePlaces(places, {
-      handleError: function handleError() {
-        do_throw("Unexpected error in adding visit.");
-      },
-      handleResult: function handleResult() {},
-      handleCompletion: () => { onVisitAdded().then(resolve, reject); },
-    });
-  });
+  await PlacesUtils.history.insertMany(places);
+  await onVisitAdded();
 });
 
 add_task(async function test_bookmark_guids() {
-  let engine = new BookmarksEngine(Service);
-  let store = engine._store;
-
-  let fxid = PlacesUtils.bookmarks.insertBookmark(
-    PlacesUtils.bookmarks.toolbarFolder,
-    fxuri,
-    PlacesUtils.bookmarks.DEFAULT_INDEX,
-    "Get Firefox!");
-  let tbid = PlacesUtils.bookmarks.insertBookmark(
-    PlacesUtils.bookmarks.toolbarFolder,
-    tburi,
-    PlacesUtils.bookmarks.DEFAULT_INDEX,
-    "Get Thunderbird!");
-
-  let fxguid = await store.GUIDForId(fxid);
-  let tbguid = await store.GUIDForId(tbid);
+  let fx = await PlacesUtils.bookmarks.insert({
+    parentGuid: PlacesUtils.bookmarks.toolbarGuid,
+    url: "http://getfirefox.com/",
+    title: "Get Firefox!",
+  });
+  let fxid = await PlacesUtils.promiseItemId(fx.guid);
+  let tb = await PlacesUtils.bookmarks.insert({
+    parentGuid: PlacesUtils.bookmarks.toolbarGuid,
+    url: "http://getthunderbird.com/",
+    title: "Get Thunderbird!",
+  });
+  let tbid = await PlacesUtils.promiseItemId(tb.guid);
 
   _("Bookmarks: Verify GUIDs are added to the guid column.");
   let db = await PlacesUtils.promiseDBConnection();
   let result = await db.execute(
     "SELECT id FROM moz_bookmarks WHERE guid = :guid",
-    {guid: fxguid}
+    {guid: fx.guid}
   );
   do_check_eq(result.length, 1);
   do_check_eq(result[0].getResultByName("id"), fxid);
 
   result = await db.execute(
     "SELECT id FROM moz_bookmarks WHERE guid = :guid",
-    {guid: tbguid}
+    {guid: tb.guid}
   );
   do_check_eq(result.length, 1);
   do_check_eq(result[0].getResultByName("id"), tbid);
 
   _("Bookmarks: Verify GUIDs weren't added to annotations.");
   result = await db.execute(
     "SELECT a.content AS guid FROM moz_items_annos a WHERE guid = :guid",
-    {guid: fxguid}
+    {guid: fx.guid}
   );
   do_check_eq(result.length, 0);
 
   result = await db.execute(
     "SELECT a.content AS guid FROM moz_items_annos a WHERE guid = :guid",
-    {guid: tbguid}
+    {guid: tb.guid}
   );
   do_check_eq(result.length, 0);
 });
 
 function run_test() {
   setPlacesDatabase("places_v10_from_v11.sqlite");
 
   run_next_test();
--- a/services/sync/tests/unit/test_syncengine_sync.js
+++ b/services/sync/tests/unit/test_syncengine_sync.js
@@ -1,12 +1,11 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
-Cu.import("resource://gre/modules/PlacesSyncUtils.jsm");
 Cu.import("resource://services-sync/constants.js");
 Cu.import("resource://services-sync/engines.js");
 Cu.import("resource://services-sync/main.js");
 Cu.import("resource://services-sync/policies.js");
 Cu.import("resource://services-sync/record.js");
 Cu.import("resource://services-sync/resource.js");
 Cu.import("resource://services-sync/service.js");
 Cu.import("resource://services-sync/util.js");
--- a/services/sync/tests/unit/test_telemetry.js
+++ b/services/sync/tests/unit/test_telemetry.js
@@ -159,32 +159,35 @@ add_task(async function test_processInco
 
 add_task(async function test_uploading() {
   let engine = new BookmarksEngine(Service);
   await engine.initialize();
   let store  = engine._store;
   let server = await serverForFoo(engine);
   await SyncTestingInfrastructure(server);
 
-  let parent = PlacesUtils.toolbarFolderId;
-  let uri = CommonUtils.makeURI("http://getfirefox.com/");
-
-  let bmk_id = PlacesUtils.bookmarks.insertBookmark(parent, uri,
-    PlacesUtils.bookmarks.DEFAULT_INDEX, "Get Firefox!");
+  let bmk = await PlacesUtils.bookmarks.insert({
+    parentGuid: PlacesUtils.bookmarks.toolbarGuid,
+    url: "http://getfirefox.com/",
+    title: "Get Firefox!",
+  });
 
   try {
     let ping = await sync_engine_and_validate_telem(engine, false);
     ok(!!ping);
     equal(ping.engines.length, 1);
     equal(ping.engines[0].name, "bookmarks");
     ok(!!ping.engines[0].outgoing);
     greater(ping.engines[0].outgoing[0].sent, 0);
     ok(!ping.engines[0].incoming);
 
-    PlacesUtils.bookmarks.setItemTitle(bmk_id, "New Title");
+    await PlacesUtils.bookmarks.update({
+      guid: bmk.guid,
+      title: "New Title",
+    });
 
     await engine.resetClient();
 
     ping = await sync_engine_and_validate_telem(engine, false);
     equal(ping.engines.length, 1);
     equal(ping.engines[0].name, "bookmarks");
     equal(ping.engines[0].outgoing.length, 1);
     ok(!!ping.engines[0].incoming);