gecko/services/sync/tests/unit/test_bookmark_smart_bookmarks.js

245 lines
8.3 KiB
JavaScript

Cu.import("resource://services-sync/engines.js");
Cu.import("resource://services-sync/engines/bookmarks.js");
Cu.import("resource://services-sync/record.js");
Cu.import("resource://services-sync/log4moz.js");
Cu.import("resource://services-sync/util.js");
Cu.import("resource://services-sync/service.js");
Cu.import("resource://gre/modules/PlacesUtils.jsm");
const SMART_BOOKMARKS_ANNO = "Places/SmartBookmark";
var IOService = Cc["@mozilla.org/network/io-service;1"]
.getService(Ci.nsIIOService);
("http://www.mozilla.com", null, null);
Engines.register(BookmarksEngine);
let engine = Engines.get("bookmarks");
let store = engine._store;
// Clean up after other tests. Only necessary in XULRunner.
store.wipe();
var syncTesting = new SyncTestingInfrastructure();
function newSmartBookmark(parent, uri, position, title, queryID) {
let id = PlacesUtils.bookmarks.insertBookmark(parent, uri, position, title);
PlacesUtils.annotations.setItemAnnotation(id, SMART_BOOKMARKS_ANNO,
queryID, 0,
PlacesUtils.annotations.EXPIRE_NEVER);
return id;
}
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);
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);
startCount = smartBookmarkCount();
}
function serverForFoo(engine) {
return serverForUsers({"foo": "password"}, {
meta: {global: {engines: {bookmarks: {version: engine.version,
syncID: engine.syncID}}}},
bookmarks: {}
});
}
// Verify that Places smart bookmarks have their annotation uploaded and
// handled locally.
add_test(function test_annotation_uploaded() {
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 parent = PlacesUtils.toolbarFolderId;
let uri =
Utils.makeURI("place:redirectsMode=" +
Ci.nsINavHistoryQueryOptions.REDIRECTS_MODE_TARGET +
"&sort=" +
Ci.nsINavHistoryQueryOptions.SORT_BY_VISITCOUNT_DESCENDING +
"&maxResults=10");
let title = "Most Visited";
let mostVisitedID = newSmartBookmark(parent, uri, -1, title, "MostVisited");
_("New item ID: " + mostVisitedID);
do_check_true(!!mostVisitedID);
let annoValue = PlacesUtils.annotations.getItemAnnotation(mostVisitedID,
SMART_BOOKMARKS_ANNO);
_("Anno: " + annoValue);
do_check_eq("MostVisited", annoValue);
let guid = store.GUIDForId(mostVisitedID);
_("GUID: " + guid);
do_check_true(!!guid);
_("Create record object and verify that it's sane.");
let record = store.createRecord(guid);
do_check_true(record instanceof Bookmark);
do_check_true(record instanceof BookmarkQuery);
do_check_eq(record.bmkUri, uri.spec);
_("Make sure the new record carries with it the annotation.");
do_check_eq("MostVisited", record.queryId);
_("Our count has increased since we started.");
do_check_eq(smartBookmarkCount(), startCount + 1);
_("Sync record to the server.");
Svc.Prefs.set("username", "foo");
Service.serverURL = "http://localhost:8080/";
Service.clusterURL = "http://localhost:8080/";
let server = serverForFoo(engine);
let collection = server.user("foo").collection("bookmarks");
try {
engine.sync();
let wbos = collection.keys(function (id) {
return ["menu", "toolbar", "mobile"].indexOf(id) == -1;
});
do_check_eq(wbos.length, 1);
_("Verify that the server WBO has the annotation.");
let serverGUID = wbos[0];
do_check_eq(serverGUID, guid);
let serverWBO = collection.wbo(serverGUID);
do_check_true(!!serverWBO);
let body = JSON.parse(JSON.parse(serverWBO.payload).ciphertext);
do_check_eq(body.queryId, "MostVisited");
_("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.setItemGUID(mostVisitedID, "abcdefabcdef");
PlacesUtils.bookmarks.setItemTitle(mostVisitedID, "Not Most Visited");
PlacesUtils.bookmarks.changeBookmarkURI(
mostVisitedID, Utils.makeURI("http://something/else"));
PlacesUtils.annotations.removeItemAnnotation(mostVisitedID,
SMART_BOOKMARKS_ANNO);
store.wipe();
engine.resetClient();
do_check_eq(smartBookmarkCount(), startCount);
_("Sync. Verify that the downloaded record carries the annotation.");
engine.sync();
_("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 = store.idForGUID(serverGUID);
let newAnnoValue = PlacesUtils.annotations.getItemAnnotation(
newID, SMART_BOOKMARKS_ANNO);
do_check_eq(newAnnoValue, "MostVisited");
do_check_eq(PlacesUtils.bookmarks.getBookmarkURI(newID).spec, uri.spec);
_("Test updating.");
let newRecord = store.createRecord(serverGUID);
do_check_eq(newRecord.queryId, newAnnoValue);
newRecord.queryId = "LeastVisited";
store.update(newRecord);
do_check_eq("LeastVisited", PlacesUtils.annotations.getItemAnnotation(
newID, SMART_BOOKMARKS_ANNO));
} finally {
// Clean up.
store.wipe();
Svc.Prefs.resetBranch("");
Records.clearCache();
server.stop(run_next_test);
}
});
add_test(function test_smart_bookmarks_duped() {
let parent = PlacesUtils.toolbarFolderId;
let uri =
Utils.makeURI("place:redirectsMode=" +
Ci.nsINavHistoryQueryOptions.REDIRECTS_MODE_TARGET +
"&sort=" +
Ci.nsINavHistoryQueryOptions.SORT_BY_VISITCOUNT_DESCENDING +
"&maxResults=10");
let title = "Most Visited";
let mostVisitedID = newSmartBookmark(parent, uri, -1, title, "MostVisited");
let mostVisitedGUID = store.GUIDForId(mostVisitedID);
let record = store.createRecord(mostVisitedGUID);
_("Prepare sync.");
Svc.Prefs.set("username", "foo");
Service.serverURL = "http://localhost:8080/";
Service.clusterURL = "http://localhost:8080/";
let server = serverForFoo(engine);
let collection = server.user("foo").collection("bookmarks");
try {
engine._syncStartup();
_("Verify that mapDupe uses the anno, discovering a dupe regardless of URI.");
do_check_eq(mostVisitedGUID, engine._mapDupe(record));
record.bmkUri = "http://foo/";
do_check_eq(mostVisitedGUID, engine._mapDupe(record));
do_check_neq(PlacesUtils.bookmarks.getBookmarkURI(mostVisitedID).spec,
record.bmkUri);
_("Verify that different annos don't dupe.");
let other = new BookmarkQuery("bookmarks", "abcdefabcdef");
other.queryId = "LeastVisited";
other.parentName = "Bookmarks Toolbar";
other.bmkUri = "place:foo";
other.title = "";
do_check_eq(undefined, engine._findDupe(other));
_("Handle records without a queryId entry.");
record.bmkUri = uri;
delete record.queryId;
do_check_eq(mostVisitedGUID, engine._mapDupe(record));
engine._syncFinish();
} finally {
// Clean up.
store.wipe();
server.stop(do_test_finished);
Svc.Prefs.resetBranch("");
Records.clearCache();
}
});
function run_test() {
initTestLogging("Trace");
Log4Moz.repository.getLogger("Sync.Engine.Bookmarks").level = Log4Moz.Level.Trace;
generateNewKeys();
run_next_test();
}