diff options
Diffstat (limited to 'toolkit/components/places/tests/bookmarks/test_async_observers.js')
-rw-r--r-- | toolkit/components/places/tests/bookmarks/test_async_observers.js | 177 |
1 files changed, 177 insertions, 0 deletions
diff --git a/toolkit/components/places/tests/bookmarks/test_async_observers.js b/toolkit/components/places/tests/bookmarks/test_async_observers.js new file mode 100644 index 000000000..86d48ac24 --- /dev/null +++ b/toolkit/components/places/tests/bookmarks/test_async_observers.js @@ -0,0 +1,177 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/* This test checks that bookmarks service is correctly forwarding async + * events like visit or favicon additions. */ + +const NOW = Date.now() * 1000; + +var observer = { + bookmarks: [], + observedBookmarks: 0, + observedVisitId: 0, + deferred: null, + + /** + * Returns a promise that is resolved when the observer determines that the + * test can continue. This is required rather than calling run_next_test + * directly in the observer because there are cases where we must wait for + * other asynchronous events to be completed in addition to this. + */ + setupCompletionPromise: function () + { + this.observedBookmarks = 0; + this.deferred = Promise.defer(); + return this.deferred.promise; + }, + + onBeginUpdateBatch: function () {}, + onEndUpdateBatch: function () {}, + onItemAdded: function () {}, + onItemRemoved: function () {}, + onItemMoved: function () {}, + onItemChanged: function(aItemId, aProperty, aIsAnnotation, aNewValue, + aLastModified, aItemType) + { + do_print("Check that we got the correct change information."); + do_check_neq(this.bookmarks.indexOf(aItemId), -1); + if (aProperty == "favicon") { + do_check_false(aIsAnnotation); + do_check_eq(aNewValue, SMALLPNG_DATA_URI.spec); + do_check_eq(aLastModified, 0); + do_check_eq(aItemType, PlacesUtils.bookmarks.TYPE_BOOKMARK); + } + else if (aProperty == "cleartime") { + do_check_false(aIsAnnotation); + do_check_eq(aNewValue, ""); + do_check_eq(aLastModified, 0); + do_check_eq(aItemType, PlacesUtils.bookmarks.TYPE_BOOKMARK); + } + else { + do_throw("Unexpected property change " + aProperty); + } + + if (++this.observedBookmarks == this.bookmarks.length) { + this.deferred.resolve(); + } + }, + onItemVisited: function(aItemId, aVisitId, aTime) + { + do_print("Check that we got the correct visit information."); + do_check_neq(this.bookmarks.indexOf(aItemId), -1); + this.observedVisitId = aVisitId; + do_check_eq(aTime, NOW); + if (++this.observedBookmarks == this.bookmarks.length) { + this.deferred.resolve(); + } + }, + + QueryInterface: XPCOMUtils.generateQI([ + Ci.nsINavBookmarkObserver, + ]) +}; +PlacesUtils.bookmarks.addObserver(observer, false); + +add_task(function* test_add_visit() +{ + let observerPromise = observer.setupCompletionPromise(); + + // Add a visit to the bookmark and wait for the observer. + let visitId; + let deferUpdatePlaces = Promise.defer(); + PlacesUtils.asyncHistory.updatePlaces({ + uri: NetUtil.newURI("http://book.ma.rk/"), + visits: [{ transitionType: TRANSITION_TYPED, visitDate: NOW }] + }, { + handleError: function TAV_handleError() { + deferUpdatePlaces.reject(new Error("Unexpected error in adding visit.")); + }, + handleResult: function (aPlaceInfo) { + visitId = aPlaceInfo.visits[0].visitId; + }, + handleCompletion: function TAV_handleCompletion() { + deferUpdatePlaces.resolve(); + } + }); + + // Wait for both the observer and the asynchronous update, in any order. + yield deferUpdatePlaces.promise; + yield observerPromise; + + // Check that both asynchronous results are consistent. + do_check_eq(observer.observedVisitId, visitId); +}); + +add_task(function* test_add_icon() +{ + let observerPromise = observer.setupCompletionPromise(); + PlacesUtils.favicons.setAndFetchFaviconForPage(NetUtil.newURI("http://book.ma.rk/"), + SMALLPNG_DATA_URI, true, + PlacesUtils.favicons.FAVICON_LOAD_NON_PRIVATE, + null, + Services.scriptSecurityManager.getSystemPrincipal()); + yield observerPromise; +}); + +add_task(function* test_remove_page() +{ + let observerPromise = observer.setupCompletionPromise(); + PlacesUtils.history.removePage(NetUtil.newURI("http://book.ma.rk/")); + yield observerPromise; +}); + +add_task(function cleanup() +{ + PlacesUtils.bookmarks.removeObserver(observer, false); +}); + +add_task(function* shutdown() +{ + // Check that async observers don't try to create async statements after + // shutdown. That would cause assertions, since the async thread is gone + // already. Note that in such a case the notifications are not fired, so we + // cannot test for them. + // Put an history notification that triggers AsyncGetBookmarksForURI between + // asyncClose() and the actual connection closing. Enqueuing a main-thread + // event just after places-will-close-connection should ensure it runs before + // places-connection-closed. + // Notice this code is not using helpers cause it depends on a very specific + // order, a change in the helpers code could make this test useless. + let deferred = Promise.defer(); + + Services.obs.addObserver(function onNotification() { + Services.obs.removeObserver(onNotification, "places-will-close-connection"); + do_check_true(true, "Observed fake places shutdown"); + + Services.tm.mainThread.dispatch(() => { + // WARNING: this is very bad, never use out of testing code. + PlacesUtils.bookmarks.QueryInterface(Ci.nsINavHistoryObserver) + .onPageChanged(NetUtil.newURI("http://book.ma.rk/"), + Ci.nsINavHistoryObserver.ATTRIBUTE_FAVICON, + "test", "test"); + deferred.resolve(promiseTopicObserved("places-connection-closed")); + }, Ci.nsIThread.DISPATCH_NORMAL); + }, "places-will-close-connection", false); + shutdownPlaces(); + + yield deferred.promise; +}); + +function run_test() +{ + // Add multiple bookmarks to the same uri. + observer.bookmarks.push( + PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId, + NetUtil.newURI("http://book.ma.rk/"), + PlacesUtils.bookmarks.DEFAULT_INDEX, + "Bookmark") + ); + observer.bookmarks.push( + PlacesUtils.bookmarks.insertBookmark(PlacesUtils.toolbarFolderId, + NetUtil.newURI("http://book.ma.rk/"), + PlacesUtils.bookmarks.DEFAULT_INDEX, + "Bookmark") + ); + + run_next_test(); +} |