1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/services/sync/tests/unit/test_bookmark_engine.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,543 @@ 1.4 +/* Any copyright is dedicated to the Public Domain. 1.5 + http://creativecommons.org/publicdomain/zero/1.0/ */ 1.6 + 1.7 +Cu.import("resource://gre/modules/PlacesUtils.jsm"); 1.8 +Cu.import("resource://gre/modules/BookmarkJSONUtils.jsm"); 1.9 +Cu.import("resource://services-common/async.js"); 1.10 +Cu.import("resource://gre/modules/Log.jsm"); 1.11 +Cu.import("resource://services-sync/engines.js"); 1.12 +Cu.import("resource://services-sync/engines/bookmarks.js"); 1.13 +Cu.import("resource://services-sync/service.js"); 1.14 +Cu.import("resource://services-sync/util.js"); 1.15 +Cu.import("resource://testing-common/services/sync/utils.js"); 1.16 +Cu.import("resource://gre/modules/Promise.jsm"); 1.17 + 1.18 +Service.engineManager.register(BookmarksEngine); 1.19 + 1.20 +add_test(function bad_record_allIDs() { 1.21 + let server = new SyncServer(); 1.22 + server.start(); 1.23 + let syncTesting = new SyncTestingInfrastructure(server.server); 1.24 + 1.25 + _("Ensure that bad Places queries don't cause an error in getAllIDs."); 1.26 + let engine = new BookmarksEngine(Service); 1.27 + let store = engine._store; 1.28 + let badRecordID = PlacesUtils.bookmarks.insertBookmark( 1.29 + PlacesUtils.bookmarks.toolbarFolder, 1.30 + Utils.makeURI("place:folder=1138"), 1.31 + PlacesUtils.bookmarks.DEFAULT_INDEX, 1.32 + null); 1.33 + 1.34 + do_check_true(badRecordID > 0); 1.35 + _("Record is " + badRecordID); 1.36 + _("Type: " + PlacesUtils.bookmarks.getItemType(badRecordID)); 1.37 + 1.38 + _("Fetching children."); 1.39 + store._getChildren("toolbar", {}); 1.40 + 1.41 + _("Fetching all IDs."); 1.42 + let all = store.getAllIDs(); 1.43 + 1.44 + _("All IDs: " + JSON.stringify(all)); 1.45 + do_check_true("menu" in all); 1.46 + do_check_true("toolbar" in all); 1.47 + 1.48 + _("Clean up."); 1.49 + PlacesUtils.bookmarks.removeItem(badRecordID); 1.50 + server.stop(run_next_test); 1.51 +}); 1.52 + 1.53 +add_test(function test_ID_caching() { 1.54 + let server = new SyncServer(); 1.55 + server.start(); 1.56 + let syncTesting = new SyncTestingInfrastructure(server.server); 1.57 + 1.58 + _("Ensure that Places IDs are not cached."); 1.59 + let engine = new BookmarksEngine(Service); 1.60 + let store = engine._store; 1.61 + _("All IDs: " + JSON.stringify(store.getAllIDs())); 1.62 + 1.63 + let mobileID = store.idForGUID("mobile"); 1.64 + _("Change the GUID for that item, and drop the mobile anno."); 1.65 + store._setGUID(mobileID, "abcdefghijkl"); 1.66 + PlacesUtils.annotations.removeItemAnnotation(mobileID, "mobile/bookmarksRoot"); 1.67 + 1.68 + let err; 1.69 + let newMobileID; 1.70 + 1.71 + // With noCreate, we don't find an entry. 1.72 + try { 1.73 + newMobileID = store.idForGUID("mobile", true); 1.74 + _("New mobile ID: " + newMobileID); 1.75 + } catch (ex) { 1.76 + err = ex; 1.77 + _("Error: " + Utils.exceptionStr(err)); 1.78 + } 1.79 + 1.80 + do_check_true(!err); 1.81 + 1.82 + // With !noCreate, lookup works, and it's different. 1.83 + newMobileID = store.idForGUID("mobile", false); 1.84 + _("New mobile ID: " + newMobileID); 1.85 + do_check_true(!!newMobileID); 1.86 + do_check_neq(newMobileID, mobileID); 1.87 + 1.88 + // And it's repeatable, even with creation enabled. 1.89 + do_check_eq(newMobileID, store.idForGUID("mobile", false)); 1.90 + 1.91 + do_check_eq(store.GUIDForId(mobileID), "abcdefghijkl"); 1.92 + server.stop(run_next_test); 1.93 +}); 1.94 + 1.95 +function serverForFoo(engine) { 1.96 + return serverForUsers({"foo": "password"}, { 1.97 + meta: {global: {engines: {bookmarks: {version: engine.version, 1.98 + syncID: engine.syncID}}}}, 1.99 + bookmarks: {} 1.100 + }); 1.101 +} 1.102 + 1.103 +add_test(function test_processIncoming_error_orderChildren() { 1.104 + _("Ensure that _orderChildren() is called even when _processIncoming() throws an error."); 1.105 + 1.106 + let engine = new BookmarksEngine(Service); 1.107 + let store = engine._store; 1.108 + let server = serverForFoo(engine); 1.109 + new SyncTestingInfrastructure(server.server); 1.110 + 1.111 + let collection = server.user("foo").collection("bookmarks"); 1.112 + 1.113 + try { 1.114 + 1.115 + let folder1_id = PlacesUtils.bookmarks.createFolder( 1.116 + PlacesUtils.bookmarks.toolbarFolder, "Folder 1", 0); 1.117 + let folder1_guid = store.GUIDForId(folder1_id); 1.118 + 1.119 + let fxuri = Utils.makeURI("http://getfirefox.com/"); 1.120 + let tburi = Utils.makeURI("http://getthunderbird.com/"); 1.121 + 1.122 + let bmk1_id = PlacesUtils.bookmarks.insertBookmark( 1.123 + folder1_id, fxuri, PlacesUtils.bookmarks.DEFAULT_INDEX, "Get Firefox!"); 1.124 + let bmk1_guid = store.GUIDForId(bmk1_id); 1.125 + let bmk2_id = PlacesUtils.bookmarks.insertBookmark( 1.126 + folder1_id, tburi, PlacesUtils.bookmarks.DEFAULT_INDEX, "Get Thunderbird!"); 1.127 + let bmk2_guid = store.GUIDForId(bmk2_id); 1.128 + 1.129 + // Create a server record for folder1 where we flip the order of 1.130 + // the children. 1.131 + let folder1_payload = store.createRecord(folder1_guid).cleartext; 1.132 + folder1_payload.children.reverse(); 1.133 + collection.insert(folder1_guid, encryptPayload(folder1_payload)); 1.134 + 1.135 + // Create a bogus record that when synced down will provoke a 1.136 + // network error which in turn provokes an exception in _processIncoming. 1.137 + const BOGUS_GUID = "zzzzzzzzzzzz"; 1.138 + let bogus_record = collection.insert(BOGUS_GUID, "I'm a bogus record!"); 1.139 + bogus_record.get = function get() { 1.140 + throw "Sync this!"; 1.141 + }; 1.142 + 1.143 + // Make the 10 minutes old so it will only be synced in the toFetch phase. 1.144 + bogus_record.modified = Date.now() / 1000 - 60 * 10; 1.145 + engine.lastSync = Date.now() / 1000 - 60; 1.146 + engine.toFetch = [BOGUS_GUID]; 1.147 + 1.148 + let error; 1.149 + try { 1.150 + engine.sync(); 1.151 + } catch(ex) { 1.152 + error = ex; 1.153 + } 1.154 + do_check_true(!!error); 1.155 + 1.156 + // Verify that the bookmark order has been applied. 1.157 + let new_children = store.createRecord(folder1_guid).children; 1.158 + do_check_eq(new_children.length, 2); 1.159 + do_check_eq(new_children[0], folder1_payload.children[0]); 1.160 + do_check_eq(new_children[1], folder1_payload.children[1]); 1.161 + 1.162 + do_check_eq(PlacesUtils.bookmarks.getItemIndex(bmk1_id), 1); 1.163 + do_check_eq(PlacesUtils.bookmarks.getItemIndex(bmk2_id), 0); 1.164 + 1.165 + } finally { 1.166 + store.wipe(); 1.167 + Svc.Prefs.resetBranch(""); 1.168 + Service.recordManager.clearCache(); 1.169 + server.stop(run_next_test); 1.170 + } 1.171 +}); 1.172 + 1.173 +add_task(function test_restorePromptsReupload() { 1.174 + _("Ensure that restoring from a backup will reupload all records."); 1.175 + let engine = new BookmarksEngine(Service); 1.176 + let store = engine._store; 1.177 + let server = serverForFoo(engine); 1.178 + new SyncTestingInfrastructure(server.server); 1.179 + 1.180 + let collection = server.user("foo").collection("bookmarks"); 1.181 + 1.182 + Svc.Obs.notify("weave:engine:start-tracking"); // We skip usual startup... 1.183 + 1.184 + try { 1.185 + 1.186 + let folder1_id = PlacesUtils.bookmarks.createFolder( 1.187 + PlacesUtils.bookmarks.toolbarFolder, "Folder 1", 0); 1.188 + let folder1_guid = store.GUIDForId(folder1_id); 1.189 + _("Folder 1: " + folder1_id + ", " + folder1_guid); 1.190 + 1.191 + let fxuri = Utils.makeURI("http://getfirefox.com/"); 1.192 + let tburi = Utils.makeURI("http://getthunderbird.com/"); 1.193 + 1.194 + _("Create a single record."); 1.195 + let bmk1_id = PlacesUtils.bookmarks.insertBookmark( 1.196 + folder1_id, fxuri, PlacesUtils.bookmarks.DEFAULT_INDEX, "Get Firefox!"); 1.197 + let bmk1_guid = store.GUIDForId(bmk1_id); 1.198 + _("Get Firefox!: " + bmk1_id + ", " + bmk1_guid); 1.199 + 1.200 + 1.201 + let dirSvc = Cc["@mozilla.org/file/directory_service;1"] 1.202 + .getService(Ci.nsIProperties); 1.203 + 1.204 + let backupFile = dirSvc.get("TmpD", Ci.nsILocalFile); 1.205 + 1.206 + _("Make a backup."); 1.207 + backupFile.append("t_b_e_" + Date.now() + ".json"); 1.208 + 1.209 + _("Backing up to file " + backupFile.path); 1.210 + backupFile.create(Ci.nsILocalFile.NORMAL_FILE_TYPE, 0600); 1.211 + yield BookmarkJSONUtils.exportToFile(backupFile); 1.212 + 1.213 + _("Create a different record and sync."); 1.214 + let bmk2_id = PlacesUtils.bookmarks.insertBookmark( 1.215 + folder1_id, tburi, PlacesUtils.bookmarks.DEFAULT_INDEX, "Get Thunderbird!"); 1.216 + let bmk2_guid = store.GUIDForId(bmk2_id); 1.217 + _("Get Thunderbird!: " + bmk2_id + ", " + bmk2_guid); 1.218 + 1.219 + PlacesUtils.bookmarks.removeItem(bmk1_id); 1.220 + 1.221 + let error; 1.222 + try { 1.223 + engine.sync(); 1.224 + } catch(ex) { 1.225 + error = ex; 1.226 + _("Got error: " + Utils.exceptionStr(ex)); 1.227 + } 1.228 + do_check_true(!error); 1.229 + 1.230 + _("Verify that there's only one bookmark on the server, and it's Thunderbird."); 1.231 + // Of course, there's also the Bookmarks Toolbar and Bookmarks Menu... 1.232 + let wbos = collection.keys(function (id) { 1.233 + return ["menu", "toolbar", "mobile", folder1_guid].indexOf(id) == -1; 1.234 + }); 1.235 + do_check_eq(wbos.length, 1); 1.236 + do_check_eq(wbos[0], bmk2_guid); 1.237 + 1.238 + _("Now restore from a backup."); 1.239 + yield BookmarkJSONUtils.importFromFile(backupFile, true); 1.240 + 1.241 + _("Ensure we have the bookmarks we expect locally."); 1.242 + let guids = store.getAllIDs(); 1.243 + _("GUIDs: " + JSON.stringify(guids)); 1.244 + let found = false; 1.245 + let count = 0; 1.246 + let newFX; 1.247 + for (let guid in guids) { 1.248 + count++; 1.249 + let id = store.idForGUID(guid, true); 1.250 + // Only one bookmark, so _all_ should be Firefox! 1.251 + if (PlacesUtils.bookmarks.getItemType(id) == PlacesUtils.bookmarks.TYPE_BOOKMARK) { 1.252 + let uri = PlacesUtils.bookmarks.getBookmarkURI(id); 1.253 + _("Found URI " + uri.spec + " for GUID " + guid); 1.254 + do_check_eq(uri.spec, fxuri.spec); 1.255 + newFX = guid; // Save the new GUID after restore. 1.256 + found = true; // Only runs if the above check passes. 1.257 + } 1.258 + } 1.259 + _("We found it: " + found); 1.260 + do_check_true(found); 1.261 + 1.262 + _("Have the correct number of IDs locally, too."); 1.263 + do_check_eq(count, ["menu", "toolbar", folder1_id, bmk1_id].length); 1.264 + 1.265 + _("Sync again. This'll wipe bookmarks from the server."); 1.266 + try { 1.267 + engine.sync(); 1.268 + } catch(ex) { 1.269 + error = ex; 1.270 + _("Got error: " + Utils.exceptionStr(ex)); 1.271 + } 1.272 + do_check_true(!error); 1.273 + 1.274 + _("Verify that there's only one bookmark on the server, and it's Firefox."); 1.275 + // Of course, there's also the Bookmarks Toolbar and Bookmarks Menu... 1.276 + let payloads = server.user("foo").collection("bookmarks").payloads(); 1.277 + let bookmarkWBOs = payloads.filter(function (wbo) { 1.278 + return wbo.type == "bookmark"; 1.279 + }); 1.280 + let folderWBOs = payloads.filter(function (wbo) { 1.281 + return ((wbo.type == "folder") && 1.282 + (wbo.id != "menu") && 1.283 + (wbo.id != "toolbar")); 1.284 + }); 1.285 + 1.286 + do_check_eq(bookmarkWBOs.length, 1); 1.287 + do_check_eq(bookmarkWBOs[0].id, newFX); 1.288 + do_check_eq(bookmarkWBOs[0].bmkUri, fxuri.spec); 1.289 + do_check_eq(bookmarkWBOs[0].title, "Get Firefox!"); 1.290 + 1.291 + _("Our old friend Folder 1 is still in play."); 1.292 + do_check_eq(folderWBOs.length, 1); 1.293 + do_check_eq(folderWBOs[0].title, "Folder 1"); 1.294 + 1.295 + } finally { 1.296 + store.wipe(); 1.297 + Svc.Prefs.resetBranch(""); 1.298 + Service.recordManager.clearCache(); 1.299 + let deferred = Promise.defer(); 1.300 + server.stop(deferred.resolve); 1.301 + yield deferred.promise; 1.302 + } 1.303 +}); 1.304 + 1.305 +function FakeRecord(constructor, r) { 1.306 + constructor.call(this, "bookmarks", r.id); 1.307 + for (let x in r) { 1.308 + this[x] = r[x]; 1.309 + } 1.310 +} 1.311 + 1.312 +// Bug 632287. 1.313 +add_test(function test_mismatched_types() { 1.314 + _("Ensure that handling a record that changes type causes deletion " + 1.315 + "then re-adding."); 1.316 + 1.317 + let oldRecord = { 1.318 + "id": "l1nZZXfB8nC7", 1.319 + "type":"folder", 1.320 + "parentName":"Bookmarks Toolbar", 1.321 + "title":"Innerst i Sneglehode", 1.322 + "description":null, 1.323 + "parentid": "toolbar" 1.324 + }; 1.325 + 1.326 + let newRecord = { 1.327 + "id": "l1nZZXfB8nC7", 1.328 + "type":"livemark", 1.329 + "siteUri":"http://sneglehode.wordpress.com/", 1.330 + "feedUri":"http://sneglehode.wordpress.com/feed/", 1.331 + "parentName":"Bookmarks Toolbar", 1.332 + "title":"Innerst i Sneglehode", 1.333 + "description":null, 1.334 + "children": 1.335 + ["HCRq40Rnxhrd", "YeyWCV1RVsYw", "GCceVZMhvMbP", "sYi2hevdArlF", 1.336 + "vjbZlPlSyGY8", "UtjUhVyrpeG6", "rVq8WMG2wfZI", "Lx0tcy43ZKhZ", 1.337 + "oT74WwV8_j4P", "IztsItWVSo3-"], 1.338 + "parentid": "toolbar" 1.339 + }; 1.340 + 1.341 + let engine = new BookmarksEngine(Service); 1.342 + let store = engine._store; 1.343 + let server = serverForFoo(engine); 1.344 + new SyncTestingInfrastructure(server.server); 1.345 + 1.346 + _("GUID: " + store.GUIDForId(6, true)); 1.347 + 1.348 + try { 1.349 + let bms = PlacesUtils.bookmarks; 1.350 + let oldR = new FakeRecord(BookmarkFolder, oldRecord); 1.351 + let newR = new FakeRecord(Livemark, newRecord); 1.352 + oldR._parent = PlacesUtils.bookmarks.toolbarFolder; 1.353 + newR._parent = PlacesUtils.bookmarks.toolbarFolder; 1.354 + 1.355 + store.applyIncoming(oldR); 1.356 + _("Applied old. It's a folder."); 1.357 + let oldID = store.idForGUID(oldR.id); 1.358 + _("Old ID: " + oldID); 1.359 + do_check_eq(bms.getItemType(oldID), bms.TYPE_FOLDER); 1.360 + do_check_false(PlacesUtils.annotations 1.361 + .itemHasAnnotation(oldID, PlacesUtils.LMANNO_FEEDURI)); 1.362 + 1.363 + store.applyIncoming(newR); 1.364 + let newID = store.idForGUID(newR.id); 1.365 + _("New ID: " + newID); 1.366 + 1.367 + _("Applied new. It's a livemark."); 1.368 + do_check_eq(bms.getItemType(newID), bms.TYPE_FOLDER); 1.369 + do_check_true(PlacesUtils.annotations 1.370 + .itemHasAnnotation(newID, PlacesUtils.LMANNO_FEEDURI)); 1.371 + 1.372 + } finally { 1.373 + store.wipe(); 1.374 + Svc.Prefs.resetBranch(""); 1.375 + Service.recordManager.clearCache(); 1.376 + server.stop(run_next_test); 1.377 + } 1.378 +}); 1.379 + 1.380 +add_test(function test_bookmark_guidMap_fail() { 1.381 + _("Ensure that failures building the GUID map cause early death."); 1.382 + 1.383 + let engine = new BookmarksEngine(Service); 1.384 + let store = engine._store; 1.385 + 1.386 + let store = engine._store; 1.387 + let server = serverForFoo(engine); 1.388 + let coll = server.user("foo").collection("bookmarks"); 1.389 + new SyncTestingInfrastructure(server.server); 1.390 + 1.391 + // Add one item to the server. 1.392 + let itemID = PlacesUtils.bookmarks.createFolder( 1.393 + PlacesUtils.bookmarks.toolbarFolder, "Folder 1", 0); 1.394 + let itemGUID = store.GUIDForId(itemID); 1.395 + let itemPayload = store.createRecord(itemGUID).cleartext; 1.396 + coll.insert(itemGUID, encryptPayload(itemPayload)); 1.397 + 1.398 + engine.lastSync = 1; // So we don't back up. 1.399 + 1.400 + // Make building the GUID map fail. 1.401 + store.getAllIDs = function () { throw "Nooo"; }; 1.402 + 1.403 + // Ensure that we throw when accessing _guidMap. 1.404 + engine._syncStartup(); 1.405 + _("No error."); 1.406 + do_check_false(engine._guidMapFailed); 1.407 + 1.408 + _("We get an error if building _guidMap fails in use."); 1.409 + let err; 1.410 + try { 1.411 + _(engine._guidMap); 1.412 + } catch (ex) { 1.413 + err = ex; 1.414 + } 1.415 + do_check_eq(err.code, Engine.prototype.eEngineAbortApplyIncoming); 1.416 + do_check_eq(err.cause, "Nooo"); 1.417 + 1.418 + _("We get an error and abort during processIncoming."); 1.419 + err = undefined; 1.420 + try { 1.421 + engine._processIncoming(); 1.422 + } catch (ex) { 1.423 + err = ex; 1.424 + } 1.425 + do_check_eq(err, "Nooo"); 1.426 + 1.427 + server.stop(run_next_test); 1.428 +}); 1.429 + 1.430 +add_test(function test_bookmark_is_taggable() { 1.431 + let engine = new BookmarksEngine(Service); 1.432 + let store = engine._store; 1.433 + 1.434 + do_check_true(store.isTaggable("bookmark")); 1.435 + do_check_true(store.isTaggable("microsummary")); 1.436 + do_check_true(store.isTaggable("query")); 1.437 + do_check_false(store.isTaggable("folder")); 1.438 + do_check_false(store.isTaggable("livemark")); 1.439 + do_check_false(store.isTaggable(null)); 1.440 + do_check_false(store.isTaggable(undefined)); 1.441 + do_check_false(store.isTaggable("")); 1.442 + 1.443 + run_next_test(); 1.444 +}); 1.445 + 1.446 +add_test(function test_bookmark_tag_but_no_uri() { 1.447 + _("Ensure that a bookmark record with tags, but no URI, doesn't throw an exception."); 1.448 + 1.449 + let engine = new BookmarksEngine(Service); 1.450 + let store = engine._store; 1.451 + 1.452 + // We're simply checking that no exception is thrown, so 1.453 + // no actual checks in this test. 1.454 + 1.455 + store._tagURI(null, ["foo"]); 1.456 + store._tagURI(null, null); 1.457 + store._tagURI(Utils.makeURI("about:fake"), null); 1.458 + 1.459 + let record = { 1.460 + _parent: PlacesUtils.bookmarks.toolbarFolder, 1.461 + id: Utils.makeGUID(), 1.462 + description: "", 1.463 + tags: ["foo"], 1.464 + title: "Taggy tag", 1.465 + type: "folder" 1.466 + }; 1.467 + 1.468 + // Because update() walks the cleartext. 1.469 + record.cleartext = record; 1.470 + 1.471 + store.create(record); 1.472 + record.tags = ["bar"]; 1.473 + store.update(record); 1.474 + 1.475 + run_next_test(); 1.476 +}); 1.477 + 1.478 +add_test(function test_misreconciled_root() { 1.479 + _("Ensure that we don't reconcile an arbitrary record with a root."); 1.480 + 1.481 + let engine = new BookmarksEngine(Service); 1.482 + let store = engine._store; 1.483 + let server = serverForFoo(engine); 1.484 + 1.485 + // Log real hard for this test. 1.486 + store._log.trace = store._log.debug; 1.487 + engine._log.trace = engine._log.debug; 1.488 + 1.489 + engine._syncStartup(); 1.490 + 1.491 + // Let's find out where the toolbar is right now. 1.492 + let toolbarBefore = store.createRecord("toolbar", "bookmarks"); 1.493 + let toolbarIDBefore = store.idForGUID("toolbar"); 1.494 + do_check_neq(-1, toolbarIDBefore); 1.495 + 1.496 + let parentGUIDBefore = toolbarBefore.parentid; 1.497 + let parentIDBefore = store.idForGUID(parentGUIDBefore); 1.498 + do_check_neq(-1, parentIDBefore); 1.499 + do_check_eq("string", typeof(parentGUIDBefore)); 1.500 + 1.501 + _("Current parent: " + parentGUIDBefore + " (" + parentIDBefore + ")."); 1.502 + 1.503 + let to_apply = { 1.504 + id: "zzzzzzzzzzzz", 1.505 + type: "folder", 1.506 + title: "Bookmarks Toolbar", 1.507 + description: "Now you're for it.", 1.508 + parentName: "", 1.509 + parentid: "mobile", // Why not? 1.510 + children: [], 1.511 + }; 1.512 + 1.513 + let rec = new FakeRecord(BookmarkFolder, to_apply); 1.514 + let encrypted = encryptPayload(rec.cleartext); 1.515 + encrypted.decrypt = function () { 1.516 + for (let x in rec) { 1.517 + encrypted[x] = rec[x]; 1.518 + } 1.519 + }; 1.520 + 1.521 + _("Applying record."); 1.522 + engine._processIncoming({ 1.523 + get: function () { 1.524 + this.recordHandler(encrypted); 1.525 + return {success: true} 1.526 + }, 1.527 + }); 1.528 + 1.529 + // Ensure that afterwards, toolbar is still there. 1.530 + // As of 2012-12-05, this only passes because Places doesn't use "toolbar" as 1.531 + // the real GUID, instead using a generated one. Sync does the translation. 1.532 + let toolbarAfter = store.createRecord("toolbar", "bookmarks"); 1.533 + let parentGUIDAfter = toolbarAfter.parentid; 1.534 + let parentIDAfter = store.idForGUID(parentGUIDAfter); 1.535 + do_check_eq(store.GUIDForId(toolbarIDBefore), "toolbar"); 1.536 + do_check_eq(parentGUIDBefore, parentGUIDAfter); 1.537 + do_check_eq(parentIDBefore, parentIDAfter); 1.538 + 1.539 + server.stop(run_next_test); 1.540 +}); 1.541 + 1.542 +function run_test() { 1.543 + initTestLogging("Trace"); 1.544 + generateNewKeys(Service.collectionKeys); 1.545 + run_next_test(); 1.546 +}